diff --git a/third_party/libjingle/source/AUTHORS b/third_party/libjingle/source/AUTHORS
deleted file mode 100644
index cbe3b77..0000000
--- a/third_party/libjingle/source/AUTHORS
+++ /dev/null
@@ -1,4 +0,0 @@
-Google Inc.
-Eric Rescorla, RTFM Inc.
-Pali Rohar
-Robert Nagy
diff --git a/third_party/libjingle/source/CHANGELOG b/third_party/libjingle/source/CHANGELOG
deleted file mode 100644
index ab264a1..0000000
--- a/third_party/libjingle/source/CHANGELOG
+++ /dev/null
@@ -1,138 +0,0 @@
-Libjingle
-
-0.6.6 - Dec 14, 2011
-  - Fix support for rtcp multiplexing (aka rtcp-mux).
-  - Add more support for FreeBSD and OpenBSD.
-  - Add more unit tests to session/phone.
-  - Add session/phone/mediarecorder.cc.
-  - Fixed httpportallocator tests.
-
-0.6.5 - Dec 8, 2011
-  - Add IPv6 support in SocketAddress.
-  - Change PeerConnectionFactory inteface.
-  - Bug fixes.
-
-0.6.4 - Nov 30, 2011
-  - Branch app/webrtc to app/webrtcv1.
-  - Add more base unit tests.
-  - Add xmllite unit tests.
-  - Refactoring and bug fixes
-
-0.6.3 - Oct 26, 2011
-  - Add media unit tests
-  - Improve OpenSSL support
-  - Add SSL unit tests
-  - Add DTLS support to SslStreamAdapter
-  - Add initial support for media processors
-  - Updated WebRTC voice and video engines
-
-0.6.2 - Oct 7, 2011
-  - Increase the video rtp buffer.
-  - Disable sound system for chromium build.
-  - Add basictype.h for NULL.
-  - Use the ref counted webrtc ADM/VCM.
-  - Add codereview.settings to use the webrtc codereview system.
-  - Add MediaSessionDescriptionFactory.
-
-0.6.1 - Sep 15, 2011
-  - Add dummydevicemanager.
-  - Remove underscores from the files names for app/webrtc folder.
-  - Remove PeerConnection OnLocalStreamInitialized callback.
-  - Fix webrtcjson.cc numeric locale formatting issue.
-  - Don't start playout until the local content has been set.
-
-0.6.0 - Sep 13, 2011
-  - Add pub sub support
-  - Add unit tests
-
-0.5.9 - Aug 31, 2011
-  - Add app/webrtc
-  - Add webrtcvoiceengine/webrtcvideoengine
-  - Add some unit tests
-  - Add XMPP MUC room config classes
-  - Update STUN support some more (RFC 5389)
-  - Add video output scaling
-  - Refactoring and bug fixes
-
-0.5.8 - July 1, 2011
-  - Support for loudest speaker detection
-
-0.5.7 - Jun 23, 2011
-  - Support for setting MUC display name
-  - Update STUN support to RFC5389
-  - Handle description-info message
-  - New call flag: --debugsrtp
-
-0.5.6 - Jun 2, 2011
-  - Improved mac socket server
-  - Add IqTask
-  - Flush output in examples/call
-  - Bug fixes
-
-0.5.5 - May 26, 2011
-  - Refactor async sockets
-  - Improve MUC joining
-  - Add OSX video renderer
-  - Bug fixes
-
-0.5.4 - May 13, 2011
-  - Support for MUC lookup by name
-  - Bug fixes
-
-0.5.3 - May 10, 2011
-  - Stream notification and selection.
-  - Better XEP-0045 support.
-  - Easier to create composite media engines where one part is fake.
-  - Make GtkVideoRenderer thread-safe.
-
-0.5.2 - Jan 11, 2010
-  - Fixed build on Windows 7 with VS 2010
-  - Fixed build on Windows x64
-  - Fixed build on Mac OSX
-  - Added option to examples/call to enable encryption
-  - Improved logging
-  - Bug fixes
-
-0.5.1 - Nov 2, 2010
-  - Added support for call encryption.
-  - Added addtional XEP-166 and XEP-167 features:
-    - Call redirection
-    - Candidates in session-accept or session-initiate
-  - Added support for bandwidth control.
-  - Added features in examples/call:
-    - bandwidth control on initiate or accept
-    - turn on/off SSL
-    - control signaling protocol
-    - send chat message
-
-0.5.0 - Sep 16, 2010
-  - Implemented Jingle protocols XEP-166 and XEP-167.
-  - Backward compatible with Google Talk Call Signaling protocol implemented
-    in previous versions.
-  - Builds on Windows, Linux, and Mac OS X with swtoolkit.
-  - Removed GipsLiteMediaEngine.
-  - Added video support.
-  - Added FileMediaEngine to support both voice and video via RTP dump.
-  - Many bug fixes.
-
-0.4.0 - Feb 01, 2007
-  - Updated protocol.
-  - Added relay server support.
-  - Added proxy detection support.
-  - Many other assorted changes.
-
-0.3.0 - Mar 16 2006
-  - New GipsLiteMediaEngine included to make calls using the GIPS
-    VoiceEngine Lite media componentry on Windows.
-
-0.2.0 - Jan 27 2006
-  - Windows build fixes with Visual Studio Express project files.
-  - Pseudo-TCP support provides TCP-like reliability over a P2PSocket
-  - TunnelSessionClient establishes sessions for reliably sending data
-    using Pseudo-TCP.
-  - A new pcp example application transfers files from one user to
-    another using TunnelSessionClient.
-  - TLS login support for both example applications.
-
-0.1.0 - Dec 15 2005
-  - Initial release.
diff --git a/third_party/libjingle/source/COPYING b/third_party/libjingle/source/COPYING
deleted file mode 100644
index d11f105..0000000
--- a/third_party/libjingle/source/COPYING
+++ /dev/null
@@ -1,25 +0,0 @@
-Copyright (c) 2004--2005, Google Inc.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
-
-    * Redistributions of source code must retain the above copyright notice,
-      this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above copyright notice,
-      this list of conditions and the following disclaimer in the documentation
-      and/or other materials provided with the distribution.
-    * The name of the author may not be used to endorse or promote products
-      derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
-GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY 
-WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
-SUCH DAMAGE.
\ No newline at end of file
diff --git a/third_party/libjingle/source/README b/third_party/libjingle/source/README
deleted file mode 100644
index 638d002..0000000
--- a/third_party/libjingle/source/README
+++ /dev/null
@@ -1,163 +0,0 @@
-Libjingle
-
-1. Introduction
-
-Libjingle is a set of components provided by Google to implement Jingle
-protocols XEP-166 (http://xmpp.org/extensions/xep-0166.html) and XEP-167
-(http://xmpp.org/extensions/xep-0167.html). Libjingle is also backward
-compatible with Google Talk Call Signaling
-(http://code.google.com/apis/talk/call_signaling.html). This package will
-create several static libraries you may link to your projects as needed.
-
--talk               - No source files in talk/, just these subdirectories
-|-base              - Contains basic low-level portable utility functions for
-|                     things like threads and sockets
-|-p2p               - The P2P stack
-  |-base            - Base p2p functionality
-  |-client          - Hooks to tie it into XMPP
-|-session           - Signaling
-  |-phone           - Signaling code specific to making phone calls
-    |-testdata      - Samples of RTP voice and video dump
-  |-tunnel          - Tunnel session and channel
-|-third_party       - Folder for third party libraries
-  |-libudev         - Folder containing libudev.h
-|-xmllite           - XML parser
-|-xmpp              - XMPP engine
-
-In addition, this package contains two examples in talk/examples which
-illustrate the basic concepts of how the provided classes work.
-
-2. How to Build
-
-2.1 Prerequisites
-
-Libjingle is built with swtoolkit (http://code.google.com/p/swtoolkit/), which
-is a set of extensions to the open-source SCons build tool (www.scons.org).
-
-  * First, install Python 2.4 or later from http://www.python.org/.
-    Please note that since swtoolkit only works with Python 2.x, you will
-    not be able to use Python 3.x.
-
-    python --version to confirm that python is in your path, and 2.4 or greater.
-
-  * Second, install the stand alone scons-local zip package 2.0.0 or later from
-    http://www.scons.org/download.php and set an environment variable,
-    SCONS_DIR, to point to the directory containing SCons.
-    For example, on Windows, download
-    http://sourceforge.net/projects/scons/files/scons-src/2.0.1/scons-local-2.0.1.zip
-    Unzip to C:\src\libjingle\scons-local\
-    set SCONS_DIR=C:\src\libjingle\scons-local\scons-local-2.0.1
-
-  * Third, install swtoolkit from http://code.google.com/p/swtoolkit/.
-    For example, on Windows download
-    http://code.google.com/p/swtoolkit/downloads/detail?name=swtoolkit.0.9.1.zip
-    Unzip to C:\src
-    Optionally add swtoolkit to path.  Otherwise call hammer.bat directly.
-    set PATH_TO_SWTOOLKIT=c:\src\swtoolkit
-    set PATH=%PATH_TO_SWTOOLKIT%;%PATH%
-
-  * Finally, download and install the unit test framework from
-    http://code.google.com/p/googletest/downloads/list
-    To install it, just unzip the package and put the file folder under
-    /talk/third_party/ directory and rename it from "gtest-x.x.x" to "gtest",
-    so that your folder structure looks like:
-    /talk/third_party/gtest/...
-
-2.2 libjingle
-
-Libjingle needs to be downloaded and patched
-
-  * First, install Libjingle.  Since this README lives within Libjingle,
-    this step is normally already done.
-    Libjingle home page is here http://code.google.com/p/libjingle/
-    For example, on Windows, download
-    http://libjingle.googlecode.com/files/libjingle-0.5.2.zip
-    unzip to C:\src\
-
-  * Second, Libjingle depends on two open-source projects, expat and srtp.
-    Download expat from http://sourceforge.net/projects/expat/ to
-    talk/third_party/expat-2.0.1/. Download srtp at
-    http://libjingle.googlecode.com/files/srtp-cvs.zip to
-    talk/third_party/srtp. Note that srtp-1.4.4 does not work since it misses
-    the extensions used by Libjingle.
-    If you put expat or srtp in a different directory, you need to edit
-    talk/libjingle.scons correspondingly.
-    rename srtp-cvs to srtp
-    For example, on Windows, download expat
-    http://sourceforge.net/projects/expat/files/expat/2.0.1/expat-2.0.1.tar.gz
-    Unzip to C:\src\libjingle-0.5.2\talk\third_party
-    Download srtp
-    http://libjingle.googlecode.com/files/srtp-cvs.zip
-    Unzip to C:\src\libjingle-0.5.2\talk\third_party
-    rename C:\src\libjingle-0.5.2\talk\third_party\srtp-cvs srtp
-
-  * Third, on Windows, copy config.h
-    copy talk\third_party\srtp\config.hw talk\third_party\srtp\crypto\include\config.h
-
-2.2 Build Libjingle under Linux or OS X
-  * On Linux, you need to install libssl-dev, libasound2-dev and gtk+2.0.
-  * Some optional new features in OpenSSL are only available in OpenSSL v1.0
-    and above. To build with new OpenSSL features, you need to add the
-    "HAS_OPENSSL_1_0" to the cppdefine under the
-    "talk.Library(env, name = jingle..." section in the "libjingle.scons" file.
-    Then download the OpenSSL v1.0 from the following URL:
-    http://www.openssl.org/source/openssl-1.0.0e.tar.gz
-    Unzip the downloaded package to the "third_party/openssl", such that it creates
-    the directory "third_party/openssl/include/", etc.
-  * To build Libjingle, first make sure the SCONS_DIR environment variable
-    is set correctly.
-  * Second, run talk/third_party/expat-2.0.1/configure and
-    talk/third_party/srtp/configure.
-  * Third, go to the talk/ directory and run $path_to_swtoolkit/hammer.sh. Run
-    $path_to_swtoolkit/hammer.sh --help for information on how to build for
-    different modes.
-
-2.3 Build Libjingle under Windows
-  * First, make sure the SCONS_DIR environment variable is set correctly and
-    Microsoft Visual Studio is installed.
-    dir %SCONS_DIR%
-    Should show a folder containing Scons\
-  * Second, go to the talk\ directory and run %PATH_TO_SWTOOLKIT%\hammer.bat.
-    To get help run:
-    %PATH_TO_SWTOOLKIT%\hammer.bat --help
-    different modes. You can run the last step under Visual Studio Command
-    Prompt if Visual Studio tools are not under the path environment variable.
-    Example to build call.exe
-    %PATH_TO_SWTOOLKIT%\hammer.bat
-    Example to build opt and dbg all programs
-    %PATH_TO_SWTOOLKIT%\hammer.bat --jobs=6 --verbose --mode=all all_programs
-
-
-The built binaries are under talk/build/dbg/staging or talk/build/opt/staging,
-depending on the build mode. When the build is complete, you can run the
-examples, login or call. For the call sample, you can specify the input and
-output RTP dump for voice and video. This package provides two samples of input
-RTP dump: voice.rtpdump is a single channel, 16Khz voice encoded with G722, and
-video.rtpdump is 320x240 video encoded with H264 AVC at 30 frames per second.
-These provided samples will inter-operate with Google Talk Video. If you use
-other input RTP dump, you may need to change the codecs in call_main.cc, lines
-215 - 222.
-
-Libjingle also builds two server tools, a relay server and a STUN server. The
-relay server may be used to relay traffic when a direct peer-to-peer connection
-could not be established. The STUN Server implements the STUN protocol for
-Simple Traversal of UDP over NAT. See the Libjingle Developer Guide at
-http://code.google.com/apis/talk/index.html for information about configuring a
-client to use this relay server and this STUN server.
-
-To use LinphoneMediaEngine, you need to perform the following additional steps:
-  * Download and install the "MediaStreamer" library on your
-    machine.
-  * Add the following lines into the libjingle.scons file.
-    In the "talk.Library(env, name = "libjingle",..." section, you need to add:
-      "HAVE_LINPHONE",
-      "HAVE_SPEEX",
-      "HAVE_ILBC",
-    to the "cppdefines = [".
-
-    In the "talk.App(env, name = "call",..." section, you need to add:
-      "mediastreamer",
-    to the "libs = [".
-  * In the libjingle.scons file, add the following line into the "srcs = [ ..."
-    section of the "libjingle" Library.
-      "session/phone/linphonemediaengine.cc",
diff --git a/third_party/libjingle/source/codereview.settings b/third_party/libjingle/source/codereview.settings
deleted file mode 100644
index b70057e..0000000
--- a/third_party/libjingle/source/codereview.settings
+++ /dev/null
@@ -1,9 +0,0 @@
-# This file is used by gcl to get repository specific information.
-CODE_REVIEW_SERVER: webrtc-codereview.appspot.com
-#CC_LIST:
-#VIEW_VC:
-#STATUS: 
-TRY_ON_UPLOAD: False
-#TRYSERVER_SVN_URL: 
-#GITCL_PREUPLOAD: 
-#GITCL_PREDCOMMIT: 
diff --git a/third_party/libjingle/source/talk/app/webrtc/peerconnection.h b/third_party/libjingle/source/talk/app/webrtc/peerconnection.h
deleted file mode 100644
index c28508f..0000000
--- a/third_party/libjingle/source/talk/app/webrtc/peerconnection.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_APP_WEBRTC_PEERCONNECTION_H_
-#define TALK_APP_WEBRTC_PEERCONNECTION_H_
-
-// TODO - Add a factory class or some kind of PeerConnection manager
-// to support multiple PeerConnection object instantiation. This class will
-// create ChannelManager object and pass it to PeerConnection object. Otherwise
-// each PeerConnection object will have its own ChannelManager hence MediaEngine
-// and VoiceEngine/VideoEngine.
-
-#include <string>
-
-namespace cricket {
-class VideoRenderer;
-}
-
-namespace talk_base {
-class Thread;
-}
-
-namespace webrtc {
-
-class PeerConnectionObserver {
- public:
-  // serialized signaling message
-  virtual void OnSignalingMessage(const std::string& msg) = 0;
-
-  // Triggered when a remote peer accepts a media connection.
-  virtual void OnAddStream(const std::string& stream_id, bool video) = 0;
-
-  // Triggered when a remote peer closes a media stream.
-  virtual void OnRemoveStream(const std::string& stream_id, bool video) = 0;
-
- protected:
-  // Dtor protected as objects shouldn't be deleted via this interface.
-  virtual ~PeerConnectionObserver() {}
-};
-
-class PeerConnection {
- public:
-  enum ReadyState {
-    NEW = 0,
-    NEGOTIATING,
-    ACTIVE,
-    CLOSED,
-  };
-
-  virtual ~PeerConnection() {}
-
-  // Register a listener
-  virtual void RegisterObserver(PeerConnectionObserver* observer) = 0;
-
-  // SignalingMessage in json format
-  virtual bool SignalingMessage(const std::string& msg) = 0;
-
-  // Asynchronously adds a local stream device to the peer
-  // connection.
-  virtual bool AddStream(const std::string& stream_id, bool video) = 0;
-
-  // Asynchronously removes a local stream device from the peer
-  // connection. The operation is complete when
-  // PeerConnectionObserver::OnRemoveStream is called.
-  virtual bool RemoveStream(const std::string& stream_id) = 0;
-
-  // Info the peerconnection that it is time to return the signaling
-  // information. The operation is complete when
-  // PeerConnectionObserver::OnSignalingMessage is called.
-  virtual bool Connect() = 0;
-
-  // Remove all the streams and tear down the session.
-  // After the Close() is called, the OnSignalingMessage will be invoked
-  // asynchronously. And before OnSignalingMessage is called,
-  // OnRemoveStream will be called for each stream that was active.
-  // TODO: Add an event such as onclose, or onreadystatechanged
-  // when the readystate reaches the closed state (no more streams in the
-  // peerconnection object.
-  virtual bool Close() = 0;
-
-  // Set the audio input & output devices based on the given device name.
-  // An empty device name means to use the default audio device.
-  virtual bool SetAudioDevice(const std::string& wave_in_device,
-                              const std::string& wave_out_device,
-                              int opts) = 0;
-
-  // Set the video renderer for the camera preview.
-  virtual bool SetLocalVideoRenderer(cricket::VideoRenderer* renderer) = 0;
-
-  // Set the video renderer for the specified stream.
-  virtual bool SetVideoRenderer(const std::string& stream_id,
-                                cricket::VideoRenderer* renderer) = 0;
-
-  // Set video capture device
-  // For Chromium the cam_device should use the capture session id.
-  // For standalone app, cam_device is the camera name. It will try to
-  // set the default capture device when cam_device is "".
-  virtual bool SetVideoCapture(const std::string& cam_device) = 0;
-
-  // Returns the state of the PeerConnection object.  See the ReadyState
-  // enum for valid values.
-  virtual ReadyState GetReadyState() = 0;
-};
-
-}  // namespace webrtc
-
-#endif  // TALK_APP_WEBRTC_PEERCONNECTION_H_
diff --git a/third_party/libjingle/source/talk/app/webrtc/peerconnectionfactory.cc b/third_party/libjingle/source/talk/app/webrtc/peerconnectionfactory.cc
deleted file mode 100644
index a3dac39..0000000
--- a/third_party/libjingle/source/talk/app/webrtc/peerconnectionfactory.cc
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/app/webrtc/peerconnectionfactory.h"
-
-#include "talk/app/webrtc/peerconnectionproxy.h"
-#include "talk/base/logging.h"
-#include "talk/p2p/client/basicportallocator.h"
-#include "talk/session/phone/channelmanager.h"
-
-namespace webrtc {
-
-PeerConnectionFactory::PeerConnectionFactory(
-    cricket::MediaEngineInterface* media_engine,
-    cricket::DeviceManagerInterface* device_manager,
-    talk_base::Thread* worker_thread)
-    : initialized_(false),
-      channel_manager_(new cricket::ChannelManager(media_engine,
-                                                   device_manager,
-                                                   worker_thread)) {
-}
-
-PeerConnectionFactory::PeerConnectionFactory(
-    talk_base::Thread* worker_thread)
-    : initialized_(false),
-      channel_manager_(new cricket::ChannelManager(worker_thread)) {
-}
-
-PeerConnectionFactory::~PeerConnectionFactory() {
-}
-
-bool PeerConnectionFactory::Initialize() {
-  ASSERT(channel_manager_.get() != NULL);
-  initialized_ = channel_manager_->Init();
-  return initialized_;
-}
-
-PeerConnection* PeerConnectionFactory::CreatePeerConnection(
-    cricket::PortAllocator* port_allocator,
-    talk_base::Thread* signaling_thread) {
-  PeerConnectionProxy* pc = NULL;
-  if (initialized_) {
-    pc =  new PeerConnectionProxy(
-        port_allocator, channel_manager_.get(), signaling_thread);
-    if (!pc->Init()) {
-      LOG(LERROR) << "Error in initializing PeerConnection";
-      delete pc;
-      pc = NULL;
-    }
-  } else {
-    LOG(LERROR) << "PeerConnectionFactory is not initialize";
-  }
-  return pc;
-}
-
-}  // namespace webrtc
diff --git a/third_party/libjingle/source/talk/app/webrtc/peerconnectionfactory.h b/third_party/libjingle/source/talk/app/webrtc/peerconnectionfactory.h
deleted file mode 100644
index ea509d6..0000000
--- a/third_party/libjingle/source/talk/app/webrtc/peerconnectionfactory.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_APP_WEBRTC_PEERCONNECTIONFACTORY_H_
-#define TALK_APP_WEBRTC_PEERCONNECTIONFACTORY_H_
-
-#include <string>
-#include <vector>
-
-#include "talk/base/scoped_ptr.h"
-
-namespace cricket {
-class ChannelManager;
-class DeviceManagerInterface;
-class MediaEngineInterface;
-class PortAllocator;
-}  // namespace cricket
-
-namespace talk_base {
-class SocketAddress;
-class Thread;
-}  // namespace talk_base
-
-namespace webrtc {
-
-class PeerConnection;
-
-class PeerConnectionFactory {
- public:
-  PeerConnectionFactory(cricket::MediaEngineInterface* media_engine,
-                        cricket::DeviceManagerInterface* device_manager,
-                        talk_base::Thread* worker_thread);
-  PeerConnectionFactory(talk_base::Thread* worker_thread);
-
-  virtual ~PeerConnectionFactory();
-  bool Initialize();
-
-  PeerConnection* CreatePeerConnection(
-      cricket::PortAllocator* port_allocator,
-      talk_base::Thread* signaling_thread);
-
- private:
-  bool initialized_;
-  talk_base::scoped_ptr<cricket::ChannelManager> channel_manager_;
-};
-
-}  // namespace webrtc
-
-#endif  // TALK_APP_WEBRTC_PEERCONNECTIONFACTORY_H_
-
diff --git a/third_party/libjingle/source/talk/app/webrtc/peerconnectionimpl.cc b/third_party/libjingle/source/talk/app/webrtc/peerconnectionimpl.cc
deleted file mode 100644
index 28e4685..0000000
--- a/third_party/libjingle/source/talk/app/webrtc/peerconnectionimpl.cc
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/app/webrtc/peerconnectionimpl.h"
-
-#include "talk/app/webrtc/webrtcjson.h"
-#include "talk/app/webrtc/webrtcsession.h"
-#include "talk/base/basicpacketsocketfactory.h"
-#include "talk/base/helpers.h"
-#include "talk/base/logging.h"
-#include "talk/base/stringencode.h"
-#include "talk/p2p/base/session.h"
-#include "talk/p2p/client/basicportallocator.h"
-
-namespace webrtc {
-
-
-PeerConnectionImpl::PeerConnectionImpl(
-    cricket::PortAllocator* port_allocator,
-    cricket::ChannelManager* channel_manager,
-    talk_base::Thread* signaling_thread)
-  : port_allocator_(port_allocator),
-    channel_manager_(channel_manager),
-    signaling_thread_(signaling_thread),
-    event_callback_(NULL),
-    session_(NULL) {
-}
-
-PeerConnectionImpl::~PeerConnectionImpl() {
-}
-
-bool PeerConnectionImpl::Init() {
-  std::string sid;
-  talk_base::CreateRandomString(8, &sid);
-  const bool incoming = false;
-  // default outgoing direction
-  session_.reset(CreateMediaSession(sid, incoming));
-  if (session_.get() == NULL) {
-    ASSERT(false && "failed to initialize a session");
-    return false;
-  }
-  return true;
-}
-
-void PeerConnectionImpl::RegisterObserver(PeerConnectionObserver* observer) {
-  // This assert is to catch cases where two observer pointers are registered.
-  // We only support one and if another is to be used, the current one must be
-  // cleared first.
-  ASSERT(observer == NULL || event_callback_ == NULL);
-  event_callback_ = observer;
-}
-
-bool PeerConnectionImpl::SignalingMessage(
-    const std::string& signaling_message) {
-  // Deserialize signaling message
-  cricket::SessionDescription* incoming_sdp = NULL;
-  std::vector<cricket::Candidate> candidates;
-  if (!ParseJsonSignalingMessage(signaling_message,
-                                 &incoming_sdp, &candidates)) {
-    return false;
-  }
-
-  bool ret = false;
-  if (GetReadyState() == NEW) {
-    // set direction to incoming, as message received first
-    session_->set_incoming(true);
-    ret = session_->OnInitiateMessage(incoming_sdp, candidates);
-  } else {
-    ret = session_->OnRemoteDescription(incoming_sdp, candidates);
-  }
-  return ret;
-}
-
-WebRtcSession* PeerConnectionImpl::CreateMediaSession(
-    const std::string& id, bool incoming) {
-  ASSERT(port_allocator_ != NULL);
-  WebRtcSession* session = new WebRtcSession(id, incoming,
-      port_allocator_, channel_manager_, signaling_thread_);
-
-  if (session->Initiate()) {
-    session->SignalAddStream.connect(
-        this,
-        &PeerConnectionImpl::OnAddStream);
-    session->SignalRemoveStream.connect(
-        this,
-        &PeerConnectionImpl::OnRemoveStream);
-    session->SignalLocalDescription.connect(
-        this,
-        &PeerConnectionImpl::OnLocalDescription);
-    session->SignalFailedCall.connect(
-        this,
-        &PeerConnectionImpl::OnFailedCall);
-  } else {
-    delete session;
-    session = NULL;
-  }
-  return session;
-}
-
-bool PeerConnectionImpl::AddStream(const std::string& stream_id, bool video) {
-  bool ret = false;
-  if (session_->HasStream(stream_id)) {
-    ASSERT(false && "A stream with this name already exists");
-  } else {
-    if (!video) {
-      ret = !session_->HasAudioChannel() &&
-            session_->CreateVoiceChannel(stream_id);
-    } else {
-      ret = !session_->HasVideoChannel() &&
-            session_->CreateVideoChannel(stream_id);
-    }
-  }
-  return ret;
-}
-
-bool PeerConnectionImpl::RemoveStream(const std::string& stream_id) {
-  return session_->RemoveStream(stream_id);
-}
-
-void PeerConnectionImpl::OnLocalDescription(
-    const cricket::SessionDescription* desc,
-    const std::vector<cricket::Candidate>& candidates) {
-  if (!desc) {
-    LOG(WARNING) << "no local SDP ";
-    return;
-  }
-
-  std::string message;
-  if (GetJsonSignalingMessage(desc, candidates, &message)) {
-    if (event_callback_) {
-      event_callback_->OnSignalingMessage(message);
-    }
-  }
-}
-
-void PeerConnectionImpl::OnFailedCall() {
-  // TODO: implement.
-}
-
-bool PeerConnectionImpl::SetAudioDevice(const std::string& wave_in_device,
-                                        const std::string& wave_out_device,
-                                        int opts) {
-  return channel_manager_->SetAudioOptions(wave_in_device,
-                                           wave_out_device,
-                                           opts);
-}
-
-bool PeerConnectionImpl::SetLocalVideoRenderer(
-    cricket::VideoRenderer* renderer) {
-  return channel_manager_->SetLocalRenderer(renderer);
-}
-
-bool PeerConnectionImpl::SetVideoRenderer(const std::string& stream_id,
-                                          cricket::VideoRenderer* renderer) {
-  return session_->SetVideoRenderer(stream_id, renderer);
-}
-
-bool PeerConnectionImpl::SetVideoCapture(const std::string& cam_device) {
-  return channel_manager_->SetVideoOptions(cam_device);
-}
-
-bool PeerConnectionImpl::Connect() {
-  return session_->Connect();
-}
-
-// TODO - Close is not used anymore, should be removed.
-bool PeerConnectionImpl::Close() {
-  session_->RemoveAllStreams();
-  return true;
-}
-
-void PeerConnectionImpl::OnAddStream(const std::string& stream_id,
-                                     bool video) {
-  if (event_callback_) {
-    event_callback_->OnAddStream(stream_id, video);
-  }
-}
-
-void PeerConnectionImpl::OnRemoveStream(const std::string& stream_id,
-                                        bool video) {
-  if (event_callback_) {
-    event_callback_->OnRemoveStream(stream_id, video);
-  }
-}
-
-PeerConnectionImpl::ReadyState PeerConnectionImpl::GetReadyState() {
-  ReadyState ready_state;
-  cricket::BaseSession::State state = session_->state();
-  if (state == cricket::BaseSession::STATE_INIT) {
-    ready_state = NEW;
-  } else if (state == cricket::BaseSession::STATE_INPROGRESS) {
-    ready_state = ACTIVE;
-  } else if (state == cricket::BaseSession::STATE_DEINIT) {
-    ready_state = CLOSED;
-  } else {
-    ready_state = NEGOTIATING;
-  }
-  return ready_state;
-}
-
-}  // namespace webrtc
diff --git a/third_party/libjingle/source/talk/app/webrtc/peerconnectionimpl.h b/third_party/libjingle/source/talk/app/webrtc/peerconnectionimpl.h
deleted file mode 100644
index 6ff2f25..0000000
--- a/third_party/libjingle/source/talk/app/webrtc/peerconnectionimpl.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_APP_WEBRTC_PEERCONNECTIONIMPL_H_
-#define TALK_APP_WEBRTC_PEERCONNECTIONIMPL_H_
-
-#include <string>
-#include <vector>
-
-#include "talk/app/webrtc/peerconnection.h"
-#include "talk/base/sigslot.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/base/thread.h"
-#include "talk/session/phone/channelmanager.h"
-
-namespace cricket {
-class ChannelManager;
-class PortAllocator;
-class SessionDescription;
-}
-
-namespace webrtc {
-class WebRtcSession;
-
-class PeerConnectionImpl : public PeerConnection,
-                           public sigslot::has_slots<> {
- public:
-  PeerConnectionImpl(cricket::PortAllocator* port_allocator,
-                     cricket::ChannelManager* channel_manager,
-                     talk_base::Thread* signaling_thread);
-  virtual ~PeerConnectionImpl();
-
-  // PeerConnection interfaces
-  virtual void RegisterObserver(PeerConnectionObserver* observer);
-  virtual bool SignalingMessage(const std::string& msg);
-  virtual bool AddStream(const std::string& stream_id, bool video);
-  virtual bool RemoveStream(const std::string& stream_id);
-  virtual bool Connect();
-  virtual bool Close();
-  virtual bool SetAudioDevice(const std::string& wave_in_device,
-                              const std::string& wave_out_device, int opts);
-  virtual bool SetLocalVideoRenderer(cricket::VideoRenderer* renderer);
-  virtual bool SetVideoRenderer(const std::string& stream_id,
-                                cricket::VideoRenderer* renderer);
-  virtual bool SetVideoCapture(const std::string& cam_device);
-  virtual ReadyState GetReadyState();
-
-  cricket::ChannelManager* channel_manager() {
-    return channel_manager_;
-  }
-
-  // Callbacks from PeerConnectionImplCallbacks
-  void OnAddStream(const std::string& stream_id, bool video);
-  void OnRemoveStream(const std::string& stream_id, bool video);
-  void OnLocalDescription(
-      const cricket::SessionDescription* desc,
-      const std::vector<cricket::Candidate>& candidates);
-  void OnFailedCall();
-  bool Init();
-
- private:
-  WebRtcSession* CreateMediaSession(const std::string& id, bool incoming);
-
-  cricket::PortAllocator* port_allocator_;
-  cricket::ChannelManager* channel_manager_;
-  talk_base::Thread* signaling_thread_;
-  PeerConnectionObserver* event_callback_;
-  talk_base::scoped_ptr<WebRtcSession> session_;
-};
-
-}  // namespace webrtc
-
-#endif  // TALK_APP_WEBRTC_PEERCONNECTIONIMPL_H_
diff --git a/third_party/libjingle/source/talk/app/webrtc/peerconnectionproxy.cc b/third_party/libjingle/source/talk/app/webrtc/peerconnectionproxy.cc
deleted file mode 100644
index fca3ad4..0000000
--- a/third_party/libjingle/source/talk/app/webrtc/peerconnectionproxy.cc
+++ /dev/null
@@ -1,313 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/app/webrtc/peerconnectionproxy.h"
-
-#include "talk/app/webrtc/peerconnectionimpl.h"
-#include "talk/base/logging.h"
-
-namespace webrtc {
-
-enum {
-  MSG_WEBRTC_ADDSTREAM = 1,
-  MSG_WEBRTC_CLOSE,
-  MSG_WEBRTC_CONNECT,
-  MSG_WEBRTC_INIT,
-  MSG_WEBRTC_REGISTEROBSERVER,
-  MSG_WEBRTC_RELEASE,
-  MSG_WEBRTC_REMOVESTREAM,
-  MSG_WEBRTC_SETAUDIODEVICE,
-  MSG_WEBRTC_SETLOCALRENDERER,
-  MSG_WEBRTC_SETVIDEOCAPTURE,
-  MSG_WEBRTC_SETVIDEORENDERER,
-  MSG_WEBRTC_SIGNALINGMESSAGE,
-  MSG_WEBRTC_GETREADYSTATE,
-};
-
-struct AddStreamParams : public talk_base::MessageData {
-  AddStreamParams(const std::string& stream_id, bool video)
-      : stream_id(stream_id),
-        video(video),
-        result(false) {}
-
-  std::string stream_id;
-  bool video;
-  bool result;
-};
-
-struct RemoveStreamParams : public talk_base::MessageData {
-  explicit RemoveStreamParams(const std::string& stream_id)
-      : stream_id(stream_id),
-        result(false) {}
-
-  std::string stream_id;
-  bool result;
-};
-
-struct SignalingMsgParams : public talk_base::MessageData {
-  explicit SignalingMsgParams(const std::string& signaling_message)
-      : signaling_message(signaling_message),
-        result(false) {}
-
-  std::string signaling_message;
-  bool result;
-};
-
-struct SetAudioDeviceParams : public talk_base::MessageData {
-  SetAudioDeviceParams(const std::string& wave_in_device,
-                       const std::string& wave_out_device,
-                       int opts)
-      : wave_in_device(wave_in_device), wave_out_device(wave_out_device),
-        opts(opts), result(false) {}
-
-  std::string wave_in_device;
-  std::string wave_out_device;
-  int opts;
-  bool result;
-};
-
-struct SetLocalRendererParams : public talk_base::MessageData {
-  explicit SetLocalRendererParams(cricket::VideoRenderer* renderer)
-      : renderer(renderer), result(false) {}
-
-  cricket::VideoRenderer* renderer;
-  bool result;
-};
-
-struct SetVideoRendererParams : public talk_base::MessageData {
-  SetVideoRendererParams(const std::string& stream_id,
-                         cricket::VideoRenderer* renderer)
-      : stream_id(stream_id), renderer(renderer), result(false) {}
-
-  std::string stream_id;
-  cricket::VideoRenderer* renderer;
-  bool result;
-};
-
-struct SetVideoCaptureParams : public talk_base::MessageData {
-  explicit SetVideoCaptureParams(const std::string& cam_device)
-      : cam_device(cam_device), result(false) {}
-
-  std::string cam_device;
-  bool result;
-};
-
-struct RegisterObserverParams : public talk_base::MessageData {
-  explicit RegisterObserverParams(PeerConnectionObserver* observer)
-      : observer(observer), result(false) {}
-
-  PeerConnectionObserver* observer;
-  bool result;
-};
-
-struct ResultParams : public talk_base::MessageData {
-  ResultParams()
-      : result(false) {}
-
-  bool result;
-};
-
-PeerConnectionProxy::PeerConnectionProxy(
-    cricket::PortAllocator* port_allocator,
-    cricket::ChannelManager* channel_manager,
-      talk_base::Thread* signaling_thread)
-  : peerconnection_impl_(new PeerConnectionImpl(port_allocator,
-                             channel_manager, signaling_thread)),
-    signaling_thread_(signaling_thread) {
-}
-
-PeerConnectionProxy::~PeerConnectionProxy() {
-  ResultParams params;
-  Send(MSG_WEBRTC_RELEASE, &params);
-}
-
-bool PeerConnectionProxy::Init() {
-  ResultParams params;
-  return (Send(MSG_WEBRTC_INIT, &params) && params.result);
-}
-
-void PeerConnectionProxy::RegisterObserver(PeerConnectionObserver* observer) {
-  RegisterObserverParams params(observer);
-  Send(MSG_WEBRTC_REGISTEROBSERVER, &params);
-}
-
-bool PeerConnectionProxy::SignalingMessage(
-    const std::string& signaling_message) {
-  SignalingMsgParams params(signaling_message);
-  return (Send(MSG_WEBRTC_SIGNALINGMESSAGE, &params) && params.result);
-}
-
-bool PeerConnectionProxy::AddStream(const std::string& stream_id, bool video) {
-  AddStreamParams params(stream_id, video);
-  return (Send(MSG_WEBRTC_ADDSTREAM, &params) && params.result);
-}
-
-bool PeerConnectionProxy::RemoveStream(const std::string& stream_id) {
-  RemoveStreamParams params(stream_id);
-  return (Send(MSG_WEBRTC_REMOVESTREAM, &params) && params.result);
-}
-
-bool PeerConnectionProxy::SetAudioDevice(const std::string& wave_in_device,
-                                         const std::string& wave_out_device,
-                                         int opts) {
-  SetAudioDeviceParams params(wave_in_device, wave_out_device, opts);
-  return (Send(MSG_WEBRTC_SETAUDIODEVICE, &params) && params.result);
-}
-
-bool PeerConnectionProxy::SetLocalVideoRenderer(
-    cricket::VideoRenderer* renderer) {
-  SetLocalRendererParams params(renderer);
-  return (Send(MSG_WEBRTC_SETLOCALRENDERER, &params) && params.result);
-}
-
-bool PeerConnectionProxy::SetVideoRenderer(const std::string& stream_id,
-                                          cricket::VideoRenderer* renderer) {
-  SetVideoRendererParams params(stream_id, renderer);
-  return (Send(MSG_WEBRTC_SETVIDEORENDERER, &params) && params.result);
-}
-
-bool PeerConnectionProxy::SetVideoCapture(const std::string& cam_device) {
-  SetVideoCaptureParams params(cam_device);
-  return (Send(MSG_WEBRTC_SETVIDEOCAPTURE, &params) && params.result);
-}
-
-PeerConnection::ReadyState PeerConnectionProxy::GetReadyState() {
-  PeerConnection::ReadyState ready_state = NEW;
-  Send(MSG_WEBRTC_GETREADYSTATE,
-       reinterpret_cast<talk_base::MessageData*>(&ready_state));
-  return ready_state;
-}
-
-bool PeerConnectionProxy::Connect() {
-  ResultParams params;
-  return (Send(MSG_WEBRTC_CONNECT, &params) && params.result);
-}
-
-bool PeerConnectionProxy::Close() {
-  ResultParams params;
-  return (Send(MSG_WEBRTC_CLOSE, &params) && params.result);
-}
-
-bool PeerConnectionProxy::Send(uint32 id, talk_base::MessageData* data) {
-  if (!signaling_thread_)
-    return false;
-  signaling_thread_->Send(this, id, data);
-  return true;
-}
-
-void PeerConnectionProxy::OnMessage(talk_base::Message* message) {
-  talk_base::MessageData* data = message->pdata;
-  switch (message->message_id) {
-    case MSG_WEBRTC_ADDSTREAM: {
-      AddStreamParams* params = reinterpret_cast<AddStreamParams*>(data);
-      params->result = peerconnection_impl_->AddStream(
-          params->stream_id, params->video);
-      break;
-    }
-    case MSG_WEBRTC_SIGNALINGMESSAGE: {
-      SignalingMsgParams* params =
-          reinterpret_cast<SignalingMsgParams*>(data);
-      params->result = peerconnection_impl_->SignalingMessage(
-          params->signaling_message);
-      break;
-    }
-    case MSG_WEBRTC_REMOVESTREAM: {
-      RemoveStreamParams* params = reinterpret_cast<RemoveStreamParams*>(data);
-      params->result = peerconnection_impl_->RemoveStream(
-          params->stream_id);
-      break;
-    }
-    case MSG_WEBRTC_SETAUDIODEVICE: {
-      SetAudioDeviceParams* params =
-          reinterpret_cast<SetAudioDeviceParams*>(data);
-      params->result = peerconnection_impl_->SetAudioDevice(
-          params->wave_in_device, params->wave_out_device, params->opts);
-      break;
-    }
-    case MSG_WEBRTC_SETLOCALRENDERER: {
-      SetLocalRendererParams* params =
-          reinterpret_cast<SetLocalRendererParams*>(data);
-      params->result = peerconnection_impl_->SetLocalVideoRenderer(
-          params->renderer);
-      break;
-    }
-    case MSG_WEBRTC_SETVIDEOCAPTURE: {
-      SetVideoCaptureParams* params =
-          reinterpret_cast<SetVideoCaptureParams*>(data);
-      params->result = peerconnection_impl_->SetVideoCapture(
-          params->cam_device);
-      break;
-    }
-    case MSG_WEBRTC_GETREADYSTATE: {
-      PeerConnection::ReadyState* ready_state =
-          reinterpret_cast<PeerConnection::ReadyState*>(data);
-      *ready_state = peerconnection_impl_->GetReadyState();
-      break;
-    }
-    case MSG_WEBRTC_SETVIDEORENDERER: {
-      SetVideoRendererParams* params =
-          reinterpret_cast<SetVideoRendererParams*>(data);
-      params->result = peerconnection_impl_->SetVideoRenderer(
-          params->stream_id, params->renderer);
-      break;
-    }
-    case MSG_WEBRTC_CONNECT: {
-      ResultParams* params =
-          reinterpret_cast<ResultParams*>(data);
-      params->result = peerconnection_impl_->Connect();
-      break;
-    }
-    case MSG_WEBRTC_CLOSE: {
-      ResultParams* params =
-          reinterpret_cast<ResultParams*>(data);
-      params->result = peerconnection_impl_->Close();
-      break;
-    }
-    case MSG_WEBRTC_INIT: {
-      ResultParams* params =
-          reinterpret_cast<ResultParams*>(data);
-      params->result = peerconnection_impl_->Init();
-      break;
-    }
-    case MSG_WEBRTC_REGISTEROBSERVER: {
-      RegisterObserverParams* params =
-          reinterpret_cast<RegisterObserverParams*>(data);
-      peerconnection_impl_->RegisterObserver(params->observer);
-      break;
-    }
-    case MSG_WEBRTC_RELEASE: {
-      peerconnection_impl_.reset();
-      break;
-    }
-    default: {
-      ASSERT(false);
-      break;
-    }
-  }
-}
-
-}  // namespace webrtc
diff --git a/third_party/libjingle/source/talk/app/webrtc/peerconnectionproxy.h b/third_party/libjingle/source/talk/app/webrtc/peerconnectionproxy.h
deleted file mode 100644
index e83b4ec..0000000
--- a/third_party/libjingle/source/talk/app/webrtc/peerconnectionproxy.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_APP_WEBRTC_PEERCONNECTIONPROXY_H_
-#define TALK_APP_WEBRTC_PEERCONNECTIONPROXY_H_
-
-#include <string>
-
-#include "talk/app/webrtc/peerconnection.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/base/thread.h"
-
-namespace cricket {
-class ChannelManager;
-class PortAllocator;
-}
-
-namespace webrtc {
-
-class PeerConnectionImpl;
-
-class PeerConnectionProxy : public PeerConnection,
-                            public talk_base::MessageHandler {
- public:
-  PeerConnectionProxy(cricket::PortAllocator* port_allocator,
-                      cricket::ChannelManager* channel_manager,
-                      talk_base::Thread* signaling_thread);
-  virtual ~PeerConnectionProxy();
-
-  // PeerConnection interface implementation.
-  virtual void RegisterObserver(PeerConnectionObserver* observer);
-  virtual bool SignalingMessage(const std::string& msg);
-  virtual bool AddStream(const std::string& stream_id, bool video);
-  virtual bool RemoveStream(const std::string& stream_id);
-  virtual bool Connect();
-  virtual bool Close();
-  virtual bool SetAudioDevice(const std::string& wave_in_device,
-                              const std::string& wave_out_device, int opts);
-  virtual bool SetLocalVideoRenderer(cricket::VideoRenderer* renderer);
-  virtual bool SetVideoRenderer(const std::string& stream_id,
-                                cricket::VideoRenderer* renderer);
-  virtual bool SetVideoCapture(const std::string& cam_device);
-  virtual ReadyState GetReadyState();
-
- private:
-  bool Init();
-  bool Send(uint32 id, talk_base::MessageData* data);
-  virtual void OnMessage(talk_base::Message* message);
-
-  talk_base::scoped_ptr<PeerConnectionImpl> peerconnection_impl_;
-  talk_base::Thread* signaling_thread_;
-
-  friend class PeerConnectionFactory;
-};
-}
-
-#endif  // TALK_APP_WEBRTC_PEERCONNECTIONPROXY_H_
diff --git a/third_party/libjingle/source/talk/app/webrtc/webrtc.scons b/third_party/libjingle/source/talk/app/webrtc/webrtc.scons
deleted file mode 100644
index 271d413..0000000
--- a/third_party/libjingle/source/talk/app/webrtc/webrtc.scons
+++ /dev/null
@@ -1,60 +0,0 @@
-# -*- Python -*-
-import talk
-
-Import('env')
-
-# local sources
-talk.Library(
-  env,
-  name = 'webrtc',
-  srcs = [
-    'peerconnectionimpl.cc',
-    'peerconnectionproxy.cc',
-    'peerconnectionfactory.cc',
-    'webrtcjson.cc',
-    'webrtcsession.cc',
-  ],
-)
-
-talk.Unittest(
-  env,
-  name = 'webrtc',
-  srcs = [
-    'peerconnection_unittest.cc',
-    'unittest_utilities.cc',
-    'webrtcsession_unittest.cc',
-  ],
-  libs = [
-    'base',
-    'expat',
-    'jpeg',
-    'json',
-    'webrtc',
-    'p2p',
-    'phone',
-    'srtp',
-    'xmpp',
-    'xmllite',
-    'yuvscaler'
-  ],
-  include_talk_media_libs = True,
-  mac_libs = [
-    'crypto',
-    'ssl',
-  ],
-  mac_FRAMEWORKS = [
-    'Foundation',
-    'IOKit',
-    'QTKit',
-  ],
-  win_link_flags = [('', '/nodefaultlib:libcmt')[env.Bit('debug')]],
-  lin_libs = [
-    'rt',
-    'dl',
-    'sound',
-    'X11',
-    'Xext',
-    'Xfixes',
-    'Xrandr'
-  ],
-)
diff --git a/third_party/libjingle/source/talk/app/webrtc/webrtcjson.cc b/third_party/libjingle/source/talk/app/webrtc/webrtcjson.cc
deleted file mode 100644
index b071746..0000000
--- a/third_party/libjingle/source/talk/app/webrtc/webrtcjson.cc
+++ /dev/null
@@ -1,469 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/app/webrtc/webrtcjson.h"
-
-#ifdef WEBRTC_RELATIVE_PATH
-#include "json/json.h"
-#else
-#include "third_party/jsoncpp/json.h"
-#endif
-
-// TODO: Remove webrtcsession.h once we can get size from signaling.
-// webrtcsession.h is for kDefaultVideoCodecWidth and kDefaultVideoCodecHeight.
-#include "talk/app/webrtc/webrtcsession.h"
-#include "talk/base/json.h"
-#include "talk/base/logging.h"
-#include "talk/base/stringutils.h"
-#include "talk/session/phone/codec.h"
-#include "talk/session/phone/mediasessionclient.h"
-
-namespace webrtc {
-static const int kIceComponent = 1;
-static const int kIceFoundation = 1;
-
-static std::vector<Json::Value> ReadValues(const Json::Value& value,
-                                           const std::string& key);
-
-static bool BuildMediaMessage(
-    const cricket::ContentInfo& content_info,
-    const std::vector<cricket::Candidate>& candidates,
-    bool video,
-    Json::Value* value);
-
-static bool BuildRtpMapParams(
-    const cricket::ContentInfo& audio_offer,
-    bool video,
-    std::vector<Json::Value>* rtpmap);
-
-static bool BuildAttributes(const std::vector<cricket::Candidate>& candidates,
-                            bool video,
-                            std::vector<Json::Value>* jcandidates);
-
-static std::string Serialize(const Json::Value& value);
-static bool Deserialize(const std::string& message, Json::Value* value);
-
-static bool ParseRtcpMux(const Json::Value& value);
-static bool ParseAudioCodec(const Json::Value& value,
-                            cricket::AudioContentDescription* content);
-static bool ParseVideoCodec(const Json::Value& value,
-                            cricket::VideoContentDescription* content);
-static bool ParseIceCandidates(const Json::Value& value,
-                               std::vector<cricket::Candidate>* candidates);
-
-static Json::Value ReadValue(const Json::Value& value, const std::string& key);
-static std::string ReadString(const Json::Value& value, const std::string& key);
-static uint32 ReadUInt(const Json::Value& value, const std::string& key);
-
-static void Append(Json::Value* object, const std::string& key, bool value);
-static void Append(Json::Value* object, const std::string& key, int value);
-static void Append(Json::Value* object, const std::string& key,
-                   const std::string& value);
-static void Append(Json::Value* object, const std::string& key, uint32 value);
-static void Append(Json::Value* object, const std::string& key,
-                   const Json::Value& value);
-static void Append(Json::Value* object,
-                   const std::string& key,
-                   const std::vector<Json::Value>& values);
-
-bool GetJsonSignalingMessage(
-    const cricket::SessionDescription* sdp,
-    const std::vector<cricket::Candidate>& candidates,
-    std::string* signaling_message) {
-  const cricket::ContentInfo* audio_content = GetFirstAudioContent(sdp);
-  const cricket::ContentInfo* video_content = GetFirstVideoContent(sdp);
-
-  std::vector<Json::Value> media;
-  if (audio_content) {
-    Json::Value value;
-    BuildMediaMessage(*audio_content, candidates, false, &value);
-    media.push_back(value);
-  }
-
-  if (video_content) {
-    Json::Value value;
-    BuildMediaMessage(*video_content, candidates, true, &value);
-    media.push_back(value);
-  }
-
-  Json::Value signal;
-  Append(&signal, "media", media);
-
-  // Now serialize.
-  *signaling_message = Serialize(signal);
-
-  return true;
-}
-
-bool BuildMediaMessage(
-    const cricket::ContentInfo& content_info,
-    const std::vector<cricket::Candidate>& candidates,
-    bool video,
-    Json::Value* params) {
-  if (video) {
-    Append(params, "label", 2);  // always video 2
-  } else {
-    Append(params, "label", 1);  // always audio 1
-  }
-
-  const cricket::MediaContentDescription* media_info =
-  static_cast<const cricket::MediaContentDescription*> (
-      content_info.description);
-  if (media_info->rtcp_mux()) {
-    Append(params, "rtcp_mux", true);
-  }
-
-  std::vector<Json::Value> rtpmap;
-  if (!BuildRtpMapParams(content_info, video, &rtpmap)) {
-    return false;
-  }
-
-  Append(params, "rtpmap", rtpmap);
-
-  Json::Value attributes;
-  std::vector<Json::Value> jcandidates;
-
-  if (!BuildAttributes(candidates, video, &jcandidates)) {
-    return false;
-  }
-  Append(&attributes, "candidate", jcandidates);
-  Append(params, "attributes", attributes);
-  return true;
-}
-
-bool BuildRtpMapParams(const cricket::ContentInfo& content_info,
-                       bool video,
-                       std::vector<Json::Value>* rtpmap) {
-  if (!video) {
-    const cricket::AudioContentDescription* audio_offer =
-        static_cast<const cricket::AudioContentDescription*>(
-            content_info.description);
-
-    std::vector<cricket::AudioCodec>::const_iterator iter =
-        audio_offer->codecs().begin();
-    std::vector<cricket::AudioCodec>::const_iterator iter_end =
-        audio_offer->codecs().end();
-    for (; iter != iter_end; ++iter) {
-      Json::Value codec;
-      std::string codec_str(std::string("audio/").append(iter->name));
-      // adding clockrate
-      Append(&codec, "clockrate", iter->clockrate);
-      Append(&codec, "codec", codec_str);
-      Json::Value codec_id;
-      Append(&codec_id, talk_base::ToString(iter->id), codec);
-      rtpmap->push_back(codec_id);
-    }
-  } else {
-    const cricket::VideoContentDescription* video_offer =
-        static_cast<const cricket::VideoContentDescription*>(
-            content_info.description);
-
-    std::vector<cricket::VideoCodec>::const_iterator iter =
-        video_offer->codecs().begin();
-    std::vector<cricket::VideoCodec>::const_iterator iter_end =
-        video_offer->codecs().end();
-    for (; iter != iter_end; ++iter) {
-      Json::Value codec;
-      std::string codec_str(std::string("video/").append(iter->name));
-      Append(&codec, "codec", codec_str);
-      Json::Value codec_id;
-      Append(&codec_id, talk_base::ToString(iter->id), codec);
-      rtpmap->push_back(codec_id);
-    }
-  }
-  return true;
-}
-
-bool BuildAttributes(const std::vector<cricket::Candidate>& candidates,
-                     bool video,
-                     std::vector<Json::Value>* jcandidates) {
-  std::vector<cricket::Candidate>::const_iterator iter =
-      candidates.begin();
-  std::vector<cricket::Candidate>::const_iterator iter_end =
-      candidates.end();
-  for (; iter != iter_end; ++iter) {
-    if ((video && (!iter->name().compare("video_rtcp") ||
-                  (!iter->name().compare("video_rtp")))) ||
-        (!video && (!iter->name().compare("rtp") ||
-                   (!iter->name().compare("rtcp"))))) {
-      Json::Value candidate;
-      Append(&candidate, "component", kIceComponent);
-      Append(&candidate, "foundation", kIceFoundation);
-      Append(&candidate, "generation", iter->generation());
-      Append(&candidate, "proto", iter->protocol());
-      Append(&candidate, "priority", iter->preference_str());
-      Append(&candidate, "ip", iter->address().IPAsString());
-      Append(&candidate, "port", iter->address().PortAsString());
-      Append(&candidate, "type", iter->type());
-      Append(&candidate, "name", iter->name());
-      Append(&candidate, "network_name", iter->network_name());
-      Append(&candidate, "username", iter->username());
-      Append(&candidate, "password", iter->password());
-      jcandidates->push_back(candidate);
-    }
-  }
-  return true;
-}
-
-std::string Serialize(const Json::Value& value) {
-  Json::StyledWriter writer;
-  return writer.write(value);
-}
-
-bool Deserialize(const std::string& message, Json::Value* value) {
-  Json::Reader reader;
-  return reader.parse(message, *value);
-}
-
-bool ParseJsonSignalingMessage(const std::string& signaling_message,
-                               cricket::SessionDescription** sdp,
-                               std::vector<cricket::Candidate>* candidates) {
-  ASSERT(!(*sdp));  // expect this to be NULL
-  // first deserialize message
-  Json::Value value;
-  if (!Deserialize(signaling_message, &value)) {
-    return false;
-  }
-
-  // get media objects
-  std::vector<Json::Value> mlines = ReadValues(value, "media");
-  if (mlines.empty()) {
-    // no m-lines found
-    return false;
-  }
-
-  *sdp = new cricket::SessionDescription();
-
-  // get codec information
-  for (size_t i = 0; i < mlines.size(); ++i) {
-    if (mlines[i]["label"].asInt() == 1) {
-      cricket::AudioContentDescription* audio_content =
-          new cricket::AudioContentDescription();
-      ParseAudioCodec(mlines[i], audio_content);
-      audio_content->set_rtcp_mux(ParseRtcpMux(mlines[i]));
-      audio_content->SortCodecs();
-      (*sdp)->AddContent(cricket::CN_AUDIO,
-                         cricket::NS_JINGLE_RTP, audio_content);
-      ParseIceCandidates(mlines[i], candidates);
-    } else {
-      cricket::VideoContentDescription* video_content =
-          new cricket::VideoContentDescription();
-      ParseVideoCodec(mlines[i], video_content);
-
-      video_content->set_rtcp_mux(ParseRtcpMux(mlines[i]));
-      video_content->SortCodecs();
-      (*sdp)->AddContent(cricket::CN_VIDEO,
-                         cricket::NS_JINGLE_RTP, video_content);
-      ParseIceCandidates(mlines[i], candidates);
-    }
-  }
-  return true;
-}
-
-bool ParseRtcpMux(const Json::Value& value) {
-  Json::Value rtcp_mux(ReadValue(value, "rtcp_mux"));
-  if (!rtcp_mux.empty()) {
-    if (rtcp_mux.asBool()) {
-      return true;
-    }
-  }
-  return false;
-}
-
-bool ParseAudioCodec(const Json::Value& value,
-                     cricket::AudioContentDescription* content) {
-  std::vector<Json::Value> rtpmap(ReadValues(value, "rtpmap"));
-  if (rtpmap.empty())
-    return false;
-
-  std::vector<Json::Value>::const_iterator iter =
-      rtpmap.begin();
-  std::vector<Json::Value>::const_iterator iter_end =
-      rtpmap.end();
-  for (; iter != iter_end; ++iter) {
-    cricket::AudioCodec codec;
-    std::string pltype(iter->begin().memberName());
-    talk_base::FromString(pltype, &codec.id);
-    Json::Value codec_info((*iter)[pltype]);
-    std::string codec_name(ReadString(codec_info, "codec"));
-    std::vector<std::string> tokens;
-    talk_base::split(codec_name, '/', &tokens);
-    codec.name = tokens[1];
-    codec.clockrate = ReadUInt(codec_info, "clockrate");
-    content->AddCodec(codec);
-  }
-
-  return true;
-}
-
-bool ParseVideoCodec(const Json::Value& value,
-                     cricket::VideoContentDescription* content) {
-  std::vector<Json::Value> rtpmap(ReadValues(value, "rtpmap"));
-  if (rtpmap.empty())
-    return false;
-
-  std::vector<Json::Value>::const_iterator iter =
-      rtpmap.begin();
-  std::vector<Json::Value>::const_iterator iter_end =
-      rtpmap.end();
-  for (; iter != iter_end; ++iter) {
-    cricket::VideoCodec codec;
-    std::string pltype(iter->begin().memberName());
-    talk_base::FromString(pltype, &codec.id);
-    Json::Value codec_info((*iter)[pltype]);
-    std::vector<std::string> tokens;
-    talk_base::split(codec_info["codec"].asString(), '/', &tokens);
-    codec.name = tokens[1];
-    // TODO: Remove once we can get size from signaling message.
-    codec.width = WebRtcSession::kDefaultVideoCodecWidth;
-    codec.height = WebRtcSession::kDefaultVideoCodecHeight;
-    content->AddCodec(codec);
-  }
-  return true;
-}
-
-bool ParseIceCandidates(const Json::Value& value,
-                        std::vector<cricket::Candidate>* candidates) {
-  Json::Value attributes(ReadValue(value, "attributes"));
-  std::string ice_pwd(ReadString(attributes, "ice-pwd"));
-  std::string ice_ufrag(ReadString(attributes, "ice-ufrag"));
-
-  std::vector<Json::Value> jcandidates(ReadValues(attributes, "candidate"));
-
-  std::vector<Json::Value>::const_iterator iter =
-      jcandidates.begin();
-  std::vector<Json::Value>::const_iterator iter_end =
-      jcandidates.end();
-  for (; iter != iter_end; ++iter) {
-    cricket::Candidate cand;
-
-    unsigned int generation;
-    if (!GetUIntFromJsonObject(*iter, "generation", &generation))
-      return false;
-    cand.set_generation_str(talk_base::ToString(generation));
-
-    std::string proto;
-    if (!GetStringFromJsonObject(*iter, "proto", &proto))
-      return false;
-    cand.set_protocol(proto);
-
-    std::string priority;
-    if (!GetStringFromJsonObject(*iter, "priority", &priority))
-      return false;
-    cand.set_preference_str(priority);
-
-    std::string str;
-    talk_base::SocketAddress addr;
-    if (!GetStringFromJsonObject(*iter, "ip", &str))
-      return false;
-    addr.SetIP(str);
-    if (!GetStringFromJsonObject(*iter, "port", &str))
-      return false;
-    int port;
-    if (!talk_base::FromString(str, &port))
-      return false;
-    addr.SetPort(port);
-    cand.set_address(addr);
-
-    if (!GetStringFromJsonObject(*iter, "type", &str))
-      return false;
-    cand.set_type(str);
-
-    if (!GetStringFromJsonObject(*iter, "name", &str))
-      return false;
-    cand.set_name(str);
-
-    if (!GetStringFromJsonObject(*iter, "network_name", &str))
-      return false;
-    cand.set_network_name(str);
-
-    if (!GetStringFromJsonObject(*iter, "username", &str))
-      return false;
-    cand.set_username(str);
-
-    if (!GetStringFromJsonObject(*iter, "password", &str))
-      return false;
-    cand.set_password(str);
-
-    candidates->push_back(cand);
-  }
-  return true;
-}
-
-std::vector<Json::Value> ReadValues(
-    const Json::Value& value, const std::string& key) {
-  std::vector<Json::Value> objects;
-  for (Json::Value::ArrayIndex i = 0; i < value[key].size(); ++i) {
-    objects.push_back(value[key][i]);
-  }
-  return objects;
-}
-
-Json::Value ReadValue(const Json::Value& value, const std::string& key) {
-  return value[key];
-}
-
-std::string ReadString(const Json::Value& value, const std::string& key) {
-  return value[key].asString();
-}
-
-uint32 ReadUInt(const Json::Value& value, const std::string& key) {
-  return value[key].asUInt();
-}
-
-void Append(Json::Value* object, const std::string& key, bool value) {
-  (*object)[key] = Json::Value(value);
-}
-
-void Append(Json::Value* object, const std::string& key, int value) {
-  (*object)[key] = Json::Value(value);
-}
-
-void Append(Json::Value* object, const std::string& key,
-            const std::string& value) {
-  (*object)[key] = Json::Value(value);
-}
-
-void Append(Json::Value* object, const std::string& key, uint32 value) {
-  (*object)[key] = Json::Value(value);
-}
-
-void Append(Json::Value* object, const std::string& key,
-            const Json::Value& value) {
-  (*object)[key] = value;
-}
-
-void Append(Json::Value* object,
-            const std::string & key,
-            const std::vector<Json::Value>& values) {
-  for (std::vector<Json::Value>::const_iterator iter = values.begin();
-      iter != values.end(); ++iter) {
-    (*object)[key].append(*iter);
-  }
-}
-
-}  // namespace webrtc
diff --git a/third_party/libjingle/source/talk/app/webrtc/webrtcjson.h b/third_party/libjingle/source/talk/app/webrtc/webrtcjson.h
deleted file mode 100644
index d923f83..0000000
--- a/third_party/libjingle/source/talk/app/webrtc/webrtcjson.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_APP_WEBRTC_WEBRTCJSON_H_
-#define TALK_APP_WEBRTC_WEBRTCJSON_H_
-
-#include <string>
-
-#include "talk/p2p/base/candidate.h"
-#include "talk/session/phone/codec.h"
-
-namespace Json {
-class Value;
-}
-
-namespace cricket {
-class AudioContentDescription;
-class VideoContentDescription;
-struct ContentInfo;
-class SessionDescription;
-}
-
-namespace webrtc {
-
-bool GetJsonSignalingMessage(
-    const cricket::SessionDescription* sdp,
-    const std::vector<cricket::Candidate>& candidates,
-    std::string* signaling_message);
-
-bool ParseJsonSignalingMessage(const std::string& signaling_message,
-                               cricket::SessionDescription** sdp,
-                               std::vector<cricket::Candidate>* candidates);
-}
-
-#endif  // TALK_APP_WEBRTC_WEBRTCJSON_H_
diff --git a/third_party/libjingle/source/talk/app/webrtc/webrtcsession.cc b/third_party/libjingle/source/talk/app/webrtc/webrtcsession.cc
deleted file mode 100644
index 634da77..0000000
--- a/third_party/libjingle/source/talk/app/webrtc/webrtcsession.cc
+++ /dev/null
@@ -1,537 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/app/webrtc/webrtcsession.h"
-
-#include <string>
-#include <vector>
-
-#include "talk/base/common.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/p2p/base/constants.h"
-#include "talk/p2p/base/sessiondescription.h"
-#include "talk/p2p/base/p2ptransport.h"
-#include "talk/session/phone/channel.h"
-#include "talk/session/phone/channelmanager.h"
-#include "talk/session/phone/mediasessionclient.h"
-#include "talk/session/phone/voicechannel.h"
-
-namespace webrtc {
-
-enum {
-  MSG_CANDIDATE_TIMEOUT = 101,
-};
-
-static const int kAudioMonitorPollFrequency = 100;
-static const int kMonitorPollFrequency = 1000;
-
-// We allow 30 seconds to establish a connection; beyond that we consider
-// it an error
-static const int kCallSetupTimeout = 30 * 1000;
-// A loss of connectivity is probably due to the Internet connection going
-// down, and it might take a while to come back on wireless networks, so we
-// use a longer timeout for that.
-static const int kCallLostTimeout = 60 * 1000;
-
-static const char kVideoStream[] = "video_rtp";
-static const char kAudioStream[] = "rtp";
-
-static const int kDefaultVideoCodecId = 100;
-static const int kDefaultVideoCodecFramerate = 30;
-static const char kDefaultVideoCodecName[] = "VP8";
-
-WebRtcSession::WebRtcSession(const std::string& id,
-                             bool incoming,
-                             cricket::PortAllocator* allocator,
-                             cricket::ChannelManager* channelmgr,
-                             talk_base::Thread* signaling_thread)
-    : BaseSession(signaling_thread, channelmgr->worker_thread(),
-                  allocator, id, "", !incoming),
-      transport_(NULL),
-      channel_manager_(channelmgr),
-      transports_writable_(false),
-      muted_(false),
-      camera_muted_(false),
-      setup_timeout_(kCallSetupTimeout),
-      signaling_thread_(signaling_thread),
-      incoming_(incoming),
-      port_allocator_(allocator),
-      desc_factory_(channel_manager_) {
-}
-
-WebRtcSession::~WebRtcSession() {
-  RemoveAllStreams();
-  // TODO: Do we still need Terminate?
-  // if (state_ != STATE_RECEIVEDTERMINATE) {
-  //   Terminate();
-  // }
-  if (transport_) {
-    delete transport_;
-    transport_ = NULL;
-  }
-}
-
-bool WebRtcSession::Initiate() {
-  const cricket::VideoCodec default_codec(kDefaultVideoCodecId,
-      kDefaultVideoCodecName, kDefaultVideoCodecWidth, kDefaultVideoCodecHeight,
-      kDefaultVideoCodecFramerate, 0);
-  channel_manager_->SetDefaultVideoEncoderConfig(
-      cricket::VideoEncoderConfig(default_codec));
-
-  if (signaling_thread_ == NULL)
-    return false;
-
-  transport_ = CreateTransport();
-
-  if (transport_ == NULL)
-    return false;
-
-  transport_->set_allow_local_ips(true);
-
-  // start transports
-  transport_->SignalRequestSignaling.connect(
-      this, &WebRtcSession::OnRequestSignaling);
-  transport_->SignalCandidatesReady.connect(
-      this, &WebRtcSession::OnCandidatesReady);
-  transport_->SignalWritableState.connect(
-      this, &WebRtcSession::OnWritableState);
-  // Limit the amount of time that setting up a call may take.
-  StartTransportTimeout(kCallSetupTimeout);
-  return true;
-}
-
-cricket::Transport* WebRtcSession::CreateTransport() {
-  ASSERT(signaling_thread()->IsCurrent());
-  return new cricket::P2PTransport(
-      talk_base::Thread::Current(),
-      channel_manager_->worker_thread(), port_allocator());
-}
-
-bool WebRtcSession::CreateVoiceChannel(const std::string& stream_id) {
-  // RTCP disabled
-  cricket::VoiceChannel* voice_channel =
-      channel_manager_->CreateVoiceChannel(this, stream_id, true);
-  if (voice_channel == NULL) {
-    LOG(LERROR) << "Unable to create voice channel.";
-    return false;
-  }
-  StreamInfo* stream_info = new StreamInfo(stream_id);
-  stream_info->channel = voice_channel;
-  stream_info->video = false;
-  streams_.push_back(stream_info);
-  return true;
-}
-
-bool WebRtcSession::CreateVideoChannel(const std::string& stream_id) {
-  // RTCP disabled
-  cricket::VideoChannel* video_channel =
-      channel_manager_->CreateVideoChannel(this, stream_id, true, NULL);
-  if (video_channel == NULL) {
-    LOG(LERROR) << "Unable to create video channel.";
-    return false;
-  }
-  StreamInfo* stream_info = new StreamInfo(stream_id);
-  stream_info->channel = video_channel;
-  stream_info->video = true;
-  streams_.push_back(stream_info);
-  return true;
-}
-
-cricket::TransportChannel* WebRtcSession::CreateChannel(
-    const std::string& content_name,
-    const std::string& name) {
-  if (!transport_) {
-    return NULL;
-  }
-  std::string type;
-  if (content_name.compare(kVideoStream) == 0) {
-    type = cricket::NS_GINGLE_VIDEO;
-  } else {
-    type = cricket::NS_GINGLE_AUDIO;
-  }
-  cricket::TransportChannel* transport_channel =
-      transport_->CreateChannel(name, type);
-  ASSERT(transport_channel != NULL);
-  return transport_channel;
-}
-
-cricket::TransportChannel* WebRtcSession::GetChannel(
-    const std::string& content_name, const std::string& name) {
-  if (!transport_)
-    return NULL;
-
-  return transport_->GetChannel(name);
-}
-
-void WebRtcSession::DestroyChannel(
-    const std::string& content_name, const std::string& name) {
-  if (!transport_)
-    return;
-
-  transport_->DestroyChannel(name);
-}
-
-void WebRtcSession::OnMessage(talk_base::Message* message) {
-  switch (message->message_id) {
-    case MSG_CANDIDATE_TIMEOUT:
-      if (transport_->writable()) {
-        // This should never happen: The timout triggered even
-        // though a call was successfully set up.
-        ASSERT(false);
-      }
-      SignalFailedCall();
-      break;
-    default:
-      cricket::BaseSession::OnMessage(message);
-      break;
-  }
-}
-
-bool WebRtcSession::Connect() {
-  if (streams_.empty()) {
-    // nothing to initiate
-    return false;
-  }
-  // lets connect all the transport channels created before for this session
-  transport_->ConnectChannels();
-
-  // create an offer now. This is to call SetState
-  // Actual offer will be send when OnCandidatesReady callback received
-  cricket::SessionDescription* offer = CreateOffer();
-  set_local_description(offer);
-  SetState((incoming()) ? STATE_SENTACCEPT : STATE_SENTINITIATE);
-
-  // Enable all the channels
-  EnableAllStreams();
-  SetVideoCapture(true);
-  return true;
-}
-
-bool WebRtcSession::SetVideoRenderer(const std::string& stream_id,
-                                     cricket::VideoRenderer* renderer) {
-  bool ret = false;
-  StreamMap::iterator iter;
-  for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
-    StreamInfo* stream_info = (*iter);
-    if (stream_info->stream_id.compare(stream_id) == 0) {
-      ASSERT(stream_info->channel != NULL);
-      ASSERT(stream_info->video);
-      cricket::VideoChannel* channel = static_cast<cricket::VideoChannel*>(
-          stream_info->channel);
-      ret = channel->SetRenderer(0, renderer);
-      break;
-    }
-  }
-  return ret;
-}
-
-bool WebRtcSession::SetVideoCapture(bool capture) {
-  channel_manager_->SetVideoCapture(capture);
-  return true;
-}
-
-bool WebRtcSession::RemoveStream(const std::string& stream_id) {
-  bool ret = false;
-  StreamMap::iterator iter;
-  for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
-    StreamInfo* sinfo = (*iter);
-    if (sinfo->stream_id.compare(stream_id) == 0) {
-      if (!sinfo->video) {
-        cricket::VoiceChannel* channel = static_cast<cricket::VoiceChannel*> (
-            sinfo->channel);
-        channel->Enable(false);
-        // Note: If later the channel is used by multiple streams, then we
-        // should not destroy the channel until all the streams are removed.
-        channel_manager_->DestroyVoiceChannel(channel);
-      } else {
-        cricket::VideoChannel* channel = static_cast<cricket::VideoChannel*> (
-            sinfo->channel);
-        channel->Enable(false);
-        // Note: If later the channel is used by multiple streams, then we
-        // should not destroy the channel until all the streams are removed.
-        channel_manager_->DestroyVideoChannel(channel);
-      }
-      // channel and transport will be deleted in
-      // DestroyVoiceChannel/DestroyVideoChannel
-      streams_.erase(iter);
-      ret = true;
-      break;
-    }
-  }
-  if (!ret) {
-    LOG(LERROR) << "No streams found for stream id " << stream_id;
-    // TODO: trigger onError callback
-  }
-  return ret;
-}
-
-void WebRtcSession::EnableAllStreams() {
-  StreamMap::const_iterator i;
-  for (i = streams_.begin(); i != streams_.end(); ++i) {
-    cricket::BaseChannel* channel = (*i)->channel;
-    if (channel)
-      channel->Enable(true);
-  }
-}
-
-void WebRtcSession::RemoveAllStreams() {
-  SetState(STATE_RECEIVEDTERMINATE);
-
-  // signaling_thread_->Post(this, MSG_RTC_REMOVEALLSTREAMS);
-  // First build a list of streams to remove and then remove them.
-  // The reason we do this is that if we remove the streams inside the
-  // loop, a stream might get removed while we're enumerating and the iterator
-  // will become invalid (and we crash).
-  // streams_ entry will be removed from ChannelManager callback method
-  // DestroyChannel
-  std::vector<std::string> streams_to_remove;
-  StreamMap::iterator iter;
-  for (iter = streams_.begin(); iter != streams_.end(); ++iter)
-    streams_to_remove.push_back((*iter)->stream_id);
-
-  for (std::vector<std::string>::iterator i = streams_to_remove.begin();
-       i != streams_to_remove.end(); ++i) {
-    RemoveStream(*i);
-  }
-}
-
-bool WebRtcSession::HasStream(const std::string& stream_id) const {
-  StreamMap::const_iterator iter;
-  for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
-    StreamInfo* sinfo = (*iter);
-    if (stream_id.compare(sinfo->stream_id) == 0) {
-      return true;
-    }
-  }
-  return false;
-}
-
-bool WebRtcSession::HasChannel(bool video) const {
-  StreamMap::const_iterator iter;
-  for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
-    StreamInfo* sinfo = (*iter);
-    if (sinfo->video == video) {
-      return true;
-    }
-  }
-  return false;
-}
-
-bool WebRtcSession::HasAudioChannel() const {
-  return HasChannel(false);
-}
-
-bool WebRtcSession::HasVideoChannel() const {
-  return HasChannel(true);
-}
-
-void WebRtcSession::OnRequestSignaling(cricket::Transport* transport) {
-  transport->OnSignalingReady();
-}
-
-void WebRtcSession::OnWritableState(cricket::Transport* transport) {
-  ASSERT(transport == transport_);
-  const bool transports_writable = transport_->writable();
-  if (transports_writable) {
-    if (transports_writable != transports_writable_) {
-      signaling_thread_->Clear(this, MSG_CANDIDATE_TIMEOUT);
-    } else {
-      // At one point all channels were writable and we had full connectivity,
-      // but then we lost it. Start the timeout again to kill the call if it
-      // doesn't come back.
-      StartTransportTimeout(kCallLostTimeout);
-    }
-    transports_writable_ = transports_writable;
-  }
-  NotifyTransportState();
-  return;
-}
-
-void WebRtcSession::StartTransportTimeout(int timeout) {
-  talk_base::Thread::Current()->PostDelayed(timeout, this,
-                                            MSG_CANDIDATE_TIMEOUT,
-                                            NULL);
-}
-
-void WebRtcSession::NotifyTransportState() {
-}
-
-bool WebRtcSession::OnInitiateMessage(
-    cricket::SessionDescription* offer,
-    const std::vector<cricket::Candidate>& candidates) {
-  if (!offer) {
-    LOG(LERROR) << "No SessionDescription from peer";
-    return false;
-  }
-
-  // Get capabilities from offer before generating an answer to it.
-  cricket::MediaSessionOptions options;
-  if (GetFirstAudioContent(offer))
-    options.has_audio = true;
-  if (GetFirstVideoContent(offer))
-    options.has_video = true;
-
-  talk_base::scoped_ptr<cricket::SessionDescription> answer;
-  answer.reset(CreateAnswer(offer, options));
-
-  if (!answer.get()) {
-    return false;
-  }
-
-  const cricket::ContentInfo* audio_content = GetFirstAudioContent(
-      answer.get());
-  const cricket::ContentInfo* video_content = GetFirstVideoContent(
-      answer.get());
-
-  if (!audio_content && !video_content) {
-    return false;
-  }
-
-  bool ret = true;
-  if (audio_content) {
-    ret = !HasAudioChannel() &&
-          CreateVoiceChannel(audio_content->name);
-    if (!ret) {
-      LOG(LERROR) << "Failed to create voice channel for "
-                  << audio_content->name;
-      return false;
-    }
-  }
-
-  if (video_content) {
-    ret = !HasVideoChannel() &&
-          CreateVideoChannel(video_content->name);
-    if (!ret) {
-      LOG(LERROR) << "Failed to create video channel for "
-                  << video_content->name;
-      return false;
-    }
-  }
-  // Provide remote candidates to the transport
-  transport_->OnRemoteCandidates(candidates);
-
-  set_remote_description(offer);
-  SetState(STATE_RECEIVEDINITIATE);
-
-  transport_->ConnectChannels();
-  EnableAllStreams();
-
-  set_local_description(answer.release());
-
-  // AddStream called only once with Video label
-  if (video_content) {
-    SignalAddStream(video_content->name, true);
-  } else {
-    SignalAddStream(audio_content->name, false);
-  }
-  SetState(STATE_SENTACCEPT);
-  return true;
-}
-
-bool WebRtcSession::OnRemoteDescription(
-    cricket::SessionDescription* desc,
-    const std::vector<cricket::Candidate>& candidates) {
-  if (state() == STATE_SENTACCEPT ||
-      state() == STATE_RECEIVEDACCEPT ||
-      state() == STATE_INPROGRESS) {
-    transport_->OnRemoteCandidates(candidates);
-    return true;
-  }
-  // Session description is always accepted.
-  set_remote_description(desc);
-  SetState(STATE_RECEIVEDACCEPT);
-  // Will trigger OnWritableState() if successful.
-  transport_->OnRemoteCandidates(candidates);
-
-  if (!incoming()) {
-    // Trigger OnAddStream callback at the initiator
-    const cricket::ContentInfo* video_content = GetFirstVideoContent(desc);
-    if (video_content && !SendSignalAddStream(true)) {
-      LOG(LERROR) << "Video stream unexpected in answer.";
-      return false;
-    } else {
-      const cricket::ContentInfo* audio_content = GetFirstAudioContent(desc);
-      if (audio_content && !SendSignalAddStream(false)) {
-        LOG(LERROR) << "Audio stream unexpected in answer.";
-        return false;
-      }
-    }
-  }
-  return true;
-}
-
-// Send the SignalAddStream with the stream_id based on the content type.
-bool WebRtcSession::SendSignalAddStream(bool video) {
-  StreamMap::const_iterator iter;
-  for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
-    StreamInfo* sinfo = (*iter);
-    if (sinfo->video == video) {
-      SignalAddStream(sinfo->stream_id, video);
-      return true;
-    }
-  }
-  return false;
-}
-
-cricket::SessionDescription* WebRtcSession::CreateOffer() {
-  cricket::MediaSessionOptions options;
-  options.has_audio = false;  // disable default option
-  StreamMap::const_iterator iter;
-  for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
-    if ((*iter)->video) {
-      options.has_video = true;
-    } else {
-      options.has_audio = true;
-    }
-  }
-  // We didn't save the previous offer.
-  const cricket::SessionDescription* previous_offer = NULL;
-  return desc_factory_.CreateOffer(options, previous_offer);
-}
-
-cricket::SessionDescription* WebRtcSession::CreateAnswer(
-    const cricket::SessionDescription* offer,
-    const cricket::MediaSessionOptions& options) {
-  // We didn't save the previous answer.
-  const cricket::SessionDescription* previous_answer = NULL;
-  return desc_factory_.CreateAnswer(offer, options, previous_answer);
-}
-
-void WebRtcSession::SetError(Error error) {
-  BaseSession::SetError(error);
-}
-
-void WebRtcSession::OnCandidatesReady(
-    cricket::Transport* transport,
-    const std::vector<cricket::Candidate>& candidates) {
-  std::vector<cricket::Candidate>::const_iterator iter;
-  for (iter = candidates.begin(); iter != candidates.end(); ++iter) {
-    local_candidates_.push_back(*iter);
-  }
-  SignalLocalDescription(local_description(), candidates);
-}
-} /* namespace webrtc */
diff --git a/third_party/libjingle/source/talk/app/webrtc/webrtcsession.h b/third_party/libjingle/source/talk/app/webrtc/webrtcsession.h
deleted file mode 100644
index 8f6c6ad..0000000
--- a/third_party/libjingle/source/talk/app/webrtc/webrtcsession.h
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_APP_WEBRTC_WEBRTCSESSION_H_
-#define TALK_APP_WEBRTC_WEBRTCSESSION_H_
-
-#include <map>
-#include <string>
-#include <vector>
-
-#include "talk/base/logging.h"
-#include "talk/base/messagehandler.h"
-#include "talk/p2p/base/candidate.h"
-#include "talk/p2p/base/session.h"
-#include "talk/session/phone/channel.h"
-#include "talk/session/phone/mediachannel.h"
-#include "talk/session/phone/mediasession.h"
-
-namespace cricket {
-class ChannelManager;
-class Transport;
-class TransportChannel;
-class VoiceChannel;
-class VideoChannel;
-struct ConnectionInfo;
-}
-
-namespace Json {
-class Value;
-}
-
-namespace webrtc {
-
-typedef std::vector<cricket::AudioCodec> AudioCodecs;
-typedef std::vector<cricket::VideoCodec> VideoCodecs;
-
-class WebRtcSession : public cricket::BaseSession {
- public:
-  WebRtcSession(const std::string& id,
-                    bool incoming,
-                    cricket::PortAllocator* allocator,
-                    cricket::ChannelManager* channelmgr,
-                    talk_base::Thread* signaling_thread);
-
-  ~WebRtcSession();
-
-  bool Initiate();
-  bool Connect();
-  bool OnRemoteDescription(cricket::SessionDescription* sdp,
-      const std::vector<cricket::Candidate>& candidates);
-  bool OnInitiateMessage(cricket::SessionDescription* sdp,
-      const std::vector<cricket::Candidate>& candidates);
-  bool CreateVoiceChannel(const std::string& stream_id);
-  bool CreateVideoChannel(const std::string& stream_id);
-  bool RemoveStream(const std::string& stream_id);
-  void RemoveAllStreams();
-
-  // Returns true if we have either a voice or video stream matching this label.
-  bool HasStream(const std::string& label) const;
-  bool HasChannel(bool video) const;
-
-  // Returns true if there's one or more audio channels in the session.
-  bool HasAudioChannel() const;
-
-  // Returns true if there's one or more video channels in the session.
-  bool HasVideoChannel() const;
-
-  bool SetVideoRenderer(const std::string& stream_id,
-                        cricket::VideoRenderer* renderer);
-
-  // This signal occurs when all the streams have been removed.
-  // It is triggered by a successful call to the RemoveAllStream or
-  // the OnRemoteDescription with stream deleted signaling message with the
-  // candidates port equal to 0.
-  sigslot::signal1<WebRtcSession*> SignalRemoveStreamMessage;
-
-  // This signal indicates a stream has been added properly.
-  // It is triggered by a successful call to the OnInitiateMessage or
-  // the OnRemoteDescription and if it's going to the STATE_RECEIVEDACCEPT.
-  sigslot::signal2<const std::string&, bool> SignalAddStream;
-
-  // This signal occurs when one stream is removed with the signaling
-  // message from the remote peer with the candidates port equal to 0.
-  sigslot::signal2<const std::string&, bool> SignalRemoveStream;
-
-  // This signal occurs when the local candidate is ready
-  sigslot::signal2<const cricket::SessionDescription*,
-      const std::vector<cricket::Candidate>&> SignalLocalDescription;
-
-  // This signal triggers when setting up or resuming a call has not been
-  // successful before a certain time out.
-  sigslot::signal0<> SignalFailedCall;
-
-  bool muted() const { return muted_; }
-  bool camera_muted() const { return camera_muted_; }
-  const std::vector<cricket::Candidate>& local_candidates() {
-    return local_candidates_;
-  }
-  void set_incoming(bool incoming) { incoming_ = incoming; }
-  bool incoming() const { return incoming_; }
-  cricket::PortAllocator* port_allocator() const { return port_allocator_; }
-  talk_base::Thread* signaling_thread() const { return signaling_thread_; }
-
-  static const int kDefaultVideoCodecWidth = 640;
-  static const int kDefaultVideoCodecHeight = 480;
-
- protected:
-  // methods from cricket::BaseSession
-  virtual void SetError(cricket::BaseSession::Error error);
-  virtual cricket::TransportChannel* CreateChannel(
-      const std::string& content_name, const std::string& name);
-  virtual cricket::TransportChannel* GetChannel(
-      const std::string& content_name, const std::string& name);
-  virtual void DestroyChannel(
-      const std::string& content_name, const std::string& name);
-
- private:
-  struct StreamInfo {
-    explicit StreamInfo(const std::string stream_id)
-        : channel(NULL),
-          video(false),
-          stream_id(stream_id) {}
-
-    StreamInfo()
-        : channel(NULL),
-          video(false) {}
-    cricket::BaseChannel* channel;
-    bool video;
-    std::string stream_id;
-  };
-  // Not really a map (vector).
-  typedef std::vector<StreamInfo*> StreamMap;
-
-  // methods signaled by the transport
-  void OnRequestSignaling(cricket::Transport* transport);
-  void OnCandidatesReady(cricket::Transport* transport,
-                         const std::vector<cricket::Candidate>& candidates);
-  void OnWritableState(cricket::Transport* transport);
-  void OnTransportError(cricket::Transport* transport);
-  void OnChannelGone(cricket::Transport* transport);
-
-  bool CheckForStreamDeleteMessage(
-      const std::vector<cricket::Candidate>& candidates);
-  void ProcessTerminateAccept(cricket::SessionDescription* desc);
-
-  void UpdateTransportWritableState();
-  bool CheckAllTransportsWritable();
-  void StartTransportTimeout(int timeout);
-  void NotifyTransportState();
-
-  cricket::SessionDescription* CreateOffer();
-  cricket::SessionDescription* CreateAnswer(
-      const cricket::SessionDescription* answer,
-      const cricket::MediaSessionOptions& options);
-
-  // from MessageHandler
-  virtual void OnMessage(talk_base::Message* message);
-
-  virtual cricket::Transport* CreateTransport();
-  cricket::Transport* GetTransport();
-
-  typedef std::map<std::string, cricket::TransportChannel*> TransportChannelMap;
-
-  bool SetVideoCapture(bool capture);
-  void EnableAllStreams();
-  bool SendSignalAddStream(bool video);
-
-  cricket::Transport* transport_;
-  cricket::ChannelManager* channel_manager_;
-  std::vector<StreamInfo*> streams_;
-  TransportChannelMap transport_channels_;
-  bool transports_writable_;
-  bool muted_;
-  bool camera_muted_;
-  int setup_timeout_;
-  std::vector<cricket::Candidate> local_candidates_;
-
-  talk_base::Thread* signaling_thread_;
-  bool incoming_;
-  cricket::PortAllocator* port_allocator_;
-  cricket::MediaSessionDescriptionFactory desc_factory_;
-};
-
-}  // namespace webrtc
-
-#endif  // TALK_APP_WEBRTC_WEBRTCSESSION_H_
diff --git a/third_party/libjingle/source/talk/app/webrtc/webrtcsession_unittest.cc b/third_party/libjingle/source/talk/app/webrtc/webrtcsession_unittest.cc
deleted file mode 100644
index 85339c0..0000000
--- a/third_party/libjingle/source/talk/app/webrtc/webrtcsession_unittest.cc
+++ /dev/null
@@ -1,407 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdio.h>
-
-#include <list>
-
-#include "base/gunit.h"
-#include "base/helpers.h"
-#include "talk/app/webrtc/unittest_utilities.h"
-#include "talk/app/webrtc/webrtcsession.h"
-#include "talk/base/fakenetwork.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/base/thread.h"
-#include "talk/p2p/base/fakesession.h"
-#include "talk/p2p/base/portallocator.h"
-#include "talk/p2p/base/sessiondescription.h"
-#include "talk/p2p/client/fakeportallocator.h"
-#include "talk/session/phone/mediasessionclient.h"
-
-class WebRtcSessionTest
-    : public sigslot::has_slots<>,
-      public testing::Test {
- public:
-  enum CallbackId {
-    kNone,
-    kOnAddStream,
-    kOnRemoveStream,
-    kOnLocalDescription,
-    kOnFailedCall,
-  };
-
-  WebRtcSessionTest()
-      : callback_ids_(),
-        last_stream_id_(""),
-        last_was_video_(false),
-        last_description_ptr_(NULL),
-        last_candidates_(),
-        session_(NULL),
-        id_(),
-        receiving_(false),
-        allocator_(NULL),
-        channel_manager_(NULL),
-        worker_thread_(NULL),
-        signaling_thread_(NULL) {
-  }
-
-  ~WebRtcSessionTest() {
-    session_.reset();
-  }
-
-  void OnAddStream(const std::string& stream_id, bool video) {
-    callback_ids_.push_back(kOnAddStream);
-    last_stream_id_ = stream_id;
-    last_was_video_ = video;
-  }
-  void OnRemoveStream(const std::string& stream_id, bool video) {
-    callback_ids_.push_back(kOnRemoveStream);
-    last_stream_id_ = stream_id;
-    last_was_video_ = video;
-  }
-  void OnLocalDescription(
-      const cricket::SessionDescription* desc,
-      const std::vector<cricket::Candidate>& candidates) {
-    callback_ids_.push_back(kOnLocalDescription);
-    last_description_ptr_.reset(CopySessionDescription(desc));
-    CopyCandidates(candidates, &last_candidates_);
-  }
-  cricket::SessionDescription* GetLocalDescription(
-      std::vector<cricket::Candidate>* candidates) {
-    if (last_candidates_.empty()) {
-      return NULL;
-    }
-    if (!last_description_ptr_.get()) {
-      return NULL;
-    }
-    CopyCandidates(last_candidates_, candidates);
-    return CopySessionDescription(last_description_ptr_.get());
-  }
-
-  void OnFailedCall() {
-    callback_ids_.push_back(kOnFailedCall);
-  }
-
-  CallbackId PopOldestCallback() {
-    if (callback_ids_.empty()) {
-      return kNone;
-    }
-    const CallbackId return_value = callback_ids_.front();
-    callback_ids_.pop_front();
-    return return_value;
-  }
-
-  CallbackId PeekOldestCallback() {
-    if (callback_ids_.empty()) {
-      return kNone;
-    }
-    const CallbackId return_value = callback_ids_.front();
-    return return_value;
-  }
-
-  void Reset() {
-    callback_ids_.clear();
-    last_stream_id_ = "";
-    last_was_video_ = false;
-    last_description_ptr_.reset();
-    last_candidates_.clear();
-  }
-
-  bool WaitForCallback(CallbackId id, int timeout_ms) {
-    bool success = false;
-    for (int ms = 0; ms < timeout_ms; ms++) {
-      const CallbackId peek_id = PeekOldestCallback();
-      if (peek_id == id) {
-        PopOldestCallback();
-        success = true;
-        break;
-      } else if (peek_id != kNone) {
-        success = false;
-        break;
-      }
-      talk_base::Thread::Current()->ProcessMessages(1);
-    }
-    return success;
-  }
-
-  bool Init(bool receiving) {
-    if (signaling_thread_ != NULL)
-        return false;
-    signaling_thread_ = talk_base::Thread::Current();
-    receiving_ = receiving;
-
-    if (worker_thread_!= NULL)
-        return false;
-    worker_thread_ = talk_base::Thread::Current();
-
-    cricket::FakePortAllocator* fake_port_allocator =
-        new cricket::FakePortAllocator(worker_thread_, NULL);
-
-    allocator_.reset(static_cast<cricket::PortAllocator*>(fake_port_allocator));
-
-    channel_manager_.reset(new cricket::ChannelManager(worker_thread_));
-    if (!channel_manager_->Init())
-      return false;
-
-    talk_base::CreateRandomString(8, &id_);
-
-    session_.reset(new webrtc::WebRtcSession(
-        id_, receiving_ , allocator_.get(),
-        channel_manager_.get(),
-        signaling_thread_));
-    session_->SignalAddStream.connect(this, &WebRtcSessionTest::OnAddStream);
-    session_->SignalRemoveStream.connect(this,
-        &WebRtcSessionTest::OnRemoveStream);
-    session_->SignalLocalDescription.connect(this,
-        &WebRtcSessionTest::OnLocalDescription);
-    session_->SignalFailedCall.connect(this, &WebRtcSessionTest::OnFailedCall);
-    return true;
-  }
-
-  // All session APIs must be called from the signaling thread.
-  bool CallInitiate() {
-    return session_->Initiate();
-  }
-
-  bool CallConnect() {
-    if (!session_->Connect())
-      return false;
-    // This callback does not happen with FakeTransport!
-    if (!WaitForCallback(kOnLocalDescription, 1000)) {
-      return false;
-    }
-    return true;
-  }
-
-  bool CallOnRemoteDescription(
-      cricket::SessionDescription* description,
-      std::vector<cricket::Candidate> candidates) {
-    if (!session_->OnRemoteDescription(description, candidates)) {
-      return false;
-    }
-    if (!WaitForCallback(kOnAddStream, 1000)) {
-      return false;
-    }
-    return true;
-  }
-
-  bool CallOnInitiateMessage(
-      cricket::SessionDescription* description,
-      const std::vector<cricket::Candidate>& candidates) {
-    if (!session_->OnInitiateMessage(description, candidates)) {
-      return false;
-    }
-    if (!WaitForCallback(kOnAddStream, 1000)) {
-      return false;
-    }
-    return true;
-  }
-
-  bool CallCreateVoiceChannel(const std::string& stream_id) {
-    if (!session_->CreateVoiceChannel(stream_id)) {
-      return false;
-    }
-    return true;
-  }
-
-  bool CallCreateVideoChannel(const std::string& stream_id) {
-    if (!session_->CreateVideoChannel(stream_id)) {
-      return false;
-    }
-    return true;
-  }
-
-  bool CallRemoveStream(const std::string& stream_id) {
-    return session_->RemoveStream(stream_id);
-  }
-
-  void CallRemoveAllStreams() {
-    session_->RemoveAllStreams();
-  }
-
-  bool CallHasChannel(const std::string& label) {
-    return session_->HasStream(label);
-  }
-
-  bool CallHasChannel(bool video) {
-    return session_->HasChannel(video);
-  }
-
-  bool CallHasAudioChannel() {
-    return session_->HasAudioChannel();
-  }
-
-  bool CallHasVideoChannel() {
-    return session_->HasVideoChannel();
-  }
-
-  bool CallSetVideoRenderer(const std::string& stream_id,
-                            cricket::VideoRenderer* renderer) {
-    return session_->SetVideoRenderer(stream_id, renderer);
-  }
-
-  const std::vector<cricket::Candidate>& CallLocalCandidates() {
-    return session_->local_candidates();
-  }
-
- private:
-  std::list<CallbackId> callback_ids_;
-
-  std::string last_stream_id_;
-  bool last_was_video_;
-  talk_base::scoped_ptr<cricket::SessionDescription> last_description_ptr_;
-  std::vector<cricket::Candidate> last_candidates_;
-
-  talk_base::scoped_ptr<webrtc::WebRtcSession> session_;
-  std::string id_;
-  bool receiving_;
-
-  talk_base::scoped_ptr<cricket::PortAllocator> allocator_;
-
-  talk_base::scoped_ptr<cricket::ChannelManager> channel_manager_;
-
-  talk_base::Thread* worker_thread_;
-  talk_base::Thread* signaling_thread_;
-};
-
-bool CallbackReceived(WebRtcSessionTest* session, int timeout) {
-  EXPECT_EQ_WAIT(WebRtcSessionTest::kNone, session->PeekOldestCallback(),
-                 timeout);
-  const WebRtcSessionTest::CallbackId peek_id =
-      session->PeekOldestCallback();
-  return peek_id != WebRtcSessionTest::kNone;
-}
-
-TEST_F(WebRtcSessionTest, InitializationReceiveSanity) {
-  const bool kReceiving = true;
-  ASSERT_TRUE(Init(kReceiving));
-  ASSERT_TRUE(CallInitiate());
-
-  // Should return false because no stream has been set up yet.
-  EXPECT_FALSE(CallConnect());
-  const bool kVideo = true;
-  EXPECT_FALSE(CallHasChannel(kVideo));
-  EXPECT_FALSE(CallHasChannel(!kVideo));
-
-  EXPECT_EQ(kNone, PopOldestCallback());
-}
-
-TEST_F(WebRtcSessionTest, AudioSendCallSetUp) {
-  const bool kReceiving = false;
-  ASSERT_TRUE(Init(kReceiving));
-
-  ASSERT_TRUE(CallInitiate());
-
-  ASSERT_TRUE(CallCreateVoiceChannel("Audio"));
-  ASSERT_TRUE(CallConnect());
-
-  std::vector<cricket::Candidate> candidates;
-  cricket::SessionDescription* local_session = GetLocalDescription(
-      &candidates);
-  ASSERT_FALSE(candidates.empty());
-  ASSERT_FALSE(local_session == NULL);
-  if (!CallOnRemoteDescription(local_session, candidates)) {
-      delete local_session;
-      FAIL();
-  }
-
-  // All callbacks should be caught. Assert it.
-  ASSERT_FALSE(CallbackReceived(this, 1000));
-  ASSERT_TRUE(CallHasAudioChannel() &&
-              !CallHasVideoChannel());
-}
-
-TEST_F(WebRtcSessionTest, VideoSendCallSetUp) {
-  const bool kReceiving = false;
-  ASSERT_TRUE(Init(kReceiving));
-
-  ASSERT_TRUE(CallInitiate());
-
-  ASSERT_TRUE(CallCreateVideoChannel("Video"));
-  ASSERT_TRUE(CallConnect());
-
-  std::vector<cricket::Candidate> candidates;
-  cricket::SessionDescription* local_session = GetLocalDescription(
-      &candidates);
-  ASSERT_FALSE(candidates.empty());
-  ASSERT_FALSE(local_session == NULL);
-
-  if (!CallOnRemoteDescription(local_session, candidates)) {
-      delete local_session;
-      FAIL();
-  }
-
-  // All callbacks should be caught. Assert it.
-  ASSERT_FALSE(CallbackReceived(this, 1000));
-  ASSERT_TRUE(!CallHasAudioChannel() &&
-              CallHasVideoChannel());
-}
-
-TEST_F(WebRtcSessionTest, AudioReceiveCallSetUp) {
-  const bool kReceiving = true;
-  const bool video = false;
-
-  ASSERT_TRUE(Init(kReceiving));
-
-  std::vector<cricket::Candidate> candidates;
-  cricket::SessionDescription* local_session =
-      GenerateFakeSession(video, &candidates);
-  ASSERT_FALSE(candidates.empty());
-  ASSERT_FALSE(local_session == NULL);
-  ASSERT_TRUE(CallInitiate());
-  if (!CallOnInitiateMessage(local_session, candidates)) {
-    delete local_session;
-    FAIL();
-  }
-  ASSERT_TRUE(CallConnect());
-  ASSERT_FALSE(CallbackReceived(this, 1000));
-
-  ASSERT_TRUE(CallHasAudioChannel() &&
-              !CallHasVideoChannel());
-}
-
-TEST_F(WebRtcSessionTest, VideoReceiveCallSetUp) {
-  const bool kReceiving = true;
-  const bool video = true;
-
-  ASSERT_TRUE(Init(kReceiving));
-
-  std::vector<cricket::Candidate> candidates;
-  cricket::SessionDescription* local_session =
-      GenerateFakeSession(video, &candidates);
-  ASSERT_FALSE(candidates.empty());
-  ASSERT_FALSE(local_session == NULL);
-  ASSERT_TRUE(CallInitiate());
-  if (!CallOnInitiateMessage(local_session, candidates)) {
-    delete local_session;
-    FAIL();
-  }
-  ASSERT_TRUE(CallConnect());
-  ASSERT_FALSE(CallbackReceived(this, 1000));
-  ASSERT_TRUE(!CallHasAudioChannel() &&
-              CallHasVideoChannel());
-}
diff --git a/third_party/libjingle/source/talk/app/webrtcv1/peerconnection.h b/third_party/libjingle/source/talk/app/webrtcv1/peerconnection.h
deleted file mode 100644
index c28508f..0000000
--- a/third_party/libjingle/source/talk/app/webrtcv1/peerconnection.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_APP_WEBRTC_PEERCONNECTION_H_
-#define TALK_APP_WEBRTC_PEERCONNECTION_H_
-
-// TODO - Add a factory class or some kind of PeerConnection manager
-// to support multiple PeerConnection object instantiation. This class will
-// create ChannelManager object and pass it to PeerConnection object. Otherwise
-// each PeerConnection object will have its own ChannelManager hence MediaEngine
-// and VoiceEngine/VideoEngine.
-
-#include <string>
-
-namespace cricket {
-class VideoRenderer;
-}
-
-namespace talk_base {
-class Thread;
-}
-
-namespace webrtc {
-
-class PeerConnectionObserver {
- public:
-  // serialized signaling message
-  virtual void OnSignalingMessage(const std::string& msg) = 0;
-
-  // Triggered when a remote peer accepts a media connection.
-  virtual void OnAddStream(const std::string& stream_id, bool video) = 0;
-
-  // Triggered when a remote peer closes a media stream.
-  virtual void OnRemoveStream(const std::string& stream_id, bool video) = 0;
-
- protected:
-  // Dtor protected as objects shouldn't be deleted via this interface.
-  virtual ~PeerConnectionObserver() {}
-};
-
-class PeerConnection {
- public:
-  enum ReadyState {
-    NEW = 0,
-    NEGOTIATING,
-    ACTIVE,
-    CLOSED,
-  };
-
-  virtual ~PeerConnection() {}
-
-  // Register a listener
-  virtual void RegisterObserver(PeerConnectionObserver* observer) = 0;
-
-  // SignalingMessage in json format
-  virtual bool SignalingMessage(const std::string& msg) = 0;
-
-  // Asynchronously adds a local stream device to the peer
-  // connection.
-  virtual bool AddStream(const std::string& stream_id, bool video) = 0;
-
-  // Asynchronously removes a local stream device from the peer
-  // connection. The operation is complete when
-  // PeerConnectionObserver::OnRemoveStream is called.
-  virtual bool RemoveStream(const std::string& stream_id) = 0;
-
-  // Info the peerconnection that it is time to return the signaling
-  // information. The operation is complete when
-  // PeerConnectionObserver::OnSignalingMessage is called.
-  virtual bool Connect() = 0;
-
-  // Remove all the streams and tear down the session.
-  // After the Close() is called, the OnSignalingMessage will be invoked
-  // asynchronously. And before OnSignalingMessage is called,
-  // OnRemoveStream will be called for each stream that was active.
-  // TODO: Add an event such as onclose, or onreadystatechanged
-  // when the readystate reaches the closed state (no more streams in the
-  // peerconnection object.
-  virtual bool Close() = 0;
-
-  // Set the audio input & output devices based on the given device name.
-  // An empty device name means to use the default audio device.
-  virtual bool SetAudioDevice(const std::string& wave_in_device,
-                              const std::string& wave_out_device,
-                              int opts) = 0;
-
-  // Set the video renderer for the camera preview.
-  virtual bool SetLocalVideoRenderer(cricket::VideoRenderer* renderer) = 0;
-
-  // Set the video renderer for the specified stream.
-  virtual bool SetVideoRenderer(const std::string& stream_id,
-                                cricket::VideoRenderer* renderer) = 0;
-
-  // Set video capture device
-  // For Chromium the cam_device should use the capture session id.
-  // For standalone app, cam_device is the camera name. It will try to
-  // set the default capture device when cam_device is "".
-  virtual bool SetVideoCapture(const std::string& cam_device) = 0;
-
-  // Returns the state of the PeerConnection object.  See the ReadyState
-  // enum for valid values.
-  virtual ReadyState GetReadyState() = 0;
-};
-
-}  // namespace webrtc
-
-#endif  // TALK_APP_WEBRTC_PEERCONNECTION_H_
diff --git a/third_party/libjingle/source/talk/app/webrtcv1/peerconnectionfactory.cc b/third_party/libjingle/source/talk/app/webrtcv1/peerconnectionfactory.cc
deleted file mode 100644
index 7bf2f89..0000000
--- a/third_party/libjingle/source/talk/app/webrtcv1/peerconnectionfactory.cc
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/app/webrtcv1/peerconnectionfactory.h"
-
-#include "talk/app/webrtcv1/peerconnectionproxy.h"
-#include "talk/base/logging.h"
-#include "talk/p2p/client/basicportallocator.h"
-#include "talk/session/phone/channelmanager.h"
-
-namespace webrtc {
-
-PeerConnectionFactory::PeerConnectionFactory(
-    cricket::MediaEngineInterface* media_engine,
-    cricket::DeviceManagerInterface* device_manager,
-    talk_base::Thread* worker_thread)
-    : initialized_(false),
-      channel_manager_(new cricket::ChannelManager(media_engine,
-                                                   device_manager,
-                                                   worker_thread)) {
-}
-
-PeerConnectionFactory::PeerConnectionFactory(
-    talk_base::Thread* worker_thread)
-    : initialized_(false),
-      channel_manager_(new cricket::ChannelManager(worker_thread)) {
-}
-
-PeerConnectionFactory::~PeerConnectionFactory() {
-}
-
-bool PeerConnectionFactory::Initialize() {
-  ASSERT(channel_manager_.get() != NULL);
-  initialized_ = channel_manager_->Init();
-  return initialized_;
-}
-
-PeerConnection* PeerConnectionFactory::CreatePeerConnection(
-    cricket::PortAllocator* port_allocator,
-    talk_base::Thread* signaling_thread) {
-  PeerConnectionProxy* pc = NULL;
-  if (initialized_) {
-    pc =  new PeerConnectionProxy(
-        port_allocator, channel_manager_.get(), signaling_thread);
-    if (!pc->Init()) {
-      LOG(LERROR) << "Error in initializing PeerConnection";
-      delete pc;
-      pc = NULL;
-    }
-  } else {
-    LOG(LERROR) << "PeerConnectionFactory is not initialize";
-  }
-  return pc;
-}
-
-}  // namespace webrtc
diff --git a/third_party/libjingle/source/talk/app/webrtcv1/peerconnectionfactory.h b/third_party/libjingle/source/talk/app/webrtcv1/peerconnectionfactory.h
deleted file mode 100644
index ea509d6..0000000
--- a/third_party/libjingle/source/talk/app/webrtcv1/peerconnectionfactory.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_APP_WEBRTC_PEERCONNECTIONFACTORY_H_
-#define TALK_APP_WEBRTC_PEERCONNECTIONFACTORY_H_
-
-#include <string>
-#include <vector>
-
-#include "talk/base/scoped_ptr.h"
-
-namespace cricket {
-class ChannelManager;
-class DeviceManagerInterface;
-class MediaEngineInterface;
-class PortAllocator;
-}  // namespace cricket
-
-namespace talk_base {
-class SocketAddress;
-class Thread;
-}  // namespace talk_base
-
-namespace webrtc {
-
-class PeerConnection;
-
-class PeerConnectionFactory {
- public:
-  PeerConnectionFactory(cricket::MediaEngineInterface* media_engine,
-                        cricket::DeviceManagerInterface* device_manager,
-                        talk_base::Thread* worker_thread);
-  PeerConnectionFactory(talk_base::Thread* worker_thread);
-
-  virtual ~PeerConnectionFactory();
-  bool Initialize();
-
-  PeerConnection* CreatePeerConnection(
-      cricket::PortAllocator* port_allocator,
-      talk_base::Thread* signaling_thread);
-
- private:
-  bool initialized_;
-  talk_base::scoped_ptr<cricket::ChannelManager> channel_manager_;
-};
-
-}  // namespace webrtc
-
-#endif  // TALK_APP_WEBRTC_PEERCONNECTIONFACTORY_H_
-
diff --git a/third_party/libjingle/source/talk/app/webrtcv1/peerconnectionimpl.cc b/third_party/libjingle/source/talk/app/webrtcv1/peerconnectionimpl.cc
deleted file mode 100644
index be67859..0000000
--- a/third_party/libjingle/source/talk/app/webrtcv1/peerconnectionimpl.cc
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/app/webrtcv1/peerconnectionimpl.h"
-
-#include "talk/app/webrtcv1/webrtcjson.h"
-#include "talk/app/webrtcv1/webrtcsession.h"
-#include "talk/base/basicpacketsocketfactory.h"
-#include "talk/base/helpers.h"
-#include "talk/base/logging.h"
-#include "talk/base/stringencode.h"
-#include "talk/p2p/base/session.h"
-#include "talk/p2p/client/basicportallocator.h"
-
-namespace webrtc {
-
-
-PeerConnectionImpl::PeerConnectionImpl(
-    cricket::PortAllocator* port_allocator,
-    cricket::ChannelManager* channel_manager,
-    talk_base::Thread* signaling_thread)
-  : port_allocator_(port_allocator),
-    channel_manager_(channel_manager),
-    signaling_thread_(signaling_thread),
-    event_callback_(NULL),
-    session_(NULL) {
-}
-
-PeerConnectionImpl::~PeerConnectionImpl() {
-}
-
-bool PeerConnectionImpl::Init() {
-  std::string sid;
-  talk_base::CreateRandomString(8, &sid);
-  const bool incoming = false;
-  // default outgoing direction
-  session_.reset(CreateMediaSession(sid, incoming));
-  if (session_.get() == NULL) {
-    ASSERT(false && "failed to initialize a session");
-    return false;
-  }
-  return true;
-}
-
-void PeerConnectionImpl::RegisterObserver(PeerConnectionObserver* observer) {
-  // This assert is to catch cases where two observer pointers are registered.
-  // We only support one and if another is to be used, the current one must be
-  // cleared first.
-  ASSERT(observer == NULL || event_callback_ == NULL);
-  event_callback_ = observer;
-}
-
-bool PeerConnectionImpl::SignalingMessage(
-    const std::string& signaling_message) {
-  // Deserialize signaling message
-  cricket::SessionDescription* incoming_sdp = NULL;
-  std::vector<cricket::Candidate> candidates;
-  if (!ParseJsonSignalingMessage(signaling_message,
-                                 &incoming_sdp, &candidates)) {
-    return false;
-  }
-
-  bool ret = false;
-  if (GetReadyState() == NEW) {
-    // set direction to incoming, as message received first
-    session_->set_incoming(true);
-    ret = session_->OnInitiateMessage(incoming_sdp, candidates);
-  } else {
-    ret = session_->OnRemoteDescription(incoming_sdp, candidates);
-  }
-  return ret;
-}
-
-WebRtcSession* PeerConnectionImpl::CreateMediaSession(
-    const std::string& id, bool incoming) {
-  ASSERT(port_allocator_ != NULL);
-  WebRtcSession* session = new WebRtcSession(id, incoming,
-      port_allocator_, channel_manager_, signaling_thread_);
-
-  if (session->Initiate()) {
-    session->SignalAddStream.connect(
-        this,
-        &PeerConnectionImpl::OnAddStream);
-    session->SignalRemoveStream.connect(
-        this,
-        &PeerConnectionImpl::OnRemoveStream);
-    session->SignalLocalDescription.connect(
-        this,
-        &PeerConnectionImpl::OnLocalDescription);
-    session->SignalFailedCall.connect(
-        this,
-        &PeerConnectionImpl::OnFailedCall);
-  } else {
-    delete session;
-    session = NULL;
-  }
-  return session;
-}
-
-bool PeerConnectionImpl::AddStream(const std::string& stream_id, bool video) {
-  bool ret = false;
-  if (session_->HasStream(stream_id)) {
-    ASSERT(false && "A stream with this name already exists");
-  } else {
-    if (!video) {
-      ret = !session_->HasAudioChannel() &&
-            session_->CreateVoiceChannel(stream_id);
-    } else {
-      ret = !session_->HasVideoChannel() &&
-            session_->CreateVideoChannel(stream_id);
-    }
-  }
-  return ret;
-}
-
-bool PeerConnectionImpl::RemoveStream(const std::string& stream_id) {
-  return session_->RemoveStream(stream_id);
-}
-
-void PeerConnectionImpl::OnLocalDescription(
-    const cricket::SessionDescription* desc,
-    const std::vector<cricket::Candidate>& candidates) {
-  if (!desc) {
-    LOG(WARNING) << "no local SDP ";
-    return;
-  }
-
-  std::string message;
-  if (GetJsonSignalingMessage(desc, candidates, &message)) {
-    if (event_callback_) {
-      event_callback_->OnSignalingMessage(message);
-    }
-  }
-}
-
-void PeerConnectionImpl::OnFailedCall() {
-  // TODO: implement.
-}
-
-bool PeerConnectionImpl::SetAudioDevice(const std::string& wave_in_device,
-                                        const std::string& wave_out_device,
-                                        int opts) {
-  return channel_manager_->SetAudioOptions(wave_in_device,
-                                           wave_out_device,
-                                           opts);
-}
-
-bool PeerConnectionImpl::SetLocalVideoRenderer(
-    cricket::VideoRenderer* renderer) {
-  return channel_manager_->SetLocalRenderer(renderer);
-}
-
-bool PeerConnectionImpl::SetVideoRenderer(const std::string& stream_id,
-                                          cricket::VideoRenderer* renderer) {
-  return session_->SetVideoRenderer(stream_id, renderer);
-}
-
-bool PeerConnectionImpl::SetVideoCapture(const std::string& cam_device) {
-  return channel_manager_->SetVideoOptions(cam_device);
-}
-
-bool PeerConnectionImpl::Connect() {
-  return session_->Connect();
-}
-
-// TODO - Close is not used anymore, should be removed.
-bool PeerConnectionImpl::Close() {
-  session_->RemoveAllStreams();
-  return true;
-}
-
-void PeerConnectionImpl::OnAddStream(const std::string& stream_id,
-                                     bool video) {
-  if (event_callback_) {
-    event_callback_->OnAddStream(stream_id, video);
-  }
-}
-
-void PeerConnectionImpl::OnRemoveStream(const std::string& stream_id,
-                                        bool video) {
-  if (event_callback_) {
-    event_callback_->OnRemoveStream(stream_id, video);
-  }
-}
-
-PeerConnectionImpl::ReadyState PeerConnectionImpl::GetReadyState() {
-  ReadyState ready_state;
-  cricket::BaseSession::State state = session_->state();
-  if (state == cricket::BaseSession::STATE_INIT) {
-    ready_state = NEW;
-  } else if (state == cricket::BaseSession::STATE_INPROGRESS) {
-    ready_state = ACTIVE;
-  } else if (state == cricket::BaseSession::STATE_DEINIT) {
-    ready_state = CLOSED;
-  } else {
-    ready_state = NEGOTIATING;
-  }
-  return ready_state;
-}
-
-}  // namespace webrtc
diff --git a/third_party/libjingle/source/talk/app/webrtcv1/peerconnectionimpl.h b/third_party/libjingle/source/talk/app/webrtcv1/peerconnectionimpl.h
deleted file mode 100644
index 8cb2414..0000000
--- a/third_party/libjingle/source/talk/app/webrtcv1/peerconnectionimpl.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_APP_WEBRTC_PEERCONNECTIONIMPL_H_
-#define TALK_APP_WEBRTC_PEERCONNECTIONIMPL_H_
-
-#include <string>
-#include <vector>
-
-#include "talk/app/webrtcv1/peerconnection.h"
-#include "talk/base/sigslot.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/base/thread.h"
-#include "talk/session/phone/channelmanager.h"
-
-namespace cricket {
-class ChannelManager;
-class PortAllocator;
-class SessionDescription;
-}
-
-namespace webrtc {
-class WebRtcSession;
-
-class PeerConnectionImpl : public PeerConnection,
-                           public sigslot::has_slots<> {
- public:
-  PeerConnectionImpl(cricket::PortAllocator* port_allocator,
-                     cricket::ChannelManager* channel_manager,
-                     talk_base::Thread* signaling_thread);
-  virtual ~PeerConnectionImpl();
-
-  // PeerConnection interfaces
-  virtual void RegisterObserver(PeerConnectionObserver* observer);
-  virtual bool SignalingMessage(const std::string& msg);
-  virtual bool AddStream(const std::string& stream_id, bool video);
-  virtual bool RemoveStream(const std::string& stream_id);
-  virtual bool Connect();
-  virtual bool Close();
-  virtual bool SetAudioDevice(const std::string& wave_in_device,
-                              const std::string& wave_out_device, int opts);
-  virtual bool SetLocalVideoRenderer(cricket::VideoRenderer* renderer);
-  virtual bool SetVideoRenderer(const std::string& stream_id,
-                                cricket::VideoRenderer* renderer);
-  virtual bool SetVideoCapture(const std::string& cam_device);
-  virtual ReadyState GetReadyState();
-
-  cricket::ChannelManager* channel_manager() {
-    return channel_manager_;
-  }
-
-  // Callbacks from PeerConnectionImplCallbacks
-  void OnAddStream(const std::string& stream_id, bool video);
-  void OnRemoveStream(const std::string& stream_id, bool video);
-  void OnLocalDescription(
-      const cricket::SessionDescription* desc,
-      const std::vector<cricket::Candidate>& candidates);
-  void OnFailedCall();
-  bool Init();
-
- private:
-  WebRtcSession* CreateMediaSession(const std::string& id, bool incoming);
-
-  cricket::PortAllocator* port_allocator_;
-  cricket::ChannelManager* channel_manager_;
-  talk_base::Thread* signaling_thread_;
-  PeerConnectionObserver* event_callback_;
-  talk_base::scoped_ptr<WebRtcSession> session_;
-};
-
-}  // namespace webrtc
-
-#endif  // TALK_APP_WEBRTC_PEERCONNECTIONIMPL_H_
diff --git a/third_party/libjingle/source/talk/app/webrtcv1/peerconnectionproxy.cc b/third_party/libjingle/source/talk/app/webrtcv1/peerconnectionproxy.cc
deleted file mode 100644
index 3994b00..0000000
--- a/third_party/libjingle/source/talk/app/webrtcv1/peerconnectionproxy.cc
+++ /dev/null
@@ -1,313 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/app/webrtcv1/peerconnectionproxy.h"
-
-#include "talk/app/webrtcv1/peerconnectionimpl.h"
-#include "talk/base/logging.h"
-
-namespace webrtc {
-
-enum {
-  MSG_WEBRTC_ADDSTREAM = 1,
-  MSG_WEBRTC_CLOSE,
-  MSG_WEBRTC_CONNECT,
-  MSG_WEBRTC_INIT,
-  MSG_WEBRTC_REGISTEROBSERVER,
-  MSG_WEBRTC_RELEASE,
-  MSG_WEBRTC_REMOVESTREAM,
-  MSG_WEBRTC_SETAUDIODEVICE,
-  MSG_WEBRTC_SETLOCALRENDERER,
-  MSG_WEBRTC_SETVIDEOCAPTURE,
-  MSG_WEBRTC_SETVIDEORENDERER,
-  MSG_WEBRTC_SIGNALINGMESSAGE,
-  MSG_WEBRTC_GETREADYSTATE,
-};
-
-struct AddStreamParams : public talk_base::MessageData {
-  AddStreamParams(const std::string& stream_id, bool video)
-      : stream_id(stream_id),
-        video(video),
-        result(false) {}
-
-  std::string stream_id;
-  bool video;
-  bool result;
-};
-
-struct RemoveStreamParams : public talk_base::MessageData {
-  explicit RemoveStreamParams(const std::string& stream_id)
-      : stream_id(stream_id),
-        result(false) {}
-
-  std::string stream_id;
-  bool result;
-};
-
-struct SignalingMsgParams : public talk_base::MessageData {
-  explicit SignalingMsgParams(const std::string& signaling_message)
-      : signaling_message(signaling_message),
-        result(false) {}
-
-  std::string signaling_message;
-  bool result;
-};
-
-struct SetAudioDeviceParams : public talk_base::MessageData {
-  SetAudioDeviceParams(const std::string& wave_in_device,
-                       const std::string& wave_out_device,
-                       int opts)
-      : wave_in_device(wave_in_device), wave_out_device(wave_out_device),
-        opts(opts), result(false) {}
-
-  std::string wave_in_device;
-  std::string wave_out_device;
-  int opts;
-  bool result;
-};
-
-struct SetLocalRendererParams : public talk_base::MessageData {
-  explicit SetLocalRendererParams(cricket::VideoRenderer* renderer)
-      : renderer(renderer), result(false) {}
-
-  cricket::VideoRenderer* renderer;
-  bool result;
-};
-
-struct SetVideoRendererParams : public talk_base::MessageData {
-  SetVideoRendererParams(const std::string& stream_id,
-                         cricket::VideoRenderer* renderer)
-      : stream_id(stream_id), renderer(renderer), result(false) {}
-
-  std::string stream_id;
-  cricket::VideoRenderer* renderer;
-  bool result;
-};
-
-struct SetVideoCaptureParams : public talk_base::MessageData {
-  explicit SetVideoCaptureParams(const std::string& cam_device)
-      : cam_device(cam_device), result(false) {}
-
-  std::string cam_device;
-  bool result;
-};
-
-struct RegisterObserverParams : public talk_base::MessageData {
-  explicit RegisterObserverParams(PeerConnectionObserver* observer)
-      : observer(observer), result(false) {}
-
-  PeerConnectionObserver* observer;
-  bool result;
-};
-
-struct ResultParams : public talk_base::MessageData {
-  ResultParams()
-      : result(false) {}
-
-  bool result;
-};
-
-PeerConnectionProxy::PeerConnectionProxy(
-    cricket::PortAllocator* port_allocator,
-    cricket::ChannelManager* channel_manager,
-      talk_base::Thread* signaling_thread)
-  : peerconnection_impl_(new PeerConnectionImpl(port_allocator,
-                             channel_manager, signaling_thread)),
-    signaling_thread_(signaling_thread) {
-}
-
-PeerConnectionProxy::~PeerConnectionProxy() {
-  ResultParams params;
-  Send(MSG_WEBRTC_RELEASE, &params);
-}
-
-bool PeerConnectionProxy::Init() {
-  ResultParams params;
-  return (Send(MSG_WEBRTC_INIT, &params) && params.result);
-}
-
-void PeerConnectionProxy::RegisterObserver(PeerConnectionObserver* observer) {
-  RegisterObserverParams params(observer);
-  Send(MSG_WEBRTC_REGISTEROBSERVER, &params);
-}
-
-bool PeerConnectionProxy::SignalingMessage(
-    const std::string& signaling_message) {
-  SignalingMsgParams params(signaling_message);
-  return (Send(MSG_WEBRTC_SIGNALINGMESSAGE, &params) && params.result);
-}
-
-bool PeerConnectionProxy::AddStream(const std::string& stream_id, bool video) {
-  AddStreamParams params(stream_id, video);
-  return (Send(MSG_WEBRTC_ADDSTREAM, &params) && params.result);
-}
-
-bool PeerConnectionProxy::RemoveStream(const std::string& stream_id) {
-  RemoveStreamParams params(stream_id);
-  return (Send(MSG_WEBRTC_REMOVESTREAM, &params) && params.result);
-}
-
-bool PeerConnectionProxy::SetAudioDevice(const std::string& wave_in_device,
-                                         const std::string& wave_out_device,
-                                         int opts) {
-  SetAudioDeviceParams params(wave_in_device, wave_out_device, opts);
-  return (Send(MSG_WEBRTC_SETAUDIODEVICE, &params) && params.result);
-}
-
-bool PeerConnectionProxy::SetLocalVideoRenderer(
-    cricket::VideoRenderer* renderer) {
-  SetLocalRendererParams params(renderer);
-  return (Send(MSG_WEBRTC_SETLOCALRENDERER, &params) && params.result);
-}
-
-bool PeerConnectionProxy::SetVideoRenderer(const std::string& stream_id,
-                                          cricket::VideoRenderer* renderer) {
-  SetVideoRendererParams params(stream_id, renderer);
-  return (Send(MSG_WEBRTC_SETVIDEORENDERER, &params) && params.result);
-}
-
-bool PeerConnectionProxy::SetVideoCapture(const std::string& cam_device) {
-  SetVideoCaptureParams params(cam_device);
-  return (Send(MSG_WEBRTC_SETVIDEOCAPTURE, &params) && params.result);
-}
-
-PeerConnection::ReadyState PeerConnectionProxy::GetReadyState() {
-  PeerConnection::ReadyState ready_state = NEW;
-  Send(MSG_WEBRTC_GETREADYSTATE,
-       reinterpret_cast<talk_base::MessageData*>(&ready_state));
-  return ready_state;
-}
-
-bool PeerConnectionProxy::Connect() {
-  ResultParams params;
-  return (Send(MSG_WEBRTC_CONNECT, &params) && params.result);
-}
-
-bool PeerConnectionProxy::Close() {
-  ResultParams params;
-  return (Send(MSG_WEBRTC_CLOSE, &params) && params.result);
-}
-
-bool PeerConnectionProxy::Send(uint32 id, talk_base::MessageData* data) {
-  if (!signaling_thread_)
-    return false;
-  signaling_thread_->Send(this, id, data);
-  return true;
-}
-
-void PeerConnectionProxy::OnMessage(talk_base::Message* message) {
-  talk_base::MessageData* data = message->pdata;
-  switch (message->message_id) {
-    case MSG_WEBRTC_ADDSTREAM: {
-      AddStreamParams* params = reinterpret_cast<AddStreamParams*>(data);
-      params->result = peerconnection_impl_->AddStream(
-          params->stream_id, params->video);
-      break;
-    }
-    case MSG_WEBRTC_SIGNALINGMESSAGE: {
-      SignalingMsgParams* params =
-          reinterpret_cast<SignalingMsgParams*>(data);
-      params->result = peerconnection_impl_->SignalingMessage(
-          params->signaling_message);
-      break;
-    }
-    case MSG_WEBRTC_REMOVESTREAM: {
-      RemoveStreamParams* params = reinterpret_cast<RemoveStreamParams*>(data);
-      params->result = peerconnection_impl_->RemoveStream(
-          params->stream_id);
-      break;
-    }
-    case MSG_WEBRTC_SETAUDIODEVICE: {
-      SetAudioDeviceParams* params =
-          reinterpret_cast<SetAudioDeviceParams*>(data);
-      params->result = peerconnection_impl_->SetAudioDevice(
-          params->wave_in_device, params->wave_out_device, params->opts);
-      break;
-    }
-    case MSG_WEBRTC_SETLOCALRENDERER: {
-      SetLocalRendererParams* params =
-          reinterpret_cast<SetLocalRendererParams*>(data);
-      params->result = peerconnection_impl_->SetLocalVideoRenderer(
-          params->renderer);
-      break;
-    }
-    case MSG_WEBRTC_SETVIDEOCAPTURE: {
-      SetVideoCaptureParams* params =
-          reinterpret_cast<SetVideoCaptureParams*>(data);
-      params->result = peerconnection_impl_->SetVideoCapture(
-          params->cam_device);
-      break;
-    }
-    case MSG_WEBRTC_GETREADYSTATE: {
-      PeerConnection::ReadyState* ready_state =
-          reinterpret_cast<PeerConnection::ReadyState*>(data);
-      *ready_state = peerconnection_impl_->GetReadyState();
-      break;
-    }
-    case MSG_WEBRTC_SETVIDEORENDERER: {
-      SetVideoRendererParams* params =
-          reinterpret_cast<SetVideoRendererParams*>(data);
-      params->result = peerconnection_impl_->SetVideoRenderer(
-          params->stream_id, params->renderer);
-      break;
-    }
-    case MSG_WEBRTC_CONNECT: {
-      ResultParams* params =
-          reinterpret_cast<ResultParams*>(data);
-      params->result = peerconnection_impl_->Connect();
-      break;
-    }
-    case MSG_WEBRTC_CLOSE: {
-      ResultParams* params =
-          reinterpret_cast<ResultParams*>(data);
-      params->result = peerconnection_impl_->Close();
-      break;
-    }
-    case MSG_WEBRTC_INIT: {
-      ResultParams* params =
-          reinterpret_cast<ResultParams*>(data);
-      params->result = peerconnection_impl_->Init();
-      break;
-    }
-    case MSG_WEBRTC_REGISTEROBSERVER: {
-      RegisterObserverParams* params =
-          reinterpret_cast<RegisterObserverParams*>(data);
-      peerconnection_impl_->RegisterObserver(params->observer);
-      break;
-    }
-    case MSG_WEBRTC_RELEASE: {
-      peerconnection_impl_.reset();
-      break;
-    }
-    default: {
-      ASSERT(false);
-      break;
-    }
-  }
-}
-
-}  // namespace webrtc
diff --git a/third_party/libjingle/source/talk/app/webrtcv1/peerconnectionproxy.h b/third_party/libjingle/source/talk/app/webrtcv1/peerconnectionproxy.h
deleted file mode 100644
index 8d7fc26..0000000
--- a/third_party/libjingle/source/talk/app/webrtcv1/peerconnectionproxy.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_APP_WEBRTC_PEERCONNECTIONPROXY_H_
-#define TALK_APP_WEBRTC_PEERCONNECTIONPROXY_H_
-
-#include <string>
-
-#include "talk/app/webrtcv1/peerconnection.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/base/thread.h"
-
-namespace cricket {
-class ChannelManager;
-class PortAllocator;
-}
-
-namespace webrtc {
-
-class PeerConnectionImpl;
-
-class PeerConnectionProxy : public PeerConnection,
-                            public talk_base::MessageHandler {
- public:
-  PeerConnectionProxy(cricket::PortAllocator* port_allocator,
-                      cricket::ChannelManager* channel_manager,
-                      talk_base::Thread* signaling_thread);
-  virtual ~PeerConnectionProxy();
-
-  // PeerConnection interface implementation.
-  virtual void RegisterObserver(PeerConnectionObserver* observer);
-  virtual bool SignalingMessage(const std::string& msg);
-  virtual bool AddStream(const std::string& stream_id, bool video);
-  virtual bool RemoveStream(const std::string& stream_id);
-  virtual bool Connect();
-  virtual bool Close();
-  virtual bool SetAudioDevice(const std::string& wave_in_device,
-                              const std::string& wave_out_device, int opts);
-  virtual bool SetLocalVideoRenderer(cricket::VideoRenderer* renderer);
-  virtual bool SetVideoRenderer(const std::string& stream_id,
-                                cricket::VideoRenderer* renderer);
-  virtual bool SetVideoCapture(const std::string& cam_device);
-  virtual ReadyState GetReadyState();
-
- private:
-  bool Init();
-  bool Send(uint32 id, talk_base::MessageData* data);
-  virtual void OnMessage(talk_base::Message* message);
-
-  talk_base::scoped_ptr<PeerConnectionImpl> peerconnection_impl_;
-  talk_base::Thread* signaling_thread_;
-
-  friend class PeerConnectionFactory;
-};
-}
-
-#endif  // TALK_APP_WEBRTC_PEERCONNECTIONPROXY_H_
diff --git a/third_party/libjingle/source/talk/app/webrtcv1/webrtcjson.cc b/third_party/libjingle/source/talk/app/webrtcv1/webrtcjson.cc
deleted file mode 100644
index 4cc4239..0000000
--- a/third_party/libjingle/source/talk/app/webrtcv1/webrtcjson.cc
+++ /dev/null
@@ -1,469 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/app/webrtcv1/webrtcjson.h"
-
-#ifdef WEBRTC_RELATIVE_PATH
-#include "json/json.h"
-#else
-#include "third_party/jsoncpp/json.h"
-#endif
-
-// TODO: Remove webrtcsession.h once we can get size from signaling.
-// webrtcsession.h is for kDefaultVideoCodecWidth and kDefaultVideoCodecHeight.
-#include "talk/app/webrtcv1/webrtcsession.h"
-#include "talk/base/json.h"
-#include "talk/base/logging.h"
-#include "talk/base/stringutils.h"
-#include "talk/session/phone/codec.h"
-#include "talk/session/phone/mediasessionclient.h"
-
-namespace webrtc {
-static const int kIceComponent = 1;
-static const int kIceFoundation = 1;
-
-static std::vector<Json::Value> ReadValues(const Json::Value& value,
-                                           const std::string& key);
-
-static bool BuildMediaMessage(
-    const cricket::ContentInfo& content_info,
-    const std::vector<cricket::Candidate>& candidates,
-    bool video,
-    Json::Value* value);
-
-static bool BuildRtpMapParams(
-    const cricket::ContentInfo& audio_offer,
-    bool video,
-    std::vector<Json::Value>* rtpmap);
-
-static bool BuildAttributes(const std::vector<cricket::Candidate>& candidates,
-                            bool video,
-                            std::vector<Json::Value>* jcandidates);
-
-static std::string Serialize(const Json::Value& value);
-static bool Deserialize(const std::string& message, Json::Value* value);
-
-static bool ParseRtcpMux(const Json::Value& value);
-static bool ParseAudioCodec(const Json::Value& value,
-                            cricket::AudioContentDescription* content);
-static bool ParseVideoCodec(const Json::Value& value,
-                            cricket::VideoContentDescription* content);
-static bool ParseIceCandidates(const Json::Value& value,
-                               std::vector<cricket::Candidate>* candidates);
-
-static Json::Value ReadValue(const Json::Value& value, const std::string& key);
-static std::string ReadString(const Json::Value& value, const std::string& key);
-static uint32 ReadUInt(const Json::Value& value, const std::string& key);
-
-static void Append(Json::Value* object, const std::string& key, bool value);
-static void Append(Json::Value* object, const std::string& key, int value);
-static void Append(Json::Value* object, const std::string& key,
-                   const std::string& value);
-static void Append(Json::Value* object, const std::string& key, uint32 value);
-static void Append(Json::Value* object, const std::string& key,
-                   const Json::Value& value);
-static void Append(Json::Value* object,
-                   const std::string& key,
-                   const std::vector<Json::Value>& values);
-
-bool GetJsonSignalingMessage(
-    const cricket::SessionDescription* sdp,
-    const std::vector<cricket::Candidate>& candidates,
-    std::string* signaling_message) {
-  const cricket::ContentInfo* audio_content = GetFirstAudioContent(sdp);
-  const cricket::ContentInfo* video_content = GetFirstVideoContent(sdp);
-
-  std::vector<Json::Value> media;
-  if (audio_content) {
-    Json::Value value;
-    BuildMediaMessage(*audio_content, candidates, false, &value);
-    media.push_back(value);
-  }
-
-  if (video_content) {
-    Json::Value value;
-    BuildMediaMessage(*video_content, candidates, true, &value);
-    media.push_back(value);
-  }
-
-  Json::Value signal;
-  Append(&signal, "media", media);
-
-  // Now serialize.
-  *signaling_message = Serialize(signal);
-
-  return true;
-}
-
-bool BuildMediaMessage(
-    const cricket::ContentInfo& content_info,
-    const std::vector<cricket::Candidate>& candidates,
-    bool video,
-    Json::Value* params) {
-  if (video) {
-    Append(params, "label", 2);  // always video 2
-  } else {
-    Append(params, "label", 1);  // always audio 1
-  }
-
-  const cricket::MediaContentDescription* media_info =
-  static_cast<const cricket::MediaContentDescription*> (
-      content_info.description);
-  if (media_info->rtcp_mux()) {
-    Append(params, "rtcp_mux", true);
-  }
-
-  std::vector<Json::Value> rtpmap;
-  if (!BuildRtpMapParams(content_info, video, &rtpmap)) {
-    return false;
-  }
-
-  Append(params, "rtpmap", rtpmap);
-
-  Json::Value attributes;
-  std::vector<Json::Value> jcandidates;
-
-  if (!BuildAttributes(candidates, video, &jcandidates)) {
-    return false;
-  }
-  Append(&attributes, "candidate", jcandidates);
-  Append(params, "attributes", attributes);
-  return true;
-}
-
-bool BuildRtpMapParams(const cricket::ContentInfo& content_info,
-                       bool video,
-                       std::vector<Json::Value>* rtpmap) {
-  if (!video) {
-    const cricket::AudioContentDescription* audio_offer =
-        static_cast<const cricket::AudioContentDescription*>(
-            content_info.description);
-
-    std::vector<cricket::AudioCodec>::const_iterator iter =
-        audio_offer->codecs().begin();
-    std::vector<cricket::AudioCodec>::const_iterator iter_end =
-        audio_offer->codecs().end();
-    for (; iter != iter_end; ++iter) {
-      Json::Value codec;
-      std::string codec_str(std::string("audio/").append(iter->name));
-      // adding clockrate
-      Append(&codec, "clockrate", iter->clockrate);
-      Append(&codec, "codec", codec_str);
-      Json::Value codec_id;
-      Append(&codec_id, talk_base::ToString(iter->id), codec);
-      rtpmap->push_back(codec_id);
-    }
-  } else {
-    const cricket::VideoContentDescription* video_offer =
-        static_cast<const cricket::VideoContentDescription*>(
-            content_info.description);
-
-    std::vector<cricket::VideoCodec>::const_iterator iter =
-        video_offer->codecs().begin();
-    std::vector<cricket::VideoCodec>::const_iterator iter_end =
-        video_offer->codecs().end();
-    for (; iter != iter_end; ++iter) {
-      Json::Value codec;
-      std::string codec_str(std::string("video/").append(iter->name));
-      Append(&codec, "codec", codec_str);
-      Json::Value codec_id;
-      Append(&codec_id, talk_base::ToString(iter->id), codec);
-      rtpmap->push_back(codec_id);
-    }
-  }
-  return true;
-}
-
-bool BuildAttributes(const std::vector<cricket::Candidate>& candidates,
-                     bool video,
-                     std::vector<Json::Value>* jcandidates) {
-  std::vector<cricket::Candidate>::const_iterator iter =
-      candidates.begin();
-  std::vector<cricket::Candidate>::const_iterator iter_end =
-      candidates.end();
-  for (; iter != iter_end; ++iter) {
-    if ((video && (!iter->name().compare("video_rtcp") ||
-                  (!iter->name().compare("video_rtp")))) ||
-        (!video && (!iter->name().compare("rtp") ||
-                   (!iter->name().compare("rtcp"))))) {
-      Json::Value candidate;
-      Append(&candidate, "component", kIceComponent);
-      Append(&candidate, "foundation", kIceFoundation);
-      Append(&candidate, "generation", iter->generation());
-      Append(&candidate, "proto", iter->protocol());
-      Append(&candidate, "priority", iter->preference_str());
-      Append(&candidate, "ip", iter->address().IPAsString());
-      Append(&candidate, "port", iter->address().PortAsString());
-      Append(&candidate, "type", iter->type());
-      Append(&candidate, "name", iter->name());
-      Append(&candidate, "network_name", iter->network_name());
-      Append(&candidate, "username", iter->username());
-      Append(&candidate, "password", iter->password());
-      jcandidates->push_back(candidate);
-    }
-  }
-  return true;
-}
-
-std::string Serialize(const Json::Value& value) {
-  Json::StyledWriter writer;
-  return writer.write(value);
-}
-
-bool Deserialize(const std::string& message, Json::Value* value) {
-  Json::Reader reader;
-  return reader.parse(message, *value);
-}
-
-bool ParseJsonSignalingMessage(const std::string& signaling_message,
-                               cricket::SessionDescription** sdp,
-                               std::vector<cricket::Candidate>* candidates) {
-  ASSERT(!(*sdp));  // expect this to be NULL
-  // first deserialize message
-  Json::Value value;
-  if (!Deserialize(signaling_message, &value)) {
-    return false;
-  }
-
-  // get media objects
-  std::vector<Json::Value> mlines = ReadValues(value, "media");
-  if (mlines.empty()) {
-    // no m-lines found
-    return false;
-  }
-
-  *sdp = new cricket::SessionDescription();
-
-  // get codec information
-  for (size_t i = 0; i < mlines.size(); ++i) {
-    if (mlines[i]["label"].asInt() == 1) {
-      cricket::AudioContentDescription* audio_content =
-          new cricket::AudioContentDescription();
-      ParseAudioCodec(mlines[i], audio_content);
-      audio_content->set_rtcp_mux(ParseRtcpMux(mlines[i]));
-      audio_content->SortCodecs();
-      (*sdp)->AddContent(cricket::CN_AUDIO,
-                         cricket::NS_JINGLE_RTP, audio_content);
-      ParseIceCandidates(mlines[i], candidates);
-    } else {
-      cricket::VideoContentDescription* video_content =
-          new cricket::VideoContentDescription();
-      ParseVideoCodec(mlines[i], video_content);
-
-      video_content->set_rtcp_mux(ParseRtcpMux(mlines[i]));
-      video_content->SortCodecs();
-      (*sdp)->AddContent(cricket::CN_VIDEO,
-                         cricket::NS_JINGLE_RTP, video_content);
-      ParseIceCandidates(mlines[i], candidates);
-    }
-  }
-  return true;
-}
-
-bool ParseRtcpMux(const Json::Value& value) {
-  Json::Value rtcp_mux(ReadValue(value, "rtcp_mux"));
-  if (!rtcp_mux.empty()) {
-    if (rtcp_mux.asBool()) {
-      return true;
-    }
-  }
-  return false;
-}
-
-bool ParseAudioCodec(const Json::Value& value,
-                     cricket::AudioContentDescription* content) {
-  std::vector<Json::Value> rtpmap(ReadValues(value, "rtpmap"));
-  if (rtpmap.empty())
-    return false;
-
-  std::vector<Json::Value>::const_iterator iter =
-      rtpmap.begin();
-  std::vector<Json::Value>::const_iterator iter_end =
-      rtpmap.end();
-  for (; iter != iter_end; ++iter) {
-    cricket::AudioCodec codec;
-    std::string pltype(iter->begin().memberName());
-    talk_base::FromString(pltype, &codec.id);
-    Json::Value codec_info((*iter)[pltype]);
-    std::string codec_name(ReadString(codec_info, "codec"));
-    std::vector<std::string> tokens;
-    talk_base::split(codec_name, '/', &tokens);
-    codec.name = tokens[1];
-    codec.clockrate = ReadUInt(codec_info, "clockrate");
-    content->AddCodec(codec);
-  }
-
-  return true;
-}
-
-bool ParseVideoCodec(const Json::Value& value,
-                     cricket::VideoContentDescription* content) {
-  std::vector<Json::Value> rtpmap(ReadValues(value, "rtpmap"));
-  if (rtpmap.empty())
-    return false;
-
-  std::vector<Json::Value>::const_iterator iter =
-      rtpmap.begin();
-  std::vector<Json::Value>::const_iterator iter_end =
-      rtpmap.end();
-  for (; iter != iter_end; ++iter) {
-    cricket::VideoCodec codec;
-    std::string pltype(iter->begin().memberName());
-    talk_base::FromString(pltype, &codec.id);
-    Json::Value codec_info((*iter)[pltype]);
-    std::vector<std::string> tokens;
-    talk_base::split(codec_info["codec"].asString(), '/', &tokens);
-    codec.name = tokens[1];
-    // TODO: Remove once we can get size from signaling message.
-    codec.width = WebRtcSession::kDefaultVideoCodecWidth;
-    codec.height = WebRtcSession::kDefaultVideoCodecHeight;
-    content->AddCodec(codec);
-  }
-  return true;
-}
-
-bool ParseIceCandidates(const Json::Value& value,
-                        std::vector<cricket::Candidate>* candidates) {
-  Json::Value attributes(ReadValue(value, "attributes"));
-  std::string ice_pwd(ReadString(attributes, "ice-pwd"));
-  std::string ice_ufrag(ReadString(attributes, "ice-ufrag"));
-
-  std::vector<Json::Value> jcandidates(ReadValues(attributes, "candidate"));
-
-  std::vector<Json::Value>::const_iterator iter =
-      jcandidates.begin();
-  std::vector<Json::Value>::const_iterator iter_end =
-      jcandidates.end();
-  for (; iter != iter_end; ++iter) {
-    cricket::Candidate cand;
-
-    unsigned int generation;
-    if (!GetUIntFromJsonObject(*iter, "generation", &generation))
-      return false;
-    cand.set_generation_str(talk_base::ToString(generation));
-
-    std::string proto;
-    if (!GetStringFromJsonObject(*iter, "proto", &proto))
-      return false;
-    cand.set_protocol(proto);
-
-    std::string priority;
-    if (!GetStringFromJsonObject(*iter, "priority", &priority))
-      return false;
-    cand.set_preference_str(priority);
-
-    std::string str;
-    talk_base::SocketAddress addr;
-    if (!GetStringFromJsonObject(*iter, "ip", &str))
-      return false;
-    addr.SetIP(str);
-    if (!GetStringFromJsonObject(*iter, "port", &str))
-      return false;
-    int port;
-    if (!talk_base::FromString(str, &port))
-      return false;
-    addr.SetPort(port);
-    cand.set_address(addr);
-
-    if (!GetStringFromJsonObject(*iter, "type", &str))
-      return false;
-    cand.set_type(str);
-
-    if (!GetStringFromJsonObject(*iter, "name", &str))
-      return false;
-    cand.set_name(str);
-
-    if (!GetStringFromJsonObject(*iter, "network_name", &str))
-      return false;
-    cand.set_network_name(str);
-
-    if (!GetStringFromJsonObject(*iter, "username", &str))
-      return false;
-    cand.set_username(str);
-
-    if (!GetStringFromJsonObject(*iter, "password", &str))
-      return false;
-    cand.set_password(str);
-
-    candidates->push_back(cand);
-  }
-  return true;
-}
-
-std::vector<Json::Value> ReadValues(
-    const Json::Value& value, const std::string& key) {
-  std::vector<Json::Value> objects;
-  for (Json::Value::ArrayIndex i = 0; i < value[key].size(); ++i) {
-    objects.push_back(value[key][i]);
-  }
-  return objects;
-}
-
-Json::Value ReadValue(const Json::Value& value, const std::string& key) {
-  return value[key];
-}
-
-std::string ReadString(const Json::Value& value, const std::string& key) {
-  return value[key].asString();
-}
-
-uint32 ReadUInt(const Json::Value& value, const std::string& key) {
-  return value[key].asUInt();
-}
-
-void Append(Json::Value* object, const std::string& key, bool value) {
-  (*object)[key] = Json::Value(value);
-}
-
-void Append(Json::Value* object, const std::string& key, int value) {
-  (*object)[key] = Json::Value(value);
-}
-
-void Append(Json::Value* object, const std::string& key,
-            const std::string& value) {
-  (*object)[key] = Json::Value(value);
-}
-
-void Append(Json::Value* object, const std::string& key, uint32 value) {
-  (*object)[key] = Json::Value(value);
-}
-
-void Append(Json::Value* object, const std::string& key,
-            const Json::Value& value) {
-  (*object)[key] = value;
-}
-
-void Append(Json::Value* object,
-            const std::string & key,
-            const std::vector<Json::Value>& values) {
-  for (std::vector<Json::Value>::const_iterator iter = values.begin();
-      iter != values.end(); ++iter) {
-    (*object)[key].append(*iter);
-  }
-}
-
-}  // namespace webrtc
diff --git a/third_party/libjingle/source/talk/app/webrtcv1/webrtcjson.h b/third_party/libjingle/source/talk/app/webrtcv1/webrtcjson.h
deleted file mode 100644
index d923f83..0000000
--- a/third_party/libjingle/source/talk/app/webrtcv1/webrtcjson.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_APP_WEBRTC_WEBRTCJSON_H_
-#define TALK_APP_WEBRTC_WEBRTCJSON_H_
-
-#include <string>
-
-#include "talk/p2p/base/candidate.h"
-#include "talk/session/phone/codec.h"
-
-namespace Json {
-class Value;
-}
-
-namespace cricket {
-class AudioContentDescription;
-class VideoContentDescription;
-struct ContentInfo;
-class SessionDescription;
-}
-
-namespace webrtc {
-
-bool GetJsonSignalingMessage(
-    const cricket::SessionDescription* sdp,
-    const std::vector<cricket::Candidate>& candidates,
-    std::string* signaling_message);
-
-bool ParseJsonSignalingMessage(const std::string& signaling_message,
-                               cricket::SessionDescription** sdp,
-                               std::vector<cricket::Candidate>* candidates);
-}
-
-#endif  // TALK_APP_WEBRTC_WEBRTCJSON_H_
diff --git a/third_party/libjingle/source/talk/app/webrtcv1/webrtcsession.cc b/third_party/libjingle/source/talk/app/webrtcv1/webrtcsession.cc
deleted file mode 100644
index 0678627..0000000
--- a/third_party/libjingle/source/talk/app/webrtcv1/webrtcsession.cc
+++ /dev/null
@@ -1,537 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/app/webrtcv1/webrtcsession.h"
-
-#include <string>
-#include <vector>
-
-#include "talk/base/common.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/p2p/base/constants.h"
-#include "talk/p2p/base/sessiondescription.h"
-#include "talk/p2p/base/p2ptransport.h"
-#include "talk/session/phone/channel.h"
-#include "talk/session/phone/channelmanager.h"
-#include "talk/session/phone/mediasessionclient.h"
-#include "talk/session/phone/voicechannel.h"
-
-namespace webrtc {
-
-enum {
-  MSG_CANDIDATE_TIMEOUT = 101,
-};
-
-static const int kAudioMonitorPollFrequency = 100;
-static const int kMonitorPollFrequency = 1000;
-
-// We allow 30 seconds to establish a connection; beyond that we consider
-// it an error
-static const int kCallSetupTimeout = 30 * 1000;
-// A loss of connectivity is probably due to the Internet connection going
-// down, and it might take a while to come back on wireless networks, so we
-// use a longer timeout for that.
-static const int kCallLostTimeout = 60 * 1000;
-
-static const char kVideoStream[] = "video_rtp";
-static const char kAudioStream[] = "rtp";
-
-static const int kDefaultVideoCodecId = 100;
-static const int kDefaultVideoCodecFramerate = 30;
-static const char kDefaultVideoCodecName[] = "VP8";
-
-WebRtcSession::WebRtcSession(const std::string& id,
-                             bool incoming,
-                             cricket::PortAllocator* allocator,
-                             cricket::ChannelManager* channelmgr,
-                             talk_base::Thread* signaling_thread)
-    : BaseSession(signaling_thread, channelmgr->worker_thread(),
-                  allocator, id, "", !incoming),
-      transport_(NULL),
-      channel_manager_(channelmgr),
-      transports_writable_(false),
-      muted_(false),
-      camera_muted_(false),
-      setup_timeout_(kCallSetupTimeout),
-      signaling_thread_(signaling_thread),
-      incoming_(incoming),
-      port_allocator_(allocator),
-      desc_factory_(channel_manager_) {
-}
-
-WebRtcSession::~WebRtcSession() {
-  RemoveAllStreams();
-  // TODO: Do we still need Terminate?
-  // if (state_ != STATE_RECEIVEDTERMINATE) {
-  //   Terminate();
-  // }
-  if (transport_) {
-    delete transport_;
-    transport_ = NULL;
-  }
-}
-
-bool WebRtcSession::Initiate() {
-  const cricket::VideoCodec default_codec(kDefaultVideoCodecId,
-      kDefaultVideoCodecName, kDefaultVideoCodecWidth, kDefaultVideoCodecHeight,
-      kDefaultVideoCodecFramerate, 0);
-  channel_manager_->SetDefaultVideoEncoderConfig(
-      cricket::VideoEncoderConfig(default_codec));
-
-  if (signaling_thread_ == NULL)
-    return false;
-
-  transport_ = CreateTransport();
-
-  if (transport_ == NULL)
-    return false;
-
-  transport_->set_allow_local_ips(true);
-
-  // start transports
-  transport_->SignalRequestSignaling.connect(
-      this, &WebRtcSession::OnRequestSignaling);
-  transport_->SignalCandidatesReady.connect(
-      this, &WebRtcSession::OnCandidatesReady);
-  transport_->SignalWritableState.connect(
-      this, &WebRtcSession::OnWritableState);
-  // Limit the amount of time that setting up a call may take.
-  StartTransportTimeout(kCallSetupTimeout);
-  return true;
-}
-
-cricket::Transport* WebRtcSession::CreateTransport() {
-  ASSERT(signaling_thread()->IsCurrent());
-  return new cricket::P2PTransport(
-      talk_base::Thread::Current(),
-      channel_manager_->worker_thread(), port_allocator());
-}
-
-bool WebRtcSession::CreateVoiceChannel(const std::string& stream_id) {
-  // RTCP disabled
-  cricket::VoiceChannel* voice_channel =
-      channel_manager_->CreateVoiceChannel(this, stream_id, true);
-  if (voice_channel == NULL) {
-    LOG(LERROR) << "Unable to create voice channel.";
-    return false;
-  }
-  StreamInfo* stream_info = new StreamInfo(stream_id);
-  stream_info->channel = voice_channel;
-  stream_info->video = false;
-  streams_.push_back(stream_info);
-  return true;
-}
-
-bool WebRtcSession::CreateVideoChannel(const std::string& stream_id) {
-  // RTCP disabled
-  cricket::VideoChannel* video_channel =
-      channel_manager_->CreateVideoChannel(this, stream_id, true, NULL);
-  if (video_channel == NULL) {
-    LOG(LERROR) << "Unable to create video channel.";
-    return false;
-  }
-  StreamInfo* stream_info = new StreamInfo(stream_id);
-  stream_info->channel = video_channel;
-  stream_info->video = true;
-  streams_.push_back(stream_info);
-  return true;
-}
-
-cricket::TransportChannel* WebRtcSession::CreateChannel(
-    const std::string& content_name,
-    const std::string& name) {
-  if (!transport_) {
-    return NULL;
-  }
-  std::string type;
-  if (content_name.compare(kVideoStream) == 0) {
-    type = cricket::NS_GINGLE_VIDEO;
-  } else {
-    type = cricket::NS_GINGLE_AUDIO;
-  }
-  cricket::TransportChannel* transport_channel =
-      transport_->CreateChannel(name, type);
-  ASSERT(transport_channel != NULL);
-  return transport_channel;
-}
-
-cricket::TransportChannel* WebRtcSession::GetChannel(
-    const std::string& content_name, const std::string& name) {
-  if (!transport_)
-    return NULL;
-
-  return transport_->GetChannel(name);
-}
-
-void WebRtcSession::DestroyChannel(
-    const std::string& content_name, const std::string& name) {
-  if (!transport_)
-    return;
-
-  transport_->DestroyChannel(name);
-}
-
-void WebRtcSession::OnMessage(talk_base::Message* message) {
-  switch (message->message_id) {
-    case MSG_CANDIDATE_TIMEOUT:
-      if (transport_->writable()) {
-        // This should never happen: The timout triggered even
-        // though a call was successfully set up.
-        ASSERT(false);
-      }
-      SignalFailedCall();
-      break;
-    default:
-      cricket::BaseSession::OnMessage(message);
-      break;
-  }
-}
-
-bool WebRtcSession::Connect() {
-  if (streams_.empty()) {
-    // nothing to initiate
-    return false;
-  }
-  // lets connect all the transport channels created before for this session
-  transport_->ConnectChannels();
-
-  // create an offer now. This is to call SetState
-  // Actual offer will be send when OnCandidatesReady callback received
-  cricket::SessionDescription* offer = CreateOffer();
-  set_local_description(offer);
-  SetState((incoming()) ? STATE_SENTACCEPT : STATE_SENTINITIATE);
-
-  // Enable all the channels
-  EnableAllStreams();
-  SetVideoCapture(true);
-  return true;
-}
-
-bool WebRtcSession::SetVideoRenderer(const std::string& stream_id,
-                                     cricket::VideoRenderer* renderer) {
-  bool ret = false;
-  StreamMap::iterator iter;
-  for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
-    StreamInfo* stream_info = (*iter);
-    if (stream_info->stream_id.compare(stream_id) == 0) {
-      ASSERT(stream_info->channel != NULL);
-      ASSERT(stream_info->video);
-      cricket::VideoChannel* channel = static_cast<cricket::VideoChannel*>(
-          stream_info->channel);
-      ret = channel->SetRenderer(0, renderer);
-      break;
-    }
-  }
-  return ret;
-}
-
-bool WebRtcSession::SetVideoCapture(bool capture) {
-  channel_manager_->SetVideoCapture(capture);
-  return true;
-}
-
-bool WebRtcSession::RemoveStream(const std::string& stream_id) {
-  bool ret = false;
-  StreamMap::iterator iter;
-  for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
-    StreamInfo* sinfo = (*iter);
-    if (sinfo->stream_id.compare(stream_id) == 0) {
-      if (!sinfo->video) {
-        cricket::VoiceChannel* channel = static_cast<cricket::VoiceChannel*> (
-            sinfo->channel);
-        channel->Enable(false);
-        // Note: If later the channel is used by multiple streams, then we
-        // should not destroy the channel until all the streams are removed.
-        channel_manager_->DestroyVoiceChannel(channel);
-      } else {
-        cricket::VideoChannel* channel = static_cast<cricket::VideoChannel*> (
-            sinfo->channel);
-        channel->Enable(false);
-        // Note: If later the channel is used by multiple streams, then we
-        // should not destroy the channel until all the streams are removed.
-        channel_manager_->DestroyVideoChannel(channel);
-      }
-      // channel and transport will be deleted in
-      // DestroyVoiceChannel/DestroyVideoChannel
-      streams_.erase(iter);
-      ret = true;
-      break;
-    }
-  }
-  if (!ret) {
-    LOG(LERROR) << "No streams found for stream id " << stream_id;
-    // TODO: trigger onError callback
-  }
-  return ret;
-}
-
-void WebRtcSession::EnableAllStreams() {
-  StreamMap::const_iterator i;
-  for (i = streams_.begin(); i != streams_.end(); ++i) {
-    cricket::BaseChannel* channel = (*i)->channel;
-    if (channel)
-      channel->Enable(true);
-  }
-}
-
-void WebRtcSession::RemoveAllStreams() {
-  SetState(STATE_RECEIVEDTERMINATE);
-
-  // signaling_thread_->Post(this, MSG_RTC_REMOVEALLSTREAMS);
-  // First build a list of streams to remove and then remove them.
-  // The reason we do this is that if we remove the streams inside the
-  // loop, a stream might get removed while we're enumerating and the iterator
-  // will become invalid (and we crash).
-  // streams_ entry will be removed from ChannelManager callback method
-  // DestroyChannel
-  std::vector<std::string> streams_to_remove;
-  StreamMap::iterator iter;
-  for (iter = streams_.begin(); iter != streams_.end(); ++iter)
-    streams_to_remove.push_back((*iter)->stream_id);
-
-  for (std::vector<std::string>::iterator i = streams_to_remove.begin();
-       i != streams_to_remove.end(); ++i) {
-    RemoveStream(*i);
-  }
-}
-
-bool WebRtcSession::HasStream(const std::string& stream_id) const {
-  StreamMap::const_iterator iter;
-  for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
-    StreamInfo* sinfo = (*iter);
-    if (stream_id.compare(sinfo->stream_id) == 0) {
-      return true;
-    }
-  }
-  return false;
-}
-
-bool WebRtcSession::HasChannel(bool video) const {
-  StreamMap::const_iterator iter;
-  for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
-    StreamInfo* sinfo = (*iter);
-    if (sinfo->video == video) {
-      return true;
-    }
-  }
-  return false;
-}
-
-bool WebRtcSession::HasAudioChannel() const {
-  return HasChannel(false);
-}
-
-bool WebRtcSession::HasVideoChannel() const {
-  return HasChannel(true);
-}
-
-void WebRtcSession::OnRequestSignaling(cricket::Transport* transport) {
-  transport->OnSignalingReady();
-}
-
-void WebRtcSession::OnWritableState(cricket::Transport* transport) {
-  ASSERT(transport == transport_);
-  const bool transports_writable = transport_->writable();
-  if (transports_writable) {
-    if (transports_writable != transports_writable_) {
-      signaling_thread_->Clear(this, MSG_CANDIDATE_TIMEOUT);
-    } else {
-      // At one point all channels were writable and we had full connectivity,
-      // but then we lost it. Start the timeout again to kill the call if it
-      // doesn't come back.
-      StartTransportTimeout(kCallLostTimeout);
-    }
-    transports_writable_ = transports_writable;
-  }
-  NotifyTransportState();
-  return;
-}
-
-void WebRtcSession::StartTransportTimeout(int timeout) {
-  talk_base::Thread::Current()->PostDelayed(timeout, this,
-                                            MSG_CANDIDATE_TIMEOUT,
-                                            NULL);
-}
-
-void WebRtcSession::NotifyTransportState() {
-}
-
-bool WebRtcSession::OnInitiateMessage(
-    cricket::SessionDescription* offer,
-    const std::vector<cricket::Candidate>& candidates) {
-  if (!offer) {
-    LOG(LERROR) << "No SessionDescription from peer";
-    return false;
-  }
-
-  // Get capabilities from offer before generating an answer to it.
-  cricket::MediaSessionOptions options;
-  if (GetFirstAudioContent(offer))
-    options.has_audio = true;
-  if (GetFirstVideoContent(offer))
-    options.has_video = true;
-
-  talk_base::scoped_ptr<cricket::SessionDescription> answer;
-  answer.reset(CreateAnswer(offer, options));
-
-  if (!answer.get()) {
-    return false;
-  }
-
-  const cricket::ContentInfo* audio_content = GetFirstAudioContent(
-      answer.get());
-  const cricket::ContentInfo* video_content = GetFirstVideoContent(
-      answer.get());
-
-  if (!audio_content && !video_content) {
-    return false;
-  }
-
-  bool ret = true;
-  if (audio_content) {
-    ret = !HasAudioChannel() &&
-          CreateVoiceChannel(audio_content->name);
-    if (!ret) {
-      LOG(LERROR) << "Failed to create voice channel for "
-                  << audio_content->name;
-      return false;
-    }
-  }
-
-  if (video_content) {
-    ret = !HasVideoChannel() &&
-          CreateVideoChannel(video_content->name);
-    if (!ret) {
-      LOG(LERROR) << "Failed to create video channel for "
-                  << video_content->name;
-      return false;
-    }
-  }
-  // Provide remote candidates to the transport
-  transport_->OnRemoteCandidates(candidates);
-
-  set_remote_description(offer);
-  SetState(STATE_RECEIVEDINITIATE);
-
-  transport_->ConnectChannels();
-  EnableAllStreams();
-
-  set_local_description(answer.release());
-
-  // AddStream called only once with Video label
-  if (video_content) {
-    SignalAddStream(video_content->name, true);
-  } else {
-    SignalAddStream(audio_content->name, false);
-  }
-  SetState(STATE_SENTACCEPT);
-  return true;
-}
-
-bool WebRtcSession::OnRemoteDescription(
-    cricket::SessionDescription* desc,
-    const std::vector<cricket::Candidate>& candidates) {
-  if (state() == STATE_SENTACCEPT ||
-      state() == STATE_RECEIVEDACCEPT ||
-      state() == STATE_INPROGRESS) {
-    transport_->OnRemoteCandidates(candidates);
-    return true;
-  }
-  // Session description is always accepted.
-  set_remote_description(desc);
-  SetState(STATE_RECEIVEDACCEPT);
-  // Will trigger OnWritableState() if successful.
-  transport_->OnRemoteCandidates(candidates);
-
-  if (!incoming()) {
-    // Trigger OnAddStream callback at the initiator
-    const cricket::ContentInfo* video_content = GetFirstVideoContent(desc);
-    if (video_content && !SendSignalAddStream(true)) {
-      LOG(LERROR) << "Video stream unexpected in answer.";
-      return false;
-    } else {
-      const cricket::ContentInfo* audio_content = GetFirstAudioContent(desc);
-      if (audio_content && !SendSignalAddStream(false)) {
-        LOG(LERROR) << "Audio stream unexpected in answer.";
-        return false;
-      }
-    }
-  }
-  return true;
-}
-
-// Send the SignalAddStream with the stream_id based on the content type.
-bool WebRtcSession::SendSignalAddStream(bool video) {
-  StreamMap::const_iterator iter;
-  for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
-    StreamInfo* sinfo = (*iter);
-    if (sinfo->video == video) {
-      SignalAddStream(sinfo->stream_id, video);
-      return true;
-    }
-  }
-  return false;
-}
-
-cricket::SessionDescription* WebRtcSession::CreateOffer() {
-  cricket::MediaSessionOptions options;
-  options.has_audio = false;  // disable default option
-  StreamMap::const_iterator iter;
-  for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
-    if ((*iter)->video) {
-      options.has_video = true;
-    } else {
-      options.has_audio = true;
-    }
-  }
-  // We didn't save the previous offer.
-  const cricket::SessionDescription* previous_offer = NULL;
-  return desc_factory_.CreateOffer(options, previous_offer);
-}
-
-cricket::SessionDescription* WebRtcSession::CreateAnswer(
-    const cricket::SessionDescription* offer,
-    const cricket::MediaSessionOptions& options) {
-  // We didn't save the previous answer.
-  const cricket::SessionDescription* previous_answer = NULL;
-  return desc_factory_.CreateAnswer(offer, options, previous_answer);
-}
-
-void WebRtcSession::SetError(Error error) {
-  BaseSession::SetError(error);
-}
-
-void WebRtcSession::OnCandidatesReady(
-    cricket::Transport* transport,
-    const std::vector<cricket::Candidate>& candidates) {
-  std::vector<cricket::Candidate>::const_iterator iter;
-  for (iter = candidates.begin(); iter != candidates.end(); ++iter) {
-    local_candidates_.push_back(*iter);
-  }
-  SignalLocalDescription(local_description(), candidates);
-}
-} /* namespace webrtc */
diff --git a/third_party/libjingle/source/talk/app/webrtcv1/webrtcsession.h b/third_party/libjingle/source/talk/app/webrtcv1/webrtcsession.h
deleted file mode 100644
index 8f6c6ad..0000000
--- a/third_party/libjingle/source/talk/app/webrtcv1/webrtcsession.h
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_APP_WEBRTC_WEBRTCSESSION_H_
-#define TALK_APP_WEBRTC_WEBRTCSESSION_H_
-
-#include <map>
-#include <string>
-#include <vector>
-
-#include "talk/base/logging.h"
-#include "talk/base/messagehandler.h"
-#include "talk/p2p/base/candidate.h"
-#include "talk/p2p/base/session.h"
-#include "talk/session/phone/channel.h"
-#include "talk/session/phone/mediachannel.h"
-#include "talk/session/phone/mediasession.h"
-
-namespace cricket {
-class ChannelManager;
-class Transport;
-class TransportChannel;
-class VoiceChannel;
-class VideoChannel;
-struct ConnectionInfo;
-}
-
-namespace Json {
-class Value;
-}
-
-namespace webrtc {
-
-typedef std::vector<cricket::AudioCodec> AudioCodecs;
-typedef std::vector<cricket::VideoCodec> VideoCodecs;
-
-class WebRtcSession : public cricket::BaseSession {
- public:
-  WebRtcSession(const std::string& id,
-                    bool incoming,
-                    cricket::PortAllocator* allocator,
-                    cricket::ChannelManager* channelmgr,
-                    talk_base::Thread* signaling_thread);
-
-  ~WebRtcSession();
-
-  bool Initiate();
-  bool Connect();
-  bool OnRemoteDescription(cricket::SessionDescription* sdp,
-      const std::vector<cricket::Candidate>& candidates);
-  bool OnInitiateMessage(cricket::SessionDescription* sdp,
-      const std::vector<cricket::Candidate>& candidates);
-  bool CreateVoiceChannel(const std::string& stream_id);
-  bool CreateVideoChannel(const std::string& stream_id);
-  bool RemoveStream(const std::string& stream_id);
-  void RemoveAllStreams();
-
-  // Returns true if we have either a voice or video stream matching this label.
-  bool HasStream(const std::string& label) const;
-  bool HasChannel(bool video) const;
-
-  // Returns true if there's one or more audio channels in the session.
-  bool HasAudioChannel() const;
-
-  // Returns true if there's one or more video channels in the session.
-  bool HasVideoChannel() const;
-
-  bool SetVideoRenderer(const std::string& stream_id,
-                        cricket::VideoRenderer* renderer);
-
-  // This signal occurs when all the streams have been removed.
-  // It is triggered by a successful call to the RemoveAllStream or
-  // the OnRemoteDescription with stream deleted signaling message with the
-  // candidates port equal to 0.
-  sigslot::signal1<WebRtcSession*> SignalRemoveStreamMessage;
-
-  // This signal indicates a stream has been added properly.
-  // It is triggered by a successful call to the OnInitiateMessage or
-  // the OnRemoteDescription and if it's going to the STATE_RECEIVEDACCEPT.
-  sigslot::signal2<const std::string&, bool> SignalAddStream;
-
-  // This signal occurs when one stream is removed with the signaling
-  // message from the remote peer with the candidates port equal to 0.
-  sigslot::signal2<const std::string&, bool> SignalRemoveStream;
-
-  // This signal occurs when the local candidate is ready
-  sigslot::signal2<const cricket::SessionDescription*,
-      const std::vector<cricket::Candidate>&> SignalLocalDescription;
-
-  // This signal triggers when setting up or resuming a call has not been
-  // successful before a certain time out.
-  sigslot::signal0<> SignalFailedCall;
-
-  bool muted() const { return muted_; }
-  bool camera_muted() const { return camera_muted_; }
-  const std::vector<cricket::Candidate>& local_candidates() {
-    return local_candidates_;
-  }
-  void set_incoming(bool incoming) { incoming_ = incoming; }
-  bool incoming() const { return incoming_; }
-  cricket::PortAllocator* port_allocator() const { return port_allocator_; }
-  talk_base::Thread* signaling_thread() const { return signaling_thread_; }
-
-  static const int kDefaultVideoCodecWidth = 640;
-  static const int kDefaultVideoCodecHeight = 480;
-
- protected:
-  // methods from cricket::BaseSession
-  virtual void SetError(cricket::BaseSession::Error error);
-  virtual cricket::TransportChannel* CreateChannel(
-      const std::string& content_name, const std::string& name);
-  virtual cricket::TransportChannel* GetChannel(
-      const std::string& content_name, const std::string& name);
-  virtual void DestroyChannel(
-      const std::string& content_name, const std::string& name);
-
- private:
-  struct StreamInfo {
-    explicit StreamInfo(const std::string stream_id)
-        : channel(NULL),
-          video(false),
-          stream_id(stream_id) {}
-
-    StreamInfo()
-        : channel(NULL),
-          video(false) {}
-    cricket::BaseChannel* channel;
-    bool video;
-    std::string stream_id;
-  };
-  // Not really a map (vector).
-  typedef std::vector<StreamInfo*> StreamMap;
-
-  // methods signaled by the transport
-  void OnRequestSignaling(cricket::Transport* transport);
-  void OnCandidatesReady(cricket::Transport* transport,
-                         const std::vector<cricket::Candidate>& candidates);
-  void OnWritableState(cricket::Transport* transport);
-  void OnTransportError(cricket::Transport* transport);
-  void OnChannelGone(cricket::Transport* transport);
-
-  bool CheckForStreamDeleteMessage(
-      const std::vector<cricket::Candidate>& candidates);
-  void ProcessTerminateAccept(cricket::SessionDescription* desc);
-
-  void UpdateTransportWritableState();
-  bool CheckAllTransportsWritable();
-  void StartTransportTimeout(int timeout);
-  void NotifyTransportState();
-
-  cricket::SessionDescription* CreateOffer();
-  cricket::SessionDescription* CreateAnswer(
-      const cricket::SessionDescription* answer,
-      const cricket::MediaSessionOptions& options);
-
-  // from MessageHandler
-  virtual void OnMessage(talk_base::Message* message);
-
-  virtual cricket::Transport* CreateTransport();
-  cricket::Transport* GetTransport();
-
-  typedef std::map<std::string, cricket::TransportChannel*> TransportChannelMap;
-
-  bool SetVideoCapture(bool capture);
-  void EnableAllStreams();
-  bool SendSignalAddStream(bool video);
-
-  cricket::Transport* transport_;
-  cricket::ChannelManager* channel_manager_;
-  std::vector<StreamInfo*> streams_;
-  TransportChannelMap transport_channels_;
-  bool transports_writable_;
-  bool muted_;
-  bool camera_muted_;
-  int setup_timeout_;
-  std::vector<cricket::Candidate> local_candidates_;
-
-  talk_base::Thread* signaling_thread_;
-  bool incoming_;
-  cricket::PortAllocator* port_allocator_;
-  cricket::MediaSessionDescriptionFactory desc_factory_;
-};
-
-}  // namespace webrtc
-
-#endif  // TALK_APP_WEBRTC_WEBRTCSESSION_H_
diff --git a/third_party/libjingle/source/talk/app/webrtcv1/webrtcsession_unittest.cc b/third_party/libjingle/source/talk/app/webrtcv1/webrtcsession_unittest.cc
deleted file mode 100644
index 2c23d6a..0000000
--- a/third_party/libjingle/source/talk/app/webrtcv1/webrtcsession_unittest.cc
+++ /dev/null
@@ -1,407 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdio.h>
-
-#include <list>
-
-#include "base/gunit.h"
-#include "base/helpers.h"
-#include "talk/app/webrtcv1/unittest_utilities.h"
-#include "talk/app/webrtcv1/webrtcsession.h"
-#include "talk/base/fakenetwork.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/base/thread.h"
-#include "talk/p2p/base/fakesession.h"
-#include "talk/p2p/base/portallocator.h"
-#include "talk/p2p/base/sessiondescription.h"
-#include "talk/p2p/client/fakeportallocator.h"
-#include "talk/session/phone/mediasessionclient.h"
-
-class WebRtcSessionTest
-    : public sigslot::has_slots<>,
-      public testing::Test {
- public:
-  enum CallbackId {
-    kNone,
-    kOnAddStream,
-    kOnRemoveStream,
-    kOnLocalDescription,
-    kOnFailedCall,
-  };
-
-  WebRtcSessionTest()
-      : callback_ids_(),
-        last_stream_id_(""),
-        last_was_video_(false),
-        last_description_ptr_(NULL),
-        last_candidates_(),
-        session_(NULL),
-        id_(),
-        receiving_(false),
-        allocator_(NULL),
-        channel_manager_(NULL),
-        worker_thread_(NULL),
-        signaling_thread_(NULL) {
-  }
-
-  ~WebRtcSessionTest() {
-    session_.reset();
-  }
-
-  void OnAddStream(const std::string& stream_id, bool video) {
-    callback_ids_.push_back(kOnAddStream);
-    last_stream_id_ = stream_id;
-    last_was_video_ = video;
-  }
-  void OnRemoveStream(const std::string& stream_id, bool video) {
-    callback_ids_.push_back(kOnRemoveStream);
-    last_stream_id_ = stream_id;
-    last_was_video_ = video;
-  }
-  void OnLocalDescription(
-      const cricket::SessionDescription* desc,
-      const std::vector<cricket::Candidate>& candidates) {
-    callback_ids_.push_back(kOnLocalDescription);
-    last_description_ptr_.reset(CopySessionDescription(desc));
-    CopyCandidates(candidates, &last_candidates_);
-  }
-  cricket::SessionDescription* GetLocalDescription(
-      std::vector<cricket::Candidate>* candidates) {
-    if (last_candidates_.empty()) {
-      return NULL;
-    }
-    if (!last_description_ptr_.get()) {
-      return NULL;
-    }
-    CopyCandidates(last_candidates_, candidates);
-    return CopySessionDescription(last_description_ptr_.get());
-  }
-
-  void OnFailedCall() {
-    callback_ids_.push_back(kOnFailedCall);
-  }
-
-  CallbackId PopOldestCallback() {
-    if (callback_ids_.empty()) {
-      return kNone;
-    }
-    const CallbackId return_value = callback_ids_.front();
-    callback_ids_.pop_front();
-    return return_value;
-  }
-
-  CallbackId PeekOldestCallback() {
-    if (callback_ids_.empty()) {
-      return kNone;
-    }
-    const CallbackId return_value = callback_ids_.front();
-    return return_value;
-  }
-
-  void Reset() {
-    callback_ids_.clear();
-    last_stream_id_ = "";
-    last_was_video_ = false;
-    last_description_ptr_.reset();
-    last_candidates_.clear();
-  }
-
-  bool WaitForCallback(CallbackId id, int timeout_ms) {
-    bool success = false;
-    for (int ms = 0; ms < timeout_ms; ms++) {
-      const CallbackId peek_id = PeekOldestCallback();
-      if (peek_id == id) {
-        PopOldestCallback();
-        success = true;
-        break;
-      } else if (peek_id != kNone) {
-        success = false;
-        break;
-      }
-      talk_base::Thread::Current()->ProcessMessages(1);
-    }
-    return success;
-  }
-
-  bool Init(bool receiving) {
-    if (signaling_thread_ != NULL)
-        return false;
-    signaling_thread_ = talk_base::Thread::Current();
-    receiving_ = receiving;
-
-    if (worker_thread_!= NULL)
-        return false;
-    worker_thread_ = talk_base::Thread::Current();
-
-    cricket::FakePortAllocator* fake_port_allocator =
-        new cricket::FakePortAllocator(worker_thread_, NULL);
-
-    allocator_.reset(static_cast<cricket::PortAllocator*>(fake_port_allocator));
-
-    channel_manager_.reset(new cricket::ChannelManager(worker_thread_));
-    if (!channel_manager_->Init())
-      return false;
-
-    talk_base::CreateRandomString(8, &id_);
-
-    session_.reset(new webrtc::WebRtcSession(
-        id_, receiving_ , allocator_.get(),
-        channel_manager_.get(),
-        signaling_thread_));
-    session_->SignalAddStream.connect(this, &WebRtcSessionTest::OnAddStream);
-    session_->SignalRemoveStream.connect(this,
-        &WebRtcSessionTest::OnRemoveStream);
-    session_->SignalLocalDescription.connect(this,
-        &WebRtcSessionTest::OnLocalDescription);
-    session_->SignalFailedCall.connect(this, &WebRtcSessionTest::OnFailedCall);
-    return true;
-  }
-
-  // All session APIs must be called from the signaling thread.
-  bool CallInitiate() {
-    return session_->Initiate();
-  }
-
-  bool CallConnect() {
-    if (!session_->Connect())
-      return false;
-    // This callback does not happen with FakeTransport!
-    if (!WaitForCallback(kOnLocalDescription, 1000)) {
-      return false;
-    }
-    return true;
-  }
-
-  bool CallOnRemoteDescription(
-      cricket::SessionDescription* description,
-      std::vector<cricket::Candidate> candidates) {
-    if (!session_->OnRemoteDescription(description, candidates)) {
-      return false;
-    }
-    if (!WaitForCallback(kOnAddStream, 1000)) {
-      return false;
-    }
-    return true;
-  }
-
-  bool CallOnInitiateMessage(
-      cricket::SessionDescription* description,
-      const std::vector<cricket::Candidate>& candidates) {
-    if (!session_->OnInitiateMessage(description, candidates)) {
-      return false;
-    }
-    if (!WaitForCallback(kOnAddStream, 1000)) {
-      return false;
-    }
-    return true;
-  }
-
-  bool CallCreateVoiceChannel(const std::string& stream_id) {
-    if (!session_->CreateVoiceChannel(stream_id)) {
-      return false;
-    }
-    return true;
-  }
-
-  bool CallCreateVideoChannel(const std::string& stream_id) {
-    if (!session_->CreateVideoChannel(stream_id)) {
-      return false;
-    }
-    return true;
-  }
-
-  bool CallRemoveStream(const std::string& stream_id) {
-    return session_->RemoveStream(stream_id);
-  }
-
-  void CallRemoveAllStreams() {
-    session_->RemoveAllStreams();
-  }
-
-  bool CallHasChannel(const std::string& label) {
-    return session_->HasStream(label);
-  }
-
-  bool CallHasChannel(bool video) {
-    return session_->HasChannel(video);
-  }
-
-  bool CallHasAudioChannel() {
-    return session_->HasAudioChannel();
-  }
-
-  bool CallHasVideoChannel() {
-    return session_->HasVideoChannel();
-  }
-
-  bool CallSetVideoRenderer(const std::string& stream_id,
-                            cricket::VideoRenderer* renderer) {
-    return session_->SetVideoRenderer(stream_id, renderer);
-  }
-
-  const std::vector<cricket::Candidate>& CallLocalCandidates() {
-    return session_->local_candidates();
-  }
-
- private:
-  std::list<CallbackId> callback_ids_;
-
-  std::string last_stream_id_;
-  bool last_was_video_;
-  talk_base::scoped_ptr<cricket::SessionDescription> last_description_ptr_;
-  std::vector<cricket::Candidate> last_candidates_;
-
-  talk_base::scoped_ptr<webrtc::WebRtcSession> session_;
-  std::string id_;
-  bool receiving_;
-
-  talk_base::scoped_ptr<cricket::PortAllocator> allocator_;
-
-  talk_base::scoped_ptr<cricket::ChannelManager> channel_manager_;
-
-  talk_base::Thread* worker_thread_;
-  talk_base::Thread* signaling_thread_;
-};
-
-bool CallbackReceived(WebRtcSessionTest* session, int timeout) {
-  EXPECT_EQ_WAIT(WebRtcSessionTest::kNone, session->PeekOldestCallback(),
-                 timeout);
-  const WebRtcSessionTest::CallbackId peek_id =
-      session->PeekOldestCallback();
-  return peek_id != WebRtcSessionTest::kNone;
-}
-
-TEST_F(WebRtcSessionTest, InitializationReceiveSanity) {
-  const bool kReceiving = true;
-  ASSERT_TRUE(Init(kReceiving));
-  ASSERT_TRUE(CallInitiate());
-
-  // Should return false because no stream has been set up yet.
-  EXPECT_FALSE(CallConnect());
-  const bool kVideo = true;
-  EXPECT_FALSE(CallHasChannel(kVideo));
-  EXPECT_FALSE(CallHasChannel(!kVideo));
-
-  EXPECT_EQ(kNone, PopOldestCallback());
-}
-
-TEST_F(WebRtcSessionTest, AudioSendCallSetUp) {
-  const bool kReceiving = false;
-  ASSERT_TRUE(Init(kReceiving));
-
-  ASSERT_TRUE(CallInitiate());
-
-  ASSERT_TRUE(CallCreateVoiceChannel("Audio"));
-  ASSERT_TRUE(CallConnect());
-
-  std::vector<cricket::Candidate> candidates;
-  cricket::SessionDescription* local_session = GetLocalDescription(
-      &candidates);
-  ASSERT_FALSE(candidates.empty());
-  ASSERT_FALSE(local_session == NULL);
-  if (!CallOnRemoteDescription(local_session, candidates)) {
-      delete local_session;
-      FAIL();
-  }
-
-  // All callbacks should be caught. Assert it.
-  ASSERT_FALSE(CallbackReceived(this, 1000));
-  ASSERT_TRUE(CallHasAudioChannel() &&
-              !CallHasVideoChannel());
-}
-
-TEST_F(WebRtcSessionTest, VideoSendCallSetUp) {
-  const bool kReceiving = false;
-  ASSERT_TRUE(Init(kReceiving));
-
-  ASSERT_TRUE(CallInitiate());
-
-  ASSERT_TRUE(CallCreateVideoChannel("Video"));
-  ASSERT_TRUE(CallConnect());
-
-  std::vector<cricket::Candidate> candidates;
-  cricket::SessionDescription* local_session = GetLocalDescription(
-      &candidates);
-  ASSERT_FALSE(candidates.empty());
-  ASSERT_FALSE(local_session == NULL);
-
-  if (!CallOnRemoteDescription(local_session, candidates)) {
-      delete local_session;
-      FAIL();
-  }
-
-  // All callbacks should be caught. Assert it.
-  ASSERT_FALSE(CallbackReceived(this, 1000));
-  ASSERT_TRUE(!CallHasAudioChannel() &&
-              CallHasVideoChannel());
-}
-
-TEST_F(WebRtcSessionTest, AudioReceiveCallSetUp) {
-  const bool kReceiving = true;
-  const bool video = false;
-
-  ASSERT_TRUE(Init(kReceiving));
-
-  std::vector<cricket::Candidate> candidates;
-  cricket::SessionDescription* local_session =
-      GenerateFakeSession(video, &candidates);
-  ASSERT_FALSE(candidates.empty());
-  ASSERT_FALSE(local_session == NULL);
-  ASSERT_TRUE(CallInitiate());
-  if (!CallOnInitiateMessage(local_session, candidates)) {
-    delete local_session;
-    FAIL();
-  }
-  ASSERT_TRUE(CallConnect());
-  ASSERT_FALSE(CallbackReceived(this, 1000));
-
-  ASSERT_TRUE(CallHasAudioChannel() &&
-              !CallHasVideoChannel());
-}
-
-TEST_F(WebRtcSessionTest, VideoReceiveCallSetUp) {
-  const bool kReceiving = true;
-  const bool video = true;
-
-  ASSERT_TRUE(Init(kReceiving));
-
-  std::vector<cricket::Candidate> candidates;
-  cricket::SessionDescription* local_session =
-      GenerateFakeSession(video, &candidates);
-  ASSERT_FALSE(candidates.empty());
-  ASSERT_FALSE(local_session == NULL);
-  ASSERT_TRUE(CallInitiate());
-  if (!CallOnInitiateMessage(local_session, candidates)) {
-    delete local_session;
-    FAIL();
-  }
-  ASSERT_TRUE(CallConnect());
-  ASSERT_FALSE(CallbackReceived(this, 1000));
-  ASSERT_TRUE(!CallHasAudioChannel() &&
-              CallHasVideoChannel());
-}
diff --git a/third_party/libjingle/source/talk/app/webrtcv1/webrtcv1.scons b/third_party/libjingle/source/talk/app/webrtcv1/webrtcv1.scons
deleted file mode 100644
index a159290..0000000
--- a/third_party/libjingle/source/talk/app/webrtcv1/webrtcv1.scons
+++ /dev/null
@@ -1,60 +0,0 @@
-# -*- Python -*-
-import talk
-
-Import('env')
-
-# local sources
-talk.Library(
-  env,
-  name = 'webrtcv1',
-  srcs = [
-    'peerconnectionimpl.cc',
-    'peerconnectionproxy.cc',
-    'peerconnectionfactory.cc',
-    'webrtcjson.cc',
-    'webrtcsession.cc',
-  ],
-)
-
-talk.Unittest(
-  env,
-  name = 'webrtcv1',
-  srcs = [
-    'peerconnection_unittest.cc',
-    'unittest_utilities.cc',
-    'webrtcsession_unittest.cc',
-  ],
-  libs = [
-    'base',
-    'expat',
-    'jpeg',
-    'json',
-    'p2p',
-    'phone',
-    'srtp',
-    'webrtcv1',
-    'xmpp',
-    'xmllite',
-    'yuvscaler'
-  ],
-  include_talk_media_libs = True,
-  mac_libs = [
-    'crypto',
-    'ssl',
-  ],
-  mac_FRAMEWORKS = [
-    'Foundation',
-    'IOKit',
-    'QTKit',
-  ],
-  win_link_flags = [('', '/nodefaultlib:libcmt')[env.Bit('debug')]],
-  lin_libs = [
-    'rt',
-    'dl',
-    'sound',
-    'X11',
-    'Xext',
-    'Xfixes',
-    'Xrandr'
-  ],
-)
diff --git a/third_party/libjingle/source/talk/base/Equifax_Secure_Global_eBusiness_CA-1.h b/third_party/libjingle/source/talk/base/Equifax_Secure_Global_eBusiness_CA-1.h
deleted file mode 100644
index 6ff97a6..0000000
--- a/third_party/libjingle/source/talk/base/Equifax_Secure_Global_eBusiness_CA-1.h
+++ /dev/null
@@ -1,55 +0,0 @@
-// This file is the Equifax Secure global eBusiness CA-1 certificate
-// in C form.
-
-// It was generated with the following command line:
-// > openssl x509 -in Equifax_Secure_Global_eBusiness_CA-1.cer -noout -C
-
-// The certificate was retrieved from:
-// http://www.geotrust.com/resources/root_certificates/certificates/Equifax_Secure_Global_eBusiness_CA-1.cer
-
-/* subject:/C=US/O=Equifax Secure Inc./CN=Equifax Secure Global eBusiness CA-1 */
-/* issuer :/C=US/O=Equifax Secure Inc./CN=Equifax Secure Global eBusiness CA-1 */
-unsigned char EquifaxSecureGlobalEBusinessCA1_certificate[660]={
-0x30,0x82,0x02,0x90,0x30,0x82,0x01,0xF9,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x01,
-0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x04,0x05,0x00,0x30,
-0x5A,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x1C,
-0x30,0x1A,0x06,0x03,0x55,0x04,0x0A,0x13,0x13,0x45,0x71,0x75,0x69,0x66,0x61,0x78,
-0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x49,0x6E,0x63,0x2E,0x31,0x2D,0x30,0x2B,
-0x06,0x03,0x55,0x04,0x03,0x13,0x24,0x45,0x71,0x75,0x69,0x66,0x61,0x78,0x20,0x53,
-0x65,0x63,0x75,0x72,0x65,0x20,0x47,0x6C,0x6F,0x62,0x61,0x6C,0x20,0x65,0x42,0x75,
-0x73,0x69,0x6E,0x65,0x73,0x73,0x20,0x43,0x41,0x2D,0x31,0x30,0x1E,0x17,0x0D,0x39,
-0x39,0x30,0x36,0x32,0x31,0x30,0x34,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x32,0x30,
-0x30,0x36,0x32,0x31,0x30,0x34,0x30,0x30,0x30,0x30,0x5A,0x30,0x5A,0x31,0x0B,0x30,
-0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x1C,0x30,0x1A,0x06,0x03,
-0x55,0x04,0x0A,0x13,0x13,0x45,0x71,0x75,0x69,0x66,0x61,0x78,0x20,0x53,0x65,0x63,
-0x75,0x72,0x65,0x20,0x49,0x6E,0x63,0x2E,0x31,0x2D,0x30,0x2B,0x06,0x03,0x55,0x04,
-0x03,0x13,0x24,0x45,0x71,0x75,0x69,0x66,0x61,0x78,0x20,0x53,0x65,0x63,0x75,0x72,
-0x65,0x20,0x47,0x6C,0x6F,0x62,0x61,0x6C,0x20,0x65,0x42,0x75,0x73,0x69,0x6E,0x65,
-0x73,0x73,0x20,0x43,0x41,0x2D,0x31,0x30,0x81,0x9F,0x30,0x0D,0x06,0x09,0x2A,0x86,
-0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8D,0x00,0x30,0x81,0x89,
-0x02,0x81,0x81,0x00,0xBA,0xE7,0x17,0x90,0x02,0x65,0xB1,0x34,0x55,0x3C,0x49,0xC2,
-0x51,0xD5,0xDF,0xA7,0xD1,0x37,0x8F,0xD1,0xE7,0x81,0x73,0x41,0x52,0x60,0x9B,0x9D,
-0xA1,0x17,0x26,0x78,0xAD,0xC7,0xB1,0xE8,0x26,0x94,0x32,0xB5,0xDE,0x33,0x8D,0x3A,
-0x2F,0xDB,0xF2,0x9A,0x7A,0x5A,0x73,0x98,0xA3,0x5C,0xE9,0xFB,0x8A,0x73,0x1B,0x5C,
-0xE7,0xC3,0xBF,0x80,0x6C,0xCD,0xA9,0xF4,0xD6,0x2B,0xC0,0xF7,0xF9,0x99,0xAA,0x63,
-0xA2,0xB1,0x47,0x02,0x0F,0xD4,0xE4,0x51,0x3A,0x12,0x3C,0x6C,0x8A,0x5A,0x54,0x84,
-0x70,0xDB,0xC1,0xC5,0x90,0xCF,0x72,0x45,0xCB,0xA8,0x59,0xC0,0xCD,0x33,0x9D,0x3F,
-0xA3,0x96,0xEB,0x85,0x33,0x21,0x1C,0x3E,0x1E,0x3E,0x60,0x6E,0x76,0x9C,0x67,0x85,
-0xC5,0xC8,0xC3,0x61,0x02,0x03,0x01,0x00,0x01,0xA3,0x66,0x30,0x64,0x30,0x11,0x06,
-0x09,0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x00,0x07,
-0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30,0x03,0x01,0x01,
-0xFF,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0xBE,0xA8,
-0xA0,0x74,0x72,0x50,0x6B,0x44,0xB7,0xC9,0x23,0xD8,0xFB,0xA8,0xFF,0xB3,0x57,0x6B,
-0x68,0x6C,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0xBE,0xA8,0xA0,
-0x74,0x72,0x50,0x6B,0x44,0xB7,0xC9,0x23,0xD8,0xFB,0xA8,0xFF,0xB3,0x57,0x6B,0x68,
-0x6C,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x04,0x05,0x00,
-0x03,0x81,0x81,0x00,0x30,0xE2,0x01,0x51,0xAA,0xC7,0xEA,0x5F,0xDA,0xB9,0xD0,0x65,
-0x0F,0x30,0xD6,0x3E,0xDA,0x0D,0x14,0x49,0x6E,0x91,0x93,0x27,0x14,0x31,0xEF,0xC4,
-0xF7,0x2D,0x45,0xF8,0xEC,0xC7,0xBF,0xA2,0x41,0x0D,0x23,0xB4,0x92,0xF9,0x19,0x00,
-0x67,0xBD,0x01,0xAF,0xCD,0xE0,0x71,0xFC,0x5A,0xCF,0x64,0xC4,0xE0,0x96,0x98,0xD0,
-0xA3,0x40,0xE2,0x01,0x8A,0xEF,0x27,0x07,0xF1,0x65,0x01,0x8A,0x44,0x2D,0x06,0x65,
-0x75,0x52,0xC0,0x86,0x10,0x20,0x21,0x5F,0x6C,0x6B,0x0F,0x6C,0xAE,0x09,0x1C,0xAF,
-0xF2,0xA2,0x18,0x34,0xC4,0x75,0xA4,0x73,0x1C,0xF1,0x8D,0xDC,0xEF,0xAD,0xF9,0xB3,
-0x76,0xB4,0x92,0xBF,0xDC,0x95,0x10,0x1E,0xBE,0xCB,0xC8,0x3B,0x5A,0x84,0x60,0x19,
-0x56,0x94,0xA9,0x55,
-};
diff --git a/third_party/libjingle/source/talk/base/asyncfile.cc b/third_party/libjingle/source/talk/base/asyncfile.cc
deleted file mode 100644
index 5c6e11d..0000000
--- a/third_party/libjingle/source/talk/base/asyncfile.cc
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * libjingle
- * Copyright 2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/asyncfile.h"
-
-namespace talk_base {
-
-AsyncFile::AsyncFile() {
-}
-
-AsyncFile::~AsyncFile() {
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/asyncfile.h b/third_party/libjingle/source/talk/base/asyncfile.h
deleted file mode 100644
index 8af52be..0000000
--- a/third_party/libjingle/source/talk/base/asyncfile.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_ASYNCFILE_H__
-#define TALK_BASE_ASYNCFILE_H__
-
-#include "talk/base/sigslot.h"
-
-namespace talk_base {
-
-// Provides the ability to perform file I/O asynchronously.
-// TODO: Create a common base class with AsyncSocket.
-class AsyncFile {
- public:
-  AsyncFile();
-  virtual ~AsyncFile();
-
-  // Determines whether the file will receive read events.
-  virtual bool readable() = 0;
-  virtual void set_readable(bool value) = 0;
-
-  // Determines whether the file will receive write events.
-  virtual bool writable() = 0;
-  virtual void set_writable(bool value) = 0;
-
-  sigslot::signal1<AsyncFile*> SignalReadEvent;
-  sigslot::signal1<AsyncFile*> SignalWriteEvent;
-  sigslot::signal2<AsyncFile*, int> SignalCloseEvent;
-};
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_ASYNCFILE_H__
diff --git a/third_party/libjingle/source/talk/base/asynchttprequest.cc b/third_party/libjingle/source/talk/base/asynchttprequest.cc
deleted file mode 100644
index 68f6100..0000000
--- a/third_party/libjingle/source/talk/base/asynchttprequest.cc
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/asynchttprequest.h"
-
-namespace talk_base {
-
-enum {
-  MSG_TIMEOUT = SignalThread::ST_MSG_FIRST_AVAILABLE,
-  MSG_LAUNCH_REQUEST
-};
-static const int kDefaultHTTPTimeout = 30 * 1000;  // 30 sec
-
-///////////////////////////////////////////////////////////////////////////////
-// AsyncHttpRequest
-///////////////////////////////////////////////////////////////////////////////
-
-AsyncHttpRequest::AsyncHttpRequest(const std::string &user_agent)
-    : start_delay_(0),
-      firewall_(NULL),
-      port_(80),
-      secure_(false),
-      timeout_(kDefaultHTTPTimeout),
-      fail_redirect_(false),
-      factory_(Thread::Current()->socketserver(), user_agent),
-      pool_(&factory_),
-      client_(user_agent.c_str(), &pool_),
-      error_(HE_NONE) {
-  client_.SignalHttpClientComplete.connect(this,
-      &AsyncHttpRequest::OnComplete);
-}
-
-AsyncHttpRequest::~AsyncHttpRequest() {
-}
-
-void AsyncHttpRequest::OnWorkStart() {
-  if (start_delay_ <= 0) {
-    LaunchRequest();
-  } else {
-    Thread::Current()->PostDelayed(start_delay_, this, MSG_LAUNCH_REQUEST);
-  }
-}
-
-void AsyncHttpRequest::OnWorkStop() {
-  // worker is already quitting, no need to explicitly quit
-  LOG(LS_INFO) << "HttpRequest cancelled";
-}
-
-void AsyncHttpRequest::OnComplete(HttpClient* client, HttpErrorType error) {
-  Thread::Current()->Clear(this, MSG_TIMEOUT);
-
-  set_error(error);
-  if (!error) {
-    LOG(LS_INFO) << "HttpRequest completed successfully";
-
-    std::string value;
-    if (client_.response().hasHeader(HH_LOCATION, &value)) {
-      response_redirect_ = value.c_str();
-    }
-  } else {
-    LOG(LS_INFO) << "HttpRequest completed with error: " << error;
-  }
-
-  worker()->Quit();
-}
-
-void AsyncHttpRequest::OnMessage(Message* message) {
-  switch (message->message_id) {
-   case MSG_TIMEOUT:
-    LOG(LS_INFO) << "HttpRequest timed out";
-    client_.reset();
-    worker()->Quit();
-    break;
-   case MSG_LAUNCH_REQUEST:
-    LaunchRequest();
-    break;
-   default:
-    SignalThread::OnMessage(message);
-    break;
-  }
-}
-
-void AsyncHttpRequest::DoWork() {
-  // Do nothing while we wait for the request to finish. We only do this so
-  // that we can be a SignalThread; in the future this class should not be
-  // a SignalThread, since it does not need to spawn a new thread.
-  Thread::Current()->ProcessMessages(kForever);
-}
-
-void AsyncHttpRequest::LaunchRequest() {
-  factory_.SetProxy(proxy_);
-  if (secure_)
-    factory_.UseSSL(host_.c_str());
-
-  bool transparent_proxy = (port_ == 80) &&
-           ((proxy_.type == PROXY_HTTPS) || (proxy_.type == PROXY_UNKNOWN));
-  if (transparent_proxy) {
-    client_.set_proxy(proxy_);
-  }
-  client_.set_fail_redirect(fail_redirect_);
-  client_.set_server(SocketAddress(host_, port_));
-
-  LOG(LS_INFO) << "HttpRequest start: " << host_ + client_.request().path;
-
-  Thread::Current()->PostDelayed(timeout_, this, MSG_TIMEOUT);
-  client_.start();
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/asynchttprequest.h b/third_party/libjingle/source/talk/base/asynchttprequest.h
deleted file mode 100644
index 13edf61..0000000
--- a/third_party/libjingle/source/talk/base/asynchttprequest.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_ASYNCHTTPREQUEST_H_
-#define TALK_BASE_ASYNCHTTPREQUEST_H_
-
-#include <string>
-#include "talk/base/event.h"
-#include "talk/base/httpclient.h"
-#include "talk/base/signalthread.h"
-#include "talk/base/socketpool.h"
-#include "talk/base/sslsocketfactory.h"
-
-namespace talk_base {
-
-class FirewallManager;
-
-///////////////////////////////////////////////////////////////////////////////
-// AsyncHttpRequest
-// Performs an HTTP request on a background thread.  Notifies on the foreground
-// thread once the request is done (successfully or unsuccessfully).
-///////////////////////////////////////////////////////////////////////////////
-
-class AsyncHttpRequest : public SignalThread {
- public:
-  explicit AsyncHttpRequest(const std::string &user_agent);
-  ~AsyncHttpRequest();
-
-  // If start_delay is less than or equal to zero, this starts immediately.
-  // Start_delay defaults to zero.
-  int start_delay() const { return start_delay_; }
-  void set_start_delay(int delay) { start_delay_ = delay; }
-
-  const ProxyInfo& proxy() const { return proxy_; }
-  void set_proxy(const ProxyInfo& proxy) {
-    proxy_ = proxy;
-  }
-  void set_firewall(FirewallManager * firewall) {
-    firewall_ = firewall;
-  }
-
-  // The DNS name of the host to connect to.
-  const std::string& host() { return host_; }
-  void set_host(const std::string& host) { host_ = host; }
-
-  // The port to connect to on the target host.
-  int port() { return port_; }
-  void set_port(int port) { port_ = port; }
-
-  // Whether the request should use SSL.
-  bool secure() { return secure_; }
-  void set_secure(bool secure) { secure_ = secure; }
-
-  // Time to wait on the download, in ms.
-  int timeout() { return timeout_; }
-  void set_timeout(int timeout) { timeout_ = timeout; }
-
-  // Fail redirects to allow analysis of redirect urls, etc.
-  bool fail_redirect() const { return fail_redirect_; }
-  void set_fail_redirect(bool redirect) { fail_redirect_ = redirect; }
-
-  // Returns the redirect when redirection occurs
-  const std::string& response_redirect() { return response_redirect_; }
-
-  HttpRequestData& request() { return client_.request(); }
-  HttpResponseData& response() { return client_.response(); }
-  HttpErrorType error() { return error_; }
-
- protected:
-  void set_error(HttpErrorType error) { error_ = error; }
-  virtual void OnWorkStart();
-  virtual void OnWorkStop();
-  void OnComplete(HttpClient* client, HttpErrorType error);
-  virtual void OnMessage(Message* message);
-  virtual void DoWork();
-
- private:
-  void LaunchRequest();
-
-  int start_delay_;
-  ProxyInfo proxy_;
-  FirewallManager* firewall_;
-  std::string host_;
-  int port_;
-  bool secure_;
-  int timeout_;
-  bool fail_redirect_;
-  SslSocketFactory factory_;
-  ReuseSocketPool pool_;
-  HttpClient client_;
-  HttpErrorType error_;
-  std::string response_redirect_;
-};
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_ASYNCHTTPREQUEST_H_
diff --git a/third_party/libjingle/source/talk/base/asynchttprequest_unittest.cc b/third_party/libjingle/source/talk/base/asynchttprequest_unittest.cc
deleted file mode 100644
index b7a8a03..0000000
--- a/third_party/libjingle/source/talk/base/asynchttprequest_unittest.cc
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string>
-#include "talk/base/asynchttprequest.h"
-#include "talk/base/gunit.h"
-#include "talk/base/httpserver.h"
-#include "talk/base/socketstream.h"
-#include "talk/base/thread.h"
-
-namespace talk_base {
-
-static const SocketAddress kServerAddr("127.0.0.1", 0);
-static const SocketAddress kServerHostnameAddr("localhost", 0);
-static const char kServerGetPath[] = "/get";
-static const char kServerPostPath[] = "/post";
-static const char kServerResponse[] = "This is a test";
-  
-class TestHttpServer : public HttpServer, public sigslot::has_slots<> {
- public:
-  TestHttpServer(Thread* thread, const SocketAddress& addr)
-      : socket_(thread->socketserver()->CreateAsyncSocket(SOCK_STREAM)) {
-    socket_->Bind(addr);
-    socket_->Listen(5);
-    socket_->SignalReadEvent.connect(this, &TestHttpServer::OnAccept);
-  }
-
-  SocketAddress address() const { return socket_->GetLocalAddress(); }
-
- private:
-  void OnAccept(AsyncSocket* socket) {
-    AsyncSocket* new_socket = socket_->Accept(NULL);
-    if (new_socket) {
-      HandleConnection(new SocketStream(new_socket));
-    }
-  }
-  talk_base::scoped_ptr<AsyncSocket> socket_;
-};
-
-class AsyncHttpRequestTest : public testing::Test,
-                             public sigslot::has_slots<> {
- public:
-  AsyncHttpRequestTest()
-      : started_(false),
-        done_(false),
-        server_(Thread::Current(), kServerAddr) {
-    server_.SignalHttpRequest.connect(this, &AsyncHttpRequestTest::OnRequest);
-  }
-
-  bool started() const { return started_; }
-  bool done() const { return done_; }
-
-  AsyncHttpRequest* CreateGetRequest(const std::string& host, int port,
-                                     const std::string& path) {
-    talk_base::AsyncHttpRequest* request =
-        new talk_base::AsyncHttpRequest("unittest");
-    request->SignalWorkDone.connect(this,
-        &AsyncHttpRequestTest::OnRequestDone);
-    request->request().verb = talk_base::HV_GET;
-    request->set_host(host);
-    request->set_port(port);
-    request->request().path = path;
-    request->response().document.reset(new MemoryStream());
-    return request;
-  }
-  AsyncHttpRequest* CreatePostRequest(const std::string& host, int port,
-                                      const std::string& path,
-                                      const std::string content_type,
-                                      StreamInterface* content) {
-    talk_base::AsyncHttpRequest* request =
-        new talk_base::AsyncHttpRequest("unittest");
-    request->SignalWorkDone.connect(this,
-        &AsyncHttpRequestTest::OnRequestDone);
-    request->request().verb = talk_base::HV_POST;
-    request->set_host(host);
-    request->set_port(port);
-    request->request().path = path;
-    request->request().setContent(content_type, content);
-    request->response().document.reset(new MemoryStream());
-    return request;
-  }
-
-  const TestHttpServer& server() const { return server_; }
-
- protected:
-  void OnRequest(HttpServer* server, HttpServerTransaction* t) {
-    started_ = true;
-
-    if (t->request.path == kServerGetPath) {
-      t->response.set_success("text/plain", new MemoryStream(kServerResponse));
-    } else if (t->request.path == kServerPostPath) {
-      // reverse the data and reply
-      size_t size;
-      StreamInterface* in = t->request.document.get();
-      StreamInterface* out = new MemoryStream();
-      in->GetSize(&size);
-      for (size_t i = 0; i < size; ++i) {
-        char ch;
-        in->SetPosition(size - i - 1);
-        in->Read(&ch, 1, NULL, NULL);
-        out->Write(&ch, 1, NULL, NULL);
-      }
-      out->Rewind();
-      t->response.set_success("text/plain", out);
-    } else {
-      t->response.set_error(404);
-    }
-    server_.Respond(t);
-  }
-  void OnRequestDone(SignalThread* thread) {
-    done_ = true;
-  }
-
- private:
-  bool started_;
-  bool done_;
-  TestHttpServer server_;
-};
-
-TEST_F(AsyncHttpRequestTest, TestGetSuccess) {
-  AsyncHttpRequest* req = CreateGetRequest(
-      kServerHostnameAddr.hostname(), server().address().port(),
-      kServerGetPath);
-  EXPECT_FALSE(started());
-  req->Start();
-  EXPECT_TRUE_WAIT(started(), 100);  // Should have started by now.
-  EXPECT_TRUE_WAIT(done(), 5000);
-  std::string response;
-  EXPECT_EQ(200U, req->response().scode);
-  ASSERT_TRUE(req->response().document.get() != NULL);
-  req->response().document->Rewind();
-  req->response().document->ReadLine(&response);
-  EXPECT_EQ(kServerResponse, response);
-  req->Release();
-}
-
-TEST_F(AsyncHttpRequestTest, TestGetNotFound) {
-  AsyncHttpRequest* req = CreateGetRequest(
-      kServerHostnameAddr.hostname(), server().address().port(),
-      "/bad");
-  req->Start();
-  EXPECT_TRUE_WAIT(done(), 5000);
-  size_t size;
-  EXPECT_EQ(404U, req->response().scode);
-  ASSERT_TRUE(req->response().document.get() != NULL);
-  req->response().document->GetSize(&size);
-  EXPECT_EQ(0U, size);
-  req->Release();
-}
-
-TEST_F(AsyncHttpRequestTest, TestPostSuccess) {
-  AsyncHttpRequest* req = CreatePostRequest(
-      kServerHostnameAddr.hostname(), server().address().port(),
-      kServerPostPath, "text/plain", new MemoryStream("abcd1234"));
-  req->Start();
-  EXPECT_TRUE_WAIT(done(), 5000);
-  std::string response;
-  EXPECT_EQ(200U, req->response().scode);
-  ASSERT_TRUE(req->response().document.get() != NULL);
-  req->response().document->Rewind();
-  req->response().document->ReadLine(&response);
-  EXPECT_EQ("4321dcba", response);
-  req->Release();
-}
-
-// Ensure that we shut down properly even if work is outstanding.
-TEST_F(AsyncHttpRequestTest, TestCancel) {
-  AsyncHttpRequest* req = CreateGetRequest(
-      kServerHostnameAddr.hostname(), server().address().port(),
-      kServerGetPath);
-  req->Start();
-  req->Destroy(true);
-}
-
-TEST_F(AsyncHttpRequestTest, TestGetSuccessDelay) {
-  AsyncHttpRequest* req = CreateGetRequest(
-      kServerHostnameAddr.hostname(), server().address().port(),
-      kServerGetPath);
-  req->set_start_delay(10);  // Delay 10ms.
-  req->Start();
-  Thread::SleepMs(5);
-  EXPECT_FALSE(started());  // Should not have started immediately.
-  EXPECT_TRUE_WAIT(started(), 200);  // Should have started by now.
-  EXPECT_TRUE_WAIT(done(), 5000);
-  std::string response;
-  EXPECT_EQ(200U, req->response().scode);
-  ASSERT_TRUE(req->response().document.get() != NULL);
-  req->response().document->Rewind();
-  req->response().document->ReadLine(&response);
-  EXPECT_EQ(kServerResponse, response);
-  req->Release();
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/asyncpacketsocket.cc b/third_party/libjingle/source/talk/base/asyncpacketsocket.cc
deleted file mode 100644
index 7628c12..0000000
--- a/third_party/libjingle/source/talk/base/asyncpacketsocket.cc
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#if defined(_MSC_VER) && _MSC_VER < 1300
-#pragma warning(disable:4786)
-#endif
-
-#include "talk/base/asyncpacketsocket.h"
-
-namespace talk_base {
-
-AsyncPacketSocket::AsyncPacketSocket(AsyncSocket* socket) : socket_(socket) {
-}
-
-AsyncPacketSocket::~AsyncPacketSocket() {
-  delete socket_;
-}
-
-SocketAddress AsyncPacketSocket::GetLocalAddress() const {
-  return socket_->GetLocalAddress();
-}
-
-SocketAddress AsyncPacketSocket::GetRemoteAddress() const {
-  return socket_->GetRemoteAddress();
-}
-
-int AsyncPacketSocket::Bind(const SocketAddress& addr) {
-  return socket_->Bind(addr);
-}
-
-int AsyncPacketSocket::Connect(const SocketAddress& addr) {
-  return socket_->Connect(addr);
-}
-
-int AsyncPacketSocket::Send(const void *pv, size_t cb) {
-  return socket_->Send(pv, cb);
-}
-
-int AsyncPacketSocket::SendTo(
-    const void *pv, size_t cb, const SocketAddress& addr) {
-  return socket_->SendTo(pv, cb, addr);
-}
-
-int AsyncPacketSocket::Close() {
-  return socket_->Close();
-}
-
-Socket::ConnState AsyncPacketSocket::GetState() const {
-  return socket_->GetState();
-}
-
-int AsyncPacketSocket::GetOption(Socket::Option opt, int* value) {
-  return socket_->GetOption(opt, value);
-}
-
-int AsyncPacketSocket::SetOption(Socket::Option opt, int value) {
-  return socket_->SetOption(opt, value);
-}
-
-int AsyncPacketSocket::GetError() const {
-  return socket_->GetError();
-}
-
-void AsyncPacketSocket::SetError(int error) {
-  return socket_->SetError(error);
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/asyncpacketsocket.h b/third_party/libjingle/source/talk/base/asyncpacketsocket.h
deleted file mode 100644
index 901b811..0000000
--- a/third_party/libjingle/source/talk/base/asyncpacketsocket.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_ASYNCPACKETSOCKET_H_
-#define TALK_BASE_ASYNCPACKETSOCKET_H_
-
-#include "talk/base/sigslot.h"
-#include "talk/base/socket.h"
-
-namespace talk_base {
-
-// Provides the ability to receive packets asynchronously. Sends are not
-// buffered since it is acceptable to drop packets under high load.
-class AsyncPacketSocket : public sigslot::has_slots<> {
- public:
-  enum State {
-    STATE_CLOSED,
-    STATE_BINDING,
-    STATE_BOUND,
-    STATE_CONNECTING,
-    STATE_CONNECTED
-  };
-
-  AsyncPacketSocket() { }
-  virtual ~AsyncPacketSocket() { }
-
-  // Returns current local address. Address may be set to NULL if the
-  // socket is not bound yet (GetState() returns STATE_BINDING).
-  virtual SocketAddress GetLocalAddress() const = 0;
-
-  // Returns remote address. Returns zeroes if this is not a client TCP socket.
-  virtual SocketAddress GetRemoteAddress() const = 0;
-
-  // Send a packet.
-  virtual int Send(const void *pv, size_t cb) = 0;
-  virtual int SendTo(const void *pv, size_t cb, const SocketAddress& addr) = 0;
-
-  // Close the socket.
-  virtual int Close() = 0;
-
-  // Returns current state of the socket.
-  virtual State GetState() const = 0;
-
-  // Get/set options.
-  virtual int GetOption(Socket::Option opt, int* value) = 0;
-  virtual int SetOption(Socket::Option opt, int value) = 0;
-
-  // Get/Set current error.
-  // TODO: Remove SetError().
-  virtual int GetError() const = 0;
-  virtual void SetError(int error) = 0;
-
-  // Emitted each time a packet is read. Used only for UDP and
-  // connected TCP sockets.
-  sigslot::signal4<AsyncPacketSocket*, const char*, size_t,
-                   const SocketAddress&> SignalReadPacket;
-
-  // Emitted after address for the socket is allocated, i.e. binding
-  // is finished. State of the socket is changed from BINDING to BOUND
-  // (for UDP and server TCP sockets) or CONNECTING (for client TCP
-  // sockets).
-  sigslot::signal2<AsyncPacketSocket*, const SocketAddress&> SignalAddressReady;
-
-  // Emitted for client TCP sockets when state is changed from
-  // CONNECTING to CONNECTED.
-  sigslot::signal1<AsyncPacketSocket*> SignalConnect;
-
-  // Emitted for client TCP sockets when state is changed from
-  // CONNECTED to CLOSED.
-  sigslot::signal2<AsyncPacketSocket*, int> SignalClose;
-
-  // Used only for listening TCP sockets.
-  sigslot::signal2<AsyncPacketSocket*, AsyncPacketSocket*> SignalNewConnection;
-
- private:
-  DISALLOW_EVIL_CONSTRUCTORS(AsyncPacketSocket);
-};
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_ASYNCPACKETSOCKET_H_
diff --git a/third_party/libjingle/source/talk/base/asyncsocket.cc b/third_party/libjingle/source/talk/base/asyncsocket.cc
deleted file mode 100644
index d9ed94c..0000000
--- a/third_party/libjingle/source/talk/base/asyncsocket.cc
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * libjingle
- * Copyright 2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/asyncsocket.h"
-
-namespace talk_base {
-
-AsyncSocket::AsyncSocket() {
-}
-
-AsyncSocket::~AsyncSocket() {
-}
-
-AsyncSocketAdapter::AsyncSocketAdapter(AsyncSocket* socket) : socket_(NULL) {
-  Attach(socket);
-}
-
-AsyncSocketAdapter::~AsyncSocketAdapter() {
-  delete socket_;
-}
-
-void AsyncSocketAdapter::Attach(AsyncSocket* socket) {
-  ASSERT(!socket_);
-  socket_ = socket;
-  if (socket_) {
-    socket_->SignalConnectEvent.connect(this,
-        &AsyncSocketAdapter::OnConnectEvent);
-    socket_->SignalReadEvent.connect(this,
-        &AsyncSocketAdapter::OnReadEvent);
-    socket_->SignalWriteEvent.connect(this,
-        &AsyncSocketAdapter::OnWriteEvent);
-    socket_->SignalCloseEvent.connect(this,
-        &AsyncSocketAdapter::OnCloseEvent);
-  }
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/asyncsocket.h b/third_party/libjingle/source/talk/base/asyncsocket.h
deleted file mode 100644
index 3d12984..0000000
--- a/third_party/libjingle/source/talk/base/asyncsocket.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_ASYNCSOCKET_H_
-#define TALK_BASE_ASYNCSOCKET_H_
-
-#include "talk/base/common.h"
-#include "talk/base/sigslot.h"
-#include "talk/base/socket.h"
-
-namespace talk_base {
-
-// TODO: Remove Socket and rename AsyncSocket to Socket.
-
-// Provides the ability to perform socket I/O asynchronously.
-class AsyncSocket : public Socket {
- public:
-  AsyncSocket();
-  virtual ~AsyncSocket();
-
-  virtual AsyncSocket* Accept(SocketAddress* paddr) = 0;
-
-  sigslot::signal1<AsyncSocket*> SignalReadEvent;        // ready to read
-  sigslot::signal1<AsyncSocket*> SignalWriteEvent;       // ready to write
-  sigslot::signal1<AsyncSocket*> SignalConnectEvent;     // connected
-  sigslot::signal2<AsyncSocket*, int> SignalCloseEvent;  // closed
-};
-
-class AsyncSocketAdapter : public AsyncSocket, public sigslot::has_slots<> {
- public:
-  // The adapted socket may explicitly be NULL, and later assigned using Attach.
-  // However, subclasses which support detached mode must override any methods
-  // that will be called during the detached period (usually GetState()), to
-  // avoid dereferencing a null pointer.
-  explicit AsyncSocketAdapter(AsyncSocket* socket);
-  virtual ~AsyncSocketAdapter();
-  void Attach(AsyncSocket* socket);
-  virtual SocketAddress GetLocalAddress() const {
-    return socket_->GetLocalAddress();
-  }
-  virtual SocketAddress GetRemoteAddress() const {
-    return socket_->GetRemoteAddress();
-  }
-  virtual int Bind(const SocketAddress& addr) {
-    return socket_->Bind(addr);
-  }
-  virtual int Connect(const SocketAddress& addr) {
-    return socket_->Connect(addr);
-  }
-  virtual int Send(const void* pv, size_t cb) {
-    return socket_->Send(pv, cb);
-  }
-  virtual int SendTo(const void* pv, size_t cb, const SocketAddress& addr) {
-    return socket_->SendTo(pv, cb, addr);
-  }
-  virtual int Recv(void* pv, size_t cb) {
-    return socket_->Recv(pv, cb);
-  }
-  virtual int RecvFrom(void* pv, size_t cb, SocketAddress* paddr) {
-    return socket_->RecvFrom(pv, cb, paddr);
-  }
-  virtual int Listen(int backlog) {
-    return socket_->Listen(backlog);
-  }
-  virtual AsyncSocket* Accept(SocketAddress* paddr) {
-    return socket_->Accept(paddr);
-  }
-  virtual int Close() {
-    return socket_->Close();
-  }
-  virtual int GetError() const {
-    return socket_->GetError();
-  }
-  virtual void SetError(int error) {
-    return socket_->SetError(error);
-  }
-  virtual ConnState GetState() const {
-    return socket_->GetState();
-  }
-  virtual int EstimateMTU(uint16* mtu) {
-    return socket_->EstimateMTU(mtu);
-  }
-  virtual int GetOption(Option opt, int* value) {
-    return socket_->GetOption(opt, value);
-  }
-  virtual int SetOption(Option opt, int value) {
-    return socket_->SetOption(opt, value);
-  }
-
- protected:
-  virtual void OnConnectEvent(AsyncSocket* socket) {
-    SignalConnectEvent(this);
-  }
-  virtual void OnReadEvent(AsyncSocket* socket) {
-    SignalReadEvent(this);
-  }
-  virtual void OnWriteEvent(AsyncSocket* socket) {
-    SignalWriteEvent(this);
-  }
-  virtual void OnCloseEvent(AsyncSocket* socket, int err) {
-    SignalCloseEvent(this, err);
-  }
-
-  AsyncSocket* socket_;
-};
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_ASYNCSOCKET_H_
diff --git a/third_party/libjingle/source/talk/base/asynctcpsocket.cc b/third_party/libjingle/source/talk/base/asynctcpsocket.cc
deleted file mode 100644
index de656ab..0000000
--- a/third_party/libjingle/source/talk/base/asynctcpsocket.cc
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/asynctcpsocket.h"
-
-#include <cstring>
-
-#include "talk/base/byteorder.h"
-#include "talk/base/common.h"
-#include "talk/base/logging.h"
-
-#ifdef POSIX
-#include <errno.h>
-#endif  // POSIX
-
-namespace talk_base {
-
-static const size_t MAX_PACKET_SIZE = 64 * 1024;
-
-typedef uint16 PacketLength;
-static const size_t PKT_LEN_SIZE = sizeof(PacketLength);
-
-static const size_t BUF_SIZE = MAX_PACKET_SIZE + PKT_LEN_SIZE;
-
-static const int LISTEN_BACKLOG = 5;
-
-// Binds and connects |socket| and creates AsyncTCPSocket for
-// it. Takes ownership of |socket|. Returns NULL if bind() or
-// connect() fail (|socket| is destroyed in that case).
-AsyncTCPSocket* AsyncTCPSocket::Create(
-    AsyncSocket* socket,
-    const SocketAddress& bind_address,
-    const SocketAddress& remote_address) {
-  scoped_ptr<AsyncSocket> owned_socket(socket);
-  if (socket->Bind(bind_address) < 0) {
-    LOG(LS_ERROR) << "Bind() failed with error " << socket->GetError();
-    return NULL;
-  }
-  if (socket->Connect(remote_address) < 0) {
-    LOG(LS_ERROR) << "Connect() failed with error " << socket->GetError();
-    return NULL;
-  }
-  return new AsyncTCPSocket(owned_socket.release(), false);
-}
-
-AsyncTCPSocket::AsyncTCPSocket(AsyncSocket* socket, bool listen)
-    : socket_(socket),
-      listen_(listen),
-      insize_(BUF_SIZE),
-      inpos_(0),
-      outsize_(BUF_SIZE),
-      outpos_(0) {
-  inbuf_ = new char[insize_];
-  outbuf_ = new char[outsize_];
-
-  ASSERT(socket_.get() != NULL);
-  socket_->SignalConnectEvent.connect(this, &AsyncTCPSocket::OnConnectEvent);
-  socket_->SignalReadEvent.connect(this, &AsyncTCPSocket::OnReadEvent);
-  socket_->SignalWriteEvent.connect(this, &AsyncTCPSocket::OnWriteEvent);
-  socket_->SignalCloseEvent.connect(this, &AsyncTCPSocket::OnCloseEvent);
-
-  if (listen_) {
-    if (socket_->Listen(LISTEN_BACKLOG) < 0) {
-      LOG(LS_ERROR) << "Listen() failed with error " << socket_->GetError();
-    }
-  }
-}
-
-AsyncTCPSocket::~AsyncTCPSocket() {
-  delete [] inbuf_;
-  delete [] outbuf_;
-}
-
-SocketAddress AsyncTCPSocket::GetLocalAddress() const {
-  return socket_->GetLocalAddress();
-}
-
-SocketAddress AsyncTCPSocket::GetRemoteAddress() const {
-  return socket_->GetRemoteAddress();
-}
-
-int AsyncTCPSocket::Send(const void *pv, size_t cb) {
-  if (cb > MAX_PACKET_SIZE) {
-    socket_->SetError(EMSGSIZE);
-    return -1;
-  }
-
-  // If we are blocking on send, then silently drop this packet
-  if (outpos_)
-    return static_cast<int>(cb);
-
-  PacketLength pkt_len = HostToNetwork16(static_cast<PacketLength>(cb));
-  memcpy(outbuf_, &pkt_len, PKT_LEN_SIZE);
-  memcpy(outbuf_ + PKT_LEN_SIZE, pv, cb);
-  outpos_ = PKT_LEN_SIZE + cb;
-
-  int res = Flush();
-  if (res <= 0) {
-    // drop packet if we made no progress
-    outpos_ = 0;
-    return res;
-  }
-
-  // We claim to have sent the whole thing, even if we only sent partial
-  return static_cast<int>(cb);
-}
-
-int AsyncTCPSocket::SendTo(const void *pv, size_t cb,
-                           const SocketAddress& addr) {
-  if (addr == GetRemoteAddress())
-    return Send(pv, cb);
-
-  ASSERT(false);
-  socket_->SetError(ENOTCONN);
-  return -1;
-}
-
-int AsyncTCPSocket::Close() {
-  return socket_->Close();
-}
-
-AsyncTCPSocket::State AsyncTCPSocket::GetState() const {
-  switch (socket_->GetState()) {
-    case Socket::CS_CLOSED:
-      return STATE_CLOSED;
-    case Socket::CS_CONNECTING:
-      if (listen_) {
-        return STATE_BOUND;
-      } else {
-        return STATE_CONNECTING;
-      }
-    case Socket::CS_CONNECTED:
-      return STATE_CONNECTED;
-    default:
-      ASSERT(false);
-      return STATE_CLOSED;
-  }
-}
-
-int AsyncTCPSocket::GetOption(Socket::Option opt, int* value) {
-  return socket_->GetOption(opt, value);
-}
-
-int AsyncTCPSocket::SetOption(Socket::Option opt, int value) {
-  return socket_->SetOption(opt, value);
-}
-
-int AsyncTCPSocket::GetError() const {
-  return socket_->GetError();
-}
-
-void AsyncTCPSocket::SetError(int error) {
-  return socket_->SetError(error);
-}
-
-int AsyncTCPSocket::SendRaw(const void * pv, size_t cb) {
-  if (outpos_ + cb > outsize_) {
-    socket_->SetError(EMSGSIZE);
-    return -1;
-  }
-
-  memcpy(outbuf_ + outpos_, pv, cb);
-  outpos_ += cb;
-
-  return Flush();
-}
-
-void AsyncTCPSocket::ProcessInput(char * data, size_t& len) {
-  SocketAddress remote_addr(GetRemoteAddress());
-
-  while (true) {
-    if (len < PKT_LEN_SIZE)
-      return;
-
-    PacketLength pkt_len;
-    memcpy(&pkt_len, data, PKT_LEN_SIZE);
-    pkt_len = NetworkToHost16(pkt_len);
-
-    if (len < PKT_LEN_SIZE + pkt_len)
-      return;
-
-    SignalReadPacket(this, data + PKT_LEN_SIZE, pkt_len, remote_addr);
-
-    len -= PKT_LEN_SIZE + pkt_len;
-    if (len > 0) {
-      memmove(data, data + PKT_LEN_SIZE + pkt_len, len);
-    }
-  }
-}
-
-int AsyncTCPSocket::Flush() {
-  int res = socket_->Send(outbuf_, outpos_);
-  if (res <= 0) {
-    return res;
-  }
-  if (static_cast<size_t>(res) <= outpos_) {
-    outpos_ -= res;
-  } else {
-    ASSERT(false);
-    return -1;
-  }
-  if (outpos_ > 0) {
-    memmove(outbuf_, outbuf_ + res, outpos_);
-  }
-  return res;
-}
-
-void AsyncTCPSocket::OnConnectEvent(AsyncSocket* socket) {
-  SignalConnect(this);
-}
-
-void AsyncTCPSocket::OnReadEvent(AsyncSocket* socket) {
-  ASSERT(socket_.get() == socket);
-
-  if (listen_) {
-    talk_base::SocketAddress address;
-    talk_base::AsyncSocket* new_socket = socket->Accept(&address);
-    if (!new_socket) {
-      // TODO: Do something better like forwarding the error
-      // to the user.
-      LOG(LS_ERROR) << "TCP accept failed with error " << socket_->GetError();
-      return;
-    }
-
-    SignalNewConnection(this, new AsyncTCPSocket(new_socket, false));
-
-    // Prime a read event in case data is waiting.
-    new_socket->SignalReadEvent(new_socket);
-  } else {
-    int len = socket_->Recv(inbuf_ + inpos_, insize_ - inpos_);
-    if (len < 0) {
-      // TODO: Do something better like forwarding the error to the user.
-      if (!socket_->IsBlocking()) {
-        LOG(LS_ERROR) << "Recv() returned error: " << socket_->GetError();
-      }
-      return;
-    }
-
-    inpos_ += len;
-
-    ProcessInput(inbuf_, inpos_);
-
-    if (inpos_ >= insize_) {
-      LOG(LS_ERROR) << "input buffer overflow";
-      ASSERT(false);
-      inpos_ = 0;
-    }
-  }
-}
-
-void AsyncTCPSocket::OnWriteEvent(AsyncSocket* socket) {
-  ASSERT(socket_.get() == socket);
-
-  if (outpos_ > 0) {
-    Flush();
-  }
-}
-
-void AsyncTCPSocket::OnCloseEvent(AsyncSocket* socket, int error) {
-  SignalClose(this, error);
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/asynctcpsocket.h b/third_party/libjingle/source/talk/base/asynctcpsocket.h
deleted file mode 100644
index 07d6284..0000000
--- a/third_party/libjingle/source/talk/base/asynctcpsocket.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_ASYNCTCPSOCKET_H_
-#define TALK_BASE_ASYNCTCPSOCKET_H_
-
-#include "talk/base/asyncpacketsocket.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/base/socketfactory.h"
-
-namespace talk_base {
-
-// Simulates UDP semantics over TCP.  Send and Recv packet sizes
-// are preserved, and drops packets silently on Send, rather than
-// buffer them in user space.
-class AsyncTCPSocket : public AsyncPacketSocket {
- public:
-  // Binds and connects |socket| and creates AsyncTCPSocket for
-  // it. Takes ownership of |socket|. Returns NULL if bind() or
-  // connect() fail (|socket| is destroyed in that case).
-  static AsyncTCPSocket* Create(AsyncSocket* socket,
-                                const SocketAddress& bind_address,
-                                const SocketAddress& remote_address);
-  explicit AsyncTCPSocket(AsyncSocket* socket, bool listen);
-  virtual ~AsyncTCPSocket();
-
-  virtual SocketAddress GetLocalAddress() const;
-  virtual SocketAddress GetRemoteAddress() const;
-  virtual int Send(const void *pv, size_t cb);
-  virtual int SendTo(const void *pv, size_t cb, const SocketAddress& addr);
-  virtual int Close();
-
-  virtual State GetState() const;
-  virtual int GetOption(Socket::Option opt, int* value);
-  virtual int SetOption(Socket::Option opt, int value);
-  virtual int GetError() const;
-  virtual void SetError(int error);
-
- protected:
-  int SendRaw(const void* pv, size_t cb);
-  virtual void ProcessInput(char* data, size_t& len);
-
- private:
-  int Flush();
-
-  // Called by the underlying socket
-  void OnConnectEvent(AsyncSocket* socket);
-  void OnReadEvent(AsyncSocket* socket);
-  void OnWriteEvent(AsyncSocket* socket);
-  void OnCloseEvent(AsyncSocket* socket, int error);
-
-  scoped_ptr<AsyncSocket> socket_;
-  bool listen_;
-  char* inbuf_, * outbuf_;
-  size_t insize_, inpos_, outsize_, outpos_;
-
-  DISALLOW_EVIL_CONSTRUCTORS(AsyncTCPSocket);
-};
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_ASYNCTCPSOCKET_H_
diff --git a/third_party/libjingle/source/talk/base/asyncudpsocket.cc b/third_party/libjingle/source/talk/base/asyncudpsocket.cc
deleted file mode 100644
index 8452a65..0000000
--- a/third_party/libjingle/source/talk/base/asyncudpsocket.cc
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/asyncudpsocket.h"
-#include "talk/base/logging.h"
-
-namespace talk_base {
-
-static const int BUF_SIZE = 64 * 1024;
-
-AsyncUDPSocket* AsyncUDPSocket::Create(
-    AsyncSocket* socket,
-    const SocketAddress& bind_address) {
-  scoped_ptr<AsyncSocket> owned_socket(socket);
-  if (socket->Bind(bind_address) < 0) {
-    LOG(LS_ERROR) << "Bind() failed with error " << socket->GetError();
-    return NULL;
-  }
-  return new AsyncUDPSocket(owned_socket.release());
-}
-
-AsyncUDPSocket* AsyncUDPSocket::Create(SocketFactory* factory,
-                                       const SocketAddress& bind_address) {
-  AsyncSocket* socket = factory->CreateAsyncSocket(SOCK_DGRAM);
-  if (!socket)
-    return NULL;
-  return Create(socket, bind_address);
-}
-
-AsyncUDPSocket::AsyncUDPSocket(AsyncSocket* socket)
-    : socket_(socket) {
-  ASSERT(socket_.get() != NULL);
-  size_ = BUF_SIZE;
-  buf_ = new char[size_];
-
-  // The socket should start out readable but not writable.
-  socket_->SignalReadEvent.connect(this, &AsyncUDPSocket::OnReadEvent);
-}
-
-AsyncUDPSocket::~AsyncUDPSocket() {
-  delete [] buf_;
-}
-
-SocketAddress AsyncUDPSocket::GetLocalAddress() const {
-  return socket_->GetLocalAddress();
-}
-
-SocketAddress AsyncUDPSocket::GetRemoteAddress() const {
-  return socket_->GetRemoteAddress();
-}
-
-int AsyncUDPSocket::Send(const void *pv, size_t cb) {
-  return socket_->Send(pv, cb);
-}
-
-int AsyncUDPSocket::SendTo(
-    const void *pv, size_t cb, const SocketAddress& addr) {
-  return socket_->SendTo(pv, cb, addr);
-}
-
-int AsyncUDPSocket::Close() {
-  return socket_->Close();
-}
-
-AsyncUDPSocket::State AsyncUDPSocket::GetState() const {
-  return STATE_BOUND;
-}
-
-int AsyncUDPSocket::GetOption(Socket::Option opt, int* value) {
-  return socket_->GetOption(opt, value);
-}
-
-int AsyncUDPSocket::SetOption(Socket::Option opt, int value) {
-  return socket_->SetOption(opt, value);
-}
-
-int AsyncUDPSocket::GetError() const {
-  return socket_->GetError();
-}
-
-void AsyncUDPSocket::SetError(int error) {
-  return socket_->SetError(error);
-}
-
-void AsyncUDPSocket::OnReadEvent(AsyncSocket* socket) {
-  ASSERT(socket_.get() == socket);
-
-  SocketAddress remote_addr;
-  int len = socket_->RecvFrom(buf_, size_, &remote_addr);
-  if (len < 0) {
-    // An error here typically means we got an ICMP error in response to our
-    // send datagram, indicating the remote address was unreachable.
-    // When doing ICE, this kind of thing will often happen.
-    // TODO: Do something better like forwarding the error to the user.
-    SocketAddress local_addr = socket_->GetLocalAddress();
-    LOG(LS_INFO) << "AsyncUDPSocket[" << local_addr.ToString() << "] "
-                 << "receive failed with error " << socket_->GetError();
-    return;
-  }
-
-  // TODO: Make sure that we got all of the packet.
-  // If we did not, then we should resize our buffer to be large enough.
-  SignalReadPacket(this, buf_, (size_t)len, remote_addr);
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/asyncudpsocket.h b/third_party/libjingle/source/talk/base/asyncudpsocket.h
deleted file mode 100644
index 207d119..0000000
--- a/third_party/libjingle/source/talk/base/asyncudpsocket.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_ASYNCUDPSOCKET_H_
-#define TALK_BASE_ASYNCUDPSOCKET_H_
-
-#include "talk/base/asyncpacketsocket.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/base/socketfactory.h"
-
-namespace talk_base {
-
-// Provides the ability to receive packets asynchronously.  Sends are not
-// buffered since it is acceptable to drop packets under high load.
-class AsyncUDPSocket : public AsyncPacketSocket {
- public:
-  // Binds |socket| and creates AsyncUDPSocket for it. Takes ownership
-  // of |socket|. Returns NULL if bind() fails (|socket| is destroyed
-  // in that case).
-  static AsyncUDPSocket* Create(AsyncSocket* socket,
-                                const SocketAddress& bind_address);
-  // Creates a new socket for sending asynchronous UDP packets using an
-  // asynchronous socket from the given factory.
-  static AsyncUDPSocket* Create(SocketFactory* factory,
-                                const SocketAddress& bind_address);
-  explicit AsyncUDPSocket(AsyncSocket* socket);
-  virtual ~AsyncUDPSocket();
-
-  virtual SocketAddress GetLocalAddress() const;
-  virtual SocketAddress GetRemoteAddress() const;
-  virtual int Send(const void *pv, size_t cb);
-  virtual int SendTo(const void *pv, size_t cb, const SocketAddress& addr);
-  virtual int Close();
-
-  virtual State GetState() const;
-  virtual int GetOption(Socket::Option opt, int* value);
-  virtual int SetOption(Socket::Option opt, int value);
-  virtual int GetError() const;
-  virtual void SetError(int error);
-
- private:
-  // Called when the underlying socket is ready to be read from.
-  void OnReadEvent(AsyncSocket* socket);
-
-  scoped_ptr<AsyncSocket> socket_;
-  char* buf_;
-  size_t size_;
-};
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_ASYNCUDPSOCKET_H_
diff --git a/third_party/libjingle/source/talk/base/atomicops.h b/third_party/libjingle/source/talk/base/atomicops.h
deleted file mode 100644
index 94ade69..0000000
--- a/third_party/libjingle/source/talk/base/atomicops.h
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * libjingle
- * Copyright 2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_ATOMICOPS_H_
-#define TALK_BASE_ATOMICOPS_H_
-
-#include <string>
-
-#include "talk/base/basictypes.h"
-#include "talk/base/common.h"
-#include "talk/base/logging.h"
-#include "talk/base/scoped_ptr.h"
-
-namespace talk_base {
-
-// A single-producer, single-consumer, fixed-size queue.
-// All methods not ending in Unsafe can be safely called without locking,
-// provided that calls to consumer methods (Peek/Pop) or producer methods (Push)
-// only happen on a single thread per method type. If multiple threads need to
-// read simultaneously or write simultaneously, other synchronization is
-// necessary. Synchronization is also required if a call into any Unsafe method
-// could happen at the same time as a call to any other method.
-template <typename T>
-class FixedSizeLockFreeQueue {
- private:
-// Atomic primitives and memory barrier
-#if defined(__arm__)
-  typedef uint32 Atomic32;
-
-  // Copied from google3/base/atomicops-internals-arm-v6plus.h
-  static inline void MemoryBarrier() {
-    asm volatile("dmb":::"memory");
-  }
-
-  // Adapted from google3/base/atomicops-internals-arm-v6plus.h
-  static inline void AtomicIncrement(volatile Atomic32* ptr) {
-    Atomic32 str_success, value;
-    asm volatile (
-        "1:\n"
-        "ldrex  %1, [%2]\n"
-        "add    %1, %1, #1\n"
-        "strex  %0, %1, [%2]\n"
-        "teq    %0, #0\n"
-        "bne    1b"
-        : "=&r"(str_success), "=&r"(value)
-        : "r" (ptr)
-        : "cc", "memory");
-  }
-#elif !defined(SKIP_ATOMIC_CHECK)
-#error "No atomic operations defined for the given architecture."
-#endif
-
- public:
-  // Constructs an empty queue, with capacity 0.
-  FixedSizeLockFreeQueue() : pushed_count_(0),
-                             popped_count_(0),
-                             capacity_(0),
-                             data_(NULL) {}
-  // Constructs an empty queue with the given capacity.
-  FixedSizeLockFreeQueue(size_t capacity) : pushed_count_(0),
-                                            popped_count_(0),
-                                            capacity_(capacity),
-                                            data_(new T[capacity]) {}
-
-  // Pushes a value onto the queue. Returns true if the value was successfully
-  // pushed (there was space in the queue). This method can be safely called at
-  // the same time as PeekFront/PopFront.
-  bool PushBack(T value) {
-    if (capacity_ == 0) {
-      LOG(LS_WARNING) << "Queue capacity is 0.";
-      return false;
-    }
-    if (IsFull()) {
-      return false;
-    }
-
-    data_[pushed_count_ % capacity_] = value;
-    // Make sure the data is written before the count is incremented, so other
-    // threads can't see the value exists before being able to read it.
-    MemoryBarrier();
-    AtomicIncrement(&pushed_count_);
-    return true;
-  }
-
-  // Retrieves the oldest value pushed onto the queue. Returns true if there was
-  // an item to peek (the queue was non-empty). This method can be safely called
-  // at the same time as PushBack.
-  bool PeekFront(T* value_out) {
-    if (capacity_ == 0) {
-      LOG(LS_WARNING) << "Queue capacity is 0.";
-      return false;
-    }
-    if (IsEmpty()) {
-      return false;
-    }
-
-    *value_out = data_[popped_count_ % capacity_];
-    return true;
-  }
-
-  // Retrieves the oldest value pushed onto the queue and removes it from the
-  // queue. Returns true if there was an item to pop (the queue was non-empty).
-  // This method can be safely called at the same time as PushBack.
-  bool PopFront(T* value_out) {
-    if (PeekFront(value_out)) {
-      AtomicIncrement(&popped_count_);
-      return true;
-    }
-    return false;
-  }
-
-  // Clears the current items in the queue and sets the new (fixed) size. This
-  // method cannot be called at the same time as any other method.
-  void ClearAndResizeUnsafe(int new_capacity) {
-    capacity_ = new_capacity;
-    data_.reset(new T[new_capacity]);
-    pushed_count_ = 0;
-    popped_count_ = 0;
-  }
-
-  // Returns true if there is no space left in the queue for new elements.
-  int IsFull() const { return pushed_count_ == popped_count_ + capacity_; }
-  // Returns true if there are no elements in the queue.
-  int IsEmpty() const { return pushed_count_ == popped_count_; }
-  // Returns the current number of elements in the queue. This is always in the
-  // range [0, capacity]
-  size_t Size() const { return pushed_count_ - popped_count_; }
-
-  // Returns the capacity of the queue (max size).
-  size_t capacity() const { return capacity_; }
-
- private:
-  volatile Atomic32 pushed_count_;
-  volatile Atomic32 popped_count_;
-  size_t capacity_;
-  talk_base::scoped_array<T> data_;
-  DISALLOW_COPY_AND_ASSIGN(FixedSizeLockFreeQueue);
-};
-
-}
-
-#endif  // TALK_BASE_ATOMICOPS_H_
diff --git a/third_party/libjingle/source/talk/base/atomicops_unittest.cc b/third_party/libjingle/source/talk/base/atomicops_unittest.cc
deleted file mode 100644
index 24804c6..0000000
--- a/third_party/libjingle/source/talk/base/atomicops_unittest.cc
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * libjingle
- * Copyright 2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#if !defined(__arm__)
-// For testing purposes, define faked versions of the atomic operations
-#include "talk/base/basictypes.h"
-namespace talk_base {
-typedef uint32 Atomic32;
-static inline void MemoryBarrier() { }
-static inline void AtomicIncrement(volatile Atomic32* ptr) {
-  *ptr = *ptr + 1;
-}
-}
-#define SKIP_ATOMIC_CHECK
-#endif
-
-#include "talk/base/atomicops.h"
-#include "talk/base/gunit.h"
-#include "talk/base/helpers.h"
-#include "talk/base/logging.h"
-
-TEST(FixedSizeLockFreeQueueTest, TestDefaultConstruct) {
-  talk_base::FixedSizeLockFreeQueue<int> queue;
-  EXPECT_EQ(0u, queue.capacity());
-  EXPECT_EQ(0u, queue.Size());
-  EXPECT_FALSE(queue.PushBack(1));
-  int val;
-  EXPECT_FALSE(queue.PopFront(&val));
-}
-
-TEST(FixedSizeLockFreeQueueTest, TestConstruct) {
-  talk_base::FixedSizeLockFreeQueue<int> queue(5);
-  EXPECT_EQ(5u, queue.capacity());
-  EXPECT_EQ(0u, queue.Size());
-  int val;
-  EXPECT_FALSE(queue.PopFront(&val));
-}
-
-TEST(FixedSizeLockFreeQueueTest, TestPushPop) {
-  talk_base::FixedSizeLockFreeQueue<int> queue(2);
-  EXPECT_EQ(2u, queue.capacity());
-  EXPECT_EQ(0u, queue.Size());
-  EXPECT_TRUE(queue.PushBack(1));
-  EXPECT_EQ(1u, queue.Size());
-  EXPECT_TRUE(queue.PushBack(2));
-  EXPECT_EQ(2u, queue.Size());
-  EXPECT_FALSE(queue.PushBack(3));
-  EXPECT_EQ(2u, queue.Size());
-  int val;
-  EXPECT_TRUE(queue.PopFront(&val));
-  EXPECT_EQ(1, val);
-  EXPECT_EQ(1u, queue.Size());
-  EXPECT_TRUE(queue.PopFront(&val));
-  EXPECT_EQ(2, val);
-  EXPECT_EQ(0u, queue.Size());
-  EXPECT_FALSE(queue.PopFront(&val));
-  EXPECT_EQ(0u, queue.Size());
-}
-
-TEST(FixedSizeLockFreeQueueTest, TestResize) {
-  talk_base::FixedSizeLockFreeQueue<int> queue(2);
-  EXPECT_EQ(2u, queue.capacity());
-  EXPECT_EQ(0u, queue.Size());
-  EXPECT_TRUE(queue.PushBack(1));
-  EXPECT_EQ(1u, queue.Size());
-
-  queue.ClearAndResizeUnsafe(5);
-  EXPECT_EQ(5u, queue.capacity());
-  EXPECT_EQ(0u, queue.Size());
-  int val;
-  EXPECT_FALSE(queue.PopFront(&val));
-}
diff --git a/third_party/libjingle/source/talk/base/autodetectproxy.cc b/third_party/libjingle/source/talk/base/autodetectproxy.cc
deleted file mode 100644
index 37faa4d..0000000
--- a/third_party/libjingle/source/talk/base/autodetectproxy.cc
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/autodetectproxy.h"
-#include "talk/base/httpcommon.h"
-#include "talk/base/httpcommon-inl.h"
-#include "talk/base/proxydetect.h"
-
-namespace talk_base {
-
-enum { MSG_TIMEOUT = SignalThread::ST_MSG_FIRST_AVAILABLE };
-
-static const ProxyType TEST_ORDER[] = {
-  PROXY_HTTPS, PROXY_SOCKS5, PROXY_UNKNOWN
-};
-
-static const int kSavedStringLimit = 128;
-
-static void SaveStringToStack(char *dst,
-                              const std::string &src,
-                              size_t dst_size) {
-  strncpy(dst, src.c_str(), dst_size - 1);
-  dst[dst_size - 1] = '\0';
-}
-
-AutoDetectProxy::AutoDetectProxy(const std::string& user_agent)
-    : agent_(user_agent), socket_(NULL), next_(0) {
-}
-
-AutoDetectProxy::~AutoDetectProxy() {
-}
-
-void AutoDetectProxy::DoWork() {
-  // TODO: Try connecting to server_url without proxy first here?
-  if (!server_url_.empty()) {
-    LOG(LS_INFO) << "GetProxySettingsForUrl(" << server_url_ << ") - start";
-    GetProxySettingsForUrl(agent_.c_str(), server_url_.c_str(), proxy_, true);
-    LOG(LS_INFO) << "GetProxySettingsForUrl - stop";
-  }
-  Url<char> url(proxy_.address.IPAsString());
-  if (url.valid()) {
-    LOG(LS_WARNING) << "AutoDetectProxy removing http prefix on proxy host";
-    proxy_.address.SetIP(url.host());
-  }
-  LOG(LS_INFO) << "AutoDetectProxy found proxy at " << proxy_.address;
-  if (proxy_.type == PROXY_UNKNOWN) {
-    LOG(LS_INFO) << "AutoDetectProxy initiating proxy classification";
-    Next();
-    // Process I/O until Stop()
-    Thread::Current()->ProcessMessages(kForever);
-    // Clean up the autodetect socket, from the thread that created it
-    delete socket_;
-  }
-  // TODO: If we found a proxy, try to use it to verify that it
-  // works by sending a request to server_url. This could either be
-  // done here or by the HttpPortAllocator.
-}
-
-void AutoDetectProxy::OnMessage(Message *msg) {
-  if (MSG_TIMEOUT == msg->message_id) {
-    OnCloseEvent(socket_, ETIMEDOUT);
-  } else {
-    // This must be the ST_MSG_WORKER_DONE message that deletes the
-    // AutoDetectProxy object. We have observed crashes within this stack that
-    // seem to be highly reproducible for a small subset of users and thus are
-    // probably correlated with a specific proxy setting, so copy potentially
-    // relevant information onto the stack to make it available in Windows
-    // minidumps.
-
-    // Save the user agent and the number of auto-detection passes that we
-    // needed.
-    char agent[kSavedStringLimit];
-    SaveStringToStack(agent, agent_, sizeof agent);
-
-    int next = next_;
-
-    // Now the detected proxy config (minus the password field, which could be
-    // sensitive).
-    ProxyType type = proxy().type;
-
-    char address_hostname[kSavedStringLimit];
-    SaveStringToStack(address_hostname,
-                      proxy().address.hostname(),
-                      sizeof address_hostname);
-
-    IPAddress address_ip = proxy().address.ipaddr();
-
-    uint16 address_port = proxy().address.port();
-
-    char autoconfig_url[kSavedStringLimit];
-    SaveStringToStack(autoconfig_url,
-                      proxy().autoconfig_url,
-                      sizeof autoconfig_url);
-
-    bool autodetect = proxy().autodetect;
-
-    char bypass_list[kSavedStringLimit];
-    SaveStringToStack(bypass_list, proxy().bypass_list, sizeof bypass_list);
-
-    char username[kSavedStringLimit];
-    SaveStringToStack(username, proxy().username, sizeof username);
-
-    SignalThread::OnMessage(msg);
-
-    // Log the gathered data at a log level that will never actually be enabled
-    // so that the compiler is forced to retain the data on the stack.
-    LOG(LS_SENSITIVE) << agent << " " << next << " " << type << " "
-                      << address_hostname << " " << address_ip << " "
-                      << address_port << " " << autoconfig_url << " "
-                      << autodetect << " " << bypass_list << " " << username;
-  }
-}
-
-void AutoDetectProxy::Next() {
-  if (TEST_ORDER[next_] >= PROXY_UNKNOWN) {
-    Complete(PROXY_UNKNOWN);
-    return;
-  }
-
-  LOG(LS_VERBOSE) << "AutoDetectProxy connecting to "
-                  << proxy_.address.ToString();
-
-  if (socket_) {
-    Thread::Current()->Clear(this, MSG_TIMEOUT);
-    socket_->Close();
-    Thread::Current()->Dispose(socket_);
-    socket_ = NULL;
-  }
-
-  socket_ = Thread::Current()->socketserver()->CreateAsyncSocket(SOCK_STREAM);
-  socket_->SignalConnectEvent.connect(this, &AutoDetectProxy::OnConnectEvent);
-  socket_->SignalReadEvent.connect(this, &AutoDetectProxy::OnReadEvent);
-  socket_->SignalCloseEvent.connect(this, &AutoDetectProxy::OnCloseEvent);
-  socket_->Connect(proxy_.address);
-
-  // Timeout after 2 seconds
-  Thread::Current()->PostDelayed(2000, this, MSG_TIMEOUT);
-}
-
-void AutoDetectProxy::Complete(ProxyType type) {
-  Thread::Current()->Clear(this, MSG_TIMEOUT);
-  socket_->Close();
-
-  proxy_.type = type;
-  LoggingSeverity sev = (proxy_.type == PROXY_UNKNOWN) ? LS_ERROR : LS_INFO;
-  LOG_V(sev) << "AutoDetectProxy detected " << proxy_.address.ToString()
-             << " as type " << proxy_.type;
-
-  Thread::Current()->Quit();
-}
-
-void AutoDetectProxy::OnConnectEvent(AsyncSocket * socket) {
-  std::string probe;
-
-  switch (TEST_ORDER[next_]) {
-    case PROXY_HTTPS:
-      probe.assign("CONNECT www.google.com:443 HTTP/1.0\r\n"
-                   "User-Agent: ");
-      probe.append(agent_);
-      probe.append("\r\n"
-                   "Host: www.google.com\r\n"
-                   "Content-Length: 0\r\n"
-                   "Proxy-Connection: Keep-Alive\r\n"
-                   "\r\n");
-      break;
-    case PROXY_SOCKS5:
-      probe.assign("\005\001\000", 3);
-      break;
-    default:
-      ASSERT(false);
-      return;
-  }
-
-  LOG(LS_VERBOSE) << "AutoDetectProxy probing type " << TEST_ORDER[next_]
-                  << " sending " << probe.size() << " bytes";
-  socket_->Send(probe.data(), probe.size());
-}
-
-void AutoDetectProxy::OnReadEvent(AsyncSocket * socket) {
-  char data[257];
-  int len = socket_->Recv(data, 256);
-  if (len > 0) {
-    data[len] = 0;
-    LOG(LS_VERBOSE) << "AutoDetectProxy read " << len << " bytes";
-  }
-
-  switch (TEST_ORDER[next_]) {
-    case PROXY_HTTPS:
-      if ((len >= 2) && (data[0] == '\x05')) {
-        Complete(PROXY_SOCKS5);
-        return;
-      }
-      if ((len >= 5) && (strncmp(data, "HTTP/", 5) == 0)) {
-        Complete(PROXY_HTTPS);
-        return;
-      }
-      break;
-    case PROXY_SOCKS5:
-      if ((len >= 2) && (data[0] == '\x05')) {
-        Complete(PROXY_SOCKS5);
-        return;
-      }
-      break;
-    default:
-      ASSERT(false);
-      return;
-  }
-
-  ++next_;
-  Next();
-}
-
-void AutoDetectProxy::OnCloseEvent(AsyncSocket * socket, int error) {
-  LOG(LS_VERBOSE) << "AutoDetectProxy closed with error: " << error;
-  ++next_;
-  Next();
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/autodetectproxy.h b/third_party/libjingle/source/talk/base/autodetectproxy.h
deleted file mode 100644
index 121737f..0000000
--- a/third_party/libjingle/source/talk/base/autodetectproxy.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_AUTODETECTPROXY_H_
-#define TALK_BASE_AUTODETECTPROXY_H_
-
-#include <string>
-
-#include "talk/base/constructormagic.h"
-#include "talk/base/cryptstring.h"
-#include "talk/base/proxyinfo.h"
-#include "talk/base/signalthread.h"
-
-namespace talk_base {
-
-///////////////////////////////////////////////////////////////////////////////
-// AutoDetectProxy
-///////////////////////////////////////////////////////////////////////////////
-
-class AsyncSocket;
-
-class AutoDetectProxy : public SignalThread {
- public:
-  explicit AutoDetectProxy(const std::string& user_agent);
-
-  const ProxyInfo& proxy() const { return proxy_; }
-
-  void set_server_url(const std::string& url) {
-    server_url_ = url;
-  }
-  void set_proxy(const SocketAddress& proxy) {
-    proxy_.type = PROXY_UNKNOWN;
-    proxy_.address = proxy;
-  }
-  void set_auth_info(bool use_auth, const std::string& username,
-                     const CryptString& password) {
-    if (use_auth) {
-      proxy_.username = username;
-      proxy_.password = password;
-    }
-  }
-
- protected:
-  virtual ~AutoDetectProxy();
-
-  // SignalThread Interface
-  virtual void DoWork();
-  virtual void OnMessage(Message *msg);
-
-  void Next();
-  void Complete(ProxyType type);
-
-  void OnConnectEvent(AsyncSocket * socket);
-  void OnReadEvent(AsyncSocket * socket);
-  void OnCloseEvent(AsyncSocket * socket, int error);
-
- private:
-  std::string agent_;
-  std::string server_url_;
-  ProxyInfo proxy_;
-  AsyncSocket* socket_;
-  int next_;
-
-  DISALLOW_IMPLICIT_CONSTRUCTORS(AutoDetectProxy);
-};
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_AUTODETECTPROXY_H_
diff --git a/third_party/libjingle/source/talk/base/autodetectproxy_unittest.cc b/third_party/libjingle/source/talk/base/autodetectproxy_unittest.cc
deleted file mode 100644
index bdf2786..0000000
--- a/third_party/libjingle/source/talk/base/autodetectproxy_unittest.cc
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/autodetectproxy.h"
-#include "talk/base/gunit.h"
-#include "talk/base/httpcommon.h"
-#include "talk/base/httpcommon-inl.h"
-
-namespace talk_base {
-
-static const char kUserAgent[] = "";
-static const char kPath[] = "/";
-static const char kHost[] = "relay.google.com";
-static const uint16 kPort = 443;
-static const bool kSecure = true;
-// Each of the two stages in AutoDetectProxy has a 2-second time-out, so 5
-// seconds total should be enough.
-static const int kTimeoutMs = 5000;
-
-class AutoDetectProxyTest : public testing::Test, public sigslot::has_slots<> {
- public:
-  AutoDetectProxyTest() : auto_detect_proxy_(NULL), done_(false) {}
-
- protected:
-  bool Create(const std::string &user_agent,
-              const std::string &path,
-              const std::string &host,
-              uint16 port,
-              bool secure) {
-    auto_detect_proxy_ = new AutoDetectProxy(user_agent);
-    EXPECT_TRUE(auto_detect_proxy_ != NULL);
-    if (!auto_detect_proxy_) {
-      return false;
-    }
-    Url<char> host_url(path, host, port);
-    host_url.set_secure(secure);
-    auto_detect_proxy_->set_server_url(host_url.url());
-    auto_detect_proxy_->SignalWorkDone.connect(
-        this,
-        &AutoDetectProxyTest::OnWorkDone);
-    auto_detect_proxy_->Start();
-    return true;
-  }
-
-  bool Run(int timeout_ms) {
-    EXPECT_TRUE_WAIT(done_, timeout_ms);
-    return done_;
-  }
-
- private:
-  void OnWorkDone(talk_base::SignalThread *thread) {
-    AutoDetectProxy *auto_detect_proxy =
-        static_cast<talk_base::AutoDetectProxy *>(thread);
-    EXPECT_TRUE(auto_detect_proxy == auto_detect_proxy_);
-    auto_detect_proxy_ = NULL;
-    auto_detect_proxy->Release();
-    done_ = true;
-  }
-
-  AutoDetectProxy *auto_detect_proxy_;
-  bool done_;
-};
-
-// Test that proxy detection completes successfully. (Does not actually verify
-// the correct detection result since we don't know what proxy to expect on an
-// arbitrary machine.)
-TEST_F(AutoDetectProxyTest, TestProxyDetection) {
-  ASSERT_TRUE(Create(kUserAgent,
-                     kPath,
-                     kHost,
-                     kPort,
-                     kSecure));
-  ASSERT_TRUE(Run(kTimeoutMs));
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/bandwidthsmoother.cc b/third_party/libjingle/source/talk/base/bandwidthsmoother.cc
deleted file mode 100644
index 130f2a8..0000000
--- a/third_party/libjingle/source/talk/base/bandwidthsmoother.cc
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * libjingle
- * Copyright 2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/bandwidthsmoother.h"
-
-#include <limits.h>
-
-namespace talk_base {
-
-BandwidthSmoother::BandwidthSmoother(int initial_bandwidth_guess,
-                                     uint32 time_between_increase,
-                                     double percent_increase,
-                                     size_t samples_count_to_average)
-    : time_between_increase_(time_between_increase),
-      percent_increase_(talk_base::_max(1.0, percent_increase)),
-      time_at_last_change_(0),
-      bandwidth_estimation_(initial_bandwidth_guess),
-      accumulator_(samples_count_to_average) {
-}
-
-// Samples a new bandwidth measurement
-// returns true if the bandwidth estimation changed
-bool BandwidthSmoother::Sample(uint32 sample_time, int bandwidth) {
-  if (bandwidth < 0) {
-    return false;
-  }
-
-  accumulator_.AddSample(bandwidth);
-
-  // Replace bandwidth with the mean of sampled bandwidths.
-  bandwidth = accumulator_.ComputeMean();
-
-  if (bandwidth < bandwidth_estimation_) {
-    time_at_last_change_ = sample_time;
-    bandwidth_estimation_ = bandwidth;
-    return true;
-  }
-
-  const int old_bandwidth_estimation = bandwidth_estimation_;
-  const double increase_threshold_d = percent_increase_ * bandwidth_estimation_;
-  if (increase_threshold_d > INT_MAX) {
-    // If bandwidth goes any higher we would overflow.
-    return false;
-  }
-
-  const int increase_threshold = static_cast<int>(increase_threshold_d);
-  if (bandwidth < increase_threshold) {
-    time_at_last_change_ = sample_time;
-    // The value of bandwidth_estimation remains the same if we don't exceed
-    // percent_increase_ * bandwidth_estimation_ for at least
-    // time_between_increase_ time.
-  } else if (sample_time >= time_at_last_change_ + time_between_increase_) {
-    time_at_last_change_ = sample_time;
-    if (increase_threshold == 0) {
-      bandwidth_estimation_ = bandwidth / 2;
-    } else {
-      bandwidth_estimation_ = increase_threshold;
-    }
-  }
-  // Else don't make a change.
-
-  return old_bandwidth_estimation != bandwidth_estimation_;
-}
-
-}  // namespace talk_base
-
diff --git a/third_party/libjingle/source/talk/base/bandwidthsmoother.h b/third_party/libjingle/source/talk/base/bandwidthsmoother.h
deleted file mode 100644
index afd1e52..0000000
--- a/third_party/libjingle/source/talk/base/bandwidthsmoother.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * libjingle
- * Copyright 2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_BANDWIDTHSMOOTHER_H_
-#define TALK_BASE_BANDWIDTHSMOOTHER_H_
-
-#include "talk/base/rollingaccumulator.h"
-#include "talk/base/timeutils.h"
-
-namespace talk_base {
-
-// The purpose of BandwidthSmoother is to smooth out bandwidth
-// estimations so that 'trstate' messages can be triggered when we
-// are "sure" there is sufficient bandwidth.  To avoid frequent fluctuations,
-// we take a slightly pessimistic view of our bandwidth.  We only increase
-// our estimation when we have sampled bandwidth measurements of values
-// at least as large as the current estimation * percent_increase
-// for at least time_between_increase time.  If a sampled bandwidth
-// is less than our current estimation we immediately decrease our estimation
-// to that sampled value.
-class BandwidthSmoother {
- public:
-  BandwidthSmoother(int initial_bandwidth_guess,
-                    uint32 time_between_increase,
-                    double percent_increase,
-                    size_t samples_count_to_average);
-
-  // Samples a new bandwidth measurement.
-  // bandwidth is expected to be non-negative.
-  // returns true if the bandwidth estimation changed
-  bool Sample(uint32 sample_time, int bandwidth);
-
-  int get_bandwidth_estimation() const {
-    return bandwidth_estimation_;
-  }
-
- private:
-  uint32 time_between_increase_;
-  double percent_increase_;
-  uint32 time_at_last_change_;
-  int bandwidth_estimation_;
-  RollingAccumulator<int> accumulator_;
-};
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_BANDWIDTHSMOOTHER_H_
diff --git a/third_party/libjingle/source/talk/base/bandwidthsmoother_unittest.cc b/third_party/libjingle/source/talk/base/bandwidthsmoother_unittest.cc
deleted file mode 100644
index 1eb79bd..0000000
--- a/third_party/libjingle/source/talk/base/bandwidthsmoother_unittest.cc
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * libjingle
- * Copyright 2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <limits.h>
-
-#include "talk/base/bandwidthsmoother.h"
-#include "talk/base/gunit.h"
-
-namespace talk_base {
-
-class BandwidthSmootherTest : public testing::Test {
- public:
-};
-
-static const int kTimeBetweenIncrease = 10;
-static const double kPercentIncrease = 1.1;
-static const size_t kSamplesCountToAverage = 1;
-
-TEST_F(BandwidthSmootherTest, TestSampleIncrease) {
-  BandwidthSmoother mon(1000,  // initial_bandwidth_guess
-                        kTimeBetweenIncrease,
-                        kPercentIncrease,
-                        kSamplesCountToAverage);
-
-  int bandwidth_sample = 1000;
-  EXPECT_EQ(bandwidth_sample, mon.get_bandwidth_estimation());
-  bandwidth_sample =
-      static_cast<int>(bandwidth_sample * kPercentIncrease);
-  EXPECT_FALSE(mon.Sample(9, bandwidth_sample));
-  EXPECT_TRUE(mon.Sample(10, bandwidth_sample));
-  EXPECT_EQ(bandwidth_sample, mon.get_bandwidth_estimation());
-  int next_expected_est =
-      static_cast<int>(bandwidth_sample * kPercentIncrease);
-  bandwidth_sample *= 2;
-  EXPECT_TRUE(mon.Sample(20, bandwidth_sample));
-  EXPECT_EQ(next_expected_est, mon.get_bandwidth_estimation());
-}
-
-TEST_F(BandwidthSmootherTest, TestSampleIncreaseFromZero) {
-  BandwidthSmoother mon(0,  // initial_bandwidth_guess
-                        kTimeBetweenIncrease,
-                        kPercentIncrease,
-                        kSamplesCountToAverage);
-
-  int bandwidth_sample = 1000;
-  EXPECT_FALSE(mon.Sample(9, bandwidth_sample));
-  EXPECT_TRUE(mon.Sample(10, bandwidth_sample));
-  EXPECT_EQ(bandwidth_sample/2, mon.get_bandwidth_estimation());
-}
-
-TEST_F(BandwidthSmootherTest, TestSampleDecrease) {
-  BandwidthSmoother mon(1000,  // initial_bandwidth_guess
-                        kTimeBetweenIncrease,
-                        kPercentIncrease,
-                        kSamplesCountToAverage);
-
-  int bandwidth_sample = 999;
-  EXPECT_TRUE(mon.Sample(1, bandwidth_sample));
-  EXPECT_EQ(bandwidth_sample, mon.get_bandwidth_estimation());
-}
-
-TEST_F(BandwidthSmootherTest, TestSampleRollover) {
-  const int initial_bandwidth_guess = 2000000000;  // > INT_MAX/1.1
-  BandwidthSmoother mon(initial_bandwidth_guess,
-                        kTimeBetweenIncrease,
-                        kPercentIncrease,
-                        kSamplesCountToAverage);
-
-  EXPECT_FALSE(mon.Sample(10, INT_MAX));
-  EXPECT_EQ(initial_bandwidth_guess, mon.get_bandwidth_estimation());
-}
-
-TEST_F(BandwidthSmootherTest, TestSampleNegative) {
-  BandwidthSmoother mon(1000,  // initial_bandwidth_guess
-                        kTimeBetweenIncrease,
-                        kPercentIncrease,
-                        kSamplesCountToAverage);
-
-  EXPECT_FALSE(mon.Sample(10, -1));
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/base64.cc b/third_party/libjingle/source/talk/base/base64.cc
deleted file mode 100644
index 0c9ee73..0000000
--- a/third_party/libjingle/source/talk/base/base64.cc
+++ /dev/null
@@ -1,243 +0,0 @@
-
-//*********************************************************************
-//* Base64 - a simple base64 encoder and decoder.
-//*
-//*     Copyright (c) 1999, Bob Withers - bwit@pobox.com
-//*
-//* This code may be freely used for any purpose, either personal
-//* or commercial, provided the authors copyright notice remains
-//* intact.
-//*
-//* Enhancements by Stanley Yamane:
-//*     o reverse lookup table for the decode function
-//*     o reserve string buffer space in advance
-//*
-//*********************************************************************
-
-#include "talk/base/base64.h"
-#include "talk/base/common.h"
-
-using std::string;
-using std::vector;
-
-namespace talk_base {
-
-static const char kPad = '=';
-static const unsigned char pd = 0xFD;  // Padding
-static const unsigned char sp = 0xFE;  // Whitespace
-static const unsigned char il = 0xFF;  // Illegal base64 character
-
-const char Base64::Base64Table[] =
-// 0000000000111111111122222222223333333333444444444455555555556666
-// 0123456789012345678901234567890123456789012345678901234567890123
-  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
-// Decode Table gives the index of any valid base64 character in the
-// Base64 table
-// 65 == A, 97 == a, 48 == 0, 43 == +, 47 == /
-
-const unsigned char Base64::DecodeTable[] = {
-// 0  1  2  3  4  5  6  7  8  9
-  il,il,il,il,il,il,il,il,il,sp,  //   0 -   9
-  sp,sp,sp,sp,il,il,il,il,il,il,  //  10 -  19
-  il,il,il,il,il,il,il,il,il,il,  //  20 -  29
-  il,il,sp,il,il,il,il,il,il,il,  //  30 -  39
-  il,il,il,62,il,il,il,63,52,53,  //  40 -  49
-  54,55,56,57,58,59,60,61,il,il,  //  50 -  59
-  il,pd,il,il,il, 0, 1, 2, 3, 4,  //  60 -  69
-   5, 6, 7, 8, 9,10,11,12,13,14,  //  70 -  79
-  15,16,17,18,19,20,21,22,23,24,  //  80 -  89
-  25,il,il,il,il,il,il,26,27,28,  //  90 -  99
-  29,30,31,32,33,34,35,36,37,38,  // 100 - 109
-  39,40,41,42,43,44,45,46,47,48,  // 110 - 119
-  49,50,51,il,il,il,il,il,il,il,  // 120 - 129
-  il,il,il,il,il,il,il,il,il,il,  // 130 - 139
-  il,il,il,il,il,il,il,il,il,il,  // 140 - 149
-  il,il,il,il,il,il,il,il,il,il,  // 150 - 159
-  il,il,il,il,il,il,il,il,il,il,  // 160 - 169
-  il,il,il,il,il,il,il,il,il,il,  // 170 - 179
-  il,il,il,il,il,il,il,il,il,il,  // 180 - 189
-  il,il,il,il,il,il,il,il,il,il,  // 190 - 199
-  il,il,il,il,il,il,il,il,il,il,  // 200 - 209
-  il,il,il,il,il,il,il,il,il,il,  // 210 - 219
-  il,il,il,il,il,il,il,il,il,il,  // 220 - 229
-  il,il,il,il,il,il,il,il,il,il,  // 230 - 239
-  il,il,il,il,il,il,il,il,il,il,  // 240 - 249
-  il,il,il,il,il,il               // 250 - 255
-};
-
-bool Base64::IsBase64Char(char ch) {
-  return (('A' <= ch) && (ch <= 'Z')) ||
-         (('a' <= ch) && (ch <= 'z')) ||
-         (('0' <= ch) && (ch <= '9')) ||
-         (ch == '+') || (ch == '/');
-}
-
-bool Base64::IsBase64Encoded(const std::string& str) {
-  for (size_t i = 0; i < str.size(); ++i) {
-    if (!IsBase64Char(str.at(i)))
-      return false;
-  }
-  return true;
-}
-
-void Base64::EncodeFromArray(const void* data, size_t len, string* result) {
-  ASSERT(NULL != result);
-  result->clear();
-  result->reserve(((len + 2) / 3) * 4);
-  const unsigned char* byte_data = static_cast<const unsigned char*>(data);
-
-  unsigned char c;
-  size_t i = 0;
-  while (i < len) {
-    c = (byte_data[i] >> 2) & 0x3f;
-    result->push_back(Base64Table[c]);
-
-    c = (byte_data[i] << 4) & 0x3f;
-    if (++i < len) {
-      c |= (byte_data[i] >> 4) & 0x0f;
-    }
-    result->push_back(Base64Table[c]);
-
-    if (i < len) {
-      c = (byte_data[i] << 2) & 0x3f;
-      if (++i < len) {
-        c |= (byte_data[i] >> 6) & 0x03;
-      }
-      result->push_back(Base64Table[c]);
-    } else {
-      result->push_back(kPad);
-    }
-
-    if (i < len) {
-      c = byte_data[i] & 0x3f;
-      result->push_back(Base64Table[c]);
-      ++i;
-    } else {
-      result->push_back(kPad);
-    }
-  }
-}
-
-size_t Base64::GetNextQuantum(DecodeFlags parse_flags, bool illegal_pads,
-                              const char* data, size_t len, size_t* dpos,
-                              unsigned char qbuf[4], bool* padded)
-{
-  size_t byte_len = 0, pad_len = 0, pad_start = 0;
-  for (; (byte_len < 4) && (*dpos < len); ++*dpos) {
-    qbuf[byte_len] = DecodeTable[static_cast<unsigned char>(data[*dpos])];
-    if ((il == qbuf[byte_len]) || (illegal_pads && (pd == qbuf[byte_len]))) {
-      if (parse_flags != DO_PARSE_ANY)
-        break;
-      // Ignore illegal characters
-    } else if (sp == qbuf[byte_len]) {
-      if (parse_flags == DO_PARSE_STRICT)
-        break;
-      // Ignore spaces
-    } else if (pd == qbuf[byte_len]) {
-      if (byte_len < 2) {
-        if (parse_flags != DO_PARSE_ANY)
-          break;
-        // Ignore unexpected padding
-      } else if (byte_len + pad_len >= 4) {
-        if (parse_flags != DO_PARSE_ANY)
-          break;
-        // Ignore extra pads
-      } else {
-        if (1 == ++pad_len) {
-          pad_start = *dpos;
-        }
-      }
-    } else {
-      if (pad_len > 0) {
-        if (parse_flags != DO_PARSE_ANY)
-          break;
-        // Ignore pads which are followed by data
-        pad_len = 0;
-      }
-      ++byte_len;
-    }
-  }
-  for (size_t i = byte_len; i < 4; ++i) {
-    qbuf[i] = 0;
-  }
-  if (4 == byte_len + pad_len) {
-    *padded = true;
-  } else {
-    *padded = false;
-    if (pad_len) {
-      // Roll back illegal padding
-      *dpos = pad_start;
-    }
-  }
-  return byte_len;
-}
-
-bool Base64::DecodeFromArray(const char* data, size_t len, DecodeFlags flags,
-                             string* result, size_t* data_used) {
-  return DecodeFromArrayTemplate<string>(data, len, flags, result, data_used);
-}
-
-bool Base64::DecodeFromArray(const char* data, size_t len, DecodeFlags flags,
-                             vector<char>* result, size_t* data_used) {
-  return DecodeFromArrayTemplate<vector<char> >(data, len, flags, result,
-                                                data_used);
-}
-
-template<typename T>
-bool Base64::DecodeFromArrayTemplate(const char* data, size_t len,
-                                     DecodeFlags flags, T* result,
-                                     size_t* data_used)
-{
-  ASSERT(NULL != result);
-  ASSERT(flags <= (DO_PARSE_MASK | DO_PAD_MASK | DO_TERM_MASK));
-
-  const DecodeFlags parse_flags = flags & DO_PARSE_MASK;
-  const DecodeFlags pad_flags   = flags & DO_PAD_MASK;
-  const DecodeFlags term_flags  = flags & DO_TERM_MASK;
-  ASSERT(0 != parse_flags);
-  ASSERT(0 != pad_flags);
-  ASSERT(0 != term_flags);
-
-  result->clear();
-  result->reserve(len);
-
-  size_t dpos = 0;
-  bool success = true, padded;
-  unsigned char c, qbuf[4];
-  while (dpos < len) {
-    size_t qlen = GetNextQuantum(parse_flags, (DO_PAD_NO == pad_flags),
-                                 data, len, &dpos, qbuf, &padded);
-    c = (qbuf[0] << 2) | ((qbuf[1] >> 4) & 0x3);
-    if (qlen >= 2) {
-      result->push_back(c);
-      c = ((qbuf[1] << 4) & 0xf0) | ((qbuf[2] >> 2) & 0xf);
-      if (qlen >= 3) {
-        result->push_back(c);
-        c = ((qbuf[2] << 6) & 0xc0) | qbuf[3];
-        if (qlen >= 4) {
-          result->push_back(c);
-          c = 0;
-        }
-      }
-    }
-    if (qlen < 4) {
-      if ((DO_TERM_ANY != term_flags) && (0 != c)) {
-        success = false;  // unused bits
-      }
-      if ((DO_PAD_YES == pad_flags) && !padded) {
-        success = false;  // expected padding
-      }
-      break;
-    }
-  }
-  if ((DO_TERM_BUFFER == term_flags) && (dpos != len)) {
-    success = false;  // unused chars
-  }
-  if (data_used) {
-    *data_used = dpos;
-  }
-  return success;
-}
-
-} // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/base64.h b/third_party/libjingle/source/talk/base/base64.h
deleted file mode 100644
index 2e37bc3..0000000
--- a/third_party/libjingle/source/talk/base/base64.h
+++ /dev/null
@@ -1,96 +0,0 @@
-
-//*********************************************************************
-//* C_Base64 - a simple base64 encoder and decoder.
-//*
-//*     Copyright (c) 1999, Bob Withers - bwit@pobox.com
-//*
-//* This code may be freely used for any purpose, either personal
-//* or commercial, provided the authors copyright notice remains
-//* intact.
-//*********************************************************************
-
-#ifndef TALK_BASE_BASE64_H__
-#define TALK_BASE_BASE64_H__
-
-#include <string>
-#include <vector>
-
-namespace talk_base {
-
-class Base64
-{
-public:
-  enum DecodeOption {
-    DO_PARSE_STRICT =  1,  // Parse only base64 characters
-    DO_PARSE_WHITE  =  2,  // Parse only base64 and whitespace characters
-    DO_PARSE_ANY    =  3,  // Parse all characters
-    DO_PARSE_MASK   =  3,
-
-    DO_PAD_YES      =  4,  // Padding is required
-    DO_PAD_ANY      =  8,  // Padding is optional
-    DO_PAD_NO       = 12,  // Padding is disallowed
-    DO_PAD_MASK     = 12,
-
-    DO_TERM_BUFFER  = 16,  // Must termiante at end of buffer
-    DO_TERM_CHAR    = 32,  // May terminate at any character boundary
-    DO_TERM_ANY     = 48,  // May terminate at a sub-character bit offset
-    DO_TERM_MASK    = 48,
-
-    // Strictest interpretation
-    DO_STRICT = DO_PARSE_STRICT | DO_PAD_YES | DO_TERM_BUFFER,
-
-    DO_LAX    = DO_PARSE_ANY | DO_PAD_ANY | DO_TERM_CHAR,
-  };
-  typedef int DecodeFlags;
-
-  static bool IsBase64Char(char ch);
-
-  // Determines whether the given string consists entirely of valid base64
-  // encoded characters.
-  static bool IsBase64Encoded(const std::string& str);
-
-  static void EncodeFromArray(const void* data, size_t len,
-                              std::string* result);
-  static bool DecodeFromArray(const char* data, size_t len, DecodeFlags flags,
-                              std::string* result, size_t* data_used);
-  static bool DecodeFromArray(const char* data, size_t len, DecodeFlags flags,
-                              std::vector<char>* result, size_t* data_used);
-
-  // Convenience Methods
-  static inline std::string Encode(const std::string& data) {
-    std::string result;
-    EncodeFromArray(data.data(), data.size(), &result);
-    return result;
-  }
-  static inline std::string Decode(const std::string& data, DecodeFlags flags) {
-    std::string result;
-    DecodeFromArray(data.data(), data.size(), flags, &result, NULL);
-    return result;
-  }
-  static inline bool Decode(const std::string& data, DecodeFlags flags,
-                            std::string* result, size_t* data_used)
-  {
-    return DecodeFromArray(data.data(), data.size(), flags, result, data_used);
-  }
-  static inline bool Decode(const std::string& data, DecodeFlags flags,
-                            std::vector<char>* result, size_t* data_used)
-  {
-    return DecodeFromArray(data.data(), data.size(), flags, result, data_used);
-  }
-
-private:
-  static const char Base64Table[];
-  static const unsigned char DecodeTable[];
-
-  static size_t GetNextQuantum(DecodeFlags parse_flags, bool illegal_pads,
-                               const char* data, size_t len, size_t* dpos,
-                               unsigned char qbuf[4], bool* padded);
-  template<typename T>
-  static bool DecodeFromArrayTemplate(const char* data, size_t len,
-                                      DecodeFlags flags, T* result,
-                                      size_t* data_used);
-};
-
-} // namespace talk_base
-
-#endif // TALK_BASE_BASE64_H__
diff --git a/third_party/libjingle/source/talk/base/basicdefs.h b/third_party/libjingle/source/talk/base/basicdefs.h
deleted file mode 100644
index 1f79228..0000000
--- a/third_party/libjingle/source/talk/base/basicdefs.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_BASICDEFS_H__
-#define TALK_BASE_BASICDEFS_H__
-
-#if HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#define ARRAY_SIZE(x) (static_cast<int>((sizeof(x)/sizeof(x[0]))))
-
-#endif // TAKL_BASE_BASICDEFS_H__
diff --git a/third_party/libjingle/source/talk/base/basicpacketsocketfactory.cc b/third_party/libjingle/source/talk/base/basicpacketsocketfactory.cc
deleted file mode 100644
index d1da08e..0000000
--- a/third_party/libjingle/source/talk/base/basicpacketsocketfactory.cc
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * libjingle
- * Copyright 2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/basicpacketsocketfactory.h"
-
-#include "talk/base/asyncudpsocket.h"
-#include "talk/base/asynctcpsocket.h"
-#include "talk/base/logging.h"
-#include "talk/base/socketadapters.h"
-#include "talk/base/thread.h"
-
-namespace talk_base {
-
-BasicPacketSocketFactory::BasicPacketSocketFactory()
-    : thread_(Thread::Current()),
-      socket_factory_(NULL) {
-}
-
-BasicPacketSocketFactory::BasicPacketSocketFactory(Thread* thread)
-    : thread_(thread),
-      socket_factory_(NULL) {
-}
-
-BasicPacketSocketFactory::BasicPacketSocketFactory(
-    SocketFactory* socket_factory)
-    : thread_(NULL),
-      socket_factory_(socket_factory) {
-}
-
-BasicPacketSocketFactory::~BasicPacketSocketFactory() {
-}
-
-AsyncPacketSocket* BasicPacketSocketFactory::CreateUdpSocket(
-    const SocketAddress& address, int min_port, int max_port) {
-  // UDP sockets are simple.
-  talk_base::AsyncSocket* socket =
-      socket_factory()->CreateAsyncSocket(SOCK_DGRAM);
-  if (!socket) {
-    return NULL;
-  }
-  if (BindSocket(socket, address, min_port, max_port) < 0) {
-    LOG(LS_ERROR) << "UDP bind failed with error "
-                    << socket->GetError();
-    delete socket;
-    return NULL;
-  }
-  return new talk_base::AsyncUDPSocket(socket);
-}
-
-AsyncPacketSocket* BasicPacketSocketFactory::CreateServerTcpSocket(
-    const SocketAddress& local_address, int min_port, int max_port, bool ssl) {
-  talk_base::AsyncSocket* socket =
-      socket_factory()->CreateAsyncSocket(SOCK_STREAM);
-  if (!socket) {
-    return NULL;
-  }
-
-  if (BindSocket(socket, local_address, min_port, max_port) < 0) {
-    LOG(LS_ERROR) << "TCP bind failed with error "
-                  << socket->GetError();
-    delete socket;
-    return NULL;
-  }
-
-  // If using SSLTCP, wrap the TCP socket in a pseudo-SSL socket.
-  if (ssl) {
-    socket = new talk_base::AsyncSSLSocket(socket);
-  }
-
-  // Set TCP_NODELAY (via OPT_NODELAY) for improved performance.
-  // See http://go/gtalktcpnodelayexperiment
-  socket->SetOption(talk_base::Socket::OPT_NODELAY, 1);
-
-  return new talk_base::AsyncTCPSocket(socket, true);
-}
-
-AsyncPacketSocket* BasicPacketSocketFactory::CreateClientTcpSocket(
-    const SocketAddress& local_address, const SocketAddress& remote_address,
-    const ProxyInfo& proxy_info, const std::string& user_agent, bool ssl) {
-  talk_base::AsyncSocket* socket =
-      socket_factory()->CreateAsyncSocket(SOCK_STREAM);
-  if (!socket) {
-    return NULL;
-  }
-
-  if (BindSocket(socket, local_address, 0, 0) < 0) {
-    LOG(LS_ERROR) << "TCP bind failed with error "
-                  << socket->GetError();
-    delete socket;
-    return NULL;
-  }
-
-  // If using a proxy, wrap the socket in a proxy socket.
-  if (proxy_info.type == talk_base::PROXY_SOCKS5) {
-    socket = new talk_base::AsyncSocksProxySocket(
-        socket, proxy_info.address, proxy_info.username, proxy_info.password);
-  } else if (proxy_info.type == talk_base::PROXY_HTTPS) {
-    socket = new talk_base::AsyncHttpsProxySocket(
-        socket, user_agent, proxy_info.address,
-        proxy_info.username, proxy_info.password);
-  }
-
-  // If using SSLTCP, wrap the TCP socket in a pseudo-SSL socket.
-  if (ssl) {
-    socket = new talk_base::AsyncSSLSocket(socket);
-  }
-
-  if (socket->Connect(remote_address) < 0) {
-    LOG(LS_ERROR) << "TCP connect failed with error "
-                  << socket->GetError();
-    delete socket;
-    return NULL;
-  }
-
-  // Finally, wrap that socket in a TCP packet socket.
-  talk_base::AsyncTCPSocket* tcp_socket =
-      new talk_base::AsyncTCPSocket(socket, false);
-
-  // Set TCP_NODELAY (via OPT_NODELAY) for improved performance.
-  // See http://go/gtalktcpnodelayexperiment
-  tcp_socket->SetOption(talk_base::Socket::OPT_NODELAY, 1);
-
-  return tcp_socket;
-}
-
-int BasicPacketSocketFactory::BindSocket(
-    AsyncSocket* socket, const SocketAddress& local_address,
-    int min_port, int max_port) {
-  int ret = -1;
-  if (min_port == 0 && max_port == 0) {
-    // If there's no port range, let the OS pick a port for us.
-    ret = socket->Bind(local_address);
-  } else {
-    // Otherwise, try to find a port in the provided range.
-    for (int port = min_port; ret < 0 && port <= max_port; ++port) {
-      ret = socket->Bind(talk_base::SocketAddress(local_address.ipaddr(),
-                                                  port));
-    }
-  }
-  return ret;
-}
-
-SocketFactory* BasicPacketSocketFactory::socket_factory() {
-  if (thread_) {
-    ASSERT(thread_ == Thread::Current());
-    return thread_->socketserver();
-  } else {
-    return socket_factory_;
-  }
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/basicpacketsocketfactory.h b/third_party/libjingle/source/talk/base/basicpacketsocketfactory.h
deleted file mode 100644
index bf66bc8..0000000
--- a/third_party/libjingle/source/talk/base/basicpacketsocketfactory.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * libjingle
- * Copyright 2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_BASICPACKETSOCKETFACTORY_H_
-#define TALK_BASE_BASICPACKETSOCKETFACTORY_H_
-
-#include "talk/base/packetsocketfactory.h"
-
-namespace talk_base {
-
-class AsyncSocket;
-class SocketFactory;
-class Thread;
-
-class BasicPacketSocketFactory : public PacketSocketFactory {
- public:
-  BasicPacketSocketFactory();
-  explicit BasicPacketSocketFactory(Thread* thread);
-  explicit BasicPacketSocketFactory(SocketFactory* socket_factory);
-  virtual ~BasicPacketSocketFactory();
-
-  virtual AsyncPacketSocket* CreateUdpSocket(
-      const SocketAddress& local_address, int min_port, int max_port);
-  virtual AsyncPacketSocket* CreateServerTcpSocket(
-      const SocketAddress& local_address, int min_port, int max_port, bool ssl);
-  virtual AsyncPacketSocket* CreateClientTcpSocket(
-      const SocketAddress& local_address, const SocketAddress& remote_address,
-      const ProxyInfo& proxy_info, const std::string& user_agent, bool ssl);
-
- private:
-  int BindSocket(AsyncSocket* socket, const SocketAddress& local_address,
-                 int min_port, int max_port);
-
-  SocketFactory* socket_factory();
-
-  Thread* thread_;
-  SocketFactory* socket_factory_;
-};
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_BASICPACKETSOCKETFACTORY_H_
diff --git a/third_party/libjingle/source/talk/base/basictypes.h b/third_party/libjingle/source/talk/base/basictypes.h
deleted file mode 100644
index f16ccf2..0000000
--- a/third_party/libjingle/source/talk/base/basictypes.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * libjingle
- * Copyright 2004 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_BASICTYPES_H__
-#define TALK_BASE_BASICTYPES_H__
-
-#include <stddef.h>  // for NULL, size_t
-
-#if !(defined(_MSC_VER) && (_MSC_VER < 1600))
-#include <stdint.h>  // for uintptr_t
-#endif
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "talk/base/constructormagic.h"
-
-#if !defined(INT_TYPES_DEFINED)
-#define INT_TYPES_DEFINED
-#ifdef COMPILER_MSVC
-typedef unsigned __int64 uint64;
-typedef __int64 int64;
-#ifndef INT64_C
-#define INT64_C(x) x ## I64
-#endif
-#ifndef UINT64_C
-#define UINT64_C(x) x ## UI64
-#endif
-#define INT64_F "I64"
-#else  // COMPILER_MSVC
-// On Mac OS X, cssmconfig.h defines uint64 as uint64_t
-#if defined(OSX)
-typedef uint64_t uint64;
-typedef int64_t int64;
-#ifndef INT64_C
-#define INT64_C(x) x ## L
-#endif
-#ifndef UINT64_C
-#define UINT64_C(x) x ## UL
-#endif
-#define INT64_F "l"
-#elif defined(__LP64__)
-typedef unsigned long uint64;
-typedef long int64;
-#ifndef INT64_C
-#define INT64_C(x) x ## L
-#endif
-#ifndef UINT64_C
-#define UINT64_C(x) x ## UL
-#endif
-#define INT64_F "l"
-#else  // __LP64__
-typedef unsigned long long uint64;
-typedef long long int64;
-#ifndef INT64_C
-#define INT64_C(x) x ## LL
-#endif
-#ifndef UINT64_C
-#define UINT64_C(x) x ## ULL
-#endif
-#define INT64_F "ll"
-#endif  // __LP64__
-#endif  // COMPILER_MSVC
-typedef unsigned int uint32;
-typedef int int32;
-typedef unsigned short uint16;
-typedef short int16;
-typedef unsigned char uint8;
-typedef signed char int8;
-#endif  // INT_TYPES_DEFINED
-
-#ifdef WIN32
-typedef int socklen_t;
-#endif
-
-namespace talk_base {
-  template<class T> inline T _min(T a, T b) { return (a > b) ? b : a; }
-  template<class T> inline T _max(T a, T b) { return (a < b) ? b : a; }
-
-  // For wait functions that take a number of milliseconds, kForever indicates
-  // unlimited time.
-  const int kForever = -1;
-}
-
-// Detect compiler is for x86 or x64.
-#if defined(__x86_64__) || defined(_M_X64) || \
-    defined(__i386__) || defined(_M_IX86)
-#define CPU_X86 1
-#endif
-
-#define ALIGNP(p, t) \
-  (reinterpret_cast<uint8*>(((reinterpret_cast<uintptr_t>(p) + \
-  ((t)-1)) & ~((t)-1))))
-#define IS_ALIGNED(p, a) (!((uintptr_t)(p) & ((a) - 1)))
-
-#ifndef UNUSED
-#define UNUSED(x) Unused(static_cast<const void *>(&x))
-#define UNUSED2(x,y) Unused(static_cast<const void *>(&x)); Unused(static_cast<const void *>(&y))
-#define UNUSED3(x,y,z) Unused(static_cast<const void *>(&x)); Unused(static_cast<const void *>(&y)); Unused(static_cast<const void *>(&z))
-#define UNUSED4(x,y,z,a) Unused(static_cast<const void *>(&x)); Unused(static_cast<const void *>(&y)); Unused(static_cast<const void *>(&z)); Unused(static_cast<const void *>(&a))
-#define UNUSED5(x,y,z,a,b) Unused(static_cast<const void *>(&x)); Unused(static_cast<const void *>(&y)); Unused(static_cast<const void *>(&z)); Unused(static_cast<const void *>(&a)); Unused(static_cast<const void *>(&b))
-inline void Unused(const void *) { }
-#endif // UNUSED
-
-#if defined(__GNUC__)
-#define GCC_ATTR(x) __attribute__ ((x))
-#else  // !__GNUC__
-#define GCC_ATTR(x)
-#endif  // !__GNUC__
-
-#endif // TALK_BASE_BASICTYPES_H__
diff --git a/third_party/libjingle/source/talk/base/buffer.h b/third_party/libjingle/source/talk/base/buffer.h
deleted file mode 100644
index 311cfad..0000000
--- a/third_party/libjingle/source/talk/base/buffer.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * libjingle
- * Copyright 2004-2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_BUFFER_H_
-#define TALK_BASE_BUFFER_H_
-
-#include <cstring>
-
-#include "talk/base/scoped_ptr.h"
-
-namespace talk_base {
-
-// Basic buffer class, can be grown and shrunk dynamically.
-// Unlike std::string/vector, does not initialize data when expanding capacity.
-class Buffer {
- public:
-  Buffer() {
-    Construct(NULL, 0, 0);
-  }
-  Buffer(const void* data, size_t length) {
-    Construct(data, length, length);
-  }
-  Buffer(const void* data, size_t length, size_t capacity) {
-    Construct(data, length, capacity);
-  }
-  Buffer(const Buffer& buf) {
-    Construct(buf.data(), buf.length(), buf.length());
-  }
-
-  const char* data() const { return data_.get(); }
-  char* data() { return data_.get(); }
-  // TODO: should this be size(), like STL?
-  size_t length() const { return length_; }
-  size_t capacity() const { return capacity_; }
-
-  Buffer& operator=(const Buffer& buf) {
-    if (&buf != this) {
-      Construct(buf.data(), buf.length(), buf.length());
-    }
-    return *this;
-  }
-  bool operator==(const Buffer& buf) const {
-    return (length_ == buf.length() &&
-            memcmp(data_.get(), buf.data(), length_) == 0);
-  }
-  bool operator!=(const Buffer& buf) const {
-    return !operator==(buf);
-  }
-
-  void SetData(const void* data, size_t length) {
-    ASSERT(data != NULL || length == 0);
-    SetLength(length);
-    memcpy(data_.get(), data, length);
-  }
-  void AppendData(const void* data, size_t length) {
-    ASSERT(data != NULL || length == 0);
-    size_t old_length = length_;
-    SetLength(length_ + length);
-    memcpy(data_.get() + old_length, data, length);
-  }
-  void SetLength(size_t length) {
-    SetCapacity(length);
-    length_ = length;
-  }
-  void SetCapacity(size_t capacity) {
-    if (capacity > capacity_) {
-      talk_base::scoped_array<char> data(new char[capacity]);
-      memcpy(data.get(), data_.get(), length_);
-      data_.swap(data);
-      capacity_ = capacity;
-    }
-  }
-
-  void TransferTo(Buffer* buf) {
-    ASSERT(buf != NULL);
-    buf->data_.reset(data_.release());
-    buf->length_ = length_;
-    buf->capacity_ = capacity_;
-    Construct(NULL, 0, 0);
-  }
-
- protected:
-  void Construct(const void* data, size_t length, size_t capacity) {
-    data_.reset(new char[capacity_ = capacity]);
-    SetData(data, length);
-  }
-
-  scoped_array<char> data_;
-  size_t length_;
-  size_t capacity_;
-};
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_BUFFER_H_
diff --git a/third_party/libjingle/source/talk/base/buffer_unittest.cc b/third_party/libjingle/source/talk/base/buffer_unittest.cc
deleted file mode 100644
index b0aa243..0000000
--- a/third_party/libjingle/source/talk/base/buffer_unittest.cc
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/buffer.h"
-#include "talk/base/gunit.h"
-
-namespace talk_base {
-
-static const char kTestData[] = {
-  0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF
-};
-
-TEST(BufferTest, TestConstructDefault) {
-  Buffer buf;
-  EXPECT_EQ(0U, buf.length());
-  EXPECT_EQ(0U, buf.capacity());
-  EXPECT_EQ(Buffer(), buf);
-}
-
-TEST(BufferTest, TestConstructEmptyWithCapacity) {
-  Buffer buf(NULL, 0, 256U);
-  EXPECT_EQ(0U, buf.length());
-  EXPECT_EQ(256U, buf.capacity());
-  EXPECT_EQ(Buffer(), buf);
-}
-
-TEST(BufferTest, TestConstructData) {
-  Buffer buf(kTestData, sizeof(kTestData));
-  EXPECT_EQ(sizeof(kTestData), buf.length());
-  EXPECT_EQ(sizeof(kTestData), buf.capacity());
-  EXPECT_EQ(0, memcmp(buf.data(), kTestData, sizeof(kTestData)));
-  EXPECT_EQ(Buffer(kTestData, sizeof(kTestData)), buf);
-}
-
-TEST(BufferTest, TestConstructDataWithCapacity) {
-  Buffer buf(kTestData, sizeof(kTestData), 256U);
-  EXPECT_EQ(sizeof(kTestData), buf.length());
-  EXPECT_EQ(256U, buf.capacity());
-  EXPECT_EQ(0, memcmp(buf.data(), kTestData, sizeof(kTestData)));
-  EXPECT_EQ(Buffer(kTestData, sizeof(kTestData)), buf);
-}
-
-TEST(BufferTest, TestConstructCopy) {
-  Buffer buf1(kTestData, sizeof(kTestData), 256), buf2(buf1);
-  EXPECT_EQ(sizeof(kTestData), buf2.length());
-  EXPECT_EQ(sizeof(kTestData), buf2.capacity());  // capacity isn't copied
-  EXPECT_EQ(0, memcmp(buf2.data(), kTestData, sizeof(kTestData)));
-  EXPECT_EQ(buf1, buf2);
-}
-
-TEST(BufferTest, TestAssign) {
-  Buffer buf1, buf2(kTestData, sizeof(kTestData), 256);
-  EXPECT_NE(buf1, buf2);
-  buf1 = buf2;
-  EXPECT_EQ(sizeof(kTestData), buf1.length());
-  EXPECT_EQ(sizeof(kTestData), buf1.capacity());  // capacity isn't copied
-  EXPECT_EQ(0, memcmp(buf1.data(), kTestData, sizeof(kTestData)));
-  EXPECT_EQ(buf1, buf2);
-}
-
-TEST(BufferTest, TestSetData) {
-  Buffer buf;
-  buf.SetData(kTestData, sizeof(kTestData));
-  EXPECT_EQ(sizeof(kTestData), buf.length());
-  EXPECT_EQ(sizeof(kTestData), buf.capacity());
-  EXPECT_EQ(0, memcmp(buf.data(), kTestData, sizeof(kTestData)));
-}
-
-TEST(BufferTest, TestAppendData) {
-  Buffer buf(kTestData, sizeof(kTestData));
-  buf.AppendData(kTestData, sizeof(kTestData));
-  EXPECT_EQ(2 * sizeof(kTestData), buf.length());
-  EXPECT_EQ(2 * sizeof(kTestData), buf.capacity());
-  EXPECT_EQ(0, memcmp(buf.data(), kTestData, sizeof(kTestData)));
-  EXPECT_EQ(0, memcmp(buf.data() + sizeof(kTestData),
-                      kTestData, sizeof(kTestData)));
-}
-
-TEST(BufferTest, TestSetLengthSmaller) {
-  Buffer buf;
-  buf.SetData(kTestData, sizeof(kTestData));
-  buf.SetLength(sizeof(kTestData) / 2);
-  EXPECT_EQ(sizeof(kTestData) / 2, buf.length());
-  EXPECT_EQ(sizeof(kTestData), buf.capacity());
-  EXPECT_EQ(0, memcmp(buf.data(), kTestData, sizeof(kTestData) / 2));
-}
-
-TEST(BufferTest, TestSetLengthLarger) {
-  Buffer buf;
-  buf.SetData(kTestData, sizeof(kTestData));
-  buf.SetLength(sizeof(kTestData) * 2);
-  EXPECT_EQ(sizeof(kTestData) * 2, buf.length());
-  EXPECT_EQ(sizeof(kTestData) * 2, buf.capacity());
-  EXPECT_EQ(0, memcmp(buf.data(), kTestData, sizeof(kTestData)));
-}
-
-TEST(BufferTest, TestSetCapacitySmaller) {
-  Buffer buf;
-  buf.SetData(kTestData, sizeof(kTestData));
-  buf.SetCapacity(sizeof(kTestData) / 2);  // should be ignored
-  EXPECT_EQ(sizeof(kTestData), buf.length());
-  EXPECT_EQ(sizeof(kTestData), buf.capacity());
-  EXPECT_EQ(0, memcmp(buf.data(), kTestData, sizeof(kTestData)));
-}
-
-TEST(BufferTest, TestSetCapacityLarger) {
-  Buffer buf(kTestData, sizeof(kTestData));
-  buf.SetCapacity(sizeof(kTestData) * 2);
-  EXPECT_EQ(sizeof(kTestData), buf.length());
-  EXPECT_EQ(sizeof(kTestData) * 2, buf.capacity());
-  EXPECT_EQ(0, memcmp(buf.data(), kTestData, sizeof(kTestData)));
-}
-
-TEST(BufferTest, TestSetCapacityThenSetLength) {
-  Buffer buf(kTestData, sizeof(kTestData));
-  buf.SetCapacity(sizeof(kTestData) * 4);
-  memcpy(buf.data() + sizeof(kTestData), kTestData, sizeof(kTestData));
-  buf.SetLength(sizeof(kTestData) * 2);
-  EXPECT_EQ(sizeof(kTestData) * 2, buf.length());
-  EXPECT_EQ(sizeof(kTestData) * 4, buf.capacity());
-  EXPECT_EQ(0, memcmp(buf.data(), kTestData, sizeof(kTestData)));
-  EXPECT_EQ(0, memcmp(buf.data() + sizeof(kTestData),
-                      kTestData, sizeof(kTestData)));
-}
-
-TEST(BufferTest, TestTransfer) {
-  Buffer buf1(kTestData, sizeof(kTestData), 256U), buf2;
-  buf1.TransferTo(&buf2);
-  EXPECT_EQ(0U, buf1.length());
-  EXPECT_EQ(0U, buf1.capacity());
-  EXPECT_EQ(sizeof(kTestData), buf2.length());
-  EXPECT_EQ(256U, buf2.capacity());  // capacity does transfer
-  EXPECT_EQ(0, memcmp(buf2.data(), kTestData, sizeof(kTestData)));
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/bytebuffer.cc b/third_party/libjingle/source/talk/base/bytebuffer.cc
deleted file mode 100644
index 12c8bc0..0000000
--- a/third_party/libjingle/source/talk/base/bytebuffer.cc
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/bytebuffer.h"
-
-#include <algorithm>
-#include <cassert>
-#include <cstring>
-
-#include "talk/base/basictypes.h"
-#include "talk/base/byteorder.h"
-
-namespace talk_base {
-
-static const int DEFAULT_SIZE = 4096;
-
-ByteBuffer::ByteBuffer() {
-  Construct(NULL, DEFAULT_SIZE, ORDER_NETWORK);
-}
-
-ByteBuffer::ByteBuffer(ByteOrder byte_order) {
-  Construct(NULL, DEFAULT_SIZE, byte_order);
-}
-
-ByteBuffer::ByteBuffer(const char* bytes, size_t len) {
-  Construct(bytes, len, ORDER_NETWORK);
-}
-
-ByteBuffer::ByteBuffer(const char* bytes, size_t len, ByteOrder byte_order) {
-  Construct(bytes, len, byte_order);
-}
-
-ByteBuffer::ByteBuffer(const char* bytes) {
-  Construct(bytes, strlen(bytes), ORDER_NETWORK);
-}
-
-void ByteBuffer::Construct(const char* bytes, size_t len,
-                           ByteOrder byte_order) {
-  start_      = 0;
-  size_       = len;
-  byte_order_ = byte_order;
-  bytes_      = new char[size_];
-
-  if (bytes) {
-    end_ = len;
-    memcpy(bytes_, bytes, end_);
-  } else {
-    end_ = 0;
-  }
-}
-
-ByteBuffer::~ByteBuffer() {
-  delete[] bytes_;
-}
-
-bool ByteBuffer::ReadUInt8(uint8* val) {
-  if (!val) return false;
-
-  return ReadBytes(reinterpret_cast<char*>(val), 1);
-}
-
-bool ByteBuffer::ReadUInt16(uint16* val) {
-  if (!val) return false;
-
-  uint16 v;
-  if (!ReadBytes(reinterpret_cast<char*>(&v), 2)) {
-    return false;
-  } else {
-    *val = (byte_order_ == ORDER_NETWORK) ? NetworkToHost16(v) : v;
-    return true;
-  }
-}
-
-bool ByteBuffer::ReadUInt24(uint32* val) {
-  if (!val) return false;
-
-  uint32 v = 0;
-  char* read_into = reinterpret_cast<char*>(&v);
-  if (byte_order_ == ORDER_NETWORK || IsHostBigEndian()) {
-    ++read_into;
-  }
-
-  if (!ReadBytes(read_into, 3)) {
-    return false;
-  } else {
-    *val = (byte_order_ == ORDER_NETWORK) ? NetworkToHost32(v) : v;
-    return true;
-  }
-}
-
-bool ByteBuffer::ReadUInt32(uint32* val) {
-  if (!val) return false;
-
-  uint32 v;
-  if (!ReadBytes(reinterpret_cast<char*>(&v), 4)) {
-    return false;
-  } else {
-    *val = (byte_order_ == ORDER_NETWORK) ? NetworkToHost32(v) : v;
-    return true;
-  }
-}
-
-bool ByteBuffer::ReadUInt64(uint64* val) {
-  if (!val) return false;
-
-  uint64 v;
-  if (!ReadBytes(reinterpret_cast<char*>(&v), 8)) {
-    return false;
-  } else {
-    *val = (byte_order_ == ORDER_NETWORK) ? NetworkToHost64(v) : v;
-    return true;
-  }
-}
-
-bool ByteBuffer::ReadString(std::string* val, size_t len) {
-  if (!val) return false;
-
-  if (len > Length()) {
-    return false;
-  } else {
-    val->append(bytes_ + start_, len);
-    start_ += len;
-    return true;
-  }
-}
-
-bool ByteBuffer::ReadBytes(char* val, size_t len) {
-  if (len > Length()) {
-    return false;
-  } else {
-    memcpy(val, bytes_ + start_, len);
-    start_ += len;
-    return true;
-  }
-}
-
-void ByteBuffer::WriteUInt8(uint8 val) {
-  WriteBytes(reinterpret_cast<const char*>(&val), 1);
-}
-
-void ByteBuffer::WriteUInt16(uint16 val) {
-  uint16 v = (byte_order_ == ORDER_NETWORK) ? HostToNetwork16(val) : val;
-  WriteBytes(reinterpret_cast<const char*>(&v), 2);
-}
-
-void ByteBuffer::WriteUInt24(uint32 val) {
-  uint32 v = (byte_order_ == ORDER_NETWORK) ? HostToNetwork32(val) : val;
-  char* start = reinterpret_cast<char*>(&v);
-  if (byte_order_ == ORDER_NETWORK || IsHostBigEndian()) {
-    ++start;
-  }
-  WriteBytes(start, 3);
-}
-
-void ByteBuffer::WriteUInt32(uint32 val) {
-  uint32 v = (byte_order_ == ORDER_NETWORK) ? HostToNetwork32(val) : val;
-  WriteBytes(reinterpret_cast<const char*>(&v), 4);
-}
-
-void ByteBuffer::WriteUInt64(uint64 val) {
-  uint64 v = (byte_order_ == ORDER_NETWORK) ? HostToNetwork64(val) : val;
-  WriteBytes(reinterpret_cast<const char*>(&v), 8);
-}
-
-void ByteBuffer::WriteString(const std::string& val) {
-  WriteBytes(val.c_str(), val.size());
-}
-
-void ByteBuffer::WriteBytes(const char* val, size_t len) {
-  if (Length() + len > Capacity())
-    Resize(Length() + len);
-
-  memcpy(bytes_ + end_, val, len);
-  end_ += len;
-}
-
-void ByteBuffer::Resize(size_t size) {
-  if (size > size_)
-    size = _max(size, 3 * size_ / 2);
-
-  size_t len = _min(end_ - start_, size);
-  char* new_bytes = new char[size];
-  memcpy(new_bytes, bytes_ + start_, len);
-  delete [] bytes_;
-
-  start_ = 0;
-  end_   = len;
-  size_  = size;
-  bytes_ = new_bytes;
-}
-
-bool ByteBuffer::Consume(size_t size) {
-  if (size > Length())
-    return false;
-
-  start_ += size;
-  return true;
-}
-
-bool ByteBuffer::Shift(size_t size) {
-  if (size > Length())
-    return false;
-
-  end_ = Length() - size;
-  memmove(bytes_, bytes_ + start_ + size, end_);
-  start_ = 0;
-  return true;
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/bytebuffer.h b/third_party/libjingle/source/talk/base/bytebuffer.h
deleted file mode 100644
index 1a494cb..0000000
--- a/third_party/libjingle/source/talk/base/bytebuffer.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_BYTEBUFFER_H_
-#define TALK_BASE_BYTEBUFFER_H_
-
-#include <string>
-
-#include "talk/base/basictypes.h"
-#include "talk/base/constructormagic.h"
-
-namespace talk_base {
-
-class ByteBuffer {
- public:
-
-  enum ByteOrder {
-    ORDER_NETWORK = 0,  // Default, use network byte order (big endian).
-    ORDER_HOST,         // Use the native order of the host.
-  };
-
-  // |byte_order| defines order of bytes in the buffer.
-  ByteBuffer();
-  explicit ByteBuffer(ByteOrder byte_order);
-  ByteBuffer(const char* bytes, size_t len);
-  ByteBuffer(const char* bytes, size_t len, ByteOrder byte_order);
-
-  // Initializes buffer from a zero-terminated string.
-  explicit ByteBuffer(const char* bytes);
-
-  ~ByteBuffer();
-
-  const char* Data() const { return bytes_ + start_; }
-  size_t Length() const { return end_ - start_; }
-  size_t Capacity() const { return size_ - start_; }
-
-  // Read a next value from the buffer. Return false if there isn't
-  // enough data left for the specified type.
-  bool ReadUInt8(uint8* val);
-  bool ReadUInt16(uint16* val);
-  bool ReadUInt24(uint32* val);
-  bool ReadUInt32(uint32* val);
-  bool ReadUInt64(uint64* val);
-  bool ReadBytes(char* val, size_t len);
-
-  // Appends next |len| bytes from the buffer to |val|. Returns false
-  // if there is less than |len| bytes left.
-  bool ReadString(std::string* val, size_t len);
-
-  // Write value to the buffer. Resizes the buffer when it is
-  // neccessary.
-  void WriteUInt8(uint8 val);
-  void WriteUInt16(uint16 val);
-  void WriteUInt24(uint32 val);
-  void WriteUInt32(uint32 val);
-  void WriteUInt64(uint64 val);
-  void WriteString(const std::string& val);
-  void WriteBytes(const char* val, size_t len);
-
-  // Resize the buffer to the specified |size|.
-  void Resize(size_t size);
-
-  // Moves current position |size| bytes forward. Return false if
-  // there is less than |size| bytes left in the buffer.
-  bool Consume(size_t size);
-
-  // Drops |size| bytes from the front of the buffer. Return false if
-  // there is less than |size| bytes left in the buffer.
-  bool Shift(size_t size);
-
- private:
-  void Construct(const char* bytes, size_t size, ByteOrder byte_order);
-
-  char* bytes_;
-  size_t size_;
-  size_t start_;
-  size_t end_;
-  ByteOrder byte_order_;
-
-  // There are sensible ways to define these, but they aren't needed in our code
-  // base.
-  DISALLOW_COPY_AND_ASSIGN(ByteBuffer);
-};
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_BYTEBUFFER_H_
diff --git a/third_party/libjingle/source/talk/base/bytebuffer_unittest.cc b/third_party/libjingle/source/talk/base/bytebuffer_unittest.cc
deleted file mode 100644
index 2970fdc..0000000
--- a/third_party/libjingle/source/talk/base/bytebuffer_unittest.cc
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/bytebuffer.h"
-#include "talk/base/byteorder.h"
-#include "talk/base/common.h"
-#include "talk/base/gunit.h"
-
-namespace talk_base {
-
-TEST(ByteBufferTest, TestByteOrder) {
-  uint16 n16 = 1;
-  uint32 n32 = 1;
-  uint64 n64 = 1;
-
-  EXPECT_EQ(n16, NetworkToHost16(HostToNetwork16(n16)));
-  EXPECT_EQ(n32, NetworkToHost32(HostToNetwork32(n32)));
-  EXPECT_EQ(n64, NetworkToHost64(HostToNetwork64(n64)));
-
-  if (IsHostBigEndian()) {
-    // The host is the network (big) endian.
-    EXPECT_EQ(n16, HostToNetwork16(n16));
-    EXPECT_EQ(n32, HostToNetwork32(n32));
-    EXPECT_EQ(n64, HostToNetwork64(n64));
-
-    // GetBE converts big endian to little endian here.
-    EXPECT_EQ(n16 >> 8, GetBE16(&n16));
-    EXPECT_EQ(n32 >> 24, GetBE32(&n32));
-    EXPECT_EQ(n64 >> 56, GetBE64(&n64));
-  } else {
-    // The host is little endian.
-    EXPECT_NE(n16, HostToNetwork16(n16));
-    EXPECT_NE(n32, HostToNetwork32(n32));
-    EXPECT_NE(n64, HostToNetwork64(n64));
-
-    // GetBE converts little endian to big endian here.
-    EXPECT_EQ(GetBE16(&n16), HostToNetwork16(n16));
-    EXPECT_EQ(GetBE32(&n32), HostToNetwork32(n32));
-    EXPECT_EQ(GetBE64(&n64), HostToNetwork64(n64));
-
-    // GetBE converts little endian to big endian here.
-    EXPECT_EQ(n16 << 8, GetBE16(&n16));
-    EXPECT_EQ(n32 << 24, GetBE32(&n32));
-    EXPECT_EQ(n64 << 56, GetBE64(&n64));
-  }
-}
-
-TEST(ByteBufferTest, TestBufferLength) {
-  ByteBuffer buffer;
-  size_t size = 0;
-  EXPECT_EQ(size, buffer.Length());
-
-  buffer.WriteUInt8(1);
-  ++size;
-  EXPECT_EQ(size, buffer.Length());
-
-  buffer.WriteUInt16(1);
-  size += 2;
-  EXPECT_EQ(size, buffer.Length());
-
-  buffer.WriteUInt24(1);
-  size += 3;
-  EXPECT_EQ(size, buffer.Length());
-
-  buffer.WriteUInt32(1);
-  size += 4;
-  EXPECT_EQ(size, buffer.Length());
-
-  buffer.WriteUInt64(1);
-  size += 8;
-  EXPECT_EQ(size, buffer.Length());
-
-  EXPECT_TRUE(buffer.Consume(0));
-  EXPECT_EQ(size, buffer.Length());
-
-  EXPECT_TRUE(buffer.Consume(4));
-  size -= 4;
-  EXPECT_EQ(size, buffer.Length());
-
-  EXPECT_TRUE(buffer.Shift(4));
-  size -= 4;
-  EXPECT_EQ(size, buffer.Length());
-}
-
-TEST(ByteBufferTest, TestReadWriteBuffer) {
-  ByteBuffer::ByteOrder orders[2] = { ByteBuffer::ORDER_HOST,
-                                      ByteBuffer::ORDER_NETWORK };
-  for (size_t i = 0; i < ARRAY_SIZE(orders); i++) {
-    ByteBuffer buffer(orders[i]);
-    uint8 ru8;
-    EXPECT_FALSE(buffer.ReadUInt8(&ru8));
-
-    // Write and read uint8.
-    uint8 wu8 = 1;
-    buffer.WriteUInt8(wu8);
-    EXPECT_TRUE(buffer.ReadUInt8(&ru8));
-    EXPECT_EQ(wu8, ru8);
-    EXPECT_EQ(0U, buffer.Length());
-
-    // Write and read uint16.
-    uint16 wu16 = (1 << 8) + 1;
-    buffer.WriteUInt16(wu16);
-    uint16 ru16;
-    EXPECT_TRUE(buffer.ReadUInt16(&ru16));
-    EXPECT_EQ(wu16, ru16);
-    EXPECT_EQ(0U, buffer.Length());
-
-    // Write and read uint24.
-    uint32 wu24 = (3 << 16) + (2 << 8) + 1;
-    buffer.WriteUInt24(wu24);
-    uint32 ru24;
-    EXPECT_TRUE(buffer.ReadUInt24(&ru24));
-    EXPECT_EQ(wu24, ru24);
-    EXPECT_EQ(0U, buffer.Length());
-
-    // Write and read uint32.
-    uint32 wu32 = (4 << 24) + (3 << 16) + (2 << 8) + 1;
-    buffer.WriteUInt32(wu32);
-    uint32 ru32;
-    EXPECT_TRUE(buffer.ReadUInt32(&ru32));
-    EXPECT_EQ(wu32, ru32);
-    EXPECT_EQ(0U, buffer.Length());
-
-    // Write and read uint64.
-    uint32 another32 = (8 << 24) + (7 << 16) + (6 << 8) + 5;
-    uint64 wu64 = (static_cast<uint64>(another32) << 32) + wu32;
-    buffer.WriteUInt64(wu64);
-    uint64 ru64;
-    EXPECT_TRUE(buffer.ReadUInt64(&ru64));
-    EXPECT_EQ(wu64, ru64);
-    EXPECT_EQ(0U, buffer.Length());
-
-    // Write and read string.
-    std::string write_string("hello");
-    buffer.WriteString(write_string);
-    std::string read_string;
-    EXPECT_TRUE(buffer.ReadString(&read_string, write_string.size()));
-    EXPECT_EQ(write_string, read_string);
-    EXPECT_EQ(0U, buffer.Length());
-
-    // Write and read in order.
-    buffer.WriteUInt8(wu8);
-    buffer.WriteUInt16(wu16);
-    buffer.WriteUInt24(wu24);
-    buffer.WriteUInt32(wu32);
-    buffer.WriteUInt64(wu64);
-    EXPECT_TRUE(buffer.ReadUInt8(&ru8));
-    EXPECT_EQ(wu8, ru8);
-    EXPECT_TRUE(buffer.ReadUInt16(&ru16));
-    EXPECT_EQ(wu16, ru16);
-    EXPECT_TRUE(buffer.ReadUInt24(&ru24));
-    EXPECT_EQ(wu24, ru24);
-    EXPECT_TRUE(buffer.ReadUInt32(&ru32));
-    EXPECT_EQ(wu32, ru32);
-    EXPECT_TRUE(buffer.ReadUInt64(&ru64));
-    EXPECT_EQ(wu64, ru64);
-    EXPECT_EQ(0U, buffer.Length());
-  }
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/byteorder.h b/third_party/libjingle/source/talk/base/byteorder.h
deleted file mode 100644
index 08094b8..0000000
--- a/third_party/libjingle/source/talk/base/byteorder.h
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_BYTEORDER_H__
-#define TALK_BASE_BYTEORDER_H__
-
-#ifdef POSIX
-#include <arpa/inet.h>
-#endif
-
-#ifdef WIN32
-#include <winsock2.h>
-#endif
-
-#include "talk/base/basictypes.h"
-
-namespace talk_base {
-
-// Reading and writing of little and big-endian numbers from memory
-// TODO: Add HostEndian #defines (HE)
-// TODO: Consider NetworkEndian as synonym for BigEndian, for clarity in use.
-// TODO: Consider creating optimized versions, such as direct read/writes of
-// integers in host-endian format, when the platform supports it.
-
-inline void Set8(void* memory, size_t offset, uint8 v) {
-  static_cast<uint8*>(memory)[offset] = v;
-}
-inline uint8 Get8(const void* memory, size_t offset) {
-  return static_cast<const uint8*>(memory)[offset];
-}
-
-inline void SetBE16(void* memory, uint16 v) {
-  Set8(memory, 0, static_cast<uint8>(v >>  8));
-  Set8(memory, 1, static_cast<uint8>(v >>  0));
-}
-inline void SetBE32(void* memory, uint32 v) {
-  Set8(memory, 0, static_cast<uint8>(v >> 24));
-  Set8(memory, 1, static_cast<uint8>(v >> 16));
-  Set8(memory, 2, static_cast<uint8>(v >>  8));
-  Set8(memory, 3, static_cast<uint8>(v >>  0));
-}
-inline void SetBE64(void* memory, uint64 v) {
-  Set8(memory, 0, static_cast<uint8>(v >> 56));
-  Set8(memory, 1, static_cast<uint8>(v >> 48));
-  Set8(memory, 2, static_cast<uint8>(v >> 40));
-  Set8(memory, 3, static_cast<uint8>(v >> 32));
-  Set8(memory, 4, static_cast<uint8>(v >> 24));
-  Set8(memory, 5, static_cast<uint8>(v >> 16));
-  Set8(memory, 6, static_cast<uint8>(v >>  8));
-  Set8(memory, 7, static_cast<uint8>(v >>  0));
-}
-inline uint16 GetBE16(const void* memory) {
-  return (static_cast<uint16>(Get8(memory, 0)) << 8)
-       | (static_cast<uint16>(Get8(memory, 1)) << 0);
-}
-inline uint32 GetBE32(const void* memory) {
-  return (static_cast<uint32>(Get8(memory, 0)) << 24)
-       | (static_cast<uint32>(Get8(memory, 1)) << 16)
-       | (static_cast<uint32>(Get8(memory, 2)) <<  8)
-       | (static_cast<uint32>(Get8(memory, 3)) <<  0);
-}
-inline uint64 GetBE64(const void* memory) {
-  return (static_cast<uint64>(Get8(memory, 0)) << 56)
-       | (static_cast<uint64>(Get8(memory, 1)) << 48)
-       | (static_cast<uint64>(Get8(memory, 2)) << 40)
-       | (static_cast<uint64>(Get8(memory, 3)) << 32)
-       | (static_cast<uint64>(Get8(memory, 4)) << 24)
-       | (static_cast<uint64>(Get8(memory, 5)) << 16)
-       | (static_cast<uint64>(Get8(memory, 6)) <<  8)
-       | (static_cast<uint64>(Get8(memory, 7)) <<  0);
-}
-
-inline void SetLE16(void* memory, uint16 v) {
-  Set8(memory, 1, static_cast<uint8>(v >>  8));
-  Set8(memory, 0, static_cast<uint8>(v >>  0));
-}
-inline void SetLE32(void* memory, uint32 v) {
-  Set8(memory, 3, static_cast<uint8>(v >> 24));
-  Set8(memory, 2, static_cast<uint8>(v >> 16));
-  Set8(memory, 1, static_cast<uint8>(v >>  8));
-  Set8(memory, 0, static_cast<uint8>(v >>  0));
-}
-inline void SetLE64(void* memory, uint64 v) {
-  Set8(memory, 7, static_cast<uint8>(v >> 56));
-  Set8(memory, 6, static_cast<uint8>(v >> 48));
-  Set8(memory, 5, static_cast<uint8>(v >> 40));
-  Set8(memory, 4, static_cast<uint8>(v >> 32));
-  Set8(memory, 3, static_cast<uint8>(v >> 24));
-  Set8(memory, 2, static_cast<uint8>(v >> 16));
-  Set8(memory, 1, static_cast<uint8>(v >>  8));
-  Set8(memory, 0, static_cast<uint8>(v >>  0));
-}
-inline uint16 GetLE16(const void* memory) {
-  return (static_cast<uint16>(Get8(memory, 1)) << 8)
-       | (static_cast<uint16>(Get8(memory, 0)) << 0);
-}
-inline uint32 GetLE32(const void* memory) {
-  return (static_cast<uint32>(Get8(memory, 3)) << 24)
-       | (static_cast<uint32>(Get8(memory, 2)) << 16)
-       | (static_cast<uint32>(Get8(memory, 1)) <<  8)
-       | (static_cast<uint32>(Get8(memory, 0)) <<  0);
-}
-inline uint64 GetLE64(const void* memory) {
-  return (static_cast<uint64>(Get8(memory, 7)) << 56)
-       | (static_cast<uint64>(Get8(memory, 6)) << 48)
-       | (static_cast<uint64>(Get8(memory, 5)) << 40)
-       | (static_cast<uint64>(Get8(memory, 4)) << 32)
-       | (static_cast<uint64>(Get8(memory, 3)) << 24)
-       | (static_cast<uint64>(Get8(memory, 2)) << 16)
-       | (static_cast<uint64>(Get8(memory, 1)) <<  8)
-       | (static_cast<uint64>(Get8(memory, 0)) <<  0);
-}
-
-// Check if the current host is big endian.
-inline bool IsHostBigEndian() {
-  static const int number = 1;
-  return (0 == *reinterpret_cast<const char*>(&number));
-}
-
-inline uint16 HostToNetwork16(uint16 n) {
-  return htons(n);
-}
-
-inline uint32 HostToNetwork32(uint32 n) {
-  return htonl(n);
-}
-
-inline uint64 HostToNetwork64(uint64 n) {
-  // If the host is little endian, GetBE64 converts n to big network endian.
-  return IsHostBigEndian() ? n : GetBE64(&n);
-}
-
-inline uint16 NetworkToHost16(uint16 n) {
-  return ntohs(n);
-}
-
-inline uint32 NetworkToHost32(uint32 n) {
-  return ntohl(n);
-}
-
-inline uint64 NetworkToHost64(uint64 n) {
-  // If the host is little endian, GetBE64 converts n to little endian.
-  return IsHostBigEndian() ? n : GetBE64(&n);
-}
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_BYTEORDER_H__
diff --git a/third_party/libjingle/source/talk/base/checks.cc b/third_party/libjingle/source/talk/base/checks.cc
deleted file mode 100644
index 5466783..0000000
--- a/third_party/libjingle/source/talk/base/checks.cc
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * libjingle
- * Copyright 2006, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-
-#include "talk/base/checks.h"
-#include "talk/base/logging.h"
-
-void Fatal(const char* file, int line, const char* format, ...) {
-  char msg[256];
-
-  va_list arguments;
-  va_start(arguments, format);
-  vsnprintf(msg, sizeof(msg), format, arguments);
-  va_end(arguments);
-
-  LOG(LS_ERROR) << "\n\n#\n# Fatal error in " << file
-                << ", line " << line << "\n#" << msg
-                << "\n#\n";
-  abort();
-}
diff --git a/third_party/libjingle/source/talk/base/checks.h b/third_party/libjingle/source/talk/base/checks.h
deleted file mode 100644
index 83ad372..0000000
--- a/third_party/libjingle/source/talk/base/checks.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * libjingle
- * Copyright 2006, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// This module contains some basic debugging facilities.
-// Originally comes from shared/commandlineflags/checks.h
-
-#ifndef TALK_BASE_CHECKS_H_
-#define TALK_BASE_CHECKS_H_
-
-#include <string.h>
-
-// Prints an error message to stderr and aborts execution.
-void Fatal(const char* file, int line, const char* format, ...);
-
-
-// The UNREACHABLE macro is very useful during development.
-#define UNREACHABLE()                                   \
-  Fatal(__FILE__, __LINE__, "unreachable code")
-
-#endif  // TALK_BASE_CHECKS_H_
diff --git a/third_party/libjingle/source/talk/base/common.cc b/third_party/libjingle/source/talk/base/common.cc
deleted file mode 100644
index 59e73d5..0000000
--- a/third_party/libjingle/source/talk/base/common.cc
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <memory.h>
-
-#if WIN32
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#endif  // WIN32
-
-#if OSX
-#include <CoreServices/CoreServices.h>
-#endif  // OSX
-
-#include <algorithm>
-#include "talk/base/common.h"
-#include "talk/base/logging.h"
-
-//////////////////////////////////////////////////////////////////////
-// Assertions
-//////////////////////////////////////////////////////////////////////
-
-namespace talk_base {
-
-void Break() {
-#if WIN32
-  ::DebugBreak();
-#elif OSX  // !WIN32
-  ::Debugger();
-#else // !OSX && !WIN32
-#if _DEBUG_HAVE_BACKTRACE
-  OutputTrace();
-#endif
-  abort();
-#endif // !OSX && !WIN32
-}
-
-void LogAssert(const char * function, const char * file, int line,
-               const char * expression) {
-  // TODO - if we put hooks in here, we can do a lot fancier logging
-  LOG(LS_ERROR) << file << "(" << line << ")" << ": ASSERT FAILED: "
-                << expression << " @ " << function;
-}
-
-} // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/common.h b/third_party/libjingle/source/talk/base/common.h
deleted file mode 100644
index 63de637..0000000
--- a/third_party/libjingle/source/talk/base/common.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * libjingle
- * Copyright 2004 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_COMMON_H_
-#define TALK_BASE_COMMON_H_
-
-#include "talk/base/constructormagic.h"
-
-#if defined(_MSC_VER)
-// warning C4355: 'this' : used in base member initializer list
-#pragma warning(disable:4355)
-#endif
-
-//////////////////////////////////////////////////////////////////////
-// General Utilities
-//////////////////////////////////////////////////////////////////////
-
-#ifndef UNUSED
-#define UNUSED(x) Unused(static_cast<const void *>(&x))
-#define UNUSED2(x,y) Unused(static_cast<const void *>(&x)); Unused(static_cast<const void *>(&y))
-#define UNUSED3(x,y,z) Unused(static_cast<const void *>(&x)); Unused(static_cast<const void *>(&y)); Unused(static_cast<const void *>(&z))
-#define UNUSED4(x,y,z,a) Unused(static_cast<const void *>(&x)); Unused(static_cast<const void *>(&y)); Unused(static_cast<const void *>(&z)); Unused(static_cast<const void *>(&a))
-#define UNUSED5(x,y,z,a,b) Unused(static_cast<const void *>(&x)); Unused(static_cast<const void *>(&y)); Unused(static_cast<const void *>(&z)); Unused(static_cast<const void *>(&a)); Unused(static_cast<const void *>(&b))
-inline void Unused(const void *) { }
-#endif // UNUSED
-
-#ifndef WIN32
-#define strnicmp(x,y,n) strncasecmp(x,y,n)
-#define stricmp(x,y) strcasecmp(x,y)
-
-// TODO: Remove this. std::max should be used everywhere in the code.
-// NOMINMAX must be defined where we include <windows.h>.
-#define stdmax(x,y) std::max(x,y)
-#else
-#define stdmax(x,y) talk_base::_max(x,y)
-#endif
-
-
-#define ARRAY_SIZE(x) (static_cast<int>((sizeof(x)/sizeof(x[0]))))
-
-/////////////////////////////////////////////////////////////////////////////
-// Assertions
-/////////////////////////////////////////////////////////////////////////////
-
-#ifndef ENABLE_DEBUG
-#define ENABLE_DEBUG _DEBUG
-#endif  // !defined(ENABLE_DEBUG)
-
-#if ENABLE_DEBUG
-
-namespace talk_base {
-
-// Break causes the debugger to stop executing, or the program to abort
-void Break();
-
-// LogAssert writes information about an assertion to the log
-void LogAssert(const char * function, const char * file, int line,
-               const char * expression);
-
-inline bool Assert(bool result, const char * function, const char * file,
-                   int line, const char * expression) {
-  if (!result) {
-    LogAssert(function, file, line, expression);
-    Break();
-    return false;
-  }
-  return true;
-}
-
-}  // namespace talk_base
-
-#if defined(_MSC_VER) && _MSC_VER < 1300
-#define __FUNCTION__ ""
-#endif
-
-#ifndef ASSERT
-#define ASSERT(x) (void)talk_base::Assert((x),__FUNCTION__,__FILE__,__LINE__,#x)
-#endif
-
-#ifndef VERIFY
-#define VERIFY(x) talk_base::Assert((x),__FUNCTION__,__FILE__,__LINE__,#x)
-#endif
-
-#else // !ENABLE_DEBUG
-
-namespace talk_base {
-
-inline bool ImplicitCastToBool(bool result) { return result; }
-
-}  // namespace talk_base
-
-#ifndef ASSERT
-#define ASSERT(x) (void)0
-#endif
-
-#ifndef VERIFY
-#define VERIFY(x) talk_base::ImplicitCastToBool(x)
-#endif
-
-#endif // !ENABLE_DEBUG
-
-#define COMPILE_TIME_ASSERT(expr)       char CTA_UNIQUE_NAME[expr]
-#define CTA_UNIQUE_NAME                 CTA_MAKE_NAME(__LINE__)
-#define CTA_MAKE_NAME(line)             CTA_MAKE_NAME2(line)
-#define CTA_MAKE_NAME2(line)            constraint_ ## line
-
-// Forces compiler to inline, even against its better judgement. Use wisely.
-#if defined(__GNUC__)
-#define FORCE_INLINE __attribute__((always_inline))
-#elif defined(WIN32)
-#define FORCE_INLINE __forceinline
-#else
-#define FORCE_INLINE
-#endif
-
-#endif // TALK_BASE_COMMON_H_
diff --git a/third_party/libjingle/source/talk/base/constructormagic.h b/third_party/libjingle/source/talk/base/constructormagic.h
deleted file mode 100644
index 8b1f7ff..0000000
--- a/third_party/libjingle/source/talk/base/constructormagic.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_CONSTRUCTORMAGIC_H_
-#define TALK_BASE_CONSTRUCTORMAGIC_H_
-
-#define DISALLOW_ASSIGN(TypeName) \
-  void operator=(const TypeName&)
-
-// A macro to disallow the evil copy constructor and operator= functions
-// This should be used in the private: declarations for a class
-#define DISALLOW_COPY_AND_ASSIGN(TypeName)    \
-  TypeName(const TypeName&);                    \
-  DISALLOW_ASSIGN(TypeName)
-
-// Alternative, less-accurate legacy name.
-#define DISALLOW_EVIL_CONSTRUCTORS(TypeName) \
-  DISALLOW_COPY_AND_ASSIGN(TypeName)
-
-// A macro to disallow all the implicit constructors, namely the
-// default constructor, copy constructor and operator= functions.
-//
-// This should be used in the private: declarations for a class
-// that wants to prevent anyone from instantiating it. This is
-// especially useful for classes containing only static methods.
-#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
-  TypeName();                                    \
-  DISALLOW_EVIL_CONSTRUCTORS(TypeName)
-
-
-#endif  // TALK_BASE_CONSTRUCTORMAGIC_H_
diff --git a/third_party/libjingle/source/talk/base/cpuid.cc b/third_party/libjingle/source/talk/base/cpuid.cc
deleted file mode 100644
index 7f0326a..0000000
--- a/third_party/libjingle/source/talk/base/cpuid.cc
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * libjingle
- * Copyright 2011 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/cpuid.h"
-
-#ifdef _MSC_VER
-#include <intrin.h>
-#elif defined(__ANDROID__)
-#include <cpu-features.h>
-#elif defined(LINUX)
-#include "talk/base/linux.h"
-#endif
-
-// TODO: Use cpuid.h when gcc 4.4 is used on OSX and Linux.
-#if (defined(__pic__) || defined(__APPLE__)) && defined(__i386__)
-static inline void __cpuid(int cpu_info[4], int info_type) {
-  __asm__ volatile (
-    "mov %%ebx, %%edi\n"
-    "cpuid\n"
-    "xchg %%edi, %%ebx\n"
-    : "=a"(cpu_info[0]), "=D"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3])
-    : "a"(info_type)
-  );
-}
-#elif defined(__i386__) || defined(__x86_64__)
-static inline void __cpuid(int cpu_info[4], int info_type) {
-  __asm__ volatile (
-    "cpuid\n"
-    : "=a"(cpu_info[0]), "=b"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3])
-    : "a"(info_type)
-  );
-}
-#endif
-
-namespace talk_base {
-
-// CPU detect function for SIMD instruction sets.
-bool CpuInfo::cpu_info_initialized_ = false;
-int CpuInfo::cpu_info_ = 0;
-// Global lock for cpu initialization.
-CriticalSection CpuInfo::crit_;
-
-#ifdef CPU_X86
-void cpuid(int cpu_info[4], int info_type) {
-  __cpuid(cpu_info, info_type);
-}
-#endif
-
-void CpuInfo::InitCpuFlags() {
-#ifdef CPU_X86
-  int cpu_info[4];
-  __cpuid(cpu_info, 1);
-  cpu_info_ = (cpu_info[2] & 0x00000200 ? kCpuHasSSSE3 : 0) |
-    (cpu_info[3] & 0x04000000 ? kCpuHasSSE2 : 0);
-#elif defined(__ANDROID__) && defined(__arm__)
-  uint64_t features = android_getCpuFeatures();
-  cpu_info_ = ((features & ANDROID_CPU_ARM_FEATURE_NEON) ? kCpuHasNEON : 0);
-#elif defined(LINUX) && defined(__arm__)
-  cpu_info_ = 0;
-  // Look for NEON support in /proc/cpuinfo
-  ProcCpuInfo proc_info;
-  size_t section_count;
-  if (proc_info.LoadFromSystem() &&
-      proc_info.GetSectionCount(&section_count)) {
-    for (size_t i = 0; i < section_count; ++i) {
-      std::string out_features;
-      if (proc_info.GetSectionStringValue(i, "Features", &out_features)) {
-        if (out_features.find("neon") != std::string::npos) {
-          cpu_info_ |= kCpuHasNEON;
-        }
-        break;
-      }
-    }
-  }
-#elif defined(__ARM_NEON__)
-  // gcc -mfpu=neon defines __ARM_NEON__
-  // if code is specifically built for Neon-only, enable the flag.
-  cpu_info_ |= kCpuHasNEON;
-#else
-  cpu_info_ = 0;
-#endif
-  cpu_info_initialized_ = true;
-}
-
-void CpuInfo::MaskCpuFlagsForTest(int enable_flags) {
-  CritScope cs(&crit_);
-  InitCpuFlags();
-  cpu_info_ &= enable_flags;
-}
-
-bool CpuInfo::TestCpuFlag(int flag) {
-  if (!cpu_info_initialized_) {
-    CritScope cs(&crit_);
-    InitCpuFlags();
-  }
-  return cpu_info_ & flag ? true : false;
-}
-
-// Returns the vendor string from the cpu, e.g. "GenuineIntel", "AuthenticAMD".
-// See "Intel Processor Identification and the CPUID Instruction"
-// (Intel document number: 241618)
-std::string CpuInfo::GetCpuVendor() {
-#ifdef CPU_X86
-  int cpu_info[4];
-  cpuid(cpu_info, 0);
-  cpu_info[0] = cpu_info[1];  // Reorder output
-  cpu_info[1] = cpu_info[3];
-  cpu_info[2] = cpu_info[2];
-  cpu_info[3] = 0;
-  return std::string(reinterpret_cast<char *>(&cpu_info[0]));
-#else
-  return std::string("Undefined");
-#endif
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/cpuid.h b/third_party/libjingle/source/talk/base/cpuid.h
deleted file mode 100644
index 3688668..0000000
--- a/third_party/libjingle/source/talk/base/cpuid.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * libjingle
- * Copyright 2011 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_CPUID_H_
-#define TALK_BASE_CPUID_H_
-
-#include <string>
-
-#include "talk/base/basictypes.h"
-#include "talk/base/criticalsection.h"
-
-namespace talk_base {
-
-#ifdef CPU_X86
-void cpuid(int cpu_info[4], int info_type);
-#endif
-
-class CpuInfo {
- public:
-  // These flags are only valid on x86 processors
-  static const int kCpuHasSSE2 = 1;
-  static const int kCpuHasSSSE3 = 2;
-
-  // SIMD support on ARM processors
-  static const int kCpuHasNEON = 4;
-
-  // Detect CPU has SSE2 etc.
-  static bool TestCpuFlag(int flag);
-
-  // Detect CPU vendor: "GenuineIntel" or "AuthenticAMD"
-  static std::string GetCpuVendor();
-
-  // For testing, allow CPU flags to be disabled.
-  static void MaskCpuFlagsForTest(int enable_flags);
-
- private:
-  // Global lock for the cpu initialization
-  static CriticalSection crit_;
-  static bool cpu_info_initialized_;
-  static int cpu_info_;
-
-  static void InitCpuFlags();
-
-  DISALLOW_IMPLICIT_CONSTRUCTORS(CpuInfo);
-};
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_CPUID_H_
diff --git a/third_party/libjingle/source/talk/base/cpuid_unittest.cc b/third_party/libjingle/source/talk/base/cpuid_unittest.cc
deleted file mode 100644
index f06178f..0000000
--- a/third_party/libjingle/source/talk/base/cpuid_unittest.cc
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * libjingle
- * Copyright 2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <iostream>
-
-#include "talk/base/cpuid.h"
-#include "talk/base/gunit.h"
-#include "talk/base/stringutils.h"
-
-
-// Tests CPUID instruction for Vendor identification.
-TEST(CpuInfoTest, CpuVendorNonEmpty) {
-  EXPECT_FALSE(talk_base::CpuInfo::GetCpuVendor().empty());
-}
-
-#ifdef CPU_X86
-
-// Tests Vendor identification is Intel or AMD.
-// See Also http://en.wikipedia.org/wiki/CPUID
-TEST(CpuInfoTest, CpuVendorIntelAMD) {
-  const std::string vendor = talk_base::CpuInfo::GetCpuVendor();
-  LOG(LS_INFO) << "CpuVendor: " << vendor;
-  EXPECT_TRUE(talk_base::string_match(vendor.c_str(),
-                                      "GenuineIntel") ||
-              talk_base::string_match(vendor.c_str(),
-                                      "AuthenticAMD"));
-}
-
-// Tests CPUID maximum function number.
-// Modern CPU has 11, but we expect at least 3.
-TEST(CpuInfoTest, CpuIdMax) {
-  int cpu_info[4] = { 0 };
-  talk_base::cpuid(cpu_info, 0);
-  LOG(LS_INFO) << "CpuId Max Function: " << cpu_info[0];
-  EXPECT_GE(cpu_info[0], 1);
-}
-
-// Tests CPUID functions 0 and 1 return different values.
-TEST(CpuInfoTest, CpuId) {
-  int cpu_info0[4] = { 0 };
-  int cpu_info1[4] = { 0 };
-  talk_base::cpuid(cpu_info0, 0);
-  talk_base::cpuid(cpu_info1, 1);
-  LOG(LS_INFO) << "CpuId Function 0: " << std::hex
-               << std::setfill('0') << std::setw(8) << cpu_info0[0] << " "
-               << std::setfill('0') << std::setw(8) << cpu_info0[1] << " "
-               << std::setfill('0') << std::setw(8) << cpu_info0[2] << " "
-               << std::setfill('0') << std::setw(8) << cpu_info0[3];
-  LOG(LS_INFO) << "CpuId Function 1: " << std::hex
-               << std::setfill('0') << std::setw(8) << cpu_info1[0] << " "
-               << std::setfill('0') << std::setw(8) << cpu_info1[1] << " "
-               << std::setfill('0') << std::setw(8) << cpu_info1[2] << " "
-               << std::setfill('0') << std::setw(8) << cpu_info1[3];
-  EXPECT_NE(memcmp(cpu_info0, cpu_info1, sizeof(cpu_info0)), 0);
-
-  LOG(LS_INFO) << "SSE2: "
-      << talk_base::CpuInfo::TestCpuFlag(talk_base::CpuInfo::kCpuHasSSE2);
-  LOG(LS_INFO) << "SSSE3: "
-      << talk_base::CpuInfo::TestCpuFlag(talk_base::CpuInfo::kCpuHasSSSE3);
-}
-#endif
-
diff --git a/third_party/libjingle/source/talk/base/cpumonitor.cc b/third_party/libjingle/source/talk/base/cpumonitor.cc
deleted file mode 100644
index 64f6147..0000000
--- a/third_party/libjingle/source/talk/base/cpumonitor.cc
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
- * libjingle
- * Copyright 2010 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/cpumonitor.h"
-
-#include <string>
-
-#include "talk/base/common.h"
-#include "talk/base/logging.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/base/systeminfo.h"
-#include "talk/base/thread.h"
-#include "talk/base/timeutils.h"
-
-#ifdef WIN32
-#include "talk/base/win32.h"
-#include <winternl.h>
-#endif
-
-#ifdef POSIX
-#include <sys/time.h>
-#endif
-
-#if defined(IOS) || defined(OSX)
-#include <mach/mach_host.h>
-#include <mach/mach_init.h>
-#include <mach/host_info.h>
-#include <mach/task.h>
-#endif  // defined(IOS) || defined(OSX)
-
-#if defined(LINUX) || defined(ANDROID)
-#include <sys/resource.h>
-#include <errno.h>
-#include <stdio.h>
-#include "talk/base/fileutils.h"
-#include "talk/base/pathutils.h"
-#endif // defined(LINUX) || defined(ANDROID)
-
-#if defined(IOS) || defined(OSX)
-static uint64 TimeValueTToInt64(const time_value_t &time_value) {
-  return talk_base::kNumMicrosecsPerSec * time_value.seconds +
-      time_value.microseconds;
-}
-#endif  // defined(IOS) || defined(OSX)
-
-// How CpuSampler works
-// When threads switch, the time they spent is accumulated to system counters.
-// The time can be treated as user, kernel or idle.
-// user time is applications.
-// kernel time is the OS, including the thread switching code itself.
-//   typically kernel time indicates IO.
-// idle time is a process that wastes time when nothing is ready to run.
-//
-// User time is broken down by process (application).  One of the applications
-// is the current process.  When you add up all application times, this is
-// system time.  If only your application is running, system time should be the
-// same as process time.
-//
-// All cores contribute to these accumulators.  A dual core process is able to
-// process twice as many cycles as a single core.  The actual code efficiency
-// may be worse, due to contention, but the available cycles is exactly twice
-// as many, and the cpu load will reflect the efficiency.  Hyperthreads behave
-// the same way.  The load will reflect 200%, but the actual amount of work
-// completed will be much less than a true dual core.
-//
-// Total available performance is the sum of all accumulators.
-// If you tracked this for 1 second, it would essentially give you the clock
-// rate - number of cycles per second.
-// Speed step / Turbo Boost is not considered, so infact more processing time
-// may be available.
-
-namespace talk_base {
-
-// Note Tests on Windows show 600 ms is minimum stable interval for Windows 7.
-static const int32 kDefaultInterval = 950;  // Slightly under 1 second.
-
-CpuSampler::CpuSampler()
-    : min_load_interval_(kDefaultInterval)
-#ifdef WIN32
-      , get_system_times_(NULL),
-      nt_query_system_information_(NULL),
-      force_fallback_(false)
-#endif
-    {
-}
-
-CpuSampler::~CpuSampler() {
-}
-
-// Set minimum interval in ms between computing new load values. Default 950.
-void CpuSampler::set_load_interval(int min_load_interval) {
-  min_load_interval_ = min_load_interval;
-}
-
-bool CpuSampler::Init() {
-  sysinfo_.reset(new SystemInfo);
-  cpus_ = sysinfo_->GetMaxCpus();
-  if (cpus_ == 0) {
-    return false;
-  }
-#ifdef WIN32
-  // Note that GetSystemTimes is available in Windows XP SP1 or later.
-  // http://msdn.microsoft.com/en-us/library/ms724400.aspx
-  // NtQuerySystemInformation is used as a fallback.
-  if (!force_fallback_) {
-    get_system_times_ = GetProcAddress(GetModuleHandle(L"kernel32.dll"),
-        "GetSystemTimes");
-  }
-  nt_query_system_information_ = GetProcAddress(GetModuleHandle(L"ntdll.dll"),
-      "NtQuerySystemInformation");
-  if ((get_system_times_ == NULL) && (nt_query_system_information_ == NULL)) {
-    return false;
-  }
-#endif
-#if defined(LINUX) || defined(ANDROID)
-  Pathname sname("/proc/stat");
-  sfile_.reset(Filesystem::OpenFile(sname, "rb"));
-  if (sfile_.get() == NULL) {
-    LOG_ERR(LS_ERROR) << "open proc/stat failed:";
-    return false;
-  }
-  if (!sfile_->DisableBuffering()) {
-    LOG_ERR(LS_ERROR) << "could not disable buffering for proc/stat";
-    return false;
-  }
-#endif // defined(LINUX) || defined(ANDROID)
-  GetProcessLoad();  // Initialize values.
-  GetSystemLoad();
-  // Help next user call return valid data by recomputing load.
-  process_.prev_load_time_ = 0u;
-  system_.prev_load_time_ = 0u;
-  return true;
-}
-
-float CpuSampler::UpdateCpuLoad(uint64 current_total_times,
-                                uint64 current_cpu_times,
-                                uint64 *prev_total_times,
-                                uint64 *prev_cpu_times) {
-  float result = 0.f;
-  if (current_total_times < *prev_total_times ||
-      current_cpu_times < *prev_cpu_times) {
-    LOG(LS_ERROR) << "Inconsistent time values are passed. ignored";
-  } else {
-    const uint64 cpu_diff = current_cpu_times - *prev_cpu_times;
-    const uint64 total_diff = current_total_times - *prev_total_times;
-    result = (total_diff == 0ULL ? 0.f :
-              static_cast<float>(1.0f * cpu_diff / total_diff));
-    if (result > static_cast<float>(cpus_)) {
-      result = static_cast<float>(cpus_);
-    }
-    *prev_total_times = current_total_times;
-    *prev_cpu_times = current_cpu_times;
-  }
-  return result;
-}
-
-float CpuSampler::GetSystemLoad() {
-  uint32 timenow = Time();
-  int elapsed = static_cast<int>(TimeDiff(timenow, system_.prev_load_time_));
-  if (min_load_interval_ != 0 && system_.prev_load_time_ != 0u &&
-      elapsed < min_load_interval_) {
-    return system_.prev_load_;
-  }
-#ifdef WIN32
-  uint64 total_times, cpu_times;
-
-  typedef BOOL (_stdcall *GST_PROC)(LPFILETIME, LPFILETIME, LPFILETIME);
-  typedef NTSTATUS (WINAPI *QSI_PROC)(SYSTEM_INFORMATION_CLASS,
-      PVOID, ULONG, PULONG);
-
-  GST_PROC get_system_times = reinterpret_cast<GST_PROC>(get_system_times_);
-  QSI_PROC nt_query_system_information = reinterpret_cast<QSI_PROC>(
-      nt_query_system_information_);
-
-  if (get_system_times) {
-    FILETIME idle_time, kernel_time, user_time;
-    if (!get_system_times(&idle_time, &kernel_time, &user_time)) {
-      LOG(LS_ERROR) << "::GetSystemTimes() failed: " << ::GetLastError();
-      return 0.f;
-    }
-    // kernel_time includes Kernel idle time, so no need to
-    // include cpu_time as total_times
-    total_times = ToUInt64(kernel_time) + ToUInt64(user_time);
-    cpu_times = total_times - ToUInt64(idle_time);
-
-  } else {
-    if (nt_query_system_information) {
-      ULONG returned_length = 0;
-      scoped_array<SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION> processor_info(
-          new SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION[cpus_]);
-      nt_query_system_information(
-          ::SystemProcessorPerformanceInformation,
-          reinterpret_cast<void*>(processor_info.get()),
-          cpus_ * sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION),
-          &returned_length);
-
-      if (returned_length !=
-          (cpus_ * sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION))) {
-        LOG(LS_ERROR) << "NtQuerySystemInformation has unexpected size";
-        return 0.f;
-      }
-
-      uint64 current_idle = 0;
-      uint64 current_kernel = 0;
-      uint64 current_user = 0;
-      for (int ix = 0; ix < cpus_; ++ix) {
-        current_idle += processor_info[ix].IdleTime.QuadPart;
-        current_kernel += processor_info[ix].UserTime.QuadPart;
-        current_user += processor_info[ix].KernelTime.QuadPart;
-      }
-      total_times = current_kernel + current_user;
-      cpu_times = total_times - current_idle;
-    } else {
-      return 0.f;
-    }
-  }
-#endif  // WIN32
-
-#if defined(IOS) || defined(OSX)
-  host_cpu_load_info_data_t cpu_info;
-  mach_msg_type_number_t info_count = HOST_CPU_LOAD_INFO_COUNT;
-  if (KERN_SUCCESS != host_statistics(mach_host_self(), HOST_CPU_LOAD_INFO,
-                                      reinterpret_cast<host_info_t>(&cpu_info),
-                                      &info_count)) {
-    LOG(LS_ERROR) << "::host_statistics() failed";
-    return 0.f;
-  }
-
-  const uint64 cpu_times = cpu_info.cpu_ticks[CPU_STATE_NICE] +
-      cpu_info.cpu_ticks[CPU_STATE_SYSTEM] +
-      cpu_info.cpu_ticks[CPU_STATE_USER];
-  const uint64 total_times = cpu_times + cpu_info.cpu_ticks[CPU_STATE_IDLE];
-#endif  // defined(IOS) || defined(OSX)
-
-#if defined(LINUX) || defined(ANDROID)
-  if (sfile_.get() == NULL) {
-    LOG(LS_ERROR) << "Invalid handle for proc/stat";
-    return 0.f;
-  }
-  std::string statbuf;
-  sfile_->SetPosition(0);
-  if (!sfile_->ReadLine(&statbuf)) {
-    LOG_ERR(LS_ERROR) << "Could not read proc/stat file";
-    return 0.f;
-  }
-
-  unsigned long long user;
-  unsigned long long nice;
-  unsigned long long system;
-  unsigned long long idle;
-  if (sscanf(statbuf.c_str(), "cpu %Lu %Lu %Lu %Lu",
-             &user, &nice,
-             &system, &idle) != 4) {
-    LOG_ERR(LS_ERROR) << "Could not parse cpu info";
-    return 0.f;
-  }
-  const uint64 cpu_times = nice + system + user;
-  const uint64 total_times = cpu_times + idle;
-#endif  // defined(LINUX) || defined(ANDROID)
-  system_.prev_load_time_ = timenow;
-  system_.prev_load_ = UpdateCpuLoad(total_times,
-                                     cpu_times * cpus_,
-                                     &system_.prev_total_times_,
-                                     &system_.prev_cpu_times_);
-  return system_.prev_load_;
-}
-
-float CpuSampler::GetProcessLoad() {
-  uint32 timenow = Time();
-  int elapsed = static_cast<int>(TimeDiff(timenow, process_.prev_load_time_));
-  if (min_load_interval_ != 0 && process_.prev_load_time_ != 0u &&
-      elapsed < min_load_interval_) {
-    return process_.prev_load_;
-  }
-#ifdef WIN32
-  FILETIME current_file_time;
-  ::GetSystemTimeAsFileTime(&current_file_time);
-
-  FILETIME create_time, exit_time, kernel_time, user_time;
-  if (!::GetProcessTimes(::GetCurrentProcess(),
-                         &create_time, &exit_time, &kernel_time, &user_time)) {
-    LOG(LS_ERROR) << "::GetProcessTimes() failed: " << ::GetLastError();
-    return 0.f;
-  }
-
-  const uint64 total_times =
-      ToUInt64(current_file_time) - ToUInt64(create_time);
-  const uint64 cpu_times =
-      (ToUInt64(kernel_time) + ToUInt64(user_time));
-#endif  // WIN32
-
-#ifdef POSIX
-  // Common to both OSX and Linux.
-  struct timeval tv;
-  gettimeofday(&tv, NULL);
-  const uint64 total_times = tv.tv_sec * kNumMicrosecsPerSec + tv.tv_usec;
-#endif
-
-#if defined(IOS) || defined(OSX)
-  // Get live thread usage.
-  task_thread_times_info task_times_info;
-  mach_msg_type_number_t info_count = TASK_THREAD_TIMES_INFO_COUNT;
-
-  if (KERN_SUCCESS != task_info(mach_task_self(), TASK_THREAD_TIMES_INFO,
-                                reinterpret_cast<task_info_t>(&task_times_info),
-                                &info_count)) {
-    LOG(LS_ERROR) << "::task_info(TASK_THREAD_TIMES_INFO) failed";
-    return 0.f;
-  }
-
-  // Get terminated thread usage.
-  task_basic_info task_term_info;
-  info_count = TASK_BASIC_INFO_COUNT;
-  if (KERN_SUCCESS != task_info(mach_task_self(), TASK_BASIC_INFO,
-                                reinterpret_cast<task_info_t>(&task_term_info),
-                                &info_count)) {
-    LOG(LS_ERROR) << "::task_info(TASK_BASIC_INFO) failed";
-    return 0.f;
-  }
-
-  const uint64 cpu_times = (TimeValueTToInt64(task_times_info.user_time) +
-      TimeValueTToInt64(task_times_info.system_time) +
-      TimeValueTToInt64(task_term_info.user_time) +
-      TimeValueTToInt64(task_term_info.system_time));
-#endif  // defined(IOS) || defined(OSX)
-
-#if defined(LINUX) || defined(ANDROID)
-  rusage usage;
-  if (getrusage(RUSAGE_SELF, &usage) < 0) {
-    LOG_ERR(LS_ERROR) << "getrusage failed";
-    return 0.f;
-  }
-
-  const uint64 cpu_times =
-      (usage.ru_utime.tv_sec + usage.ru_stime.tv_sec) * kNumMicrosecsPerSec +
-      usage.ru_utime.tv_usec + usage.ru_stime.tv_usec;
-#endif  // defined(LINUX) || defined(ANDROID)
-  process_.prev_load_time_ = timenow;
-  process_.prev_load_ = UpdateCpuLoad(total_times,
-                                     cpu_times,
-                                     &process_.prev_total_times_,
-                                     &process_.prev_cpu_times_);
-  return process_.prev_load_;
-}
-
-int CpuSampler::GetMaxCpus() const {
-  return cpus_;
-}
-
-int CpuSampler::GetCurrentCpus() {
-  return sysinfo_->GetCurCpus();
-}
-
-///////////////////////////////////////////////////////////////////
-// Implementation of class CpuMonitor.
-CpuMonitor::CpuMonitor(Thread* thread)
-    : monitor_thread_(thread ? thread : Thread::Current()) {
-  monitor_thread_->SignalQueueDestroyed.connect(
-      this, &CpuMonitor::OnMessageQueueDestroyed);
-}
-
-CpuMonitor::~CpuMonitor() {
-  Stop();
-}
-
-bool CpuMonitor::Start(int period_ms) {
-  if (!sampler_.Init()) return false;
-
-  period_ms_ = period_ms;
-  if (monitor_thread_) {
-    monitor_thread_->PostDelayed(period_ms_, this);
-  }
-  return true;
-}
-
-void CpuMonitor::Stop() {
-  if (monitor_thread_) {
-    monitor_thread_->Clear(this);
-  }
-}
-
-void CpuMonitor::OnMessage(Message* msg) {
-  int max_cpus = sampler_.GetMaxCpus();
-  int current_cpus = sampler_.GetCurrentCpus();
-  float process_load = sampler_.GetProcessLoad();
-  float system_load = sampler_.GetSystemLoad();
-  SignalUpdate(current_cpus, max_cpus, process_load, system_load);
-
-  if (monitor_thread_) {
-    monitor_thread_->PostDelayed(period_ms_, this);
-  }
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/cpumonitor.h b/third_party/libjingle/source/talk/base/cpumonitor.h
deleted file mode 100644
index f633f50..0000000
--- a/third_party/libjingle/source/talk/base/cpumonitor.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * libjingle
- * Copyright 2010 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_CPUMONITOR_H_
-#define TALK_BASE_CPUMONITOR_H_
-
-#include "talk/base/basictypes.h"
-#include "talk/base/messagehandler.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/base/sigslot.h"
-#if defined(LINUX) || defined(ANDROID)
-#include "talk/base/stream.h"
-#endif // defined(LINUX) || defined(ANDROID)
-
-namespace talk_base {
-class Thread;
-class SystemInfo;
-
-struct CpuStats {
-  CpuStats()
-      : prev_total_times_(0),
-        prev_cpu_times_(0),
-        prev_load_(0.f),
-        prev_load_time_(0u) {
-  }
-
-  uint64 prev_total_times_;
-  uint64 prev_cpu_times_;
-  float prev_load_;  // Previous load value.
-  uint32 prev_load_time_;  // Time previous load value was taken.
-};
-
-// CpuSampler samples the process and system load.
-class CpuSampler {
- public:
-  CpuSampler();
-  ~CpuSampler();
-
-  // Initialize CpuSampler.  Returns true if successful.
-  bool Init();
-
-  // Set minimum interval in ms between computing new load values.
-  // Default 950 ms.  Set to 0 to disable interval.
-  void set_load_interval(int min_load_interval);
-
-  // Return CPU load of current process as a float from 0 to 1.
-  float GetProcessLoad();
-
-  // Return CPU load of current process as a float from 0 to 1.
-  float GetSystemLoad();
-
-  // Return number of cpus. Includes hyperthreads.
-  int GetMaxCpus() const;
-
-  // Return current number of cpus available to this process.
-  int GetCurrentCpus();
-
-  // For testing. Allows forcing of fallback to using NTDLL functions.
-  void set_force_fallback(bool fallback) {
-#ifdef WIN32
-    force_fallback_ = fallback;
-#endif
-  }
-
- private:
-  float UpdateCpuLoad(uint64 current_total_times,
-                      uint64 current_cpu_times,
-                      uint64 *prev_total_times,
-                      uint64 *prev_cpu_times);
-  CpuStats process_;
-  CpuStats system_;
-  int cpus_;
-  int min_load_interval_;  // Minimum time between computing new load.
-  scoped_ptr<SystemInfo> sysinfo_;
-#ifdef WIN32
-  void* get_system_times_;
-  void* nt_query_system_information_;
-  bool force_fallback_;
-#endif
-#if defined(LINUX) || defined(ANDROID)
-  // File for reading /proc/stat
-  scoped_ptr<FileStream> sfile_;
-#endif // defined(LINUX) || defined(ANDROID)
-};
-
-// CpuMonitor samples and signals the CPU load periodically.
-class CpuMonitor
-    : public talk_base::MessageHandler, public sigslot::has_slots<> {
- public:
-  explicit CpuMonitor(Thread* thread);
-  virtual ~CpuMonitor();
-
-  bool Start(int period_ms);
-  void Stop();
-  // Signal parameters are current cpus, max cpus, process load and system load.
-  sigslot::signal4<int, int, float, float> SignalUpdate;
-
- protected:
-  // Override virtual method of parent MessageHandler.
-  virtual void OnMessage(talk_base::Message* msg);
-  // Clear the monitor thread and stop sending it messages if the thread goes
-  // away before our lifetime.
-  void OnMessageQueueDestroyed() { monitor_thread_ = NULL; }
-
- private:
-  Thread* monitor_thread_;
-  CpuSampler sampler_;
-  int period_ms_;
-
-  DISALLOW_COPY_AND_ASSIGN(CpuMonitor);
-};
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_CPUMONITOR_H_
diff --git a/third_party/libjingle/source/talk/base/cpumonitor_unittest.cc b/third_party/libjingle/source/talk/base/cpumonitor_unittest.cc
deleted file mode 100644
index e83c969..0000000
--- a/third_party/libjingle/source/talk/base/cpumonitor_unittest.cc
+++ /dev/null
@@ -1,401 +0,0 @@
-/*
- * libjingle
- * Copyright 2010 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <iomanip>
-#include <iostream>
-#include <vector>
-
-#ifdef WIN32
-#include "talk/base/win32.h"
-#endif
-
-#include "talk/base/cpumonitor.h"
-#include "talk/base/flags.h"
-#include "talk/base/gunit.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/base/thread.h"
-#include "talk/base/timeutils.h"
-#include "talk/base/timing.h"
-
-namespace talk_base {
-
-static const int kMaxCpus = 1024;
-static const int kSettleTime = 100;  // Amount of time to between tests.
-static const int kIdleTime = 500;  // Amount of time to be idle in ms.
-static const int kBusyTime = 1000;  // Amount of time to be busy in ms.
-
-class BusyThread : public talk_base::Thread {
- public:
-  BusyThread(double load, double duration, double interval) :
-    load_(load), duration_(duration), interval_(interval) {
-  }
-  void Run() {
-    Timing time;
-    double busy_time = interval_ * load_ / 100.0;
-    for (;;) {
-      time.BusyWait(busy_time);
-      time.IdleWait(interval_ - busy_time);
-      if (duration_) {
-        duration_ -= interval_;
-        if (duration_ <= 0) {
-          break;
-        }
-      }
-    }
-  }
- private:
-  double load_;
-  double duration_;
-  double interval_;
-};
-
-class CpuLoadListener : public sigslot::has_slots<> {
- public:
-  CpuLoadListener()
-      : current_cpus_(0),
-        cpus_(0),
-        process_load_(.0f),
-        system_load_(.0f),
-        count_(0) {
-  }
-
-  void OnCpuLoad(int current_cpus, int cpus, float proc_load, float sys_load) {
-    current_cpus_ = current_cpus;
-    cpus_ = cpus;
-    process_load_ = proc_load;
-    system_load_ = sys_load;
-    ++count_;
-  }
-
-  int current_cpus() const { return current_cpus_; }
-  int cpus() const { return cpus_; }
-  float process_load() const { return process_load_; }
-  float system_load() const { return system_load_; }
-  int count() const { return count_; }
-
- private:
-  int current_cpus_;
-  int cpus_;
-  float process_load_;
-  float system_load_;
-  int count_;
-};
-
-// Set affinity (which cpu to run on), but respecting FLAG_affinity:
-// -1 means no affinity - run on whatever cpu is available.
-// 0 .. N means run on specific cpu.  The tool will create N threads and call
-//   SetThreadAffinity on 0 to N - 1 as cpu.  FLAG_affinity sets the first cpu
-//   so the range becomes affinity to affinity + N - 1
-// Note that this function affects Windows scheduling, effectively giving
-//   the thread with affinity for a specified CPU more priority on that CPU.
-bool SetThreadAffinity(BusyThread* t, int cpu, int affinity) {
-#ifdef WIN32
-  if (affinity >= 0) {
-    return ::SetThreadAffinityMask(t->GetHandle(),
-        1 << (cpu + affinity)) != FALSE;
-  }
-#endif
-  return true;
-}
-
-bool SetThreadPriority(BusyThread* t, int prio) {
-  if (!prio) {
-    return true;
-  }
-  bool ok = t->SetPriority(static_cast<talk_base::ThreadPriority>(prio));
-  if (!ok) {
-    std::cout << "Error setting thread priority." << std::endl;
-  }
-  return ok;
-}
-
-int CpuLoad(double cpuload, double duration, int numthreads,
-            int priority, double interval, int affinity) {
-  int ret = 0;
-  std::vector<BusyThread*> threads;
-  for (int i = 0; i < numthreads; ++i) {
-    threads.push_back(new BusyThread(cpuload, duration, interval));
-    // NOTE(fbarchard): Priority must be done before Start.
-    if (!SetThreadPriority(threads[i], priority) ||
-       !threads[i]->Start() ||
-       !SetThreadAffinity(threads[i], i, affinity)) {
-      ret = 1;
-      break;
-    }
-  }
-  // Wait on each thread
-  if (ret == 0) {
-    for (int i = 0; i < numthreads; ++i) {
-      threads[i]->Stop();
-    }
-  }
-
-  for (int i = 0; i < numthreads; ++i) {
-    delete threads[i];
-  }
-  return ret;
-}
-
-// Make 2 CPUs busy
-static void CpuTwoBusyLoop(int busytime) {
-  CpuLoad(100.0, busytime / 1000.0, 2, 1, 0.050, -1);
-}
-
-// Make 1 CPUs busy
-static void CpuBusyLoop(int busytime) {
-  CpuLoad(100.0, busytime / 1000.0, 1, 1, 0.050, -1);
-}
-
-// Make 1 use half CPU time.
-static void CpuHalfBusyLoop(int busytime) {
-  CpuLoad(50.0, busytime / 1000.0, 1, 1, 0.050, -1);
-}
-
-void TestCpuSampler(bool test_proc, bool test_sys, bool force_fallback) {
-  CpuSampler sampler;
-  sampler.set_force_fallback(force_fallback);
-  EXPECT_TRUE(sampler.Init());
-  sampler.set_load_interval(100);
-  int cpus = sampler.GetMaxCpus();
-
-  // Test1: CpuSampler under idle situation.
-  Thread::SleepMs(kSettleTime);
-  sampler.GetProcessLoad();
-  sampler.GetSystemLoad();
-
-  Thread::SleepMs(kIdleTime);
-
-  float proc_idle = 0.f, sys_idle = 0.f;
-  if (test_proc) {
-    proc_idle = sampler.GetProcessLoad();
-  }
-  if (test_sys) {
-      sys_idle = sampler.GetSystemLoad();
-  }
-  if (test_proc) {
-    LOG(LS_INFO) << "ProcessLoad Idle:      "
-                 << setiosflags(std::ios_base::fixed)
-                 << std::setprecision(2) << std::setw(6) << proc_idle;
-    EXPECT_GE(proc_idle, 0.f);
-    EXPECT_LE(proc_idle, static_cast<float>(cpus));
-  }
-  if (test_sys) {
-    LOG(LS_INFO) << "SystemLoad Idle:       "
-                 << setiosflags(std::ios_base::fixed)
-                 << std::setprecision(2) << std::setw(6) << sys_idle;
-    EXPECT_GE(sys_idle, 0.f);
-    EXPECT_LE(sys_idle, static_cast<float>(cpus));
-  }
-
-  // Test2: CpuSampler with main process at 50% busy.
-  Thread::SleepMs(kSettleTime);
-  sampler.GetProcessLoad();
-  sampler.GetSystemLoad();
-
-  CpuHalfBusyLoop(kBusyTime);
-
-  float proc_halfbusy = 0.f, sys_halfbusy = 0.f;
-  if (test_proc) {
-    proc_halfbusy = sampler.GetProcessLoad();
-  }
-  if (test_sys) {
-    sys_halfbusy = sampler.GetSystemLoad();
-  }
-  if (test_proc) {
-    LOG(LS_INFO) << "ProcessLoad Halfbusy:  "
-                 << setiosflags(std::ios_base::fixed)
-                 << std::setprecision(2) << std::setw(6) << proc_halfbusy;
-    EXPECT_GE(proc_halfbusy, 0.f);
-    EXPECT_LE(proc_halfbusy, static_cast<float>(cpus));
-  }
-  if (test_sys) {
-    LOG(LS_INFO) << "SystemLoad Halfbusy:   "
-                 << setiosflags(std::ios_base::fixed)
-                 << std::setprecision(2) << std::setw(6) << sys_halfbusy;
-    EXPECT_GE(sys_halfbusy, 0.f);
-    EXPECT_LE(sys_halfbusy, static_cast<float>(cpus));
-  }
-
-  // Test3: CpuSampler with main process busy.
-  Thread::SleepMs(kSettleTime);
-  sampler.GetProcessLoad();
-  sampler.GetSystemLoad();
-
-  CpuBusyLoop(kBusyTime);
-
-  float proc_busy = 0.f, sys_busy = 0.f;
-  if (test_proc) {
-    proc_busy = sampler.GetProcessLoad();
-  }
-  if (test_sys) {
-    sys_busy = sampler.GetSystemLoad();
-  }
-  if (test_proc) {
-    LOG(LS_INFO) << "ProcessLoad Busy:      "
-                 << setiosflags(std::ios_base::fixed)
-                 << std::setprecision(2) << std::setw(6) << proc_busy;
-    EXPECT_GE(proc_busy, 0.f);
-    EXPECT_LE(proc_busy, static_cast<float>(cpus));
-  }
-  if (test_sys) {
-    LOG(LS_INFO) << "SystemLoad Busy:       "
-                 << setiosflags(std::ios_base::fixed)
-                 << std::setprecision(2) << std::setw(6) << sys_busy;
-    EXPECT_GE(sys_busy, 0.f);
-    EXPECT_LE(sys_busy, static_cast<float>(cpus));
-  }
-
-  // Test4: CpuSampler with 2 cpus process busy.
-  if (cpus >= 2) {
-    Thread::SleepMs(kSettleTime);
-    sampler.GetProcessLoad();
-    sampler.GetSystemLoad();
-
-    CpuTwoBusyLoop(kBusyTime);
-
-    float proc_twobusy = 0.f, sys_twobusy = 0.f;
-    if (test_proc) {
-      proc_twobusy = sampler.GetProcessLoad();
-    }
-    if (test_sys) {
-      sys_twobusy = sampler.GetSystemLoad();
-    }
-    if (test_proc) {
-      LOG(LS_INFO) << "ProcessLoad 2 CPU Busy:"
-                   << setiosflags(std::ios_base::fixed)
-                   << std::setprecision(2) << std::setw(6) << proc_twobusy;
-      EXPECT_GE(proc_twobusy, 0.f);
-      EXPECT_LE(proc_twobusy, static_cast<float>(cpus));
-    }
-    if (test_sys) {
-      LOG(LS_INFO) << "SystemLoad 2 CPU Busy: "
-                   << setiosflags(std::ios_base::fixed)
-                   << std::setprecision(2) << std::setw(6) << sys_twobusy;
-      EXPECT_GE(sys_twobusy, 0.f);
-      EXPECT_LE(sys_twobusy, static_cast<float>(cpus));
-    }
-  }
-
-  // Test5: CpuSampler with idle process after being busy.
-  Thread::SleepMs(kSettleTime);
-  sampler.GetProcessLoad();
-  sampler.GetSystemLoad();
-
-  Thread::SleepMs(kIdleTime);
-
-  if (test_proc) {
-    proc_idle = sampler.GetProcessLoad();
-  }
-  if (test_sys) {
-    sys_idle = sampler.GetSystemLoad();
-  }
-  if (test_proc) {
-    LOG(LS_INFO) << "ProcessLoad Idle:      "
-                 << setiosflags(std::ios_base::fixed)
-                 << std::setprecision(2) << std::setw(6) << proc_idle;
-    EXPECT_GE(proc_idle, 0.f);
-    EXPECT_LE(proc_idle, proc_busy);
-  }
-  if (test_sys) {
-    LOG(LS_INFO) << "SystemLoad Idle:       "
-                 << setiosflags(std::ios_base::fixed)
-                 << std::setprecision(2) << std::setw(6) << sys_idle;
-    EXPECT_GE(sys_idle, 0.f);
-    EXPECT_LE(sys_idle, static_cast<float>(cpus));
-  }
-}
-
-TEST(CpuMonitorTest, TestCpus) {
-  CpuSampler sampler;
-  EXPECT_TRUE(sampler.Init());
-  int current_cpus = sampler.GetCurrentCpus();
-  int cpus = sampler.GetMaxCpus();
-  LOG(LS_INFO) << "Current Cpus:     " << std::setw(9) << current_cpus;
-  LOG(LS_INFO) << "Maximum Cpus:     " << std::setw(9) << cpus;
-  EXPECT_GT(cpus, 0);
-  EXPECT_LE(cpus, kMaxCpus);
-  EXPECT_GT(current_cpus, 0);
-  EXPECT_LE(current_cpus, cpus);
-}
-
-#ifdef WIN32
-// Tests overall system CpuSampler using legacy OS fallback code if applicable.
-TEST(CpuMonitorTest, TestGetSystemLoadForceFallback) {
-  TestCpuSampler(false, true, true);
-}
-#endif
-
-// Tests both process and system functions in use at same time.
-TEST(CpuMonitorTest, TestGetBothLoad) {
-  TestCpuSampler(true, true, false);
-}
-
-// Tests a query less than the interval produces the same value.
-TEST(CpuMonitorTest, TestInterval) {
-  CpuSampler sampler;
-  EXPECT_TRUE(sampler.Init());
-
-  // Test1: Interval of 500 ms
-  sampler.set_load_interval(500);
-
-  sampler.GetProcessLoad();
-  sampler.GetSystemLoad();
-
-  float proc_orig = sampler.GetProcessLoad();
-  float sys_orig = sampler.GetSystemLoad();
-
-  CpuBusyLoop(200);
-
-  float proc_halftime = sampler.GetProcessLoad();
-  float sys_halftime = sampler.GetSystemLoad();
-
-  EXPECT_EQ(proc_orig, proc_halftime);
-  EXPECT_EQ(sys_orig, sys_halftime);
-}
-
-TEST(CpuMonitorTest, TestCpuMonitor) {
-  CpuMonitor monitor(Thread::Current());
-  CpuLoadListener listener;
-  monitor.SignalUpdate.connect(&listener, &CpuLoadListener::OnCpuLoad);
-  EXPECT_TRUE(monitor.Start(10));
-  Thread::Current()->ProcessMessages(50);
-  EXPECT_GT(listener.count(), 2);  // We have checked cpu load more than twice.
-  EXPECT_GT(listener.current_cpus(), 0);
-  EXPECT_GT(listener.cpus(), 0);
-  EXPECT_GE(listener.process_load(), .0f);
-  EXPECT_GE(listener.system_load(), .0f);
-
-  monitor.Stop();
-  // Wait 20 ms to ake sure all signals are delivered.
-  Thread::Current()->ProcessMessages(20);
-  int old_count = listener.count();
-  Thread::Current()->ProcessMessages(20);
-  // Verfy no more siganls.
-  EXPECT_EQ(old_count, listener.count());
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/criticalsection.h b/third_party/libjingle/source/talk/base/criticalsection.h
deleted file mode 100644
index 5a09a93..0000000
--- a/third_party/libjingle/source/talk/base/criticalsection.h
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_CRITICALSECTION_H__
-#define TALK_BASE_CRITICALSECTION_H__
-
-#ifdef WIN32
-#include "talk/base/win32.h"
-#endif
-
-#ifdef POSIX
-#include <pthread.h>
-#endif
-
-#ifdef _DEBUG
-#define CS_TRACK_OWNER 1
-#endif  // _DEBUG
-
-#if CS_TRACK_OWNER
-#define TRACK_OWNER(x) x
-#else  // !CS_TRACK_OWNER
-#define TRACK_OWNER(x)
-#endif  // !CS_TRACK_OWNER
-
-namespace talk_base {
-
-#ifdef WIN32
-class CriticalSection {
-public:
-  CriticalSection() {
-    InitializeCriticalSection(&crit_);
-    // Windows docs say 0 is not a valid thread id
-    TRACK_OWNER(thread_ = 0);
-  }
-  ~CriticalSection() {
-    DeleteCriticalSection(&crit_);
-  }
-  void Enter() {
-    EnterCriticalSection(&crit_);
-    TRACK_OWNER(thread_ = GetCurrentThreadId());
-  }
-  bool TryEnter() {
-    if (TryEnterCriticalSection(&crit_) != FALSE) {
-      TRACK_OWNER(thread_ = GetCurrentThreadId());
-      return true;
-    }
-    return false;
-  }
-  void Leave() {
-    TRACK_OWNER(thread_ = 0);
-    LeaveCriticalSection(&crit_);
-  }
-
-#if CS_TRACK_OWNER
-  bool CurrentThreadIsOwner() const { return thread_ == GetCurrentThreadId(); }
-#endif  // CS_TRACK_OWNER
-
-private:
-  CRITICAL_SECTION crit_;
-  TRACK_OWNER(DWORD thread_);  // The section's owning thread id
-};
-#endif // WIN32
-
-#ifdef POSIX
-class CriticalSection {
-public:
-  CriticalSection() {
-    pthread_mutexattr_t mutex_attribute;
-    pthread_mutexattr_init(&mutex_attribute);
-    pthread_mutexattr_settype(&mutex_attribute, PTHREAD_MUTEX_RECURSIVE);
-    pthread_mutex_init(&mutex_, &mutex_attribute);
-    pthread_mutexattr_destroy(&mutex_attribute);
-    TRACK_OWNER(thread_ = 0);
-  }
-  ~CriticalSection() {
-    pthread_mutex_destroy(&mutex_);
-  }
-  void Enter() {
-    pthread_mutex_lock(&mutex_);
-    TRACK_OWNER(thread_ = pthread_self());
-  }
-  bool TryEnter() {
-    if (pthread_mutex_trylock(&mutex_) == 0) {
-      TRACK_OWNER(thread_ = pthread_self());
-      return true;
-    }
-    return false;
-  }
-  void Leave() {
-    TRACK_OWNER(thread_ = 0);
-    pthread_mutex_unlock(&mutex_);
-  }
-
-#if CS_TRACK_OWNER
-  bool CurrentThreadIsOwner() const { return pthread_equal(thread_, pthread_self()); }
-#endif  // CS_TRACK_OWNER
-
-private:
-  pthread_mutex_t mutex_;
-  TRACK_OWNER(pthread_t thread_);
-};
-#endif // POSIX
-
-// CritScope, for serializing exection through a scope
-
-class CritScope {
-public:
-  CritScope(CriticalSection *pcrit) {
-    pcrit_ = pcrit;
-    pcrit_->Enter();
-  }
-  ~CritScope() {
-    pcrit_->Leave();
-  }
-private:
-  CriticalSection *pcrit_;
-};
-
-// TODO: Replace with platform-specific "atomic" ops.
-// Something like: google3/base/atomicops.h TODO: And, move
-// it to atomicops.h, which can't be done easily because of complex
-// compile rules.
-class AtomicOps {
- public:
-#ifdef WIN32
-  // Assumes sizeof(int) == sizeof(LONG), which it is on Win32 and Win64.
-  static int Increment(int* i) {
-    return ::InterlockedIncrement(reinterpret_cast<LONG*>(i));
-  }
-  static int Decrement(int* i) {
-    return ::InterlockedDecrement(reinterpret_cast<LONG*>(i));
-  }
-#else
-  static int Increment(int* i) {
-    // Could be faster, and less readable:
-    // static CriticalSection* crit = StaticCrit();
-    // CritScope scope(crit);
-    CritScope scope(StaticCrit());
-    return ++(*i);
-  }
-
-  static int Decrement(int* i) {
-    // Could be faster, and less readable:
-    // static CriticalSection* crit = StaticCrit();
-    // CritScope scope(crit);
-    CritScope scope(StaticCrit());
-    return --(*i);
-  }
-
- private:
-  static CriticalSection* StaticCrit() {
-    static CriticalSection* crit = new CriticalSection();
-    return crit;
-  }
-#endif
-};
-
-} // namespace talk_base
-
-#endif // TALK_BASE_CRITICALSECTION_H__
diff --git a/third_party/libjingle/source/talk/base/cryptstring.h b/third_party/libjingle/source/talk/base/cryptstring.h
deleted file mode 100644
index eb39be2..0000000
--- a/third_party/libjingle/source/talk/base/cryptstring.h
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _TALK_BASE_CRYPTSTRING_H_
-#define _TALK_BASE_CRYPTSTRING_H_
-
-#include <cstring>
-#include <string>
-#include <vector>
-#include "talk/base/linked_ptr.h"
-#include "talk/base/scoped_ptr.h"
-
-namespace talk_base {
-
-class CryptStringImpl {
-public:
-  virtual ~CryptStringImpl() {}
-  virtual size_t GetLength() const = 0;
-  virtual void CopyTo(char * dest, bool nullterminate) const = 0;
-  virtual std::string UrlEncode() const = 0;
-  virtual CryptStringImpl * Copy() const = 0;
-  virtual void CopyRawTo(std::vector<unsigned char> * dest) const = 0;
-};
-
-class EmptyCryptStringImpl : public CryptStringImpl {
-public:
-  virtual ~EmptyCryptStringImpl() {}
-  virtual size_t GetLength() const { return 0; }
-  virtual void CopyTo(char * dest, bool nullterminate) const {
-    if (nullterminate) {
-      *dest = '\0';
-    }
-  }
-  virtual std::string UrlEncode() const { return ""; }
-  virtual CryptStringImpl * Copy() const { return new EmptyCryptStringImpl(); }
-  virtual void CopyRawTo(std::vector<unsigned char> * dest) const {
-    dest->clear();
-  }
-};
-
-class CryptString {
-public:
-  CryptString() : impl_(new EmptyCryptStringImpl()) {}
-  size_t GetLength() const { return impl_->GetLength(); }
-  void CopyTo(char * dest, bool nullterminate) const { impl_->CopyTo(dest, nullterminate); }
-  CryptString(const CryptString & other) : impl_(other.impl_->Copy()) {}
-  explicit CryptString(const CryptStringImpl & impl) : impl_(impl.Copy()) {}
-  CryptString & operator=(const CryptString & other) {
-    if (this != &other) {
-      impl_.reset(other.impl_->Copy());
-    }
-    return *this;
-  }
-  void Clear() { impl_.reset(new EmptyCryptStringImpl()); }
-  std::string UrlEncode() const { return impl_->UrlEncode(); }
-  void CopyRawTo(std::vector<unsigned char> * dest) const {
-    return impl_->CopyRawTo(dest);
-  }
-  
-private:
-  scoped_ptr<const CryptStringImpl> impl_;
-};
-
-
-// Used for constructing strings where a password is involved and we
-// need to ensure that we zero memory afterwards
-class FormatCryptString {
-public:
-  FormatCryptString() {
-    storage_ = new char[32];
-    capacity_ = 32;
-    length_ = 0;
-    storage_[0] = 0;
-  }
-  
-  void Append(const std::string & text) {
-    Append(text.data(), text.length());
-  }
-
-  void Append(const char * data, size_t length) {
-    EnsureStorage(length_ + length + 1);
-    memcpy(storage_ + length_, data, length);
-    length_ += length;
-    storage_[length_] = '\0';
-  }
-  
-  void Append(const CryptString * password) {
-    size_t len = password->GetLength();
-    EnsureStorage(length_ + len + 1);
-    password->CopyTo(storage_ + length_, true);
-    length_ += len;
-  }
-
-  size_t GetLength() {
-    return length_;
-  }
-
-  const char * GetData() {
-    return storage_;
-  }
-
-
-  // Ensures storage of at least n bytes
-  void EnsureStorage(size_t n) {
-    if (capacity_ >= n) {
-      return;
-    }
-
-    size_t old_capacity = capacity_;
-    char * old_storage = storage_;
-
-    for (;;) {
-      capacity_ *= 2;
-      if (capacity_ >= n)
-        break;
-    }
-
-    storage_ = new char[capacity_];
-
-    if (old_capacity) {
-      memcpy(storage_, old_storage, length_);
-    
-      // zero memory in a way that an optimizer won't optimize it out
-      old_storage[0] = 0;
-      for (size_t i = 1; i < old_capacity; i++) {
-        old_storage[i] = old_storage[i - 1];
-      }
-      delete[] old_storage;
-    }
-  }  
-
-  ~FormatCryptString() {
-    if (capacity_) {
-      storage_[0] = 0;
-      for (size_t i = 1; i < capacity_; i++) {
-        storage_[i] = storage_[i - 1];
-      }
-    }
-    delete[] storage_;
-  }
-private:
-  char * storage_;
-  size_t capacity_;
-  size_t length_;
-};
-
-class InsecureCryptStringImpl : public CryptStringImpl {
- public:
-  std::string& password() { return password_; }
-  const std::string& password() const { return password_; }
-
-  virtual ~InsecureCryptStringImpl() {}
-  virtual size_t GetLength() const { return password_.size(); }
-  virtual void CopyTo(char * dest, bool nullterminate) const {
-    memcpy(dest, password_.data(), password_.size());
-    if (nullterminate) dest[password_.size()] = 0;
-  }
-  virtual std::string UrlEncode() const { return password_; }
-  virtual CryptStringImpl * Copy() const {
-    InsecureCryptStringImpl * copy = new InsecureCryptStringImpl;
-    copy->password() = password_;
-    return copy;
-  }
-  virtual void CopyRawTo(std::vector<unsigned char> * dest) const {
-    dest->resize(password_.size());
-    memcpy(&dest->front(), password_.data(), password_.size());
-  }
- private:
-  std::string password_;
-};
-
-}
-
-#endif  // _TALK_BASE_CRYPTSTRING_H_
diff --git a/third_party/libjingle/source/talk/base/diskcache.cc b/third_party/libjingle/source/talk/base/diskcache.cc
deleted file mode 100644
index afaf9d2..0000000
--- a/third_party/libjingle/source/talk/base/diskcache.cc
+++ /dev/null
@@ -1,364 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <time.h>
-
-#ifdef WIN32
-#include "talk/base/win32.h"
-#endif
-
-#include "talk/base/common.h"
-#include "talk/base/diskcache.h"
-#include "talk/base/fileutils.h"
-#include "talk/base/pathutils.h"
-#include "talk/base/stream.h"
-#include "talk/base/stringencode.h"
-#include "talk/base/stringutils.h"
-
-#ifdef _DEBUG
-#define TRANSPARENT_CACHE_NAMES 1
-#else  // !_DEBUG
-#define TRANSPARENT_CACHE_NAMES 0
-#endif  // !_DEBUG
-
-namespace talk_base {
-
-class DiskCache;
-
-///////////////////////////////////////////////////////////////////////////////
-// DiskCacheAdapter
-///////////////////////////////////////////////////////////////////////////////
-
-class DiskCacheAdapter : public StreamAdapterInterface {
-public:
-  DiskCacheAdapter(const DiskCache* cache, const std::string& id, size_t index,
-                   StreamInterface* stream)
-  : StreamAdapterInterface(stream), cache_(cache), id_(id), index_(index)
-  { }
-  virtual ~DiskCacheAdapter() {
-    Close();
-    cache_->ReleaseResource(id_, index_);
-  }
-
-private:
-  const DiskCache* cache_;
-  std::string id_;
-  size_t index_;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// DiskCache
-///////////////////////////////////////////////////////////////////////////////
-
-DiskCache::DiskCache() : max_cache_(0), total_size_(0), total_accessors_(0) {
-}
-
-DiskCache::~DiskCache() {
-  ASSERT(0 == total_accessors_);
-}
-
-bool DiskCache::Initialize(const std::string& folder, size_t size) {
-  if (!folder_.empty() || !Filesystem::CreateFolder(folder))
-    return false;
-
-  folder_ = folder;
-  max_cache_ = size;
-  ASSERT(0 == total_size_);
-
-  if (!InitializeEntries())
-    return false;
-
-  return CheckLimit();
-}
-
-bool DiskCache::Purge() {
-  if (folder_.empty())
-    return false;
-
-  if (total_accessors_ > 0) {
-    LOG_F(LS_WARNING) << "Cache files open";
-    return false;
-  }
-
-  if (!PurgeFiles())
-    return false;
-
-  map_.clear();
-  return true;
-}
-
-bool DiskCache::LockResource(const std::string& id) {
-  Entry* entry = GetOrCreateEntry(id, true);
-  if (LS_LOCKED == entry->lock_state)
-    return false;
-  if ((LS_UNLOCKED == entry->lock_state) && (entry->accessors > 0))
-    return false;
-  if ((total_size_ > max_cache_) && !CheckLimit()) {
-    LOG_F(LS_WARNING) << "Cache overfull";
-    return false;
-  }
-  entry->lock_state = LS_LOCKED;
-  return true;
-}
-
-StreamInterface* DiskCache::WriteResource(const std::string& id, size_t index) {
-  Entry* entry = GetOrCreateEntry(id, false);
-  if (LS_LOCKED != entry->lock_state)
-    return NULL;
-
-  size_t previous_size = 0;
-  std::string filename(IdToFilename(id, index));
-  FileStream::GetSize(filename, &previous_size);
-  ASSERT(previous_size <= entry->size);
-  if (previous_size > entry->size) {
-    previous_size = entry->size;
-  }
-
-  scoped_ptr<FileStream> file(new FileStream);
-  if (!file->Open(filename, "wb", NULL)) {
-    LOG_F(LS_ERROR) << "Couldn't create cache file";
-    return NULL;
-  }
-
-  entry->streams = stdmax(entry->streams, index + 1);
-  entry->size -= previous_size;
-  total_size_ -= previous_size;
-
-  entry->accessors += 1;
-  total_accessors_ += 1;
-  return new DiskCacheAdapter(this, id, index, file.release());
-}
-
-bool DiskCache::UnlockResource(const std::string& id) {
-  Entry* entry = GetOrCreateEntry(id, false);
-  if (LS_LOCKED != entry->lock_state)
-    return false;
-
-  if (entry->accessors > 0) {
-    entry->lock_state = LS_UNLOCKING;
-  } else {
-    entry->lock_state = LS_UNLOCKED;
-    entry->last_modified = time(0);
-    CheckLimit();
-  }
-  return true;
-}
-
-StreamInterface* DiskCache::ReadResource(const std::string& id,
-                                         size_t index) const {
-  const Entry* entry = GetEntry(id);
-  if (LS_UNLOCKED != entry->lock_state)
-    return NULL;
-  if (index >= entry->streams)
-    return NULL;
-
-  scoped_ptr<FileStream> file(new FileStream);
-  if (!file->Open(IdToFilename(id, index), "rb", NULL))
-    return NULL;
-
-  entry->accessors += 1;
-  total_accessors_ += 1;
-  return new DiskCacheAdapter(this, id, index, file.release());
-}
-
-bool DiskCache::HasResource(const std::string& id) const {
-  const Entry* entry = GetEntry(id);
-  return (NULL != entry) && (entry->streams > 0);
-}
-
-bool DiskCache::HasResourceStream(const std::string& id, size_t index) const {
-  const Entry* entry = GetEntry(id);
-  if ((NULL == entry) || (index >= entry->streams))
-    return false;
-
-  std::string filename = IdToFilename(id, index);
-
-  return FileExists(filename);
-}
-
-bool DiskCache::DeleteResource(const std::string& id) {
-  Entry* entry = GetOrCreateEntry(id, false);
-  if (!entry)
-    return true;
-
-  if ((LS_UNLOCKED != entry->lock_state) || (entry->accessors > 0))
-    return false;
-
-  bool success = true;
-  for (size_t index = 0; index < entry->streams; ++index) {
-    std::string filename = IdToFilename(id, index);
-
-    if (!FileExists(filename))
-      continue;
-
-    if (!DeleteFile(filename)) {
-      LOG_F(LS_ERROR) << "Couldn't remove cache file: " << filename;
-      success = false;
-    }
-  }
-
-  total_size_ -= entry->size;
-  map_.erase(id);
-  return success;
-}
-
-bool DiskCache::CheckLimit() {
-#ifdef _DEBUG
-  // Temporary check to make sure everything is working correctly.
-  size_t cache_size = 0;
-  for (EntryMap::iterator it = map_.begin(); it != map_.end(); ++it) {
-    cache_size += it->second.size;
-  }
-  ASSERT(cache_size == total_size_);
-#endif  // _DEBUG
-
-  // TODO: Replace this with a non-brain-dead algorithm for clearing out the
-  // oldest resources... something that isn't O(n^2)
-  while (total_size_ > max_cache_) {
-    EntryMap::iterator oldest = map_.end();
-    for (EntryMap::iterator it = map_.begin(); it != map_.end(); ++it) {
-      if ((LS_UNLOCKED != it->second.lock_state) || (it->second.accessors > 0))
-        continue;
-      oldest = it;
-      break;
-    }
-    if (oldest == map_.end()) {
-      LOG_F(LS_WARNING) << "All resources are locked!";
-      return false;
-    }
-    for (EntryMap::iterator it = oldest++; it != map_.end(); ++it) {
-      if (it->second.last_modified < oldest->second.last_modified) {
-        oldest = it;
-      }
-    }
-    if (!DeleteResource(oldest->first)) {
-      LOG_F(LS_ERROR) << "Couldn't delete from cache!";
-      return false;
-    }
-  }
-  return true;
-}
-
-std::string DiskCache::IdToFilename(const std::string& id, size_t index) const {
-#ifdef TRANSPARENT_CACHE_NAMES
-  // This escapes colons and other filesystem characters, so the user can't open
-  // special devices (like "COM1:"), or access other directories.
-  size_t buffer_size = id.length()*3 + 1;
-  char* buffer = new char[buffer_size];
-  encode(buffer, buffer_size, id.data(), id.length(),
-         unsafe_filename_characters(), '%');
-  // TODO: ASSERT(strlen(buffer) < FileSystem::MaxBasenameLength());
-#else  // !TRANSPARENT_CACHE_NAMES
-  // We might want to just use a hash of the filename at some point, both for
-  // obfuscation, and to avoid both filename length and escaping issues.
-  ASSERT(false);
-#endif  // !TRANSPARENT_CACHE_NAMES
-
-  char extension[32];
-  sprintfn(extension, ARRAY_SIZE(extension), ".%u", index);
-
-  Pathname pathname;
-  pathname.SetFolder(folder_);
-  pathname.SetBasename(buffer);
-  pathname.SetExtension(extension);
-
-#ifdef TRANSPARENT_CACHE_NAMES
-  delete [] buffer;
-#endif  // TRANSPARENT_CACHE_NAMES
-
-  return pathname.pathname();
-}
-
-bool DiskCache::FilenameToId(const std::string& filename, std::string* id,
-                             size_t* index) const {
-  Pathname pathname(filename);
-  unsigned tempdex;
-  if (1 != sscanf(pathname.extension().c_str(), ".%u", &tempdex))
-    return false;
-
-  *index = static_cast<size_t>(tempdex);
-
-  size_t buffer_size = pathname.basename().length() + 1;
-  char* buffer = new char[buffer_size];
-  decode(buffer, buffer_size, pathname.basename().data(),
-         pathname.basename().length(), '%');
-  id->assign(buffer);
-  delete [] buffer;
-  return true;
-}
-
-DiskCache::Entry* DiskCache::GetOrCreateEntry(const std::string& id,
-                                              bool create) {
-  EntryMap::iterator it = map_.find(id);
-  if (it != map_.end())
-    return &it->second;
-  if (!create)
-    return NULL;
-  Entry e;
-  e.lock_state = LS_UNLOCKED;
-  e.accessors = 0;
-  e.size = 0;
-  e.streams = 0;
-  e.last_modified = time(0);
-  it = map_.insert(EntryMap::value_type(id, e)).first;
-  return &it->second;
-}
-
-void DiskCache::ReleaseResource(const std::string& id, size_t index) const {
-  const Entry* entry = GetEntry(id);
-  if (!entry) {
-    LOG_F(LS_WARNING) << "Missing cache entry";
-    ASSERT(false);
-    return;
-  }
-
-  entry->accessors -= 1;
-  total_accessors_ -= 1;
-
-  if (LS_UNLOCKED != entry->lock_state) {
-    // This is safe, because locked resources only issue WriteResource, which
-    // is non-const.  Think about a better way to handle it.
-    DiskCache* this2 = const_cast<DiskCache*>(this);
-    Entry* entry2 = this2->GetOrCreateEntry(id, false);
-
-    size_t new_size = 0;
-    std::string filename(IdToFilename(id, index));
-    FileStream::GetSize(filename, &new_size);
-    entry2->size += new_size;
-    this2->total_size_ += new_size;
-
-    if ((LS_UNLOCKING == entry->lock_state) && (0 == entry->accessors)) {
-      entry2->last_modified = time(0);
-      entry2->lock_state = LS_UNLOCKED;
-      this2->CheckLimit();
-    }
-  }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-} // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/diskcache.h b/third_party/libjingle/source/talk/base/diskcache.h
deleted file mode 100644
index c5a1dfc..0000000
--- a/third_party/libjingle/source/talk/base/diskcache.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_DISKCACHE_H__
-#define TALK_BASE_DISKCACHE_H__
-
-#include <map>
-#include <string>
-
-#ifdef WIN32
-#undef UnlockResource
-#endif  // WIN32
-
-namespace talk_base {
-
-class StreamInterface;
-
-///////////////////////////////////////////////////////////////////////////////
-// DiskCache - An LRU cache of streams, stored on disk.
-//
-// Streams are identified by a unique resource id.  Multiple streams can be
-// associated with each resource id, distinguished by an index.  When old
-// resources are flushed from the cache, all streams associated with those
-// resources are removed together.
-// DiskCache is designed to persist across executions of the program.  It is
-// safe for use from an arbitrary number of users on a single thread, but not
-// from multiple threads or other processes.
-///////////////////////////////////////////////////////////////////////////////
-
-class DiskCache {
-public:
-  DiskCache();
-  virtual ~DiskCache();
-
-  bool Initialize(const std::string& folder, size_t size);
-  bool Purge();
-
-  bool LockResource(const std::string& id);
-  StreamInterface* WriteResource(const std::string& id, size_t index);
-  bool UnlockResource(const std::string& id);
-
-  StreamInterface* ReadResource(const std::string& id, size_t index) const;
-
-  bool HasResource(const std::string& id) const;
-  bool HasResourceStream(const std::string& id, size_t index) const;
-  bool DeleteResource(const std::string& id);
-
- protected:
-  virtual bool InitializeEntries() = 0;
-  virtual bool PurgeFiles() = 0;
-
-  virtual bool FileExists(const std::string& filename) const = 0;
-  virtual bool DeleteFile(const std::string& filename) const = 0;
-
-  enum LockState { LS_UNLOCKED, LS_LOCKED, LS_UNLOCKING };
-  struct Entry {
-    LockState lock_state;
-    mutable size_t accessors;
-    size_t size;
-    size_t streams;
-    time_t last_modified;
-  };
-  typedef std::map<std::string, Entry> EntryMap;
-  friend class DiskCacheAdapter;
-
-  bool CheckLimit();
-
-  std::string IdToFilename(const std::string& id, size_t index) const;
-  bool FilenameToId(const std::string& filename, std::string* id,
-                    size_t* index) const;
-
-  const Entry* GetEntry(const std::string& id) const {
-    return const_cast<DiskCache*>(this)->GetOrCreateEntry(id, false);
-  }
-  Entry* GetOrCreateEntry(const std::string& id, bool create);
-
-  void ReleaseResource(const std::string& id, size_t index) const;
-
-  std::string folder_;
-  size_t max_cache_, total_size_;
-  EntryMap map_;
-  mutable size_t total_accessors_;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// CacheLock - Automatically manage locking and unlocking, with optional
-// rollback semantics
-///////////////////////////////////////////////////////////////////////////////
-
-class CacheLock {
-public:
-  CacheLock(DiskCache* cache, const std::string& id, bool rollback = false)
-  : cache_(cache), id_(id), rollback_(rollback)
-  {
-    locked_ = cache_->LockResource(id_);
-  }
-  ~CacheLock() {
-    if (locked_) {
-      cache_->UnlockResource(id_);
-      if (rollback_) {
-        cache_->DeleteResource(id_);
-      }
-    }
-  }
-  bool IsLocked() const { return locked_; }
-  void Commit() { rollback_ = false; }
-
-private:
-  DiskCache* cache_;
-  std::string id_;
-  bool rollback_, locked_;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-
-}  // namespace talk_base
-
-#endif // TALK_BASE_DISKCACHE_H__
diff --git a/third_party/libjingle/source/talk/base/event.cc b/third_party/libjingle/source/talk/base/event.cc
deleted file mode 100644
index f2fd04d..0000000
--- a/third_party/libjingle/source/talk/base/event.cc
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2008, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/event.h"
-
-#if defined(WIN32)
-#include <windows.h>
-#elif defined(POSIX)
-#include <pthread.h>
-#include <sys/time.h>
-#include <time.h>
-#else
-#error "Must define either WIN32 or POSIX."
-#endif
-
-namespace talk_base {
-
-#if defined(WIN32)
-
-Event::Event(bool manual_reset, bool initially_signaled)
-    : is_manual_reset_(manual_reset),
-      is_initially_signaled_(initially_signaled),
-      event_handle_(NULL) {
-}
-
-bool Event::EnsureInitialized() {
-  if (event_handle_ == NULL) {
-    event_handle_ = ::CreateEvent(NULL,                 // Security attributes.
-                                  is_manual_reset_,
-                                  is_initially_signaled_,
-                                  NULL);                // Name.
-  }
-
-  return (event_handle_ != NULL);
-}
-
-Event::~Event() {
-  if (event_handle_ != NULL) {
-    CloseHandle(event_handle_);
-    event_handle_ = NULL;
-  }
-}
-
-bool Event::Set() {
-  if (!EnsureInitialized())
-    return false;
-
-  SetEvent(event_handle_);
-  return true;
-}
-
-bool Event::Reset() {
-  if (!EnsureInitialized())
-    return false;
-
-  ResetEvent(event_handle_);
-  return true;
-}
-
-bool Event::Wait(int cms) {
-  DWORD ms = (cms == kForever)? INFINITE : cms;
-
-  if (!EnsureInitialized())
-    return false;
-  else
-    return (WaitForSingleObject(event_handle_, ms) == WAIT_OBJECT_0);
-}
-
-#elif defined(POSIX)
-
-Event::Event(bool manual_reset, bool initially_signaled)
-    : is_manual_reset_(manual_reset),
-      event_status_(initially_signaled),
-      event_mutex_initialized_(false),
-      event_cond_initialized_(false) {
-}
-
-bool Event::EnsureInitialized() {
-  if (!event_mutex_initialized_) {
-    if (pthread_mutex_init(&event_mutex_, NULL) == 0)
-      event_mutex_initialized_ = true;
-  }
-
-  if (!event_cond_initialized_) {
-    if (pthread_cond_init(&event_cond_, NULL) == 0)
-      event_cond_initialized_ = true;
-  }
-
-  return (event_mutex_initialized_ && event_cond_initialized_);
-}
-
-Event::~Event() {
-  if (event_mutex_initialized_) {
-    pthread_mutex_destroy(&event_mutex_);
-    event_mutex_initialized_ = false;
-  }
-
-  if (event_cond_initialized_) {
-    pthread_cond_destroy(&event_cond_);
-    event_cond_initialized_ = false;
-  }
-}
-
-bool Event::Set() {
-  if (!EnsureInitialized())
-    return false;
-
-  pthread_mutex_lock(&event_mutex_);
-  event_status_ = true;
-  pthread_cond_broadcast(&event_cond_);
-  pthread_mutex_unlock(&event_mutex_);
-  return true;
-}
-
-bool Event::Reset() {
-  if (!EnsureInitialized())
-    return false;
-
-  pthread_mutex_lock(&event_mutex_);
-  event_status_ = false;
-  pthread_mutex_unlock(&event_mutex_);
-  return true;
-}
-
-bool Event::Wait(int cms) {
-  if (!EnsureInitialized())
-    return false;
-
-  pthread_mutex_lock(&event_mutex_);
-  int error = 0;
-
-  if (cms != kForever) {
-    // Converting from seconds and microseconds (1e-6) plus
-    // milliseconds (1e-3) to seconds and nanoseconds (1e-9).
-
-    struct timeval tv;
-    gettimeofday(&tv, NULL);
-
-    struct timespec ts;
-    ts.tv_sec = tv.tv_sec + (cms / 1000);
-    ts.tv_nsec = tv.tv_usec * 1000 + (cms % 1000) * 1000000;
-
-    // Handle overflow.
-    if (ts.tv_nsec >= 1000000000) {
-      ts.tv_sec++;
-      ts.tv_nsec -= 1000000000;
-    }
-
-    while (!event_status_ && error == 0)
-      error = pthread_cond_timedwait(&event_cond_, &event_mutex_, &ts);
-  } else {
-    while (!event_status_ && error == 0)
-      error = pthread_cond_wait(&event_cond_, &event_mutex_);
-  }
-
-  // NOTE(liulk): Exactly one thread will auto-reset this event. All
-  // the other threads will think it's unsignaled.  This seems to be
-  // consistent with auto-reset events in WIN32.
-  if (error == 0 && !is_manual_reset_)
-    event_status_ = false;
-
-  pthread_mutex_unlock(&event_mutex_);
-
-  return (error == 0);
-}
-
-#endif
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/event.h b/third_party/libjingle/source/talk/base/event.h
deleted file mode 100644
index 757164c..0000000
--- a/third_party/libjingle/source/talk/base/event.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2008, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_EVENT_H__
-#define TALK_BASE_EVENT_H__
-
-#if defined(WIN32)
-#include "talk/base/win32.h"  // NOLINT: consider this a system header.
-#elif defined(POSIX)
-#include <pthread.h>
-#else
-#error "Must define either WIN32 or POSIX."
-#endif
-
-#include "talk/base/basictypes.h"
-
-namespace talk_base {
-
-class Event {
- public:
-  Event(bool manual_reset, bool initially_signaled);
-  ~Event();
-
-  bool Set();
-  bool Reset();
-  bool Wait(int cms);
-
- private:
-  bool EnsureInitialized();
-
-  bool is_manual_reset_;
-
-#if defined(WIN32)
-  bool is_initially_signaled_;
-  HANDLE event_handle_;
-#elif defined(POSIX)
-  bool event_status_;
-  bool event_mutex_initialized_;
-  pthread_mutex_t event_mutex_;
-  bool event_cond_initialized_;
-  pthread_cond_t event_cond_;
-#endif
-};
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_EVENT_H__
diff --git a/third_party/libjingle/source/talk/base/event_unittest.cc b/third_party/libjingle/source/talk/base/event_unittest.cc
deleted file mode 100644
index 5a3c1c6..0000000
--- a/third_party/libjingle/source/talk/base/event_unittest.cc
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/event.h"
-#include "talk/base/gunit.h"
-
-namespace talk_base {
-
-TEST(EventTest, InitiallySignaled) {
-  Event event(false, true);
-  ASSERT_TRUE(event.Wait(0));
-}
-
-TEST(EventTest, ManualReset) {
-  Event event(true, false);
-  ASSERT_FALSE(event.Wait(0));
-
-  event.Set();
-  ASSERT_TRUE(event.Wait(0));
-  ASSERT_TRUE(event.Wait(0));
-
-  event.Reset();
-  ASSERT_FALSE(event.Wait(0));
-}
-
-TEST(EventTest, AutoReset) {
-  Event event(false, false);
-  ASSERT_FALSE(event.Wait(0));
-
-  event.Set();
-  ASSERT_TRUE(event.Wait(0));
-  ASSERT_FALSE(event.Wait(0));
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/fakenetwork.h b/third_party/libjingle/source/talk/base/fakenetwork.h
deleted file mode 100644
index c5ae4b6..0000000
--- a/third_party/libjingle/source/talk/base/fakenetwork.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * libjingle
- * Copyright 2009 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_FAKENETWORK_H_
-#define TALK_BASE_FAKENETWORK_H_
-
-#include <string>
-#include <vector>
-
-#include "talk/base/network.h"
-#include "talk/base/messagehandler.h"
-#include "talk/base/socketaddress.h"
-#include "talk/base/stringencode.h"
-#include "talk/base/thread.h"
-
-namespace talk_base {
-
-// Fake network manager that allows us to manually specify the IPs to use.
-class FakeNetworkManager : public NetworkManagerBase,
-                           public MessageHandler {
- public:
-  FakeNetworkManager()
-      : thread_(Thread::Current()),
-        next_index_(0),
-        started_(false) {
-  }
-
-  void AddInterface(const SocketAddress& iface) {
-    // ensure a unique name for the interface
-    SocketAddress address("test" + talk_base::ToString(next_index_++), 0);
-    address.SetResolvedIP(iface.ipaddr());
-    ifaces_.push_back(address);
-    DoUpdateNetworks();
-  }
-
-  void RemoveInterface(const SocketAddress& iface) {
-    for (std::vector<SocketAddress>::iterator it = ifaces_.begin();
-         it != ifaces_.end(); ++it) {
-      if (it->EqualIPs(iface)) {
-        ifaces_.erase(it);
-        break;
-      }
-    }
-    DoUpdateNetworks();
-  }
-
-  virtual void StartUpdating() {
-    started_ = true;
-    thread_->Post(this);
-  }
-
-  virtual void StopUpdating() {
-    started_ = false;
-  }
-
-  // MessageHandler interface.
-  virtual void OnMessage(Message* msg) {
-    DoUpdateNetworks();
-  }
-
- private:
-  void DoUpdateNetworks() {
-    if (!started_)
-      return;
-    std::vector<Network*> networks;
-    for (std::vector<SocketAddress>::iterator it = ifaces_.begin();
-         it != ifaces_.end(); ++it) {
-      networks.push_back(new Network(it->hostname(), it->hostname(),
-                                     it->ipaddr()));
-    }
-    MergeNetworkList(networks, true);
-  }
-
-  Thread* thread_;
-  std::vector<SocketAddress> ifaces_;
-  int next_index_;
-  bool started_;
-};
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_FAKENETWORK_H_
diff --git a/third_party/libjingle/source/talk/base/faketaskrunner.h b/third_party/libjingle/source/talk/base/faketaskrunner.h
deleted file mode 100644
index 6b5b035..0000000
--- a/third_party/libjingle/source/talk/base/faketaskrunner.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * libjingle
- * Copyright 2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// A fake TaskRunner for use in unit tests.
-
-#ifndef TALK_BASE_FAKETASKRUNNER_H_
-#define TALK_BASE_FAKETASKRUNNER_H_
-
-#include "talk/base/taskparent.h"
-#include "talk/base/taskrunner.h"
-
-namespace talk_base {
-
-class FakeTaskRunner : public TaskRunner {
- public:
-  FakeTaskRunner() : current_time_(0) {}
-  virtual ~FakeTaskRunner() {}
-
-  virtual void WakeTasks() { RunTasks(); }
-
-  virtual int64 CurrentTime() {
-    // Implement if needed.
-    return current_time_++;
-  }
-
-  int64 current_time_;
-};
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_FAKETASKRUNNER_H_
diff --git a/third_party/libjingle/source/talk/base/filelock.cc b/third_party/libjingle/source/talk/base/filelock.cc
deleted file mode 100644
index 2bc7045..0000000
--- a/third_party/libjingle/source/talk/base/filelock.cc
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * libjingle
- * Copyright 2009, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/filelock.h"
-
-#include "talk/base/fileutils.h"
-#include "talk/base/logging.h"
-#include "talk/base/pathutils.h"
-#include "talk/base/stream.h"
-
-namespace talk_base {
-
-FileLock::FileLock(const std::string& path, FileStream* file)
-    : path_(path), file_(file) {
-}
-
-FileLock::~FileLock() {
-  MaybeUnlock();
-}
-
-void FileLock::Unlock() {
-  LOG_F(LS_INFO);
-  MaybeUnlock();
-}
-
-void FileLock::MaybeUnlock() {
-  if (file_.get() != NULL) {
-    LOG(LS_INFO) << "Unlocking:" << path_;
-    file_->Close();
-    Filesystem::DeleteFile(path_);
-    file_.reset();
-  }
-}
-
-FileLock* FileLock::TryLock(const std::string& path) {
-  FileStream* stream = new FileStream();
-  bool ok = false;
-#ifdef WIN32
-  // Open and lock in a single operation.
-  ok = stream->OpenShare(path, "a", _SH_DENYRW, NULL);
-#else // Linux and OSX
-  ok = stream->Open(path, "a", NULL) && stream->TryLock();
-#endif
-  if (ok) {
-    return new FileLock(path, stream);
-  } else {
-    // Something failed, either we didn't succeed to open the
-    // file or we failed to lock it. Anyway remove the heap
-    // allocated object and then return NULL to indicate failure.
-    delete stream;
-    return NULL;
-  }
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/filelock.h b/third_party/libjingle/source/talk/base/filelock.h
deleted file mode 100644
index a4936f5..0000000
--- a/third_party/libjingle/source/talk/base/filelock.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * libjingle
- * Copyright 2009, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_FILELOCK_H_
-#define TALK_BASE_FILELOCK_H_
-
-#include <string>
-
-#include "talk/base/constructormagic.h"
-#include "talk/base/scoped_ptr.h"
-
-namespace talk_base {
-
-class FileStream;
-
-// Implements a very simple cross process lock based on a file.
-// When Lock(...) is called we try to open/create the file in read/write
-// mode without any sharing. (Or locking it with flock(...) on Unix)
-// If the process crash the OS will make sure that the file descriptor
-// is released and another process can accuire the lock.
-// This doesn't work on ancient OSX/Linux versions if used on NFS.
-// (Nfs-client before: ~2.6 and Linux Kernel < 2.6.)
-class FileLock {
- public:
-  virtual ~FileLock();
-
-  // Attempts to lock the file. The caller owns the returned
-  // lock object. Returns NULL if the file already was locked.
-  static FileLock* TryLock(const std::string& path);
-  void Unlock();
-
- protected:
-  FileLock(const std::string& path, FileStream* file);
-
- private:
-  void MaybeUnlock();
-
-  std::string path_;
-  scoped_ptr<FileStream> file_;
-
-  DISALLOW_EVIL_CONSTRUCTORS(FileLock);
-};
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_FILELOCK_H_
diff --git a/third_party/libjingle/source/talk/base/filelock_unittest.cc b/third_party/libjingle/source/talk/base/filelock_unittest.cc
deleted file mode 100644
index e585f91..0000000
--- a/third_party/libjingle/source/talk/base/filelock_unittest.cc
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * libjingle
- * Copyright 2009, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string>
-
-#include "talk/base/event.h"
-#include "talk/base/filelock.h"
-#include "talk/base/fileutils.h"
-#include "talk/base/gunit.h"
-#include "talk/base/pathutils.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/base/thread.h"
-
-namespace talk_base {
-
-const static std::string kLockFile = "TestLockFile";
-const static int kTimeoutMS = 5000;
-
-class FileLockTest : public testing::Test, public Runnable {
- public:
-  FileLockTest() : done_(false, false), thread_lock_failed_(false) {
-  }
-
-  virtual void Run(Thread* t) {
-    scoped_ptr<FileLock> lock(FileLock::TryLock(temp_file_.pathname()));
-    // The lock is already owned by the main thread of
-    // this test, therefore the TryLock(...) call should fail.
-    thread_lock_failed_ = lock.get() == NULL;
-    done_.Set();
-  }
-
- protected:
-  virtual void SetUp() {
-    thread_lock_failed_ = false;
-    Filesystem::GetAppTempFolder(&temp_dir_);
-    temp_file_ = Pathname(temp_dir_.pathname(), kLockFile);
-  }
-
-  void LockOnThread() {
-    locker_.Start(this);
-    done_.Wait(kTimeoutMS);
-  }
-
-  Event done_;
-  Thread locker_;
-  bool thread_lock_failed_;
-  Pathname temp_dir_;
-  Pathname temp_file_;
-};
-
-TEST_F(FileLockTest, TestLockFileDeleted) {
-  scoped_ptr<FileLock> lock(FileLock::TryLock(temp_file_.pathname()));
-  EXPECT_TRUE(lock.get() != NULL);
-  EXPECT_FALSE(Filesystem::IsAbsent(temp_file_.pathname()));
-  lock->Unlock();
-  EXPECT_TRUE(Filesystem::IsAbsent(temp_file_.pathname()));
-}
-
-TEST_F(FileLockTest, TestLock) {
-  scoped_ptr<FileLock> lock(FileLock::TryLock(temp_file_.pathname()));
-  EXPECT_TRUE(lock.get() != NULL);
-}
-
-TEST_F(FileLockTest, TestLockX2) {
-  scoped_ptr<FileLock> lock1(FileLock::TryLock(temp_file_.pathname()));
-  EXPECT_TRUE(lock1.get() != NULL);
-
-  scoped_ptr<FileLock> lock2(FileLock::TryLock(temp_file_.pathname()));
-  EXPECT_TRUE(lock2.get() == NULL);
-}
-
-TEST_F(FileLockTest, TestThreadedLock) {
-  scoped_ptr<FileLock> lock(FileLock::TryLock(temp_file_.pathname()));
-  EXPECT_TRUE(lock.get() != NULL);
-
-  LockOnThread();
-  EXPECT_TRUE(thread_lock_failed_);
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/fileutils.cc b/third_party/libjingle/source/talk/base/fileutils.cc
deleted file mode 100644
index 7b0d348..0000000
--- a/third_party/libjingle/source/talk/base/fileutils.cc
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2006, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <cassert>
-
-#ifdef WIN32
-#include "talk/base/win32.h"
-#endif
-
-#include "talk/base/pathutils.h"
-#include "talk/base/fileutils.h"
-#include "talk/base/stringutils.h"
-#include "talk/base/stream.h"
-
-#include "talk/base/unixfilesystem.h"
-#include "talk/base/win32filesystem.h"
-
-#ifndef WIN32
-#define MAX_PATH 260
-#endif
-
-namespace talk_base {
-
-//////////////////////////
-// Directory Iterator   //
-//////////////////////////
-
-// A DirectoryIterator is created with a given directory. It originally points
-// to the first file in the directory, and can be advanecd with Next(). This
-// allows you to get information about each file.
-
-  // Constructor
-DirectoryIterator::DirectoryIterator()
-#ifdef _WIN32
-    : handle_(INVALID_HANDLE_VALUE) {
-#else
-    : dir_(NULL), dirent_(NULL) {
-#endif
-}
-
-  // Destructor
-DirectoryIterator::~DirectoryIterator() {
-#ifdef WIN32
-  if (handle_ != INVALID_HANDLE_VALUE)
-    ::FindClose(handle_);
-#else
-  if (dir_)
-    closedir(dir_);
-#endif
-}
-
-  // Starts traversing a directory.
-  // dir is the directory to traverse
-  // returns true if the directory exists and is valid
-bool DirectoryIterator::Iterate(const Pathname &dir) {
-  directory_ = dir.pathname();
-#ifdef WIN32
-  if (handle_ != INVALID_HANDLE_VALUE)
-    ::FindClose(handle_);
-  std::string d = dir.pathname() + '*';
-  handle_ = ::FindFirstFile(ToUtf16(d).c_str(), &data_);
-  if (handle_ == INVALID_HANDLE_VALUE)
-    return false;
-#else
-  if (dir_ != NULL)
-    closedir(dir_);
-  dir_ = ::opendir(directory_.c_str());
-  if (dir_ == NULL)
-    return false;
-  dirent_ = readdir(dir_);
-  if (dirent_ == NULL)
-    return false;
-
-  if (::stat(std::string(directory_ + Name()).c_str(), &stat_) != 0)
-    return false;
-#endif
-  return true;
-}
-
-  // Advances to the next file
-  // returns true if there were more files in the directory.
-bool DirectoryIterator::Next() {
-#ifdef WIN32
-  return ::FindNextFile(handle_, &data_) == TRUE;
-#else
-  dirent_ = ::readdir(dir_);
-  if (dirent_ == NULL)
-    return false;
-
-  return ::stat(std::string(directory_ + Name()).c_str(), &stat_) == 0;
-#endif
-}
-
-  // returns true if the file currently pointed to is a directory
-bool DirectoryIterator::IsDirectory() const {
-#ifdef WIN32
-  return (data_.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != FALSE;
-#else
-  return S_ISDIR(stat_.st_mode);
-#endif
-}
-
-  // returns the name of the file currently pointed to
-std::string DirectoryIterator::Name() const {
-#ifdef WIN32
-  return ToUtf8(data_.cFileName);
-#else
-  assert(dirent_ != NULL);
-  return dirent_->d_name;
-#endif
-}
-
-  // returns the size of the file currently pointed to
-size_t DirectoryIterator::FileSize() const {
-#ifndef WIN32
-  return stat_.st_size;
-#else
-  return data_.nFileSizeLow;
-#endif
-}
-
-  // returns the last modified time of this file
-time_t DirectoryIterator::FileModifyTime() const {
-#ifdef WIN32
-  time_t val;
-  FileTimeToUnixTime(data_.ftLastWriteTime, &val);
-  return val;
-#else
-  return stat_.st_mtime;
-#endif
-}
-
-FilesystemInterface* Filesystem::default_filesystem_ = NULL;
-
-FilesystemInterface *Filesystem::EnsureDefaultFilesystem() {
-  if (!default_filesystem_) {
-#ifdef WIN32
-    default_filesystem_ = new Win32Filesystem();
-#else
-    default_filesystem_ = new UnixFilesystem();
-#endif
-  }
-  return default_filesystem_;
-}
-
-bool FilesystemInterface::CopyFolder(const Pathname &old_path,
-                                     const Pathname &new_path) {
-  bool success = true;
-  VERIFY(IsFolder(old_path));
-  Pathname new_dir;
-  new_dir.SetFolder(new_path.pathname());
-  Pathname old_dir;
-  old_dir.SetFolder(old_path.pathname());
-  if (!CreateFolder(new_dir))
-    return false;
-  DirectoryIterator *di = IterateDirectory();
-  if (!di)
-    return false;
-  if (di->Iterate(old_dir.pathname())) {
-    do {
-      if (di->Name() == "." || di->Name() == "..")
-        continue;
-      Pathname source;
-      Pathname dest;
-      source.SetFolder(old_dir.pathname());
-      dest.SetFolder(new_path.pathname());
-      source.SetFilename(di->Name());
-      dest.SetFilename(di->Name());
-      if (!CopyFileOrFolder(source, dest))
-        success = false;
-    } while (di->Next());
-  }
-  delete di;
-  return success;
-}
-
-bool FilesystemInterface::DeleteFolderContents(const Pathname &folder) {
-  bool success = true;
-  VERIFY(IsFolder(folder));
-  DirectoryIterator *di = IterateDirectory();
-  if (!di)
-    return false;
-  if (di->Iterate(folder)) {
-    do {
-      if (di->Name() == "." || di->Name() == "..")
-        continue;
-      Pathname subdir;
-      subdir.SetFolder(folder.pathname());
-      if (di->IsDirectory()) {
-        subdir.AppendFolder(di->Name());
-        if (!DeleteFolderAndContents(subdir)) {
-          success = false;
-        }
-      } else {
-        subdir.SetFilename(di->Name());
-        if (!DeleteFile(subdir)) {
-          success = false;
-        }
-      }
-    } while (di->Next());
-  }
-  delete di;
-  return success;
-}
-
-bool FilesystemInterface::CleanAppTempFolder() {
-  Pathname path;
-  if (!GetAppTempFolder(&path))
-    return false;
-  if (IsAbsent(path))
-    return true;
-  if (!IsTemporaryPath(path)) {
-    ASSERT(false);
-    return false;
-  }
-  return DeleteFolderContents(path);
-}
-
-Pathname Filesystem::GetCurrentDirectory() {
-  return EnsureDefaultFilesystem()->GetCurrentDirectory();
-}
-
-bool CreateUniqueFile(Pathname& path, bool create_empty) {
-  LOG(LS_INFO) << "Path " << path.pathname() << std::endl;
-  // If no folder is supplied, use the temporary folder
-  if (path.folder().empty()) {
-    Pathname temporary_path;
-    if (!Filesystem::GetTemporaryFolder(temporary_path, true, NULL)) {
-      printf("Get temp failed\n");
-      return false;
-    }
-    path.SetFolder(temporary_path.pathname());
-  }
-
-  // If no filename is supplied, use a temporary name
-  if (path.filename().empty()) {
-    std::string folder(path.folder());
-    std::string filename = Filesystem::TempFilename(folder, "gt");
-    path.SetPathname(filename);
-    if (!create_empty) {
-      Filesystem::DeleteFile(path.pathname());
-    }
-    return true;
-  }
-
-  // Otherwise, create a unique name based on the given filename
-  // foo.txt -> foo-N.txt
-  const std::string basename = path.basename();
-  const size_t MAX_VERSION = 100;
-  size_t version = 0;
-  while (version < MAX_VERSION) {
-    std::string pathname = path.pathname();
-
-    if (!Filesystem::IsFile(pathname)) {
-      if (create_empty) {
-        FileStream* fs = Filesystem::OpenFile(pathname, "w");
-        delete fs;
-      }
-      return true;
-    }
-    version += 1;
-    char version_base[MAX_PATH];
-    sprintfn(version_base, ARRAY_SIZE(version_base), "%s-%u",
-             basename.c_str(), version);
-    path.SetBasename(version_base);
-  }
-  return true;
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/fileutils.h b/third_party/libjingle/source/talk/base/fileutils.h
deleted file mode 100644
index 186c963..0000000
--- a/third_party/libjingle/source/talk/base/fileutils.h
+++ /dev/null
@@ -1,457 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2006, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_FILEUTILS_H_
-#define TALK_BASE_FILEUTILS_H_
-
-#include <string>
-
-#ifdef WIN32
-#include "talk/base/win32.h"
-#else
-#include <sys/types.h>
-#include <dirent.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#endif
-
-#include "talk/base/basictypes.h"
-#include "talk/base/common.h"
-#include "talk/base/scoped_ptr.h"
-
-namespace talk_base {
-
-class FileStream;
-class Pathname;
-
-//////////////////////////
-// Directory Iterator   //
-//////////////////////////
-
-// A DirectoryIterator is created with a given directory. It originally points
-// to the first file in the directory, and can be advanecd with Next(). This
-// allows you to get information about each file.
-
-class DirectoryIterator {
-  friend class Filesystem;
- public:
-  // Constructor
-  DirectoryIterator();
-  // Destructor
-  virtual ~DirectoryIterator();
-
-  // Starts traversing a directory
-  // dir is the directory to traverse
-  // returns true if the directory exists and is valid
-  // The iterator will point to the first entry in the directory
-  virtual bool Iterate(const Pathname &path);
-
-  // Advances to the next file
-  // returns true if there were more files in the directory.
-  virtual bool Next();
-
-  // returns true if the file currently pointed to is a directory
-  virtual bool IsDirectory() const;
-
-  // returns the name of the file currently pointed to
-  virtual std::string Name() const;
-
-  // returns the size of the file currently pointed to
-  virtual size_t FileSize() const;
-
-  // returns the last modified time of the file currently pointed to
-  virtual time_t FileModifyTime() const;
-
-  // checks whether current file is a special directory file "." or ".."
-  bool IsDots() const {
-    std::string filename(Name());
-    return (filename.compare(".") == 0) || (filename.compare("..") == 0);
-  }
-
- private:
-  std::string directory_;
-#ifdef WIN32
-  WIN32_FIND_DATA data_;
-  HANDLE handle_;
-#else
-  DIR *dir_;
-  struct dirent *dirent_;
-  struct stat stat_;
-#endif
-};
-
-enum FileTimeType { FTT_CREATED, FTT_MODIFIED, FTT_ACCESSED };
-
-class FilesystemInterface {
- public:
-  virtual ~FilesystemInterface() {}
-
-  // Returns a DirectoryIterator for a given pathname.
-  // TODO: Do fancy abstracted stuff
-  virtual DirectoryIterator *IterateDirectory() {
-    return new DirectoryIterator();
-  }
-
-  // Opens a file. Returns an open StreamInterface if function succeeds.
-  // Otherwise, returns NULL.
-  // TODO: Add an error param to indicate failure reason, similar to
-  // FileStream::Open
-  virtual FileStream *OpenFile(const Pathname &filename,
-                               const std::string &mode) = 0;
-
-  // Atomically creates an empty file accessible only to the current user if one
-  // does not already exist at the given path, otherwise fails. This is the only
-  // secure way to create a file in a shared temp directory (e.g., C:\Temp on
-  // Windows or /tmp on Linux).
-  // Note that if it is essential that a file be successfully created then the
-  // app must generate random names and retry on failure, or else it will be
-  // vulnerable to a trivial DoS.
-  virtual bool CreatePrivateFile(const Pathname &filename) = 0;
-
-  // This will attempt to delete the path located at filename.
-  // It ASSERTS and returns false if the path points to a folder or a
-  // non-existent file.
-  virtual bool DeleteFile(const Pathname &filename) = 0;
-
-  // This will attempt to delete the empty folder located at 'folder'
-  // It ASSERTS and returns false if the path points to a file or a non-existent
-  // folder. It fails normally if the folder is not empty or can otherwise
-  // not be deleted.
-  virtual bool DeleteEmptyFolder(const Pathname &folder) = 0;
-
-  // This will call IterateDirectory, to get a directory iterator, and then
-  // call DeleteFolderAndContents and DeleteFile on every path contained in this
-  // folder. If the folder is empty, this returns true.
-  virtual bool DeleteFolderContents(const Pathname &folder);
-
-  // This deletes the contents of a folder, recursively, and then deletes
-  // the folder itself.
-  virtual bool DeleteFolderAndContents(const Pathname &folder) {
-    return DeleteFolderContents(folder) && DeleteEmptyFolder(folder);
-  }
-
-  // This will delete whatever is located at path, be it a file or a folder.
-  // If it is a folder, it will delete it recursively by calling
-  // DeleteFolderAndContents
-  bool DeleteFileOrFolder(const Pathname &path) {
-    if (IsFolder(path))
-      return DeleteFolderAndContents(path);
-    else
-      return DeleteFile(path);
-  }
-
-  // Creates a directory. This will call itself recursively to create /foo/bar
-  // even if /foo does not exist. Returns true if the function succeeds.
-  virtual bool CreateFolder(const Pathname &pathname) = 0;
-
-  // This moves a file from old_path to new_path, where "old_path" is a
-  // plain file. This ASSERTs and returns false if old_path points to a
-  // directory, and returns true if the function succeeds.
-  // If the new path is on a different volume than the old path, this function
-  // will attempt to copy and, if that succeeds, delete the old path.
-  virtual bool MoveFolder(const Pathname &old_path,
-                          const Pathname &new_path) = 0;
-
-  // This moves a directory from old_path to new_path, where "old_path" is a
-  // directory. This ASSERTs and returns false if old_path points to a plain
-  // file, and returns true if the function succeeds.
-  // If the new path is on a different volume, this function will attempt to
-  // copy and if that succeeds, delete the old path.
-  virtual bool MoveFile(const Pathname &old_path, const Pathname &new_path) = 0;
-
-  // This attempts to move whatever is located at old_path to new_path,
-  // be it a file or folder.
-  bool MoveFileOrFolder(const Pathname &old_path, const Pathname &new_path) {
-    if (IsFile(old_path)) {
-      return MoveFile(old_path, new_path);
-    } else {
-      return MoveFolder(old_path, new_path);
-    }
-  }
-
-  // This copies a file from old_path to new_path. This method ASSERTs and
-  // returns false if old_path is a folder, and returns true if the copy
-  // succeeds.
-  virtual bool CopyFile(const Pathname &old_path, const Pathname &new_path) = 0;
-
-  // This copies a folder from old_path to new_path.
-  bool CopyFolder(const Pathname &old_path, const Pathname &new_path);
-
-  bool CopyFileOrFolder(const Pathname &old_path, const Pathname &new_path) {
-    if (IsFile(old_path))
-      return CopyFile(old_path, new_path);
-    else
-      return CopyFolder(old_path, new_path);
-  }
-
-  // Returns true if pathname refers to a directory
-  virtual bool IsFolder(const Pathname& pathname) = 0;
-
-  // Returns true if pathname refers to a file
-  virtual bool IsFile(const Pathname& pathname) = 0;
-
-  // Returns true if pathname refers to no filesystem object, every parent
-  // directory either exists, or is also absent.
-  virtual bool IsAbsent(const Pathname& pathname) = 0;
-
-  // Returns true if pathname represents a temporary location on the system.
-  virtual bool IsTemporaryPath(const Pathname& pathname) = 0;
-
-  // A folder appropriate for storing temporary files (Contents are
-  // automatically deleted when the program exits)
-  virtual bool GetTemporaryFolder(Pathname &path, bool create,
-                                  const std::string *append) = 0;
-
-  virtual std::string TempFilename(const Pathname &dir,
-                                   const std::string &prefix) = 0;
-
-  // Determines the size of the file indicated by path.
-  virtual bool GetFileSize(const Pathname& path, size_t* size) = 0;
-
-  // Determines a timestamp associated with the file indicated by path.
-  virtual bool GetFileTime(const Pathname& path, FileTimeType which,
-                           time_t* time) = 0;
-
-  // Returns the path to the running application.
-  // Note: This is not guaranteed to work on all platforms.  Be aware of the
-  // limitations before using it, and robustly handle failure.
-  virtual bool GetAppPathname(Pathname* path) = 0;
-
-  // Get a folder that is unique to the current application, which is suitable
-  // for sharing data between executions of the app.  If the per_user arg is
-  // true, the folder is also specific to the current user.
-  virtual bool GetAppDataFolder(Pathname* path, bool per_user) = 0;
-
-  // Get a temporary folder that is unique to the current user and application.
-  // TODO: Re-evaluate the goals of this function.  We probably just need any
-  // directory that won't collide with another existing directory, and which
-  // will be cleaned up when the program exits.
-  virtual bool GetAppTempFolder(Pathname* path) = 0;
-
-  // Delete the contents of the folder returned by GetAppTempFolder
-  bool CleanAppTempFolder();
-
-  virtual bool GetDiskFreeSpace(const Pathname& path, int64 *freebytes) = 0;
-
-  // Returns the absolute path of the current directory.
-  virtual Pathname GetCurrentDirectory() = 0;
-
-  // Note: These might go into some shared config section later, but they're
-  // used by some methods in this interface, so we're leaving them here for now.
-  void SetOrganizationName(const std::string& organization) {
-    organization_name_ = organization;
-  }
-  void GetOrganizationName(std::string* organization) {
-    ASSERT(NULL != organization);
-    *organization = organization_name_;
-  }
-  void SetApplicationName(const std::string& application) {
-    application_name_ = application;
-  }
-  void GetApplicationName(std::string* application) {
-    ASSERT(NULL != application);
-    *application = application_name_;
-  }
-
- protected:
-  std::string organization_name_;
-  std::string application_name_;
-};
-
-class Filesystem {
- public:
-  static FilesystemInterface *default_filesystem() {
-    ASSERT(default_filesystem_ != NULL);
-    return default_filesystem_;
-  }
-
-  static void set_default_filesystem(FilesystemInterface *filesystem) {
-    default_filesystem_ = filesystem;
-  }
-
-  static FilesystemInterface *swap_default_filesystem(
-      FilesystemInterface *filesystem) {
-    FilesystemInterface *cur = default_filesystem_;
-    default_filesystem_ = filesystem;
-    return cur;
-  }
-
-  static DirectoryIterator *IterateDirectory() {
-    return EnsureDefaultFilesystem()->IterateDirectory();
-  }
-
-  static bool CreateFolder(const Pathname &pathname) {
-    return EnsureDefaultFilesystem()->CreateFolder(pathname);
-  }
-
-  static FileStream *OpenFile(const Pathname &filename,
-                              const std::string &mode) {
-    return EnsureDefaultFilesystem()->OpenFile(filename, mode);
-  }
-
-  static bool CreatePrivateFile(const Pathname &filename) {
-    return EnsureDefaultFilesystem()->CreatePrivateFile(filename);
-  }
-
-  static bool DeleteFile(const Pathname &filename) {
-    return EnsureDefaultFilesystem()->DeleteFile(filename);
-  }
-
-  static bool DeleteEmptyFolder(const Pathname &folder) {
-    return EnsureDefaultFilesystem()->DeleteEmptyFolder(folder);
-  }
-
-  static bool DeleteFolderContents(const Pathname &folder) {
-    return EnsureDefaultFilesystem()->DeleteFolderContents(folder);
-  }
-
-  static bool DeleteFolderAndContents(const Pathname &folder) {
-    return EnsureDefaultFilesystem()->DeleteFolderAndContents(folder);
-  }
-
-  static bool MoveFolder(const Pathname &old_path, const Pathname &new_path) {
-    return EnsureDefaultFilesystem()->MoveFolder(old_path, new_path);
-  }
-
-  static bool MoveFile(const Pathname &old_path, const Pathname &new_path) {
-    return EnsureDefaultFilesystem()->MoveFile(old_path, new_path);
-  }
-
-  static bool CopyFolder(const Pathname &old_path, const Pathname &new_path) {
-    return EnsureDefaultFilesystem()->CopyFolder(old_path, new_path);
-  }
-
-  static bool CopyFile(const Pathname &old_path, const Pathname &new_path) {
-    return EnsureDefaultFilesystem()->CopyFile(old_path, new_path);
-  }
-
-  static bool IsFolder(const Pathname& pathname) {
-    return EnsureDefaultFilesystem()->IsFolder(pathname);
-  }
-
-  static bool IsFile(const Pathname &pathname) {
-    return EnsureDefaultFilesystem()->IsFile(pathname);
-  }
-
-  static bool IsAbsent(const Pathname &pathname) {
-    return EnsureDefaultFilesystem()->IsAbsent(pathname);
-  }
-
-  static bool IsTemporaryPath(const Pathname& pathname) {
-    return EnsureDefaultFilesystem()->IsTemporaryPath(pathname);
-  }
-
-  static bool GetTemporaryFolder(Pathname &path, bool create,
-                                 const std::string *append) {
-    return EnsureDefaultFilesystem()->GetTemporaryFolder(path, create, append);
-  }
-
-  static std::string TempFilename(const Pathname &dir,
-                                  const std::string &prefix) {
-    return EnsureDefaultFilesystem()->TempFilename(dir, prefix);
-  }
-
-  static bool GetFileSize(const Pathname& path, size_t* size) {
-    return EnsureDefaultFilesystem()->GetFileSize(path, size);
-  }
-
-  static bool GetFileTime(const Pathname& path, FileTimeType which,
-                          time_t* time) {
-    return EnsureDefaultFilesystem()->GetFileTime(path, which, time);
-  }
-
-  static bool GetAppPathname(Pathname* path) {
-    return EnsureDefaultFilesystem()->GetAppPathname(path);
-  }
-
-  static bool GetAppDataFolder(Pathname* path, bool per_user) {
-    return EnsureDefaultFilesystem()->GetAppDataFolder(path, per_user);
-  }
-
-  static bool GetAppTempFolder(Pathname* path) {
-    return EnsureDefaultFilesystem()->GetAppTempFolder(path);
-  }
-
-  static bool CleanAppTempFolder() {
-    return EnsureDefaultFilesystem()->CleanAppTempFolder();
-  }
-
-  static bool GetDiskFreeSpace(const Pathname& path, int64 *freebytes) {
-    return EnsureDefaultFilesystem()->GetDiskFreeSpace(path, freebytes);
-  }
-
-  // Definition has to be in the .cc file due to returning forward-declared
-  // Pathname by value.
-  static Pathname GetCurrentDirectory();
-
-  static void SetOrganizationName(const std::string& organization) {
-    EnsureDefaultFilesystem()->SetOrganizationName(organization);
-  }
-
-  static void GetOrganizationName(std::string* organization) {
-    EnsureDefaultFilesystem()->GetOrganizationName(organization);
-  }
-
-  static void SetApplicationName(const std::string& application) {
-    EnsureDefaultFilesystem()->SetApplicationName(application);
-  }
-
-  static void GetApplicationName(std::string* application) {
-    EnsureDefaultFilesystem()->GetApplicationName(application);
-  }
-
- private:
-  static FilesystemInterface* default_filesystem_;
-
-  static FilesystemInterface *EnsureDefaultFilesystem();
-  DISALLOW_IMPLICIT_CONSTRUCTORS(Filesystem);
-};
-
-class FilesystemScope{
- public:
-  explicit FilesystemScope(FilesystemInterface *new_fs) {
-    old_fs_ = Filesystem::swap_default_filesystem(new_fs);
-  }
-  ~FilesystemScope() {
-    Filesystem::set_default_filesystem(old_fs_);
-  }
- private:
-  FilesystemInterface* old_fs_;
-  DISALLOW_IMPLICIT_CONSTRUCTORS(FilesystemScope);
-};
-
-// Generates a unique filename based on the input path.  If no path component
-// is specified, it uses the temporary directory.  If a filename is provided,
-// up to 100 variations of form basename-N.extension are tried.  When
-// create_empty is true, an empty file of this name is created (which
-// decreases the chance of a temporary filename collision with another
-// process).
-bool CreateUniqueFile(Pathname& path, bool create_empty);
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_FILEUTILS_H_
diff --git a/third_party/libjingle/source/talk/base/fileutils_mock.h b/third_party/libjingle/source/talk/base/fileutils_mock.h
deleted file mode 100644
index 2ccb6a3..0000000
--- a/third_party/libjingle/source/talk/base/fileutils_mock.h
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_FILEUTILS_MOCK_H_
-#define TALK_BASE_FILEUTILS_MOCK_H_
-
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "talk/base/fileutils.h"
-#include "talk/base/pathutils.h"
-#include "talk/base/stream.h"
-#include "testing/base/public/gmock.h"
-
-namespace talk_base {
-
-class FakeFileStream : public FileStream {
-  public:
-    explicit FakeFileStream(const std::string & contents) :
-      string_stream_(contents)
-    {}
-
-    virtual StreamResult Read(void* buffer, size_t buffer_len,
-                              size_t* read, int* error) {
-      return string_stream_.Read(buffer, buffer_len, read, error);
-    }
-
-    virtual void Close() {
-      return string_stream_.Close();
-    }
-    virtual bool GetSize(size_t* size) const {
-      return string_stream_.GetSize(size);
-    }
-
-  private:
-    StringStream string_stream_;
-};
-
-class FakeDirectoryIterator : public DirectoryIterator {
-  public:
-    typedef std::pair<std::string, std::string> File;
-
-    /*
-     * files should be sorted by directory
-     * put '/' at the end of file if you want it to be a directory
-     *
-     * Sample list:
-     *  /var/dir/file1
-     *  /var/dir/file2
-     *  /var/dir/subdir1/
-     *  /var/dir/subdir2/
-     *  /var/dir2/file2
-     *  /var/dir3/
-     *
-     *  you can call Iterate for any path: /var, /var/dir, /var/dir2
-     *  unrelated files will be ignored
-     */
-    explicit FakeDirectoryIterator(const std::vector<File>& all_files) :
-      all_files_(all_files) {}
-
-    virtual bool Iterate(const Pathname& path) {
-      path_iterator_ = all_files_.begin();
-      path_ = path.pathname();
-
-      // make sure path ends end with '/'
-      if (path_.rfind(Pathname::DefaultFolderDelimiter()) != path_.size() - 1)
-        path_ += Pathname::DefaultFolderDelimiter();
-
-      return  FakeDirectoryIterator::Search(std::string(""));
-    }
-
-    virtual bool Next() {
-      std::string current_name = Name();
-      path_iterator_++;
-      return FakeDirectoryIterator::Search(current_name);
-    }
-
-    bool Search(const std::string& current_name) {
-      for (; path_iterator_ != all_files_.end(); path_iterator_++) {
-        if (path_iterator_->first.find(path_) == 0
-            && Name().compare(current_name) != 0) {
-          return true;
-        }
-      }
-
-      return false;
-    }
-
-    virtual bool IsDirectory() const {
-      std::string sub_path = path_iterator_->first;
-
-      return std::string::npos !=
-        sub_path.find(Pathname::DefaultFolderDelimiter(), path_.size());
-    }
-
-    virtual std::string Name() const {
-      std::string sub_path = path_iterator_->first;
-
-      // path     - top level path  (ex. /var/lib)
-      // sub_path - subpath under top level path (ex. /var/lib/dir/dir/file )
-      // find shortest non-trivial common path. (ex. /var/lib/dir)
-      size_t start  = path_.size();
-      size_t end    = sub_path.find(Pathname::DefaultFolderDelimiter(), start);
-
-      if (end != std::string::npos) {
-        return sub_path.substr(start, end - start);
-      } else {
-        return sub_path.substr(start);
-      }
-    }
-
-  private:
-    const std::vector<File> all_files_;
-
-    std::string path_;
-    std::vector<File>::const_iterator path_iterator_;
-};
-
-class FakeFileSystem : public FilesystemInterface {
-  public:
-    typedef std::pair<std::string, std::string> File;
-
-    explicit FakeFileSystem(const std::vector<File>& all_files) :
-     all_files_(all_files) {}
-
-    virtual DirectoryIterator *IterateDirectory() {
-     return new FakeDirectoryIterator(all_files_);
-    }
-
-    virtual FileStream * OpenFile(
-       const Pathname &filename,
-       const std::string &mode) {
-     std::vector<File>::const_iterator i_files = all_files_.begin();
-     std::string path = filename.pathname();
-
-     for (; i_files != all_files_.end(); i_files++) {
-       if (i_files->first.compare(path) == 0) {
-         return new FakeFileStream(i_files->second);
-       }
-     }
-
-     return NULL;
-    }
-
-    bool CreatePrivateFile(const Pathname &filename) {
-      EXPECT_TRUE_M(false, "Unsupported operation");
-      return false;
-    }
-    bool DeleteFile(const Pathname &filename) {
-      EXPECT_TRUE_M(false, "Unsupported operation");
-      return false;
-    }
-    bool DeleteEmptyFolder(const Pathname &folder) {
-      EXPECT_TRUE_M(false, "Unsupported operation");
-      return false;
-    }
-    bool DeleteFolderContents(const Pathname &folder) {
-      EXPECT_TRUE_M(false, "Unsupported operation");
-      return false;
-    }
-    bool DeleteFolderAndContents(const Pathname &folder) {
-      EXPECT_TRUE_M(false, "Unsupported operation");
-      return false;
-    }
-    bool CreateFolder(const Pathname &pathname) {
-      EXPECT_TRUE_M(false, "Unsupported operation");
-      return false;
-    }
-    bool MoveFolder(const Pathname &old_path, const Pathname &new_path) {
-      EXPECT_TRUE_M(false, "Unsupported operation");
-      return false;
-    }
-    bool MoveFile(const Pathname &old_path, const Pathname &new_path) {
-      EXPECT_TRUE_M(false, "Unsupported operation");
-      return false;
-    }
-    bool CopyFile(const Pathname &old_path, const Pathname &new_path) {
-      EXPECT_TRUE_M(false, "Unsupported operation");
-      return false;
-    }
-    bool IsFolder(const Pathname &pathname) {
-      EXPECT_TRUE_M(false, "Unsupported operation");
-      return false;
-    }
-    bool IsFile(const Pathname &pathname) {
-      EXPECT_TRUE_M(false, "Unsupported operation");
-      return false;
-    }
-    bool IsAbsent(const Pathname &pathname) {
-      EXPECT_TRUE_M(false, "Unsupported operation");
-      return false;
-    }
-    bool IsTemporaryPath(const Pathname &pathname) {
-      EXPECT_TRUE_M(false, "Unsupported operation");
-      return false;
-    }
-    bool GetTemporaryFolder(Pathname &path, bool create,
-                            const std::string *append) {
-      EXPECT_TRUE_M(false, "Unsupported operation");
-      return false;
-    }
-    std::string TempFilename(const Pathname &dir, const std::string &prefix) {
-      EXPECT_TRUE_M(false, "Unsupported operation");
-      return std::string();
-    }
-    bool GetFileSize(const Pathname &path, size_t *size) {
-      EXPECT_TRUE_M(false, "Unsupported operation");
-      return false;
-    }
-    bool GetFileTime(const Pathname &path, FileTimeType which,
-                     time_t* time) {
-      EXPECT_TRUE_M(false, "Unsupported operation");
-      return false;
-    }
-    bool GetAppPathname(Pathname *path) {
-      EXPECT_TRUE_M(false, "Unsupported operation");
-      return false;
-    }
-    bool GetAppDataFolder(Pathname *path, bool per_user) {
-      EXPECT_TRUE_M(per_user, "Unsupported operation");
-#ifdef WIN32
-      path->SetPathname("c:\\Users\\test_user", "");
-#else
-      path->SetPathname("/home/user/test_user", "");
-#endif
-      return true;
-    }
-    bool GetAppTempFolder(Pathname *path) {
-      EXPECT_TRUE_M(false, "Unsupported operation");
-      return false;
-    }
-    bool GetDiskFreeSpace(const Pathname &path, int64 *freebytes) {
-      EXPECT_TRUE_M(false, "Unsupported operation");
-      return false;
-    }
-    Pathname GetCurrentDirectory() {
-      return Pathname();
-    }
-
-  private:
-    const std::vector<File> all_files_;
-};
-}  // namespace talk_base
-
-#endif  // TALK_BASE_FILEUTILS_MOCK_H_
diff --git a/third_party/libjingle/source/talk/base/fileutils_unittest.cc b/third_party/libjingle/source/talk/base/fileutils_unittest.cc
deleted file mode 100644
index 992ea82..0000000
--- a/third_party/libjingle/source/talk/base/fileutils_unittest.cc
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/fileutils.h"
-#include "talk/base/gunit.h"
-#include "talk/base/pathutils.h"
-#include "talk/base/stream.h"
-
-namespace talk_base {
-
-// Make sure we can get a temp folder for the later tests.
-TEST(FilesystemTest, GetTemporaryFolder) {
-  Pathname path;
-  EXPECT_TRUE(Filesystem::GetTemporaryFolder(path, true, NULL));
-}
-
-// Test creating a temp file, reading it back in, and deleting it.
-TEST(FilesystemTest, TestOpenFile) {
-  Pathname path;
-  EXPECT_TRUE(Filesystem::GetTemporaryFolder(path, true, NULL));
-  path.SetPathname(Filesystem::TempFilename(path, "ut"));
-
-  FileStream* fs;
-  char buf[256];
-  size_t bytes;
-
-  fs = Filesystem::OpenFile(path, "wb");
-  ASSERT_TRUE(fs != NULL);
-  EXPECT_EQ(SR_SUCCESS, fs->Write("test", 4, &bytes, NULL));
-  EXPECT_EQ(4U, bytes);
-  delete fs;
-
-  EXPECT_TRUE(Filesystem::IsFile(path));
-
-  fs = Filesystem::OpenFile(path, "rb");
-  ASSERT_TRUE(fs != NULL);
-  EXPECT_EQ(SR_SUCCESS, fs->Read(buf, sizeof(buf), &bytes, NULL));
-  EXPECT_EQ(4U, bytes);
-  delete fs;
-
-  EXPECT_TRUE(Filesystem::DeleteFile(path));
-  EXPECT_FALSE(Filesystem::IsFile(path));
-}
-
-// Test opening a non-existent file.
-TEST(FilesystemTest, TestOpenBadFile) {
-  Pathname path;
-  EXPECT_TRUE(Filesystem::GetTemporaryFolder(path, true, NULL));
-  path.SetFilename("not an actual file");
-
-  EXPECT_FALSE(Filesystem::IsFile(path));
-
-  FileStream* fs = Filesystem::OpenFile(path, "rb");
-  EXPECT_FALSE(fs != NULL);
-}
-
-// Test that CreatePrivateFile fails for existing files and succeeds for
-// non-existent ones.
-TEST(FilesystemTest, TestCreatePrivateFile) {
-  Pathname path;
-  EXPECT_TRUE(Filesystem::GetTemporaryFolder(path, true, NULL));
-  path.SetFilename("private_file_test");
-
-  // First call should succeed because the file doesn't exist yet.
-  EXPECT_TRUE(Filesystem::CreatePrivateFile(path));
-  // Next call should fail, because now it exists.
-  EXPECT_FALSE(Filesystem::CreatePrivateFile(path));
-
-  // Verify that we have permission to open the file for reading and writing.
-  scoped_ptr<FileStream> fs(Filesystem::OpenFile(path, "wb"));
-  EXPECT_TRUE(fs.get() != NULL);
-  // Have to close the file on Windows before it will let us delete it.
-  fs.reset();
-
-  // Verify that we have permission to delete the file.
-  EXPECT_TRUE(Filesystem::DeleteFile(path));
-}
-
-// Test checking for free disk space.
-TEST(FilesystemTest, TestGetDiskFreeSpace) {
-  // Note that we should avoid picking any file/folder which could be located
-  // at the remotely mounted drive/device.
-  Pathname path;
-  ASSERT_TRUE(Filesystem::GetAppDataFolder(&path, true));
-
-  int64 free1 = 0;
-  EXPECT_TRUE(Filesystem::IsFolder(path));
-  EXPECT_FALSE(Filesystem::IsFile(path));
-  EXPECT_TRUE(Filesystem::GetDiskFreeSpace(path, &free1));
-  EXPECT_GT(free1, 0);
-
-  int64 free2 = 0;
-  path.AppendFolder("this_folder_doesnt_exist");
-  EXPECT_FALSE(Filesystem::IsFolder(path));
-  EXPECT_TRUE(Filesystem::IsAbsent(path));
-  EXPECT_TRUE(Filesystem::GetDiskFreeSpace(path, &free2));
-  // These should be the same disk, and disk free space should not have changed
-  // by more than 1% between the two calls.
-  EXPECT_LT(static_cast<int64>(free1 * .9), free2);
-  EXPECT_LT(free2, static_cast<int64>(free1 * 1.1));
-
-  int64 free3 = 0;
-  path.clear();
-  EXPECT_TRUE(path.empty());
-  EXPECT_TRUE(Filesystem::GetDiskFreeSpace(path, &free3));
-  // Current working directory may not be where exe is.
-  // EXPECT_LT(static_cast<int64>(free1 * .9), free3);
-  // EXPECT_LT(free3, static_cast<int64>(free1 * 1.1));
-  EXPECT_GT(free3, 0);
-}
-
-// Tests that GetCurrentDirectory() returns something.
-TEST(FilesystemTest, TestGetCurrentDirectory) {
-  EXPECT_FALSE(Filesystem::GetCurrentDirectory().empty());
-}
-
-// Tests that GetAppPathname returns something.
-TEST(FilesystemTest, TestGetAppPathname) {
-  Pathname path;
-  EXPECT_TRUE(Filesystem::GetAppPathname(&path));
-  EXPECT_FALSE(path.empty());
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/firewallsocketserver.cc b/third_party/libjingle/source/talk/base/firewallsocketserver.cc
deleted file mode 100644
index 71385f8..0000000
--- a/third_party/libjingle/source/talk/base/firewallsocketserver.cc
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/firewallsocketserver.h"
-
-#include <cassert>
-#include <algorithm>
-
-#include "talk/base/asyncsocket.h"
-#include "talk/base/logging.h"
-
-namespace talk_base {
-
-class FirewallSocket : public AsyncSocketAdapter {
- public:
-  FirewallSocket(FirewallSocketServer* server, AsyncSocket* socket, int type)
-    : AsyncSocketAdapter(socket), server_(server), type_(type) {
-  }
-
-  virtual int Connect(const SocketAddress& addr) {
-    if (type_ == SOCK_STREAM) {
-      if (!server_->Check(FP_TCP, GetLocalAddress(), addr)) {
-        LOG(LS_VERBOSE) << "FirewallSocket outbound TCP connection from "
-                        << GetLocalAddress().ToString() << " to "
-                        << addr.ToString() << " denied";
-        // TODO: Handle this asynchronously.
-        SetError(EHOSTUNREACH);
-        return SOCKET_ERROR;
-      }
-    }
-    return AsyncSocketAdapter::Connect(addr);
-  }
-  virtual int Send(const void* pv, size_t cb) {
-    return SendTo(pv, cb, GetRemoteAddress());
-  }
-  virtual int SendTo(const void* pv, size_t cb, const SocketAddress& addr) {
-    if (type_ == SOCK_DGRAM) {
-      if (!server_->Check(FP_UDP, GetLocalAddress(), addr)) {
-        LOG(LS_VERBOSE) << "FirewallSocket outbound UDP packet from "
-                        << GetLocalAddress().ToString() << " to "
-                        << addr.ToString() << " dropped";
-        return static_cast<int>(cb);
-      }
-    }
-    return AsyncSocketAdapter::SendTo(pv, cb, addr);
-  }
-  virtual int Recv(void* pv, size_t cb) {
-    SocketAddress addr;
-    return RecvFrom(pv, cb, &addr);
-  }
-  virtual int RecvFrom(void* pv, size_t cb, SocketAddress* paddr) {
-    if (type_ == SOCK_DGRAM) {
-      while (true) {
-        int res = AsyncSocketAdapter::RecvFrom(pv, cb, paddr);
-        if (res <= 0)
-          return res;
-        if (server_->Check(FP_UDP, *paddr, GetLocalAddress()))
-          return res;
-        LOG(LS_VERBOSE) << "FirewallSocket inbound UDP packet from "
-                        << paddr->ToString() << " to "
-                        << GetLocalAddress().ToString() << " dropped";
-      }
-    }
-    return AsyncSocketAdapter::RecvFrom(pv, cb, paddr);
-  }
-
-  virtual int Listen(int backlog) {
-    if (!server_->tcp_listen_enabled()) {
-      LOG(LS_VERBOSE) << "FirewallSocket listen attempt denied";
-      return -1;
-    }
-
-    return AsyncSocketAdapter::Listen(backlog);
-  }
-  virtual AsyncSocket* Accept(SocketAddress* paddr) {
-    SocketAddress addr;
-    while (AsyncSocket* sock = AsyncSocketAdapter::Accept(&addr)) {
-      if (server_->Check(FP_TCP, addr, GetLocalAddress())) {
-        if (paddr)
-          *paddr = addr;
-        return sock;
-      }
-      sock->Close();
-      delete sock;
-      LOG(LS_VERBOSE) << "FirewallSocket inbound TCP connection from "
-                      << addr.ToString() << " to "
-                      << GetLocalAddress().ToString() << " denied";
-    }
-    return 0;
-  }
-
- private:
-  FirewallSocketServer* server_;
-  int type_;
-};
-
-FirewallSocketServer::FirewallSocketServer(SocketServer* server,
-                                           FirewallManager* manager,
-                                           bool should_delete_server)
-    : server_(server), manager_(manager),
-      should_delete_server_(should_delete_server),
-      udp_sockets_enabled_(true), tcp_sockets_enabled_(true),
-      tcp_listen_enabled_(true) {
-  if (manager_)
-    manager_->AddServer(this);
-}
-
-FirewallSocketServer::~FirewallSocketServer() {
-  if (manager_)
-    manager_->RemoveServer(this);
-
-  if (server_ && should_delete_server_) {
-    delete server_;
-    server_ = NULL;
-  }
-}
-
-void FirewallSocketServer::AddRule(bool allow, FirewallProtocol p,
-                                   FirewallDirection d,
-                                   const SocketAddress& addr) {
-  SocketAddress src, dst;
-  if (d == FD_IN) {
-    dst = addr;
-  } else {
-    src = addr;
-  }
-  AddRule(allow, p, src, dst);
-}
-
-
-void FirewallSocketServer::AddRule(bool allow, FirewallProtocol p,
-                                   const SocketAddress& src,
-                                   const SocketAddress& dst) {
-  Rule r;
-  r.allow = allow;
-  r.p = p;
-  r.src = src;
-  r.dst = dst;
-  CritScope scope(&crit_);
-  rules_.push_back(r);
-}
-
-void FirewallSocketServer::ClearRules() {
-  CritScope scope(&crit_);
-  rules_.clear();
-}
-
-bool FirewallSocketServer::Check(FirewallProtocol p,
-                                 const SocketAddress& src,
-                                 const SocketAddress& dst) {
-  CritScope scope(&crit_);
-  for (size_t i = 0; i < rules_.size(); ++i) {
-    const Rule& r = rules_[i];
-    if ((r.p != p) && (r.p != FP_ANY))
-      continue;
-    if ((r.src.ipaddr() != src.ipaddr()) && !r.src.IsAny())
-      continue;
-    if ((r.src.port() != src.port()) && (r.src.port() != 0))
-      continue;
-    if ((r.dst.ipaddr() != dst.ipaddr()) && !r.dst.IsAny())
-      continue;
-    if ((r.dst.port() != dst.port()) && (r.dst.port() != 0))
-      continue;
-    return r.allow;
-  }
-  return true;
-}
-
-Socket* FirewallSocketServer::CreateSocket(int type) {
-  return WrapSocket(server_->CreateAsyncSocket(type), type);
-}
-
-AsyncSocket* FirewallSocketServer::CreateAsyncSocket(int type) {
-  return WrapSocket(server_->CreateAsyncSocket(type), type);
-}
-
-AsyncSocket* FirewallSocketServer::WrapSocket(AsyncSocket* sock, int type) {
-  if (!sock ||
-      (type == SOCK_STREAM && !tcp_sockets_enabled_) ||
-      (type == SOCK_DGRAM && !udp_sockets_enabled_)) {
-    LOG(LS_VERBOSE) << "FirewallSocketServer socket creation denied";
-    return NULL;
-  }
-  return new FirewallSocket(this, sock, type);
-}
-
-FirewallManager::FirewallManager() {
-}
-
-FirewallManager::~FirewallManager() {
-  assert(servers_.empty());
-}
-
-void FirewallManager::AddServer(FirewallSocketServer* server) {
-  CritScope scope(&crit_);
-  servers_.push_back(server);
-}
-
-void FirewallManager::RemoveServer(FirewallSocketServer* server) {
-  CritScope scope(&crit_);
-  servers_.erase(std::remove(servers_.begin(), servers_.end(), server),
-                 servers_.end());
-}
-
-void FirewallManager::AddRule(bool allow, FirewallProtocol p,
-                              FirewallDirection d, const SocketAddress& addr) {
-  CritScope scope(&crit_);
-  for (std::vector<FirewallSocketServer*>::const_iterator it =
-      servers_.begin(); it != servers_.end(); ++it) {
-    (*it)->AddRule(allow, p, d, addr);
-  }
-}
-
-void FirewallManager::ClearRules() {
-  CritScope scope(&crit_);
-  for (std::vector<FirewallSocketServer*>::const_iterator it =
-      servers_.begin(); it != servers_.end(); ++it) {
-    (*it)->ClearRules();
-  }
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/firewallsocketserver.h b/third_party/libjingle/source/talk/base/firewallsocketserver.h
deleted file mode 100644
index 94ba2d2..0000000
--- a/third_party/libjingle/source/talk/base/firewallsocketserver.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_FIREWALLSOCKETSERVER_H_
-#define TALK_BASE_FIREWALLSOCKETSERVER_H_
-
-#include <vector>
-#include "talk/base/socketserver.h"
-#include "talk/base/criticalsection.h"
-
-namespace talk_base {
-
-class FirewallManager;
-
-// This SocketServer shim simulates a rule-based firewall server.
-
-enum FirewallProtocol { FP_UDP, FP_TCP, FP_ANY };
-enum FirewallDirection { FD_IN, FD_OUT, FD_ANY };
-
-class FirewallSocketServer : public SocketServer {
- public:
-  FirewallSocketServer(SocketServer * server,
-                       FirewallManager * manager = NULL,
-                       bool should_delete_server = false);
-  virtual ~FirewallSocketServer();
-
-  SocketServer* socketserver() const { return server_; }
-  void set_socketserver(SocketServer* server) {
-    if (server_ && should_delete_server_) {
-      delete server_;
-      server_ = NULL;
-      should_delete_server_ = false;
-    }
-    server_ = server;
-  }
-
-  // Settings to control whether CreateSocket or Socket::Listen succeed.
-  void set_udp_sockets_enabled(bool enabled) { udp_sockets_enabled_ = enabled; }
-  void set_tcp_sockets_enabled(bool enabled) { tcp_sockets_enabled_ = enabled; }
-  bool tcp_listen_enabled() const { return tcp_listen_enabled_; }
-  void set_tcp_listen_enabled(bool enabled) { tcp_listen_enabled_ = enabled; }
-
-  // Rules govern the behavior of Connect/Accept/Send/Recv attempts.
-  void AddRule(bool allow, FirewallProtocol p = FP_ANY,
-               FirewallDirection d = FD_ANY,
-               const SocketAddress& addr = SocketAddress());
-  void AddRule(bool allow, FirewallProtocol p,
-               const SocketAddress& src, const SocketAddress& dst);
-  void ClearRules();
-
-  bool Check(FirewallProtocol p,
-             const SocketAddress& src, const SocketAddress& dst);
-
-  virtual Socket* CreateSocket(int type);
-  virtual AsyncSocket* CreateAsyncSocket(int type);
-  virtual void SetMessageQueue(MessageQueue* queue) {
-    server_->SetMessageQueue(queue);
-  }
-  virtual bool Wait(int cms, bool process_io) {
-    return server_->Wait(cms, process_io);
-  }
-  virtual void WakeUp() {
-    return server_->WakeUp();
-  }
-
-  Socket * WrapSocket(Socket * sock, int type);
-  AsyncSocket * WrapSocket(AsyncSocket * sock, int type);
-
- private:
-  SocketServer * server_;
-  FirewallManager * manager_;
-  CriticalSection crit_;
-  struct Rule {
-    bool allow;
-    FirewallProtocol p;
-    FirewallDirection d;
-    SocketAddress src;
-    SocketAddress dst;
-  };
-  std::vector<Rule> rules_;
-  bool should_delete_server_;
-  bool udp_sockets_enabled_;
-  bool tcp_sockets_enabled_;
-  bool tcp_listen_enabled_;
-};
-
-// FirewallManager allows you to manage firewalls in multiple threads together
-
-class FirewallManager {
- public:
-  FirewallManager();
-  ~FirewallManager();
-
-  void AddServer(FirewallSocketServer * server);
-  void RemoveServer(FirewallSocketServer * server);
-
-  void AddRule(bool allow, FirewallProtocol p = FP_ANY,
-               FirewallDirection d = FD_ANY,
-               const SocketAddress& addr = SocketAddress());
-  void ClearRules();
-
- private:
-  CriticalSection crit_;
-  std::vector<FirewallSocketServer *> servers_;
-};
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_FIREWALLSOCKETSERVER_H_
diff --git a/third_party/libjingle/source/talk/base/flags.cc b/third_party/libjingle/source/talk/base/flags.cc
deleted file mode 100644
index 09a8edf..0000000
--- a/third_party/libjingle/source/talk/base/flags.cc
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- * libjingle
- * Copyright 2006, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-
-#ifdef WIN32
-#include "talk/base/win32.h"
-#include <shellapi.h>
-#endif
-
-#include "talk/base/flags.h"
-
-
-// -----------------------------------------------------------------------------
-// Implementation of Flag
-
-Flag::Flag(const char* file, const char* name, const char* comment,
-           Type type, void* variable, FlagValue default__)
-    : file_(file),
-      name_(name),
-      comment_(comment),
-      type_(type),
-      variable_(reinterpret_cast<FlagValue*>(variable)),
-      default_(default__) {
-  FlagList::Register(this);
-}
-
-
-void Flag::SetToDefault() {
-  // Note that we cannot simply do '*variable_ = default_;' since
-  // flag variables are not really of type FlagValue and thus may
-  // be smaller! The FlagValue union is simply 'overlayed' on top
-  // of a flag variable for convenient access. Since union members
-  // are guarantee to be aligned at the beginning, this works.
-  switch (type_) {
-    case Flag::BOOL:
-      variable_->b = default_.b;
-      return;
-    case Flag::INT:
-      variable_->i = default_.i;
-      return;
-    case Flag::FLOAT:
-      variable_->f = default_.f;
-      return;
-    case Flag::STRING:
-      variable_->s = default_.s;
-      return;
-  }
-  UNREACHABLE();
-}
-
-
-static const char* Type2String(Flag::Type type) {
-  switch (type) {
-    case Flag::BOOL: return "bool";
-    case Flag::INT: return "int";
-    case Flag::FLOAT: return "float";
-    case Flag::STRING: return "string";
-  }
-  UNREACHABLE();
-  return NULL;
-}
-
-
-static void PrintFlagValue(Flag::Type type, FlagValue* p) {
-  switch (type) {
-    case Flag::BOOL:
-      printf("%s", (p->b ? "true" : "false"));
-      return;
-    case Flag::INT:
-      printf("%d", p->i);
-      return;
-    case Flag::FLOAT:
-      printf("%f", p->f);
-      return;
-    case Flag::STRING:
-      printf("%s", p->s);
-      return;
-  }
-  UNREACHABLE();
-}
-
-
-void Flag::Print(bool print_current_value) {
-  printf("  --%s (%s)  type: %s  default: ", name_, comment_,
-          Type2String(type_));
-  PrintFlagValue(type_, &default_);
-  if (print_current_value) {
-    printf("  current value: ");
-    PrintFlagValue(type_, variable_);
-  }
-  printf("\n");
-}
-
-
-// -----------------------------------------------------------------------------
-// Implementation of FlagList
-
-Flag* FlagList::list_ = NULL;
-
-
-FlagList::FlagList() {
-  list_ = NULL;
-}
-
-void FlagList::Print(const char* file, bool print_current_value) {
-  // Since flag registration is likely by file (= C++ file),
-  // we don't need to sort by file and still get grouped output.
-  const char* current = NULL;
-  for (Flag* f = list_; f != NULL; f = f->next()) {
-    if (file == NULL || file == f->file()) {
-      if (current != f->file()) {
-        printf("Flags from %s:\n", f->file());
-        current = f->file();
-      }
-      f->Print(print_current_value);
-    }
-  }
-}
-
-
-Flag* FlagList::Lookup(const char* name) {
-  Flag* f = list_;
-  while (f != NULL && strcmp(name, f->name()) != 0)
-    f = f->next();
-  return f;
-}
-
-
-void FlagList::SplitArgument(const char* arg,
-                             char* buffer, int buffer_size,
-                             const char** name, const char** value,
-                             bool* is_bool) {
-  *name = NULL;
-  *value = NULL;
-  *is_bool = false;
-
-  if (*arg == '-') {
-    // find the begin of the flag name
-    arg++;  // remove 1st '-'
-    if (*arg == '-')
-      arg++;  // remove 2nd '-'
-    if (arg[0] == 'n' && arg[1] == 'o') {
-      arg += 2;  // remove "no"
-      *is_bool = true;
-    }
-    *name = arg;
-
-    // find the end of the flag name
-    while (*arg != '\0' && *arg != '=')
-      arg++;
-
-    // get the value if any
-    if (*arg == '=') {
-      // make a copy so we can NUL-terminate flag name
-      int n = arg - *name;
-      if (n >= buffer_size)
-        Fatal(__FILE__, __LINE__, "CHECK(%s) failed", "n < buffer_size");
-      memcpy(buffer, *name, n * sizeof(char));
-      buffer[n] = '\0';
-      *name = buffer;
-      // get the value
-      *value = arg + 1;
-    }
-  }
-}
-
-
-int FlagList::SetFlagsFromCommandLine(int* argc, const char** argv,
-                                      bool remove_flags) {
-  // parse arguments
-  for (int i = 1; i < *argc; /* see below */) {
-    int j = i;  // j > 0
-    const char* arg = argv[i++];
-
-    // split arg into flag components
-    char buffer[1024];
-    const char* name;
-    const char* value;
-    bool is_bool;
-    SplitArgument(arg, buffer, sizeof buffer, &name, &value, &is_bool);
-
-    if (name != NULL) {
-      // lookup the flag
-      Flag* flag = Lookup(name);
-      if (flag == NULL) {
-        fprintf(stderr, "Error: unrecognized flag %s\n", arg);
-        return j;
-      }
-
-      // if we still need a flag value, use the next argument if available
-      if (flag->type() != Flag::BOOL && value == NULL) {
-        if (i < *argc) {
-          value = argv[i++];
-        } else {
-          fprintf(stderr, "Error: missing value for flag %s of type %s\n",
-            arg, Type2String(flag->type()));
-          return j;
-        }
-      }
-
-      // set the flag
-      char empty[] = { '\0' };
-      char* endp = empty;
-      switch (flag->type()) {
-        case Flag::BOOL:
-          *flag->bool_variable() = !is_bool;
-          break;
-        case Flag::INT:
-          *flag->int_variable() = strtol(value, &endp, 10);
-          break;
-        case Flag::FLOAT:
-          *flag->float_variable() = strtod(value, &endp);
-          break;
-        case Flag::STRING:
-          *flag->string_variable() = value;
-          break;
-      }
-
-      // handle errors
-      if ((flag->type() == Flag::BOOL && value != NULL) ||
-          (flag->type() != Flag::BOOL && is_bool) ||
-          *endp != '\0') {
-        fprintf(stderr, "Error: illegal value for flag %s of type %s\n",
-          arg, Type2String(flag->type()));
-        return j;
-      }
-
-      // remove the flag & value from the command
-      if (remove_flags)
-        while (j < i)
-          argv[j++] = NULL;
-    }
-  }
-
-  // shrink the argument list
-  if (remove_flags) {
-    int j = 1;
-    for (int i = 1; i < *argc; i++) {
-      if (argv[i] != NULL)
-        argv[j++] = argv[i];
-    }
-    *argc = j;
-  }
-
-  // parsed all flags successfully
-  return 0;
-}
-
-void FlagList::Register(Flag* flag) {
-  assert(flag != NULL && strlen(flag->name()) > 0);
-  if (Lookup(flag->name()) != NULL)
-    Fatal(flag->file(), 0, "flag %s declared twice", flag->name());
-  flag->next_ = list_;
-  list_ = flag;
-}
-
-#ifdef WIN32
-WindowsCommandLineArguments::WindowsCommandLineArguments() {
-  // start by getting the command line.
-  LPTSTR command_line = ::GetCommandLine();
-   // now, convert it to a list of wide char strings.
-  LPWSTR *wide_argv = ::CommandLineToArgvW(command_line, &argc_);
-  // now allocate an array big enough to hold that many string pointers.
-  argv_ = new char*[argc_];
-
-  // iterate over the returned wide strings;
-  for(int i = 0; i < argc_; ++i) {
-    // for each, create a char buffer big enough to hold it; so, find out
-    // how much space we need.
-    int len8 = WideCharToMultiByte(CP_UTF8, 0, wide_argv[i],
-                                   wcslen(wide_argv[i]), NULL, 0,
-                                   NULL, NULL);
-    // then allocate the buffer...
-    char *buffer = new char[1 + len8]; // +1 for trailing \0
-    // and do the conversion.
-    WideCharToMultiByte(CP_UTF8, 0, wide_argv[i],
-                        wcslen(wide_argv[i]), buffer, len8,
-                        NULL, NULL);
-    // WideCharToMultibyte doesn't give us a trailing \0, so we add it.
-    buffer[len8] = '\0';
-    // make sure the argv array has the right string at this point.
-    argv_[i] = buffer;
-  }
-  LocalFree(wide_argv);
-}
-
-WindowsCommandLineArguments::~WindowsCommandLineArguments() {
-  // need to free each string in the array, and then the array.
-  for(int i = 0; i < argc_; i++) {
-    delete[] argv_[i];
-  }
-
-  delete[] argv_;
-}
-#endif  // WIN32
-
diff --git a/third_party/libjingle/source/talk/base/flags.h b/third_party/libjingle/source/talk/base/flags.h
deleted file mode 100644
index f22e125..0000000
--- a/third_party/libjingle/source/talk/base/flags.h
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * libjingle
- * Copyright 2006, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-// Originally comes from shared/commandlineflags/flags.h
-
-// Flags are defined and declared using DEFINE_xxx and DECLARE_xxx macros,
-// where xxx is the flag type. Flags are referred to via FLAG_yyy,
-// where yyy is the flag name. For intialization and iteration of flags,
-// see the FlagList class. For full programmatic access to any
-// flag, see the Flag class.
-//
-// The implementation only relies and basic C++ functionality
-// and needs no special library or STL support.
-
-#ifndef TALK_BASE_FLAGS_H__
-#define TALK_BASE_FLAGS_H__
-
-#include <assert.h>
-
-#include "talk/base/checks.h"
-#include "talk/base/common.h"
-
-// Internal use only.
-union FlagValue {
-  // Note: Because in C++ non-bool values are silently converted into
-  // bool values ('bool b = "false";' results in b == true!), we pass
-  // and int argument to New_BOOL as this appears to be safer - sigh.
-  // In particular, it prevents the (not uncommon!) bug where a bool
-  // flag is defined via: DEFINE_bool(flag, "false", "some comment");.
-  static FlagValue New_BOOL(int b) {
-    FlagValue v;
-    v.b = (b != 0);
-    return v;
-  }
-
-  static FlagValue New_INT(int i) {
-    FlagValue v;
-    v.i = i;
-    return v;
-  }
-
-  static FlagValue New_FLOAT(float f) {
-    FlagValue v;
-    v.f = f;
-    return v;
-  }
-
-  static FlagValue New_STRING(const char* s) {
-    FlagValue v;
-    v.s = s;
-    return v;
-  }
-
-  bool b;
-  int i;
-  double f;
-  const char* s;
-};
-
-
-// Each flag can be accessed programmatically via a Flag object.
-class Flag {
- public:
-  enum Type { BOOL, INT, FLOAT, STRING };
-
-  // Internal use only.
-  Flag(const char* file, const char* name, const char* comment,
-       Type type, void* variable, FlagValue default_);
-
-  // General flag information
-  const char* file() const  { return file_; }
-  const char* name() const  { return name_; }
-  const char* comment() const  { return comment_; }
-
-  // Flag type
-  Type type() const  { return type_; }
-
-  // Flag variables
-  bool* bool_variable() const {
-    assert(type_ == BOOL);
-    return &variable_->b;
-  }
-  
-  int* int_variable() const {
-    assert(type_ == INT);
-    return &variable_->i;
-  }
-  
-  double* float_variable() const {
-    assert(type_ == FLOAT);
-    return &variable_->f;
-  }
-  
-  const char** string_variable() const {
-    assert(type_ == STRING);
-    return &variable_->s;
-  }
-
-  // Default values
-  bool bool_default() const {
-    assert(type_ == BOOL);
-    return default_.b;
-  }
-  
-  int int_default() const {
-    assert(type_ == INT);
-    return default_.i;
-  }
-  
-  double float_default() const {
-    assert(type_ == FLOAT);
-    return default_.f;
-  }
-  
-  const char* string_default() const {
-    assert(type_ == STRING);
-    return default_.s;
-  }
-
-  // Resets a flag to its default value
-  void SetToDefault();
-
-  // Iteration support
-  Flag* next() const  { return next_; }
-
-  // Prints flag information. The current flag value is only printed
-  // if print_current_value is set.
-  void Print(bool print_current_value);
-
- private:
-  const char* file_;
-  const char* name_;
-  const char* comment_;
-
-  Type type_;
-  FlagValue* variable_;
-  FlagValue default_;
-
-  Flag* next_;
-
-  friend class FlagList;  // accesses next_
-};
-
-
-// Internal use only.
-#define DEFINE_FLAG(type, c_type, name, default, comment) \
-  /* define and initialize the flag */                    \
-  c_type FLAG_##name = (default);                         \
-  /* register the flag */                                 \
-  static Flag Flag_##name(__FILE__, #name, (comment),   \
-                          Flag::type, &FLAG_##name,       \
-                          FlagValue::New_##type(default))
-
-
-// Internal use only.
-#define DECLARE_FLAG(c_type, name)              \
-  /* declare the external flag */               \
-  extern c_type FLAG_##name
-
-
-// Use the following macros to define a new flag:
-#define DEFINE_bool(name, default, comment) \
-  DEFINE_FLAG(BOOL, bool, name, default, comment)
-#define DEFINE_int(name, default, comment) \
-  DEFINE_FLAG(INT, int, name, default, comment)
-#define DEFINE_float(name, default, comment) \
-  DEFINE_FLAG(FLOAT, double, name, default, comment)
-#define DEFINE_string(name, default, comment) \
-  DEFINE_FLAG(STRING, const char*, name, default, comment)
-
-
-// Use the following macros to declare a flag defined elsewhere:
-#define DECLARE_bool(name)  DECLARE_FLAG(bool, name)
-#define DECLARE_int(name)  DECLARE_FLAG(int, name)
-#define DECLARE_float(name)  DECLARE_FLAG(double, name)
-#define DECLARE_string(name)  DECLARE_FLAG(const char*, name)
-
-
-// The global list of all flags.
-class FlagList {
- public:
-  FlagList();
-
-  // The NULL-terminated list of all flags. Traverse with Flag::next().
-  static Flag* list()  { return list_; }
-
-  // If file != NULL, prints information for all flags defined in file;
-  // otherwise prints information for all flags in all files. The current
-  // flag value is only printed if print_current_value is set.
-  static void Print(const char* file, bool print_current_value);
-
-  // Lookup a flag by name. Returns the matching flag or NULL.
-  static Flag* Lookup(const char* name);
-
-  // Helper function to parse flags: Takes an argument arg and splits it into
-  // a flag name and flag value (or NULL if they are missing). is_bool is set
-  // if the arg started with "-no" or "--no". The buffer may be used to NUL-
-  // terminate the name, it must be large enough to hold any possible name.
-  static void SplitArgument(const char* arg,
-                            char* buffer, int buffer_size,
-                            const char** name, const char** value,
-                            bool* is_bool);
-
-  // Set the flag values by parsing the command line. If remove_flags
-  // is set, the flags and associated values are removed from (argc,
-  // argv). Returns 0 if no error occurred. Otherwise, returns the
-  // argv index > 0 for the argument where an error occurred. In that
-  // case, (argc, argv) will remain unchanged indepdendent of the
-  // remove_flags value, and no assumptions about flag settings should
-  // be made.
-  //
-  // The following syntax for flags is accepted (both '-' and '--' are ok):
-  //
-  //   --flag        (bool flags only)
-  //   --noflag      (bool flags only)
-  //   --flag=value  (non-bool flags only, no spaces around '=')
-  //   --flag value  (non-bool flags only)
-  static int SetFlagsFromCommandLine(int* argc,
-                                     const char** argv,
-                                     bool remove_flags);
-  static inline int SetFlagsFromCommandLine(int* argc,
-                                            char** argv,
-                                            bool remove_flags) {
-    return SetFlagsFromCommandLine(argc, const_cast<const char**>(argv),
-                                   remove_flags);
-  }
-
-  // Registers a new flag. Called during program initialization. Not
-  // thread-safe.
-  static void Register(Flag* flag);
-
- private:
-  static Flag* list_;
-};
-
-#ifdef WIN32
-// A helper class to translate Windows command line arguments into UTF8,
-// which then allows us to just pass them to the flags system.
-// This encapsulates all the work of getting the command line and translating
-// it to an array of 8-bit strings; all you have to do is create one of these,
-// and then call argc() and argv().
-class WindowsCommandLineArguments {
- public:
-  WindowsCommandLineArguments();
-  ~WindowsCommandLineArguments();
-
-  int argc() { return argc_; }
-  char **argv() { return argv_; }
- private:
-  int argc_;
-  char **argv_;
-
- private:
-  DISALLOW_EVIL_CONSTRUCTORS(WindowsCommandLineArguments);
-};
-#endif  // WIN32
-
-
-#endif  // SHARED_COMMANDLINEFLAGS_FLAGS_H__
diff --git a/third_party/libjingle/source/talk/base/gunit.h b/third_party/libjingle/source/talk/base/gunit.h
deleted file mode 100644
index 0682337..0000000
--- a/third_party/libjingle/source/talk/base/gunit.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2008, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_GUNIT_H_
-#define TALK_BASE_GUNIT_H_
-
-#include "talk/base/logging.h"
-#include "talk/base/thread.h"
-#ifdef ANDROID
-#include <gtest/gtest.h>
-#elif LIBJINGLE_UNITTEST
-#include "third_party/gtest/include/gtest/gtest.h"
-#else
-#include "testing/base/public/gunit.h"
-#endif
-
-// forward declarations
-namespace talk_base {
-class Pathname;
-}
-
-// Wait until "ex" is true, or "timeout" expires.
-#define WAIT(ex, timeout) \
-  for (uint32 start = talk_base::Time(); \
-      !(ex) && talk_base::Time() < start + timeout;) \
-    talk_base::Thread::Current()->ProcessMessages(1);
-
-// This returns the result of the test in res, so that we don't re-evaluate
-// the expression in the XXXX_WAIT macros below, since that causes problems
-// when the expression is only true the first time you check it.
-#define WAIT_(ex, timeout, res) \
-  do { \
-    uint32 start = talk_base::Time(); \
-    res = (ex); \
-    while (!res && talk_base::Time() < start + timeout) { \
-      talk_base::Thread::Current()->ProcessMessages(1); \
-      res = (ex); \
-    } \
-  } while (0);
-
-// The typical EXPECT_XXXX and ASSERT_XXXXs, but done until true or a timeout.
-#define EXPECT_TRUE_WAIT(ex, timeout) \
-  do { \
-    bool res; \
-    WAIT_(ex, timeout, res); \
-    if (!res) EXPECT_TRUE(ex); \
-  } while (0);
-
-#define EXPECT_EQ_WAIT(v1, v2, timeout) \
-  do { \
-    bool res; \
-    WAIT_(v1 == v2, timeout, res); \
-    if (!res) EXPECT_EQ(v1, v2); \
-  } while (0);
-
-#define ASSERT_TRUE_WAIT(ex, timeout) \
-  do { \
-    bool res; \
-    WAIT_(ex, timeout, res); \
-    if (!res) ASSERT_TRUE(ex); \
-  } while (0);
-
-#define ASSERT_EQ_WAIT(v1, v2, timeout) \
-  do { \
-    bool res; \
-    WAIT_(v1 == v2, timeout, res); \
-    if (!res) ASSERT_EQ(v1, v2); \
-  } while (0);
-
-// Version with a "soft" timeout and a margin. This logs if the timeout is
-// exceeded, but it only fails if the expression still isn't true after the
-// margin time passes.
-#define EXPECT_TRUE_WAIT_MARGIN(ex, timeout, margin) \
-  do { \
-    bool res; \
-    WAIT_(ex, timeout, res); \
-    if (res) { \
-      break; \
-    } \
-    LOG(LS_WARNING) << "Expression " << #ex << " still not true after " << \
-        timeout << "ms; waiting an additional " << margin << "ms"; \
-    WAIT_(ex, margin, res); \
-    if (!res) { \
-      EXPECT_TRUE(ex); \
-    } \
-  } while (0);
-
-talk_base::Pathname GetTalkDirectory();
-
-#endif  // TALK_BASE_GUNIT_H_
diff --git a/third_party/libjingle/source/talk/base/helpers.cc b/third_party/libjingle/source/talk/base/helpers.cc
deleted file mode 100644
index 855305e..0000000
--- a/third_party/libjingle/source/talk/base/helpers.cc
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/helpers.h"
-
-#include <limits>
-
-#ifdef WIN32
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <ntsecapi.h>
-#else
-#ifdef SSL_USE_OPENSSL
-#include <openssl/rand.h>
-#endif
-#endif
-
-#include "talk/base/base64.h"
-#include "talk/base/logging.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/base/timeutils.h"
-
-// Protect against max macro inclusion.
-#undef max
-
-namespace talk_base {
-
-// Base class for RNG implementations.
-class RandomGenerator {
- public:
-  virtual ~RandomGenerator() {}
-  virtual bool Init(const void* seed, size_t len) = 0;
-  virtual bool Generate(void* buf, size_t len) = 0;
-};
-
-// The real random generators, using either CryptoAPI or OpenSSL.
-// We also support the 'old' generator on Mac/Linux until we have time to
-// fully test the OpenSSL one.
-#ifdef WIN32
-class SecureRandomGenerator : public RandomGenerator {
- public:
-  SecureRandomGenerator() : advapi32_(NULL), rtl_gen_random_(NULL) {}
-  ~SecureRandomGenerator() {
-    FreeLibrary(advapi32_);
-  }
-
-  virtual bool Init(const void* seed, size_t seed_len) {
-    // We don't do any additional seeding on Win32, we just use the CryptoAPI
-    // RNG (which is exposed as a hidden function off of ADVAPI32 so that we
-    // don't need to drag in all of CryptoAPI)
-    if (rtl_gen_random_) {
-      return true;
-    }
-
-    advapi32_ = LoadLibrary(L"advapi32.dll");
-    if (!advapi32_) {
-      return false;
-    }
-
-    rtl_gen_random_ = reinterpret_cast<RtlGenRandomProc>(
-        GetProcAddress(advapi32_, "SystemFunction036"));
-    if (!rtl_gen_random_) {
-      FreeLibrary(advapi32_);
-      return false;
-    }
-
-    return true;
-  }
-  virtual bool Generate(void* buf, size_t len) {
-    if (!rtl_gen_random_ && !Init(NULL, 0)) {
-      return false;
-    }
-    return (rtl_gen_random_(buf, len) != FALSE);
-  }
-
- private:
-  typedef BOOL (WINAPI *RtlGenRandomProc)(PVOID, ULONG);
-  HINSTANCE advapi32_;
-  RtlGenRandomProc rtl_gen_random_;
-};
-#else
-#ifndef SSL_USE_OPENSSL
-// The old RNG.
-class SecureRandomGenerator : public RandomGenerator {
- public:
-  SecureRandomGenerator() : seed_(1) {
-  }
-  ~SecureRandomGenerator() {
-  }
-  virtual bool Init(const void* seed, size_t len) {
-    uint32 hash = 0;
-    for (size_t i = 0; i < len; ++i) {
-      hash = ((hash << 2) + hash) + static_cast<const char*>(seed)[i];
-    }
-
-    seed_ = Time() ^ hash;
-    return true;
-  }
-  virtual bool Generate(void* buf, size_t len) {
-    for (size_t i = 0; i < len; ++i) {
-      static_cast<uint8*>(buf)[i] = static_cast<uint8>(GetRandom());
-    }
-    return true;
-  }
-
- private:
-  int GetRandom() {
-    return ((seed_ = seed_ * 214013L + 2531011L) >> 16) & 0x7fff;
-  }
-  int seed_;
-};
-#else
-// The OpenSSL RNG. Need to make sure it doesn't run out of entropy.
-class SecureRandomGenerator : public RandomGenerator {
- public:
-  SecureRandomGenerator() : inited_(false) {
-  }
-  ~SecureRandomGenerator() {
-  }
-  virtual bool Init(const void* seed, size_t len) {
-    // By default, seed from the system state.
-    if (!inited_) {
-      if (RAND_poll() <= 0) {
-        return false;
-      }
-      inited_ = true;
-    }
-    // Allow app data to be mixed in, if provided.
-    if (seed) {
-      RAND_seed(seed, len);
-    }
-    return true;
-  }
-  virtual bool Generate(void* buf, size_t len) {
-    if (!inited_ && !Init(NULL, 0)) {
-      return false;
-    }
-    return (RAND_bytes(reinterpret_cast<unsigned char*>(buf), len) > 0);
-  }
-
- private:
-  bool inited_;
-};
-#endif  // SSL_USE_OPENSSL
-#endif  // WIN32
-
-// A test random generator, for predictable output.
-class TestRandomGenerator : public RandomGenerator {
- public:
-  TestRandomGenerator() : seed_(7) {
-  }
-  ~TestRandomGenerator() {
-  }
-  virtual bool Init(const void* seed, size_t len) {
-    return true;
-  }
-  virtual bool Generate(void* buf, size_t len) {
-    for (size_t i = 0; i < len; ++i) {
-      static_cast<uint8*>(buf)[i] = static_cast<uint8>(GetRandom());
-    }
-    return true;
-  }
-
- private:
-  int GetRandom() {
-    return ((seed_ = seed_ * 214013L + 2531011L) >> 16) & 0x7fff;
-  }
-  int seed_;
-};
-
-// TODO: Use Base64::Base64Table instead.
-static const char BASE64[64] = {
-  'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
-  'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
-  'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
-  'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
-  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
-};
-
-namespace {
-
-// This round about way of creating a global RNG is to safe-guard against
-// indeterminant static initialization order.
-RandomGenerator*& GetGlobalRng() {
-  static RandomGenerator* g_rng = new SecureRandomGenerator();
-  return g_rng;
-}
-
-RandomGenerator& Rng() {
-  return *GetGlobalRng();
-}
-
-}  // namespace
-
-void SetRandomTestMode(bool test) {
-  if (!test) {
-    GetGlobalRng() = new SecureRandomGenerator();
-  } else {
-    GetGlobalRng() = new TestRandomGenerator();
-  }
-}
-
-bool InitRandom(int seed) {
-  return InitRandom(reinterpret_cast<const char*>(&seed), sizeof(seed));
-}
-
-bool InitRandom(const char* seed, size_t len) {
-  if (!Rng().Init(seed, len)) {
-    LOG(LS_ERROR) << "Failed to init random generator!";
-    return false;
-  }
-  return true;
-}
-
-std::string CreateRandomString(size_t len) {
-  std::string str;
-  CreateRandomString(len, &str);
-  return str;
-}
-
-bool CreateRandomString(size_t len,
-                        const char* table, int table_size,
-                        std::string* str) {
-  str->clear();
-  scoped_array<uint8> bytes(new uint8[len]);
-  if (!Rng().Generate(bytes.get(), len)) {
-    LOG(LS_ERROR) << "Failed to generate random string!";
-    return false;
-  }
-  str->reserve(len);
-  for (size_t i = 0; i < len; ++i) {
-    str->push_back(table[bytes[i] % table_size]);
-  }
-  return true;
-}
-
-bool CreateRandomString(size_t len, std::string* str) {
-  return CreateRandomString(len, BASE64, 64, str);
-}
-
-bool CreateRandomString(size_t len, const std::string& table,
-                        std::string* str) {
-  return CreateRandomString(len, table.c_str(), table.size(), str);
-}
-
-uint32 CreateRandomId() {
-  uint32 id;
-  if (!Rng().Generate(&id, sizeof(id))) {
-    LOG(LS_ERROR) << "Failed to generate random id!";
-  }
-  return id;
-}
-
-uint32 CreateRandomNonZeroId() {
-  uint32 id;
-  do {
-    id = CreateRandomId();
-  } while (id == 0);
-  return id;
-}
-
-double CreateRandomDouble() {
-  return CreateRandomId() / (std::numeric_limits<uint32>::max() +
-      std::numeric_limits<double>::epsilon());
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/helpers.h b/third_party/libjingle/source/talk/base/helpers.h
deleted file mode 100644
index 3e3eea7..0000000
--- a/third_party/libjingle/source/talk/base/helpers.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_HELPERS_H_
-#define TALK_BASE_HELPERS_H_
-
-#include <string>
-#include "talk/base/basictypes.h"
-
-namespace talk_base {
-
-// For testing, we can return predictable data.
-void SetRandomTestMode(bool test);
-
-// Initializes the RNG, and seeds it with the specified entropy.
-bool InitRandom(int seed);
-bool InitRandom(const char* seed, size_t len);
-
-// Generates a (cryptographically) random string of the given length.
-// We generate base64 values so that they will be printable.
-// WARNING: could silently fail. Use the version below instead.
-std::string CreateRandomString(size_t length);
-
-// Generates a (cryptographically) random string of the given length.
-// We generate base64 values so that they will be printable.
-// Return false if the random number generator failed.
-bool CreateRandomString(size_t length, std::string* str);
-
-// Generates a (cryptographically) random string of the given length,
-// with characters from the given table. Return false if the random
-// number generator failed.
-bool CreateRandomString(size_t length, const std::string& table,
-                        std::string* str);
-
-// Generates a random id.
-uint32 CreateRandomId();
-
-// Generates a random id > 0.
-uint32 CreateRandomNonZeroId();
-
-// Generates a random double between 0.0 (inclusive) and 1.0 (exclusive).
-double CreateRandomDouble();
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_HELPERS_H_
diff --git a/third_party/libjingle/source/talk/base/helpers_unittest.cc b/third_party/libjingle/source/talk/base/helpers_unittest.cc
deleted file mode 100644
index 0fe1d5b..0000000
--- a/third_party/libjingle/source/talk/base/helpers_unittest.cc
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string>
-
-#include "talk/base/gunit.h"
-#include "talk/base/helpers.h"
-
-namespace talk_base {
-
-TEST(RandomTest, TestCreateRandomId) {
-  CreateRandomId();
-}
-
-TEST(RandomTest, TestCreateRandomDouble) {
-  for (int i = 0; i < 100; ++i) {
-    double r = CreateRandomDouble();
-    EXPECT_GE(r, 0.0);
-    EXPECT_LT(r, 1.0);
-  }
-}
-
-TEST(RandomTest, TestCreateNonZeroRandomId) {
-  EXPECT_NE(0U, CreateRandomNonZeroId());
-}
-
-TEST(RandomTest, TestCreateRandomString) {
-  std::string random = CreateRandomString(256);
-  EXPECT_EQ(256U, random.size());
-  std::string random2;
-  EXPECT_TRUE(CreateRandomString(256, &random2));
-  EXPECT_NE(random, random2);
-  EXPECT_EQ(256U, random2.size());
-}
-
-TEST(RandomTest, TestCreateRandomForTest) {
-  // Make sure we get the output we expect.
-  SetRandomTestMode(true);
-  EXPECT_EQ(2154761789U, CreateRandomId());
-  EXPECT_EQ("h0ISP4S5SJKH/9EY", CreateRandomString(16));
-
-  // Reset and make sure we get the same output.
-  SetRandomTestMode(true);
-  EXPECT_EQ(2154761789U, CreateRandomId());
-  EXPECT_EQ("h0ISP4S5SJKH/9EY", CreateRandomString(16));
-
-  // Test different character sets.
-  SetRandomTestMode(true);
-  std::string str;
-  EXPECT_TRUE(CreateRandomString(16, "a", &str));
-  EXPECT_EQ("aaaaaaaaaaaaaaaa", str);
-  EXPECT_TRUE(CreateRandomString(16, "abc", &str));
-  EXPECT_EQ("acbccaaaabbaacbb", str);
-
-  // Turn off test mode for other tests.
-  SetRandomTestMode(false);
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/host.cc b/third_party/libjingle/source/talk/base/host.cc
deleted file mode 100644
index 7decc49..0000000
--- a/third_party/libjingle/source/talk/base/host.cc
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/host.h"
-
-#ifdef POSIX
-#include <sys/utsname.h>
-#endif  // POSIX
-
-#include <string>
-
-namespace talk_base {
-
-std::string GetHostName() {
-  // TODO: fix or get rid of this
-#if 0
-  struct utsname nm;
-  if (uname(&nm) < 0)
-    FatalError("uname", LAST_SYSTEM_ERROR);
-  return std::string(nm.nodename);
-#endif
-  return "cricket";
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/host.h b/third_party/libjingle/source/talk/base/host.h
deleted file mode 100644
index 8528240..0000000
--- a/third_party/libjingle/source/talk/base/host.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_HOST_H_
-#define TALK_BASE_HOST_H_
-
-#include <string>
-
-namespace talk_base {
-
-// Returns the name of the local host.
-std::string GetHostName();
-
-} // namespace talk_base
-
-#endif // TALK_BASE_HOST_H_
diff --git a/third_party/libjingle/source/talk/base/host_unittest.cc b/third_party/libjingle/source/talk/base/host_unittest.cc
deleted file mode 100644
index aba87af..0000000
--- a/third_party/libjingle/source/talk/base/host_unittest.cc
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/gunit.h"
-#include "talk/base/host.h"
-
-TEST(Host, GetHostName) {
-  EXPECT_NE("", talk_base::GetHostName());
-}
diff --git a/third_party/libjingle/source/talk/base/httpbase.cc b/third_party/libjingle/source/talk/base/httpbase.cc
deleted file mode 100644
index f5dc60e..0000000
--- a/third_party/libjingle/source/talk/base/httpbase.cc
+++ /dev/null
@@ -1,894 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// Copyright 2005 Google Inc.  All Rights Reserved.
-//
-
-
-#ifdef WIN32
-#include "talk/base/win32.h"
-#else  // !WIN32
-#define SEC_E_CERT_EXPIRED (-2146893016)
-#endif  // !WIN32
-
-#include "talk/base/common.h"
-#include "talk/base/httpbase.h"
-#include "talk/base/logging.h"
-#include "talk/base/socket.h"
-#include "talk/base/stringutils.h"
-#include "talk/base/thread.h"
-
-namespace talk_base {
-
-//////////////////////////////////////////////////////////////////////
-// Helpers
-//////////////////////////////////////////////////////////////////////
-
-bool MatchHeader(const char* str, size_t len, HttpHeader header) {
-  const char* const header_str = ToString(header);
-  const size_t header_len = strlen(header_str);
-  return (len == header_len) && (_strnicmp(str, header_str, header_len) == 0);
-}
-
-enum {
-  MSG_READ
-};
-
-//////////////////////////////////////////////////////////////////////
-// HttpParser
-//////////////////////////////////////////////////////////////////////
-
-HttpParser::HttpParser() {
-  reset();
-}
-
-HttpParser::~HttpParser() {
-}
-
-void
-HttpParser::reset() {
-  state_ = ST_LEADER;
-  chunked_ = false;
-  data_size_ = SIZE_UNKNOWN;
-}
-
-HttpParser::ProcessResult
-HttpParser::Process(const char* buffer, size_t len, size_t* processed,
-                    HttpError* error) {
-  *processed = 0;
-  *error = HE_NONE;
-
-  if (state_ >= ST_COMPLETE) {
-    ASSERT(false);
-    return PR_COMPLETE;
-  }
-
-  while (true) {
-    if (state_ < ST_DATA) {
-      size_t pos = *processed;
-      while ((pos < len) && (buffer[pos] != '\n')) {
-        pos += 1;
-      }
-      if (pos >= len) {
-        break;  // don't have a full header
-      }
-      const char* line = buffer + *processed;
-      size_t len = (pos - *processed);
-      *processed = pos + 1;
-      while ((len > 0) && isspace(static_cast<unsigned char>(line[len-1]))) {
-        len -= 1;
-      }
-      ProcessResult result = ProcessLine(line, len, error);
-      LOG(LS_VERBOSE) << "Processed line, result=" << result;
-
-      if (PR_CONTINUE != result) {
-        return result;
-      }
-    } else if (data_size_ == 0) {
-      if (chunked_) {
-        state_ = ST_CHUNKTERM;
-      } else {
-        return PR_COMPLETE;
-      }
-    } else {
-      size_t available = len - *processed;
-      if (available <= 0) {
-        break; // no more data
-      }
-      if ((data_size_ != SIZE_UNKNOWN) && (available > data_size_)) {
-        available = data_size_;
-      }
-      size_t read = 0;
-      ProcessResult result = ProcessData(buffer + *processed, available, read,
-                                         error);
-      LOG(LS_VERBOSE) << "Processed data, result: " << result << " read: "
-                      << read << " err: " << error;
-
-      if (PR_CONTINUE != result) {
-        return result;
-      }
-      *processed += read;
-      if (data_size_ != SIZE_UNKNOWN) {
-        data_size_ -= read;
-      }
-    }
-  }
-
-  return PR_CONTINUE;
-}
-
-HttpParser::ProcessResult
-HttpParser::ProcessLine(const char* line, size_t len, HttpError* error) {
-  LOG_F(LS_VERBOSE) << " state: " << state_ << " line: "
-                    << std::string(line, len) << " len: " << len << " err: "
-                    << error;
-
-  switch (state_) {
-  case ST_LEADER:
-    state_ = ST_HEADERS;
-    return ProcessLeader(line, len, error);
-
-  case ST_HEADERS:
-    if (len > 0) {
-      const char* value = strchrn(line, len, ':');
-      if (!value) {
-        *error = HE_PROTOCOL;
-        return PR_COMPLETE;
-      }
-      size_t nlen = (value - line);
-      const char* eol = line + len;
-      do {
-        value += 1;
-      } while ((value < eol) && isspace(static_cast<unsigned char>(*value)));
-      size_t vlen = eol - value;
-      if (MatchHeader(line, nlen, HH_CONTENT_LENGTH)) {
-	unsigned int temp_size;
-        if (sscanf(value, "%u", &temp_size) != 1) {
-          *error = HE_PROTOCOL;
-          return PR_COMPLETE;
-        }
-	data_size_ = static_cast<size_t>(temp_size);
-      } else if (MatchHeader(line, nlen, HH_TRANSFER_ENCODING)) {
-        if ((vlen == 7) && (_strnicmp(value, "chunked", 7) == 0)) {
-          chunked_ = true;
-        } else if ((vlen == 8) && (_strnicmp(value, "identity", 8) == 0)) {
-          chunked_ = false;
-        } else {
-          *error = HE_PROTOCOL;
-          return PR_COMPLETE;
-        }
-      }
-      return ProcessHeader(line, nlen, value, vlen, error);
-    } else {
-      state_ = chunked_ ? ST_CHUNKSIZE : ST_DATA;
-      return ProcessHeaderComplete(chunked_, data_size_, error);
-    }
-    break;
-
-  case ST_CHUNKSIZE:
-    if (len > 0) {
-      char* ptr = NULL;
-      data_size_ = strtoul(line, &ptr, 16);
-      if (ptr != line + len) {
-        *error = HE_PROTOCOL;
-        return PR_COMPLETE;
-      }
-      state_ = (data_size_ == 0) ? ST_TRAILERS : ST_DATA;
-    } else {
-      *error = HE_PROTOCOL;
-      return PR_COMPLETE;
-    }
-    break;
-
-  case ST_CHUNKTERM:
-    if (len > 0) {
-      *error = HE_PROTOCOL;
-      return PR_COMPLETE;
-    } else {
-      state_ = chunked_ ? ST_CHUNKSIZE : ST_DATA;
-    }
-    break;
-
-  case ST_TRAILERS:
-    if (len == 0) {
-      return PR_COMPLETE;
-    }
-    // *error = onHttpRecvTrailer();
-    break;
-
-  default:
-    ASSERT(false);
-    break;
-  }
-
-  return PR_CONTINUE;
-}
-
-bool
-HttpParser::is_valid_end_of_input() const {
-  return (state_ == ST_DATA) && (data_size_ == SIZE_UNKNOWN);
-}
-
-void
-HttpParser::complete(HttpError error) {
-  if (state_ < ST_COMPLETE) {
-    state_ = ST_COMPLETE;
-    OnComplete(error);
-  }
-}
-
-//////////////////////////////////////////////////////////////////////
-// HttpBase::DocumentStream
-//////////////////////////////////////////////////////////////////////
-
-class BlockingMemoryStream : public ExternalMemoryStream {
-public:
-  BlockingMemoryStream(char* buffer, size_t size)
-  : ExternalMemoryStream(buffer, size) { }
-
-  virtual StreamResult DoReserve(size_t size, int* error) {
-    return (buffer_length_ >= size) ? SR_SUCCESS : SR_BLOCK;
-  }
-};
-
-class HttpBase::DocumentStream : public StreamInterface {
-public:
-  DocumentStream(HttpBase* base) : base_(base), error_(HE_DEFAULT) { }
-
-  virtual StreamState GetState() const {
-    if (NULL == base_)
-      return SS_CLOSED;
-    if (HM_RECV == base_->mode_)
-      return SS_OPEN;
-    return SS_OPENING;
-  }
-
-  virtual StreamResult Read(void* buffer, size_t buffer_len,
-                            size_t* read, int* error) {
-    if (!base_) {
-      if (error) *error = error_;
-      return (HE_NONE == error_) ? SR_EOS : SR_ERROR;
-    }
-
-    if (HM_RECV != base_->mode_) {
-      return SR_BLOCK;
-    }
-
-    // DoReceiveLoop writes http document data to the StreamInterface* document
-    // member of HttpData.  In this case, we want this data to be written
-    // directly to our buffer.  To accomplish this, we wrap our buffer with a
-    // StreamInterface, and replace the existing document with our wrapper.
-    // When the method returns, we restore the old document.  Ideally, we would
-    // pass our StreamInterface* to DoReceiveLoop, but due to the callbacks
-    // of HttpParser, we would still need to store the pointer temporarily.
-    scoped_ptr<StreamInterface>
-        stream(new BlockingMemoryStream(reinterpret_cast<char*>(buffer),
-                                        buffer_len));
-
-    // Replace the existing document with our wrapped buffer.
-    base_->data_->document.swap(stream);
-
-    // Pump the I/O loop.  DoReceiveLoop is guaranteed not to attempt to
-    // complete the I/O process, which means that our wrapper is not in danger
-    // of being deleted.  To ensure this, DoReceiveLoop returns true when it
-    // wants complete to be called.  We make sure to uninstall our wrapper
-    // before calling complete().
-    HttpError http_error;
-    bool complete = base_->DoReceiveLoop(&http_error);
-
-    // Reinstall the original output document.
-    base_->data_->document.swap(stream);
-
-    // If we reach the end of the receive stream, we disconnect our stream
-    // adapter from the HttpBase, and further calls to read will either return
-    // EOS or ERROR, appropriately.  Finally, we call complete().
-    StreamResult result = SR_BLOCK;
-    if (complete) {
-      HttpBase* base = Disconnect(http_error);
-      if (error) *error = error_;
-      result = (HE_NONE == error_) ? SR_EOS : SR_ERROR;
-      base->complete(http_error);
-    }
-
-    // Even if we are complete, if some data was read we must return SUCCESS.
-    // Future Reads will return EOS or ERROR based on the error_ variable.
-    size_t position;
-    stream->GetPosition(&position);
-    if (position > 0) {
-      if (read) *read = position;
-      result = SR_SUCCESS;
-    }
-    return result;
-  }
-
-  virtual StreamResult Write(const void* data, size_t data_len,
-                             size_t* written, int* error) {
-    if (error) *error = -1;
-    return SR_ERROR;
-  }
-
-  virtual void Close() {
-    if (base_) {
-      HttpBase* base = Disconnect(HE_NONE);
-      if (HM_RECV == base->mode_ && base->http_stream_) {
-        // Read I/O could have been stalled on the user of this DocumentStream,
-        // so restart the I/O process now that we've removed ourselves.
-        base->http_stream_->PostEvent(SE_READ, 0);
-      }
-    }
-  }
-
-  virtual bool GetAvailable(size_t* size) const {
-    if (!base_ || HM_RECV != base_->mode_)
-      return false;
-    size_t data_size = base_->GetDataRemaining();
-    if (SIZE_UNKNOWN == data_size)
-      return false;
-    if (size)
-      *size = data_size;
-    return true;
-  }
-
-  HttpBase* Disconnect(HttpError error) {
-    ASSERT(NULL != base_);
-    ASSERT(NULL != base_->doc_stream_);
-    HttpBase* base = base_;
-    base_->doc_stream_ = NULL;
-    base_ = NULL;
-    error_ = error;
-    return base;
-  }
-
-private:
-  HttpBase* base_;
-  HttpError error_;
-};
-
-//////////////////////////////////////////////////////////////////////
-// HttpBase
-//////////////////////////////////////////////////////////////////////
-
-HttpBase::HttpBase() : mode_(HM_NONE), data_(NULL), notify_(NULL),
-                       http_stream_(NULL), doc_stream_(NULL) {
-}
-
-HttpBase::~HttpBase() {
-  ASSERT(HM_NONE == mode_);
-}
-
-bool
-HttpBase::isConnected() const {
-  return (http_stream_ != NULL) && (http_stream_->GetState() == SS_OPEN);
-}
-
-bool
-HttpBase::attach(StreamInterface* stream) {
-  if ((mode_ != HM_NONE) || (http_stream_ != NULL) || (stream == NULL)) {
-    ASSERT(false);
-    return false;
-  }
-  http_stream_ = stream;
-  http_stream_->SignalEvent.connect(this, &HttpBase::OnHttpStreamEvent);
-  mode_ = (http_stream_->GetState() == SS_OPENING) ? HM_CONNECT : HM_NONE;
-  return true;
-}
-
-StreamInterface*
-HttpBase::detach() {
-  ASSERT(HM_NONE == mode_);
-  if (mode_ != HM_NONE) {
-    return NULL;
-  }
-  StreamInterface* stream = http_stream_;
-  http_stream_ = NULL;
-  if (stream) {
-    stream->SignalEvent.disconnect(this);
-  }
-  return stream;
-}
-
-void
-HttpBase::send(HttpData* data) {
-  ASSERT(HM_NONE == mode_);
-  if (mode_ != HM_NONE) {
-    return;
-  } else if (!isConnected()) {
-    OnHttpStreamEvent(http_stream_, SE_CLOSE, HE_DISCONNECTED);
-    return;
-  }
-
-  mode_ = HM_SEND;
-  data_ = data;
-  len_ = 0;
-  ignore_data_ = chunk_data_ = false;
-
-  if (data_->document.get()) {
-    data_->document->SignalEvent.connect(this, &HttpBase::OnDocumentEvent);
-  }
-
-  std::string encoding;
-  if (data_->hasHeader(HH_TRANSFER_ENCODING, &encoding)
-      && (encoding == "chunked")) {
-    chunk_data_ = true;
-  }
-
-  len_ = data_->formatLeader(buffer_, sizeof(buffer_));
-  len_ += strcpyn(buffer_ + len_, sizeof(buffer_) - len_, "\r\n");
-
-  header_ = data_->begin();
-  if (header_ == data_->end()) {
-    // We must call this at least once, in the case where there are no headers.
-    queue_headers();
-  }
-
-  flush_data();
-}
-
-void
-HttpBase::recv(HttpData* data) {
-  ASSERT(HM_NONE == mode_);
-  if (mode_ != HM_NONE) {
-    return;
-  } else if (!isConnected()) {
-    OnHttpStreamEvent(http_stream_, SE_CLOSE, HE_DISCONNECTED);
-    return;
-  }
-
-  mode_ = HM_RECV;
-  data_ = data;
-  len_ = 0;
-  ignore_data_ = chunk_data_ = false;
-
-  reset();
-  if (doc_stream_) {
-    doc_stream_->SignalEvent(doc_stream_, SE_OPEN | SE_READ, 0);
-  } else {
-    read_and_process_data();
-  }
-}
-
-void
-HttpBase::abort(HttpError err) {
-  if (mode_ != HM_NONE) {
-    if (http_stream_ != NULL) {
-      http_stream_->Close();
-    }
-    do_complete(err);
-  }
-}
-
-StreamInterface* HttpBase::GetDocumentStream() {
-  if (doc_stream_)
-    return NULL;
-  doc_stream_ = new DocumentStream(this);
-  return doc_stream_;
-}
-
-HttpError HttpBase::HandleStreamClose(int error) {
-  if (http_stream_ != NULL) {
-    http_stream_->Close();
-  }
-  if (error == 0) {
-    if ((mode_ == HM_RECV) && is_valid_end_of_input()) {
-      return HE_NONE;
-    } else {
-      return HE_DISCONNECTED;
-    }
-  } else if (error == SOCKET_EACCES) {
-    return HE_AUTH;
-  } else if (error == SEC_E_CERT_EXPIRED) {
-    return HE_CERTIFICATE_EXPIRED;
-  }
-  LOG_F(LS_ERROR) << "(" << error << ")";
-  return (HM_CONNECT == mode_) ? HE_CONNECT_FAILED : HE_SOCKET_ERROR;
-}
-
-bool HttpBase::DoReceiveLoop(HttpError* error) {
-  ASSERT(HM_RECV == mode_);
-  ASSERT(NULL != error);
-
-  // Do to the latency between receiving read notifications from
-  // pseudotcpchannel, we rely on repeated calls to read in order to acheive
-  // ideal throughput.  The number of reads is limited to prevent starving
-  // the caller.
-
-  size_t loop_count = 0;
-  const size_t kMaxReadCount = 20;
-  bool process_requires_more_data = false;
-  do {
-    // The most frequent use of this function is response to new data available
-    // on http_stream_.  Therefore, we optimize by attempting to read from the
-    // network first (as opposed to processing existing data first).
-
-    if (len_ < sizeof(buffer_)) {
-      // Attempt to buffer more data.
-      size_t read;
-      int read_error;
-      StreamResult read_result = http_stream_->Read(buffer_ + len_,
-                                                    sizeof(buffer_) - len_,
-                                                    &read, &read_error);
-      switch (read_result) {
-      case SR_SUCCESS:
-        ASSERT(len_ + read <= sizeof(buffer_));
-        len_ += read;
-        break;
-      case SR_BLOCK:
-        if (process_requires_more_data) {
-          // We're can't make progress until more data is available.
-          return false;
-        }
-        // Attempt to process the data already in our buffer.
-        break;
-      case SR_EOS:
-        // Clean close, with no error.  Fall through to HandleStreamClose.
-        read_error = 0;
-      case SR_ERROR:
-        *error = HandleStreamClose(read_error);
-        return true;
-      }
-    } else if (process_requires_more_data) {
-      // We have too much unprocessed data in our buffer.  This should only
-      // occur when a single HTTP header is longer than the buffer size (32K).
-      // Anything longer than that is almost certainly an error.
-      *error = HE_OVERFLOW;
-      return true;
-    }
-
-    // Process data in our buffer.  Process is not guaranteed to process all
-    // the buffered data.  In particular, it will wait until a complete
-    // protocol element (such as http header, or chunk size) is available,
-    // before processing it in its entirety.  Also, it is valid and sometimes
-    // necessary to call Process with an empty buffer, since the state machine
-    // may have interrupted state transitions to complete.
-    size_t processed;
-    ProcessResult process_result = Process(buffer_, len_, &processed,
-                                            error);
-    ASSERT(processed <= len_);
-    len_ -= processed;
-    memmove(buffer_, buffer_ + processed, len_);
-    switch (process_result) {
-    case PR_CONTINUE:
-      // We need more data to make progress.
-      process_requires_more_data = true;
-      break;
-    case PR_BLOCK:
-      // We're stalled on writing the processed data.
-      return false;
-    case PR_COMPLETE:
-      // *error already contains the correct code.
-      return true;
-    }
-  } while (++loop_count <= kMaxReadCount);
-
-  LOG_F(LS_WARNING) << "danger of starvation";
-  return false;
-}
-
-void
-HttpBase::read_and_process_data() {
-  HttpError error;
-  if (DoReceiveLoop(&error)) {
-    complete(error);
-  }
-}
-
-void
-HttpBase::flush_data() {
-  ASSERT(HM_SEND == mode_);
-
-  // When send_required is true, no more buffering can occur without a network
-  // write.
-  bool send_required = (len_ >= sizeof(buffer_));
-
-  while (true) {
-    ASSERT(len_ <= sizeof(buffer_));
-
-    // HTTP is inherently sensitive to round trip latency, since a frequent use
-    // case is for small requests and responses to be sent back and forth, and
-    // the lack of pipelining forces a single request to take a minimum of the
-    // round trip time.  As a result, it is to our benefit to pack as much data
-    // into each packet as possible.  Thus, we defer network writes until we've
-    // buffered as much data as possible.
-
-    if (!send_required && (header_ != data_->end())) {
-      // First, attempt to queue more header data.
-      send_required = queue_headers();
-    }
-
-    if (!send_required && (NULL != data_->document.get())) {
-      // Next, attempt to queue document data.
-
-      const size_t kChunkDigits = 8;
-      size_t offset, reserve;
-      if (chunk_data_) {
-        // Reserve characters at the start for X-byte hex value and \r\n
-        offset = len_ + kChunkDigits + 2;
-        // ... and 2 characters at the end for \r\n
-        reserve = offset + 2;
-      } else {
-        offset = len_;
-        reserve = offset;
-      }
-
-      if (reserve >= sizeof(buffer_)) {
-        send_required = true;
-      } else {
-        size_t read;
-        int error;
-        StreamResult result = data_->document->Read(buffer_ + offset,
-                                                    sizeof(buffer_) - reserve,
-                                                    &read, &error);
-        if (result == SR_SUCCESS) {
-          ASSERT(reserve + read <= sizeof(buffer_));
-          if (chunk_data_) {
-            // Prepend the chunk length in hex.
-            // Note: sprintfn appends a null terminator, which is why we can't
-            // combine it with the line terminator.
-            sprintfn(buffer_ + len_, kChunkDigits + 1, "%.*x",
-                     kChunkDigits, read);
-            // Add line terminator to the chunk length.
-            memcpy(buffer_ + len_ + kChunkDigits, "\r\n", 2);
-            // Add line terminator to the end of the chunk.
-            memcpy(buffer_ + offset + read, "\r\n", 2);
-          }
-          len_ = reserve + read;
-        } else if (result == SR_BLOCK) {
-          // Nothing to do but flush data to the network.
-          send_required = true;
-        } else if (result == SR_EOS) {
-          if (chunk_data_) {
-            // Append the empty chunk and empty trailers, then turn off
-            // chunking.
-            ASSERT(len_ + 5 <= sizeof(buffer_));
-            memcpy(buffer_ + len_, "0\r\n\r\n", 5);
-            len_ += 5;
-            chunk_data_ = false;
-          } else if (0 == len_) {
-            // No more data to read, and no more data to write.
-            do_complete();
-            return;
-          }
-          // Although we are done reading data, there is still data which needs
-          // to be flushed to the network.
-          send_required = true;
-        } else {
-          LOG_F(LS_ERROR) << "Read error: " << error;
-          do_complete(HE_STREAM);
-          return;
-        }
-      }
-    }
-
-    if (0 == len_) {
-      // No data currently available to send.
-      if (NULL == data_->document.get()) {
-        // If there is no source document, that means we're done.
-        do_complete();
-      }
-      return;
-    }
-
-    size_t written;
-    int error;
-    StreamResult result = http_stream_->Write(buffer_, len_, &written, &error);
-    if (result == SR_SUCCESS) {
-      ASSERT(written <= len_);
-      len_ -= written;
-      memmove(buffer_, buffer_ + written, len_);
-      send_required = false;
-    } else if (result == SR_BLOCK) {
-      if (send_required) {
-        // Nothing more we can do until network is writeable.
-        return;
-      }
-    } else {
-      ASSERT(result == SR_ERROR);
-      LOG_F(LS_ERROR) << "error";
-      OnHttpStreamEvent(http_stream_, SE_CLOSE, error);
-      return;
-    }
-  }
-
-  ASSERT(false);
-}
-
-bool
-HttpBase::queue_headers() {
-  ASSERT(HM_SEND == mode_);
-  while (header_ != data_->end()) {
-    size_t len = sprintfn(buffer_ + len_, sizeof(buffer_) - len_,
-                          "%.*s: %.*s\r\n",
-                          header_->first.size(), header_->first.data(),
-                          header_->second.size(), header_->second.data());
-    if (len_ + len < sizeof(buffer_) - 3) {
-      len_ += len;
-      ++header_;
-    } else if (len_ == 0) {
-      LOG(WARNING) << "discarding header that is too long: " << header_->first;
-      ++header_;
-    } else {
-      // Not enough room for the next header, write to network first.
-      return true;
-    }
-  }
-  // End of headers
-  len_ += strcpyn(buffer_ + len_, sizeof(buffer_) - len_, "\r\n");
-  return false;
-}
-
-void
-HttpBase::do_complete(HttpError err) {
-  ASSERT(mode_ != HM_NONE);
-  HttpMode mode = mode_;
-  mode_ = HM_NONE;
-  if (data_ && data_->document.get()) {
-    data_->document->SignalEvent.disconnect(this);
-  }
-  data_ = NULL;
-  if ((HM_RECV == mode) && doc_stream_) {
-    ASSERT(HE_NONE != err);  // We should have Disconnected doc_stream_ already.
-    DocumentStream* ds = doc_stream_;
-    ds->Disconnect(err);
-    ds->SignalEvent(ds, SE_CLOSE, err);
-  }
-  if (notify_) {
-    notify_->onHttpComplete(mode, err);
-  }
-}
-
-//
-// Stream Signals
-//
-
-void
-HttpBase::OnHttpStreamEvent(StreamInterface* stream, int events, int error) {
-  ASSERT(stream == http_stream_);
-  if ((events & SE_OPEN) && (mode_ == HM_CONNECT)) {
-    do_complete();
-    return;
-  }
-
-  if ((events & SE_WRITE) && (mode_ == HM_SEND)) {
-    flush_data();
-    return;
-  }
-
-  if ((events & SE_READ) && (mode_ == HM_RECV)) {
-    if (doc_stream_) {
-      doc_stream_->SignalEvent(doc_stream_, SE_READ, 0);
-    } else {
-      read_and_process_data();
-    }
-    return;
-  }
-
-  if ((events & SE_CLOSE) == 0)
-    return;
-
-  HttpError http_error = HandleStreamClose(error);
-  if (mode_ == HM_RECV) {
-    complete(http_error);
-  } else if (mode_ != HM_NONE) {
-    do_complete(http_error);
-  } else if (notify_) {
-    notify_->onHttpClosed(http_error);
-  }
-}
-
-void
-HttpBase::OnDocumentEvent(StreamInterface* stream, int events, int error) {
-  ASSERT(stream == data_->document.get());
-  if ((events & SE_WRITE) && (mode_ == HM_RECV)) {
-    read_and_process_data();
-    return;
-  }
-
-  if ((events & SE_READ) && (mode_ == HM_SEND)) {
-    flush_data();
-    return;
-  }
-
-  if (events & SE_CLOSE) {
-    LOG_F(LS_ERROR) << "Read error: " << error;
-    do_complete(HE_STREAM);
-    return;
-  }
-}
-
-//
-// HttpParser Implementation
-//
-
-HttpParser::ProcessResult
-HttpBase::ProcessLeader(const char* line, size_t len, HttpError* error) {
-  *error = data_->parseLeader(line, len);
-  return (HE_NONE == *error) ? PR_CONTINUE : PR_COMPLETE;
-}
-
-HttpParser::ProcessResult
-HttpBase::ProcessHeader(const char* name, size_t nlen, const char* value,
-                        size_t vlen, HttpError* error) {
-  std::string sname(name, nlen), svalue(value, vlen);
-  data_->addHeader(sname, svalue);
-  return PR_CONTINUE;
-}
-
-HttpParser::ProcessResult
-HttpBase::ProcessHeaderComplete(bool chunked, size_t& data_size,
-                                HttpError* error) {
-  StreamInterface* old_docstream = doc_stream_;
-  if (notify_) {
-    *error = notify_->onHttpHeaderComplete(chunked, data_size);
-    // The request must not be aborted as a result of this callback.
-    ASSERT(NULL != data_);
-  }
-  if ((HE_NONE == *error) && (NULL != data_->document.get())) {
-    data_->document->SignalEvent.connect(this, &HttpBase::OnDocumentEvent);
-  }
-  if (HE_NONE != *error) {
-    return PR_COMPLETE;
-  }
-  if (old_docstream != doc_stream_) {
-    // Break out of Process loop, since our I/O model just changed.
-    return PR_BLOCK;
-  }
-  return PR_CONTINUE;
-}
-
-HttpParser::ProcessResult
-HttpBase::ProcessData(const char* data, size_t len, size_t& read,
-                      HttpError* error) {
-  LOG_F(LS_VERBOSE) << "data: " << std::string(data, len);
-  if (ignore_data_ || !data_->document.get()) {
-    read = len;
-    return PR_CONTINUE;
-  }
-  int write_error = 0;
-  switch (data_->document->Write(data, len, &read, &write_error)) {
-  case SR_SUCCESS:
-    return PR_CONTINUE;
-  case SR_BLOCK:
-    return PR_BLOCK;
-  case SR_EOS:
-    LOG_F(LS_ERROR) << "Unexpected EOS";
-    *error = HE_STREAM;
-    return PR_COMPLETE;
-  case SR_ERROR:
-  default:
-    LOG_F(LS_ERROR) << "Write error: " << write_error;
-    *error = HE_STREAM;
-    return PR_COMPLETE;
-  }
-}
-
-void
-HttpBase::OnComplete(HttpError err) {
-  LOG_F(LS_VERBOSE);
-  do_complete(err);
-}
-
-} // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/httpbase.h b/third_party/libjingle/source/talk/base/httpbase.h
deleted file mode 100644
index 97527eb..0000000
--- a/third_party/libjingle/source/talk/base/httpbase.h
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// Copyright 2005 Google Inc.  All Rights Reserved.
-//
-
-
-#ifndef TALK_BASE_HTTPBASE_H__
-#define TALK_BASE_HTTPBASE_H__
-
-#include "talk/base/httpcommon.h"
-
-namespace talk_base {
-
-class StreamInterface;
-
-///////////////////////////////////////////////////////////////////////////////
-// HttpParser - Parses an HTTP stream provided via Process and end_of_input, and
-// generates events for:
-//  Structural Elements: Leader, Headers, Document Data
-//  Events: End of Headers, End of Document, Errors
-///////////////////////////////////////////////////////////////////////////////
-
-class HttpParser {
-public:
-  enum ProcessResult { PR_CONTINUE, PR_BLOCK, PR_COMPLETE };
-  HttpParser();
-  virtual ~HttpParser();
-  
-  void reset();
-  ProcessResult Process(const char* buffer, size_t len, size_t* processed,
-                        HttpError* error);
-  bool is_valid_end_of_input() const;
-  void complete(HttpError err);
-  
-  size_t GetDataRemaining() const { return data_size_; }
-
-protected:
-  ProcessResult ProcessLine(const char* line, size_t len, HttpError* error);
-
-  // HttpParser Interface
-  virtual ProcessResult ProcessLeader(const char* line, size_t len,
-                                      HttpError* error) = 0;
-  virtual ProcessResult ProcessHeader(const char* name, size_t nlen,
-                                      const char* value, size_t vlen,
-                                      HttpError* error) = 0;
-  virtual ProcessResult ProcessHeaderComplete(bool chunked, size_t& data_size,
-                                              HttpError* error) = 0;
-  virtual ProcessResult ProcessData(const char* data, size_t len, size_t& read,
-                                    HttpError* error) = 0;
-  virtual void OnComplete(HttpError err) = 0;
-  
-private:
-  enum State {
-    ST_LEADER, ST_HEADERS,
-    ST_CHUNKSIZE, ST_CHUNKTERM, ST_TRAILERS,
-    ST_DATA, ST_COMPLETE
-  } state_;
-  bool chunked_;
-  size_t data_size_;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// IHttpNotify
-///////////////////////////////////////////////////////////////////////////////
-
-enum HttpMode { HM_NONE, HM_CONNECT, HM_RECV, HM_SEND };
-
-class IHttpNotify {
-public:
-  virtual ~IHttpNotify() {}
-  virtual HttpError onHttpHeaderComplete(bool chunked, size_t& data_size) = 0;
-  virtual void onHttpComplete(HttpMode mode, HttpError err) = 0;
-  virtual void onHttpClosed(HttpError err) = 0;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// HttpBase - Provides a state machine for implementing HTTP-based components.
-// Attach HttpBase to a StreamInterface which represents a bidirectional HTTP
-// stream, and then call send() or recv() to initiate sending or receiving one
-// side of an HTTP transaction.  By default, HttpBase operates as an I/O pump,
-// moving data from the HTTP stream to the HttpData object and vice versa.
-// However, it can also operate in stream mode, in which case the user of the
-// stream interface drives I/O via calls to Read().
-///////////////////////////////////////////////////////////////////////////////
-
-class HttpBase
-: private HttpParser,
-  public sigslot::has_slots<>
-{
-public:
-  HttpBase();
-  virtual ~HttpBase();
-
-  void notify(IHttpNotify* notify) { notify_ = notify; }
-  bool attach(StreamInterface* stream);
-  StreamInterface* stream() { return http_stream_; }
-  StreamInterface* detach();
-  bool isConnected() const;
-
-  void send(HttpData* data);
-  void recv(HttpData* data);
-  void abort(HttpError err);
-
-  HttpMode mode() const { return mode_; }
-
-  void set_ignore_data(bool ignore) { ignore_data_ = ignore; }
-  bool ignore_data() const { return ignore_data_; }
-
-  // Obtaining this stream puts HttpBase into stream mode until the stream
-  // is closed.  HttpBase can only expose one open stream interface at a time.
-  // Further calls will return NULL.
-  StreamInterface* GetDocumentStream();
-
-protected:
-  // Do cleanup when the http stream closes (error may be 0 for a clean
-  // shutdown), and return the error code to signal.
-  HttpError HandleStreamClose(int error);
-
-  // DoReceiveLoop acts as a data pump, pulling data from the http stream,
-  // pushing it through the HttpParser, and then populating the HttpData object
-  // based on the callbacks from the parser.  One of the most interesting
-  // callbacks is ProcessData, which provides the actual http document body.
-  // This data is then written to the HttpData::document.  As a result, data
-  // flows from the network to the document, with some incidental protocol
-  // parsing in between.
-  // Ideally, we would pass in the document* to DoReceiveLoop, to more easily
-  // support GetDocumentStream().  However, since the HttpParser is callback
-  // driven, we are forced to store the pointer somewhere until the callback
-  // is triggered.
-  // Returns true if the received document has finished, and
-  // HttpParser::complete should be called.
-  bool DoReceiveLoop(HttpError* err);
-
-  void read_and_process_data();
-  void flush_data();
-  bool queue_headers();
-  void do_complete(HttpError err = HE_NONE);
-
-  void OnHttpStreamEvent(StreamInterface* stream, int events, int error);
-  void OnDocumentEvent(StreamInterface* stream, int events, int error);
-
-  // HttpParser Interface
-  virtual ProcessResult ProcessLeader(const char* line, size_t len,
-                                      HttpError* error);
-  virtual ProcessResult ProcessHeader(const char* name, size_t nlen,
-                                      const char* value, size_t vlen,
-                                      HttpError* error);
-  virtual ProcessResult ProcessHeaderComplete(bool chunked, size_t& data_size,
-                                              HttpError* error);
-  virtual ProcessResult ProcessData(const char* data, size_t len, size_t& read,
-                                    HttpError* error);
-  virtual void OnComplete(HttpError err);
-
-private:
-  class DocumentStream;
-  friend class DocumentStream;
-
-  enum { kBufferSize = 32 * 1024 };
-
-  HttpMode mode_;
-  HttpData* data_;
-  IHttpNotify* notify_;
-  StreamInterface* http_stream_;
-  DocumentStream* doc_stream_;
-  char buffer_[kBufferSize];
-  size_t len_;
-
-  bool ignore_data_, chunk_data_;
-  HttpData::const_iterator header_;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-
-} // namespace talk_base
-
-#endif // TALK_BASE_HTTPBASE_H__
diff --git a/third_party/libjingle/source/talk/base/httpbase_unittest.cc b/third_party/libjingle/source/talk/base/httpbase_unittest.cc
deleted file mode 100644
index 73ef949..0000000
--- a/third_party/libjingle/source/talk/base/httpbase_unittest.cc
+++ /dev/null
@@ -1,536 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/gunit.h"
-#include "talk/base/httpbase.h"
-#include "talk/base/testutils.h"
-
-namespace talk_base {
-
-const char* const kHttpResponse =
-  "HTTP/1.1 200\r\n"
-  "Connection: Keep-Alive\r\n"
-  "Content-Type: text/plain\r\n"
-  "Proxy-Authorization: 42\r\n"
-  "Transfer-Encoding: chunked\r\n"
-  "\r\n"
-  "00000008\r\n"
-  "Goodbye!\r\n"
-  "0\r\n\r\n";
-
-const char* const kHttpEmptyResponse =
-  "HTTP/1.1 200\r\n"
-  "Connection: Keep-Alive\r\n"
-  "Content-Length: 0\r\n"
-  "Proxy-Authorization: 42\r\n"
-  "\r\n";
-
-const char* const kHttpResponsePrefix =
-  "HTTP/1.1 200\r\n"
-  "Connection: Keep-Alive\r\n"
-  "Content-Type: text/plain\r\n"
-  "Proxy-Authorization: 42\r\n"
-  "Transfer-Encoding: chunked\r\n"
-  "\r\n"
-  "8\r\n"
-  "Goodbye!\r\n";
-
-class HttpBaseTest : public testing::Test, public IHttpNotify {
-public:
-  enum EventType { E_HEADER_COMPLETE, E_COMPLETE, E_CLOSED };
-  struct Event {
-    EventType event;
-    bool chunked;
-    size_t data_size;
-    HttpMode mode;
-    HttpError err;
-  };
-  HttpBaseTest() : mem(NULL), obtain_stream(false), http_stream(NULL) { }
-
-  virtual void SetUp() { }
-  virtual void TearDown() {
-    // Avoid an ASSERT, in case a test doesn't clean up properly
-    base.abort(HE_NONE);
-  }
-
-  virtual HttpError onHttpHeaderComplete(bool chunked, size_t& data_size) {
-    LOG_F(LS_VERBOSE) << "chunked: " << chunked << " size: " << data_size;
-    Event e = { E_HEADER_COMPLETE, chunked, data_size, HM_NONE, HE_NONE};
-    events.push_back(e);
-    if (obtain_stream) {
-      ObtainDocumentStream();
-    }
-    return HE_NONE;
-  }
-  virtual void onHttpComplete(HttpMode mode, HttpError err) {
-    LOG_F(LS_VERBOSE) << "mode: " << mode << " err: " << err;
-    Event e = { E_COMPLETE, false, 0, mode, err };
-    events.push_back(e);
-  }
-  virtual void onHttpClosed(HttpError err) {
-    LOG_F(LS_VERBOSE) << "err: " << err;
-    Event e = { E_CLOSED, false, 0, HM_NONE, err };
-    events.push_back(e);
-  }
-
-  void SetupSource(const char* response);
-
-  void VerifyHeaderComplete(size_t event_count, bool empty_doc);
-  void VerifyDocumentContents(const char* expected_data,
-                              size_t expected_length = SIZE_UNKNOWN);
-
-  void ObtainDocumentStream();
-  void VerifyDocumentStreamIsOpening();
-  void VerifyDocumentStreamOpenEvent();
-  void ReadDocumentStreamData(const char* expected_data);
-  void VerifyDocumentStreamIsEOS();
-
-  void SetupDocument(const char* response);
-  void VerifySourceContents(const char* expected_data,
-                            size_t expected_length = SIZE_UNKNOWN);
-
-  void VerifyTransferComplete(HttpMode mode, HttpError error);
-
-  HttpBase base;
-  MemoryStream* mem;
-  HttpResponseData data;
-
-  // The source of http data, and source events
-  testing::StreamSource src;
-  std::vector<Event> events;
-
-  // Document stream, and stream events
-  bool obtain_stream;
-  StreamInterface* http_stream;
-  testing::StreamSink sink;
-};
-
-void HttpBaseTest::SetupSource(const char* http_data) {
-  LOG_F(LS_VERBOSE) << "Enter";
-
-  src.SetState(SS_OPENING);
-  src.QueueString(http_data);
-
-  base.notify(this);
-  base.attach(&src);
-  EXPECT_TRUE(events.empty());
-
-  src.SetState(SS_OPEN);
-  ASSERT_EQ(1U, events.size());
-  EXPECT_EQ(E_COMPLETE, events[0].event);
-  EXPECT_EQ(HM_CONNECT, events[0].mode);
-  EXPECT_EQ(HE_NONE, events[0].err);
-  events.clear();
-
-  mem = new MemoryStream;
-  data.document.reset(mem);
-  LOG_F(LS_VERBOSE) << "Exit";
-}
-
-void HttpBaseTest::VerifyHeaderComplete(size_t event_count, bool empty_doc) {
-  LOG_F(LS_VERBOSE) << "Enter";
-
-  ASSERT_EQ(event_count, events.size());
-  EXPECT_EQ(E_HEADER_COMPLETE, events[0].event);
-
-  std::string header;
-  EXPECT_EQ(HVER_1_1, data.version);
-  EXPECT_EQ(static_cast<uint32>(HC_OK), data.scode);
-  EXPECT_TRUE(data.hasHeader(HH_PROXY_AUTHORIZATION, &header));
-  EXPECT_EQ("42", header);
-  EXPECT_TRUE(data.hasHeader(HH_CONNECTION, &header));
-  EXPECT_EQ("Keep-Alive", header);
-
-  if (empty_doc) {
-    EXPECT_FALSE(events[0].chunked);
-    EXPECT_EQ(0U, events[0].data_size);
-
-    EXPECT_TRUE(data.hasHeader(HH_CONTENT_LENGTH, &header));
-    EXPECT_EQ("0", header);
-  } else {
-    EXPECT_TRUE(events[0].chunked);
-    EXPECT_EQ(SIZE_UNKNOWN, events[0].data_size);
-
-    EXPECT_TRUE(data.hasHeader(HH_CONTENT_TYPE, &header));
-    EXPECT_EQ("text/plain", header);
-    EXPECT_TRUE(data.hasHeader(HH_TRANSFER_ENCODING, &header));
-    EXPECT_EQ("chunked", header);
-  }
-  LOG_F(LS_VERBOSE) << "Exit";
-}
-
-void HttpBaseTest::VerifyDocumentContents(const char* expected_data,
-                                          size_t expected_length) {
-  LOG_F(LS_VERBOSE) << "Enter";
-
-  if (SIZE_UNKNOWN == expected_length) {
-    expected_length = strlen(expected_data);
-  }
-  EXPECT_EQ(mem, data.document.get());
-
-  size_t length;
-  mem->GetSize(&length);
-  EXPECT_EQ(expected_length, length);
-  EXPECT_TRUE(0 == memcmp(expected_data, mem->GetBuffer(), length));
-  LOG_F(LS_VERBOSE) << "Exit";
-}
-
-void HttpBaseTest::ObtainDocumentStream() {
-  LOG_F(LS_VERBOSE) << "Enter";
-  EXPECT_FALSE(http_stream);
-  http_stream = base.GetDocumentStream();
-  ASSERT_TRUE(NULL != http_stream);
-  sink.Monitor(http_stream);
-  LOG_F(LS_VERBOSE) << "Exit";
-}
-
-void HttpBaseTest::VerifyDocumentStreamIsOpening() {
-  LOG_F(LS_VERBOSE) << "Enter";
-  ASSERT_TRUE(NULL != http_stream);
-  EXPECT_EQ(0, sink.Events(http_stream));
-  EXPECT_EQ(SS_OPENING, http_stream->GetState());
-
-  size_t read = 0;
-  char buffer[5] = { 0 };
-  EXPECT_EQ(SR_BLOCK, http_stream->Read(buffer, sizeof(buffer), &read, NULL));
-  LOG_F(LS_VERBOSE) << "Exit";
-}
-
-void HttpBaseTest::VerifyDocumentStreamOpenEvent() {
-  LOG_F(LS_VERBOSE) << "Enter";
-
-  ASSERT_TRUE(NULL != http_stream);
-  EXPECT_EQ(SE_OPEN | SE_READ, sink.Events(http_stream));
-  EXPECT_EQ(SS_OPEN, http_stream->GetState());
-
-  // HTTP headers haven't arrived yet
-  EXPECT_EQ(0U, events.size());
-  EXPECT_EQ(static_cast<uint32>(HC_INTERNAL_SERVER_ERROR), data.scode);
-  LOG_F(LS_VERBOSE) << "Exit";
-}
-
-void HttpBaseTest::ReadDocumentStreamData(const char* expected_data) {
-  LOG_F(LS_VERBOSE) << "Enter";
-
-  ASSERT_TRUE(NULL != http_stream);
-  EXPECT_EQ(SS_OPEN, http_stream->GetState());
-
-  // Pump the HTTP I/O using Read, and verify the results.
-  size_t verified_length = 0;
-  const size_t expected_length = strlen(expected_data);
-  while (verified_length < expected_length) {
-    size_t read = 0;
-    char buffer[5] = { 0 };
-    size_t amt_to_read = _min(expected_length - verified_length, sizeof(buffer));
-    EXPECT_EQ(SR_SUCCESS, http_stream->Read(buffer, amt_to_read, &read, NULL));
-    EXPECT_EQ(amt_to_read, read);
-    EXPECT_TRUE(0 == memcmp(expected_data + verified_length, buffer, read));
-    verified_length += read;
-  }
-  LOG_F(LS_VERBOSE) << "Exit";
-}
-
-void HttpBaseTest::VerifyDocumentStreamIsEOS() {
-  LOG_F(LS_VERBOSE) << "Enter";
-
-  ASSERT_TRUE(NULL != http_stream);
-  size_t read = 0;
-  char buffer[5] = { 0 };
-  EXPECT_EQ(SR_EOS, http_stream->Read(buffer, sizeof(buffer), &read, NULL));
-  EXPECT_EQ(SS_CLOSED, http_stream->GetState());
-
-  // When EOS is caused by Read, we don't expect SE_CLOSE
-  EXPECT_EQ(0, sink.Events(http_stream));
-  LOG_F(LS_VERBOSE) << "Exit";
-}
-
-void HttpBaseTest::SetupDocument(const char* document_data) {
-  LOG_F(LS_VERBOSE) << "Enter";
-  src.SetState(SS_OPEN);
-
-  base.notify(this);
-  base.attach(&src);
-  EXPECT_TRUE(events.empty());
-
-  if (document_data) {
-    // Note: we could just call data.set_success("text/plain", mem), but that
-    // won't allow us to use the chunked transfer encoding.
-    mem = new MemoryStream(document_data);
-    data.document.reset(mem);
-    data.setHeader(HH_CONTENT_TYPE, "text/plain");
-    data.setHeader(HH_TRANSFER_ENCODING, "chunked");
-  } else {
-    data.setHeader(HH_CONTENT_LENGTH, "0");
-  }
-  data.scode = HC_OK;
-  data.setHeader(HH_PROXY_AUTHORIZATION, "42");
-  data.setHeader(HH_CONNECTION, "Keep-Alive");
-  LOG_F(LS_VERBOSE) << "Exit";
-}
-
-void HttpBaseTest::VerifySourceContents(const char* expected_data,
-                                        size_t expected_length) {
-  LOG_F(LS_VERBOSE) << "Enter";
-  if (SIZE_UNKNOWN == expected_length) {
-    expected_length = strlen(expected_data);
-  }
-  std::string contents = src.ReadData();
-  EXPECT_EQ(expected_length, contents.length());
-  EXPECT_TRUE(0 == memcmp(expected_data, contents.data(), expected_length));
-  LOG_F(LS_VERBOSE) << "Exit";
-}
-
-void HttpBaseTest::VerifyTransferComplete(HttpMode mode, HttpError error) {
-  LOG_F(LS_VERBOSE) << "Enter";
-  // Verify that http operation has completed
-  ASSERT_TRUE(events.size() > 0);
-  size_t last_event = events.size() - 1;
-  EXPECT_EQ(E_COMPLETE, events[last_event].event);
-  EXPECT_EQ(mode, events[last_event].mode);
-  EXPECT_EQ(error, events[last_event].err);
-  LOG_F(LS_VERBOSE) << "Exit";
-}
-
-//
-// Tests
-//
-
-TEST_F(HttpBaseTest, SupportsSend) {
-  // Queue response document
-  SetupDocument("Goodbye!");
-
-  // Begin send
-  base.send(&data);
-
-  // Send completed successfully
-  VerifyTransferComplete(HM_SEND, HE_NONE);
-  VerifySourceContents(kHttpResponse);
-}
-
-TEST_F(HttpBaseTest, SupportsSendNoDocument) {
-  // Queue response document
-  SetupDocument(NULL);
-
-  // Begin send
-  base.send(&data);
-
-  // Send completed successfully
-  VerifyTransferComplete(HM_SEND, HE_NONE);
-  VerifySourceContents(kHttpEmptyResponse);
-}
-
-TEST_F(HttpBaseTest, SignalsCompleteOnInterruptedSend) {
-  // This test is attempting to expose a bug that occurs when a particular
-  // base objects is used for receiving, and then used for sending.  In
-  // particular, the HttpParser state is different after receiving.  Simulate
-  // that here.
-  SetupSource(kHttpResponse);
-  base.recv(&data);
-  VerifyTransferComplete(HM_RECV, HE_NONE);
-
-  src.Clear();
-  data.clear(true);
-  events.clear();
-  base.detach();
-
-  // Queue response document
-  SetupDocument("Goodbye!");
-
-  // Prevent entire response from being sent
-  const size_t kInterruptedLength = strlen(kHttpResponse) - 1;
-  src.SetWriteBlock(kInterruptedLength);
-
-  // Begin send
-  base.send(&data);
-
-  // Document is mostly complete, but no completion signal yet.
-  EXPECT_TRUE(events.empty());
-  VerifySourceContents(kHttpResponse, kInterruptedLength);
-
-  src.SetState(SS_CLOSED);
-
-  // Send completed with disconnect error, and no additional data.
-  VerifyTransferComplete(HM_SEND, HE_DISCONNECTED);
-  EXPECT_TRUE(src.ReadData().empty());
-}
-
-TEST_F(HttpBaseTest, SupportsReceiveViaDocumentPush) {
-  // Queue response document
-  SetupSource(kHttpResponse);
-
-  // Begin receive
-  base.recv(&data);
-
-  // Document completed successfully
-  VerifyHeaderComplete(2, false);
-  VerifyTransferComplete(HM_RECV, HE_NONE);
-  VerifyDocumentContents("Goodbye!");
-}
-
-TEST_F(HttpBaseTest, SupportsReceiveViaStreamPull) {
-  // Switch to pull mode
-  ObtainDocumentStream();
-  VerifyDocumentStreamIsOpening();
-
-  // Queue response document
-  SetupSource(kHttpResponse);
-  VerifyDocumentStreamIsOpening();
-
-  // Begin receive
-  base.recv(&data);
-
-  // Pull document data
-  VerifyDocumentStreamOpenEvent();
-  ReadDocumentStreamData("Goodbye!");
-  VerifyDocumentStreamIsEOS();
-
-  // Document completed successfully
-  VerifyHeaderComplete(2, false);
-  VerifyTransferComplete(HM_RECV, HE_NONE);
-  VerifyDocumentContents("");
-}
-
-TEST_F(HttpBaseTest, DISABLED_AllowsCloseStreamBeforeDocumentIsComplete) {
-
-  // TODO: Remove extra logging once test failure is understood
-  int old_sev = talk_base::LogMessage::GetLogToDebug();
-  talk_base::LogMessage::LogToDebug(LS_VERBOSE);
-
-
-  // Switch to pull mode
-  ObtainDocumentStream();
-  VerifyDocumentStreamIsOpening();
-
-  // Queue response document
-  SetupSource(kHttpResponse);
-  VerifyDocumentStreamIsOpening();
-
-  // Begin receive
-  base.recv(&data);
-
-  // Pull some of the data
-  VerifyDocumentStreamOpenEvent();
-  ReadDocumentStreamData("Goodb");
-
-  // We've seen the header by now
-  VerifyHeaderComplete(1, false);
-
-  // Close the pull stream, this will transition back to push I/O.
-  http_stream->Close();
-  Thread::Current()->ProcessMessages(0);
-
-  // Remainder of document completed successfully
-  VerifyTransferComplete(HM_RECV, HE_NONE);
-  VerifyDocumentContents("ye!");
-
-  talk_base::LogMessage::LogToDebug(old_sev);
-}
-
-TEST_F(HttpBaseTest, AllowsGetDocumentStreamInResponseToHttpHeader) {
-  // Queue response document
-  SetupSource(kHttpResponse);
-
-  // Switch to pull mode in response to header arrival
-  obtain_stream = true;
-
-  // Begin receive
-  base.recv(&data);
-
-  // We've already seen the header, but not data has arrived
-  VerifyHeaderComplete(1, false);
-  VerifyDocumentContents("");
-
-  // Pull the document data
-  ReadDocumentStreamData("Goodbye!");
-  VerifyDocumentStreamIsEOS();
-
-  // Document completed successfully
-  VerifyTransferComplete(HM_RECV, HE_NONE);
-  VerifyDocumentContents("");
-}
-
-TEST_F(HttpBaseTest, AllowsGetDocumentStreamWithEmptyDocumentBody) {
-  // Queue empty response document
-  SetupSource(kHttpEmptyResponse);
-
-  // Switch to pull mode in response to header arrival
-  obtain_stream = true;
-
-  // Begin receive
-  base.recv(&data);
-
-  // We've already seen the header, but not data has arrived
-  VerifyHeaderComplete(1, true);
-  VerifyDocumentContents("");
-
-  // The document is still open, until we attempt to read
-  ASSERT_TRUE(NULL != http_stream);
-  EXPECT_EQ(SS_OPEN, http_stream->GetState());
-
-  // Attempt to read data, and discover EOS
-  VerifyDocumentStreamIsEOS();
-
-  // Document completed successfully
-  VerifyTransferComplete(HM_RECV, HE_NONE);
-  VerifyDocumentContents("");
-}
-
-TEST_F(HttpBaseTest, SignalsDocumentStreamCloseOnUnexpectedClose) {
-  // Switch to pull mode
-  ObtainDocumentStream();
-  VerifyDocumentStreamIsOpening();
-
-  // Queue response document
-  SetupSource(kHttpResponsePrefix);
-  VerifyDocumentStreamIsOpening();
-
-  // Begin receive
-  base.recv(&data);
-
-  // Pull document data
-  VerifyDocumentStreamOpenEvent();
-  ReadDocumentStreamData("Goodbye!");
-
-  // Simulate unexpected close
-  src.SetState(SS_CLOSED);
-
-  // Observe error event on document stream
-  EXPECT_EQ(testing::SSE_ERROR, sink.Events(http_stream));
-
-  // Future reads give an error
-  int error = 0;
-  char buffer[5] = { 0 };
-  EXPECT_EQ(SR_ERROR, http_stream->Read(buffer, sizeof(buffer), NULL, &error));
-  EXPECT_EQ(HE_DISCONNECTED, error);
-
-  // Document completed with error
-  VerifyHeaderComplete(2, false);
-  VerifyTransferComplete(HM_RECV, HE_DISCONNECTED);
-  VerifyDocumentContents("");
-}
-
-} // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/httpclient.cc b/third_party/libjingle/source/talk/base/httpclient.cc
deleted file mode 100644
index 3b6e97e..0000000
--- a/third_party/libjingle/source/talk/base/httpclient.cc
+++ /dev/null
@@ -1,813 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <time.h>
-
-#include "talk/base/httpcommon-inl.h"
-
-#include "talk/base/asyncsocket.h"
-#include "talk/base/common.h"
-#include "talk/base/diskcache.h"
-#include "talk/base/httpclient.h"
-#include "talk/base/logging.h"
-#include "talk/base/pathutils.h"
-#include "talk/base/socketstream.h"
-#include "talk/base/stringencode.h"
-#include "talk/base/stringutils.h"
-#include "talk/base/thread.h"
-
-namespace talk_base {
-
-//////////////////////////////////////////////////////////////////////
-// Helpers
-//////////////////////////////////////////////////////////////////////
-
-namespace {
-
-const size_t kCacheHeader = 0;
-const size_t kCacheBody = 1;
-
-// Convert decimal string to integer
-bool HttpStringToInt(const std::string& str, unsigned long* val) {
-  ASSERT(NULL != val);
-  char* eos = NULL;
-  *val = strtoul(str.c_str(), &eos, 10);
-  return (*eos == '\0');
-}
-
-bool HttpShouldCache(const HttpTransaction& t) {
-  bool verb_allows_cache = (t.request.verb == HV_GET)
-                           || (t.request.verb == HV_HEAD);
-  bool is_range_response = t.response.hasHeader(HH_CONTENT_RANGE, NULL);
-  bool has_expires = t.response.hasHeader(HH_EXPIRES, NULL);
-  bool request_allows_cache =
-    has_expires || (std::string::npos != t.request.path.find('?'));
-  bool response_allows_cache =
-    has_expires || HttpCodeIsCacheable(t.response.scode);
-
-  bool may_cache = verb_allows_cache
-                   && request_allows_cache
-                   && response_allows_cache
-                   && !is_range_response;
-
-  std::string value;
-  if (t.response.hasHeader(HH_CACHE_CONTROL, &value)) {
-    HttpAttributeList directives;
-    HttpParseAttributes(value.data(), value.size(), directives);
-    // Response Directives Summary:
-    // public - always cacheable
-    // private - do not cache in a shared cache
-    // no-cache - may cache, but must revalidate whether fresh or stale
-    // no-store - sensitive information, do not cache or store in any way
-    // max-age - supplants Expires for staleness
-    // s-maxage - use as max-age for shared caches, ignore otherwise
-    // must-revalidate - may cache, but must revalidate after stale
-    // proxy-revalidate - shared cache must revalidate
-    if (HttpHasAttribute(directives, "no-store", NULL)) {
-      may_cache = false;
-    } else if (HttpHasAttribute(directives, "public", NULL)) {
-      may_cache = true;
-    }
-  }
-  return may_cache;
-}
-
-enum HttpCacheState {
-  HCS_FRESH,  // In cache, may use
-  HCS_STALE,  // In cache, must revalidate
-  HCS_NONE    // Not in cache
-};
-
-HttpCacheState HttpGetCacheState(const HttpTransaction& t) {
-  // Temporaries
-  std::string s_temp;
-  unsigned long i_temp;
-
-  // Current time
-  unsigned long now = time(0);
-
-  HttpAttributeList cache_control;
-  if (t.response.hasHeader(HH_CACHE_CONTROL, &s_temp)) {
-    HttpParseAttributes(s_temp.data(), s_temp.size(), cache_control);
-  }
-
-  // Compute age of cache document
-  unsigned long date;
-  if (!t.response.hasHeader(HH_DATE, &s_temp)
-      || !HttpDateToSeconds(s_temp, &date))
-    return HCS_NONE;
-
-  // TODO: Timestamp when cache request sent and response received?
-  unsigned long request_time = date;
-  unsigned long response_time = date;
-
-  unsigned long apparent_age = 0;
-  if (response_time > date) {
-    apparent_age = response_time - date;
-  }
-
-  unsigned long corrected_received_age = apparent_age;
-  if (t.response.hasHeader(HH_AGE, &s_temp)
-      && HttpStringToInt(s_temp, &i_temp)) {
-    corrected_received_age = stdmax(apparent_age, i_temp);
-  }
-
-  unsigned long response_delay = response_time - request_time;
-  unsigned long corrected_initial_age = corrected_received_age + response_delay;
-  unsigned long resident_time = now - response_time;
-  unsigned long current_age = corrected_initial_age + resident_time;
-
-  // Compute lifetime of document
-  unsigned long lifetime;
-  if (HttpHasAttribute(cache_control, "max-age", &s_temp)) {
-    lifetime = atoi(s_temp.c_str());
-  } else if (t.response.hasHeader(HH_EXPIRES, &s_temp)
-             && HttpDateToSeconds(s_temp, &i_temp)) {
-    lifetime = i_temp - date;
-  } else if (t.response.hasHeader(HH_LAST_MODIFIED, &s_temp)
-             && HttpDateToSeconds(s_temp, &i_temp)) {
-    // TODO: Issue warning 113 if age > 24 hours
-    lifetime = (now - i_temp) / 10;
-  } else {
-    return HCS_STALE;
-  }
-
-  return (lifetime > current_age) ? HCS_FRESH : HCS_STALE;
-}
-
-enum HttpValidatorStrength {
-  HVS_NONE,
-  HVS_WEAK,
-  HVS_STRONG
-};
-
-HttpValidatorStrength
-HttpRequestValidatorLevel(const HttpRequestData& request) {
-  if (HV_GET != request.verb)
-    return HVS_STRONG;
-  return request.hasHeader(HH_RANGE, NULL) ? HVS_STRONG : HVS_WEAK;
-}
-
-HttpValidatorStrength
-HttpResponseValidatorLevel(const HttpResponseData& response) {
-  std::string value;
-  if (response.hasHeader(HH_ETAG, &value)) {
-    bool is_weak = (strnicmp(value.c_str(), "W/", 2) == 0);
-    return is_weak ? HVS_WEAK : HVS_STRONG;
-  }
-  if (response.hasHeader(HH_LAST_MODIFIED, &value)) {
-    unsigned long last_modified, date;
-    if (HttpDateToSeconds(value, &last_modified)
-        && response.hasHeader(HH_DATE, &value)
-        && HttpDateToSeconds(value, &date)
-        && (last_modified + 60 < date)) {
-      return HVS_STRONG;
-    }
-    return HVS_WEAK;
-  }
-  return HVS_NONE;
-}
-
-std::string GetCacheID(const HttpRequestData& request) {
-  std::string id, url;
-  id.append(ToString(request.verb));
-  id.append("_");
-  request.getAbsoluteUri(&url);
-  id.append(url);
-  return id;
-}
-
-}  // anonymous namespace
-
-//////////////////////////////////////////////////////////////////////
-// Public Helpers
-//////////////////////////////////////////////////////////////////////
-
-bool HttpWriteCacheHeaders(const HttpResponseData* response,
-                           StreamInterface* output, size_t* size) {
-  size_t length = 0;
-  // Write all unknown and end-to-end headers to a cache file
-  for (HttpData::const_iterator it = response->begin();
-       it != response->end(); ++it) {
-    HttpHeader header;
-    if (FromString(header, it->first) && !HttpHeaderIsEndToEnd(header))
-      continue;
-    length += it->first.length() + 2 + it->second.length() + 2;
-    if (!output)
-      continue;
-    std::string formatted_header(it->first);
-    formatted_header.append(": ");
-    formatted_header.append(it->second);
-    formatted_header.append("\r\n");
-    StreamResult result = output->WriteAll(formatted_header.data(),
-                                           formatted_header.length(),
-                                           NULL, NULL);
-    if (SR_SUCCESS != result) {
-      return false;
-    }
-  }
-  if (output && (SR_SUCCESS != output->WriteAll("\r\n", 2, NULL, NULL))) {
-    return false;
-  }
-  length += 2;
-  if (size)
-    *size = length;
-  return true;
-}
-
-bool HttpReadCacheHeaders(StreamInterface* input, HttpResponseData* response,
-                          HttpData::HeaderCombine combine) {
-  while (true) {
-    std::string formatted_header;
-    StreamResult result = input->ReadLine(&formatted_header);
-    if ((SR_EOS == result) || (1 == formatted_header.size())) {
-      break;
-    }
-    if (SR_SUCCESS != result) {
-      return false;
-    }
-    size_t end_of_name = formatted_header.find(':');
-    if (std::string::npos == end_of_name) {
-      LOG_F(LS_WARNING) << "Malformed cache header";
-      continue;
-    }
-    size_t start_of_value = end_of_name + 1;
-    size_t end_of_value = formatted_header.length();
-    while ((start_of_value < end_of_value)
-           && isspace(formatted_header[start_of_value]))
-      ++start_of_value;
-    while ((start_of_value < end_of_value)
-           && isspace(formatted_header[end_of_value-1]))
-     --end_of_value;
-    size_t value_length = end_of_value - start_of_value;
-
-    std::string name(formatted_header.substr(0, end_of_name));
-    std::string value(formatted_header.substr(start_of_value, value_length));
-    response->changeHeader(name, value, combine);
-  }
-  return true;
-}
-
-//////////////////////////////////////////////////////////////////////
-// HttpClient
-//////////////////////////////////////////////////////////////////////
-
-const size_t kDefaultRetries = 1;
-const size_t kMaxRedirects = 5;
-
-HttpClient::HttpClient(const std::string& agent, StreamPool* pool,
-                       HttpTransaction* transaction)
-    : agent_(agent), pool_(pool),
-      transaction_(transaction), free_transaction_(false),
-      retries_(kDefaultRetries), attempt_(0), redirects_(0),
-      redirect_action_(REDIRECT_DEFAULT),
-      uri_form_(URI_DEFAULT), cache_(NULL), cache_state_(CS_READY) {
-  base_.notify(this);
-  if (NULL == transaction_) {
-    free_transaction_ = true;
-    transaction_ = new HttpTransaction;
-  }
-}
-
-HttpClient::~HttpClient() {
-  base_.notify(NULL);
-  base_.abort(HE_SHUTDOWN);
-  release();
-  if (free_transaction_)
-    delete transaction_;
-}
-
-void HttpClient::reset() {
-  server_.Clear();
-  request().clear(true);
-  response().clear(true);
-  context_.reset();
-  redirects_ = 0;
-  base_.abort(HE_OPERATION_CANCELLED);
-}
-
-void HttpClient::set_server(const SocketAddress& address) {
-  server_ = address;
-  // Setting 'Host' here allows it to be overridden before starting the request,
-  // if necessary.
-  request().setHeader(HH_HOST, HttpAddress(server_, false), true);
-}
-
-StreamInterface* HttpClient::GetDocumentStream() {
-  return base_.GetDocumentStream();
-}
-
-void HttpClient::start() {
-  if (base_.mode() != HM_NONE) {
-    // call reset() to abort an in-progress request
-    ASSERT(false);
-    return;
-  }
-
-  ASSERT(!IsCacheActive());
-
-  if (request().hasHeader(HH_TRANSFER_ENCODING, NULL)) {
-    // Exact size must be known on the client.  Instead of using chunked
-    // encoding, wrap data with auto-caching file or memory stream.
-    ASSERT(false);
-    return;
-  }
-
-  attempt_ = 0;
-
-  // If no content has been specified, using length of 0.
-  request().setHeader(HH_CONTENT_LENGTH, "0", false);
-
-  if (!agent_.empty()) {
-    request().setHeader(HH_USER_AGENT, agent_, false);
-  }
-
-  UriForm uri_form = uri_form_;
-  if (PROXY_HTTPS == proxy_.type) {
-    // Proxies require absolute form
-    uri_form = URI_ABSOLUTE;
-    request().version = HVER_1_0;
-    request().setHeader(HH_PROXY_CONNECTION, "Keep-Alive", false);
-  } else {
-    request().setHeader(HH_CONNECTION, "Keep-Alive", false);
-  }
-
-  if (URI_ABSOLUTE == uri_form) {
-    // Convert to absolute uri form
-    std::string url;
-    if (request().getAbsoluteUri(&url)) {
-      request().path = url;
-    } else {
-      LOG(LS_WARNING) << "Couldn't obtain absolute uri";
-    }
-  } else if (URI_RELATIVE == uri_form) {
-    // Convert to relative uri form
-    std::string host, path;
-    if (request().getRelativeUri(&host, &path)) {
-      request().setHeader(HH_HOST, host);
-      request().path = path;
-    } else {
-      LOG(LS_WARNING) << "Couldn't obtain relative uri";
-    }
-  }
-
-  if ((NULL != cache_) && CheckCache()) {
-    return;
-  }
-
-  connect();
-}
-
-void HttpClient::connect() {
-  int stream_err;
-  StreamInterface* stream = pool_->RequestConnectedStream(server_, &stream_err);
-  if (stream == NULL) {
-    ASSERT(0 != stream_err);
-    LOG(LS_ERROR) << "RequestConnectedStream error: " << stream_err;
-    onHttpComplete(HM_CONNECT, HE_CONNECT_FAILED);
-  } else {
-    base_.attach(stream);
-    if (stream->GetState() == SS_OPEN) {
-      base_.send(&transaction_->request);
-    }
-  }
-}
-
-void HttpClient::prepare_get(const std::string& url) {
-  reset();
-  Url<char> purl(url);
-  set_server(SocketAddress(purl.host(), purl.port()));
-  request().verb = HV_GET;
-  request().path = purl.full_path();
-}
-
-void HttpClient::prepare_post(const std::string& url,
-                              const std::string& content_type,
-                              StreamInterface* request_doc) {
-  reset();
-  Url<char> purl(url);
-  set_server(SocketAddress(purl.host(), purl.port()));
-  request().verb = HV_POST;
-  request().path = purl.full_path();
-  request().setContent(content_type, request_doc);
-}
-
-void HttpClient::release() {
-  if (StreamInterface* stream = base_.detach()) {
-    pool_->ReturnConnectedStream(stream);
-  }
-}
-
-bool HttpClient::ShouldRedirect(std::string* location) const {
-  // TODO: Unittest redirection.
-  if ((REDIRECT_NEVER == redirect_action_)
-      || !HttpCodeIsRedirection(response().scode)
-      || !response().hasHeader(HH_LOCATION, location)
-      || (redirects_ >= kMaxRedirects))
-    return false;
-  return (REDIRECT_ALWAYS == redirect_action_)
-         || (HC_SEE_OTHER == response().scode)
-         || (HV_HEAD == request().verb)
-         || (HV_GET == request().verb);
-}
-
-bool HttpClient::BeginCacheFile() {
-  ASSERT(NULL != cache_);
-  ASSERT(CS_READY == cache_state_);
-
-  std::string id = GetCacheID(request());
-  CacheLock lock(cache_, id, true);
-  if (!lock.IsLocked()) {
-    LOG_F(LS_WARNING) << "Couldn't lock cache";
-    return false;
-  }
-
-  if (HE_NONE != WriteCacheHeaders(id)) {
-    return false;
-  }
-
-  scoped_ptr<StreamInterface> stream(cache_->WriteResource(id, kCacheBody));
-  if (!stream.get()) {
-    LOG_F(LS_ERROR) << "Couldn't open body cache";
-    return false;
-  }
-  lock.Commit();
-
-  // Let's secretly replace the response document with Folgers Crystals,
-  // er, StreamTap, so that we can mirror the data to our cache.
-  StreamInterface* output = response().document.release();
-  if (!output) {
-    output = new NullStream;
-  }
-  StreamTap* tap = new StreamTap(output, stream.release());
-  response().document.reset(tap);
-  return true;
-}
-
-HttpError HttpClient::WriteCacheHeaders(const std::string& id) {
-  scoped_ptr<StreamInterface> stream(cache_->WriteResource(id, kCacheHeader));
-  if (!stream.get()) {
-    LOG_F(LS_ERROR) << "Couldn't open header cache";
-    return HE_CACHE;
-  }
-
-  if (!HttpWriteCacheHeaders(&transaction_->response, stream.get(), NULL)) {
-    LOG_F(LS_ERROR) << "Couldn't write header cache";
-    return HE_CACHE;
-  }
-
-  return HE_NONE;
-}
-
-void HttpClient::CompleteCacheFile() {
-  // Restore previous response document
-  StreamTap* tap = static_cast<StreamTap*>(response().document.release());
-  response().document.reset(tap->Detach());
-
-  int error;
-  StreamResult result = tap->GetTapResult(&error);
-
-  // Delete the tap and cache stream (which completes cache unlock)
-  delete tap;
-
-  if (SR_SUCCESS != result) {
-    LOG(LS_ERROR) << "Cache file error: " << error;
-    cache_->DeleteResource(GetCacheID(request()));
-  }
-}
-
-bool HttpClient::CheckCache() {
-  ASSERT(NULL != cache_);
-  ASSERT(CS_READY == cache_state_);
-
-  std::string id = GetCacheID(request());
-  if (!cache_->HasResource(id)) {
-    // No cache file available
-    return false;
-  }
-
-  HttpError error = ReadCacheHeaders(id, true);
-
-  if (HE_NONE == error) {
-    switch (HttpGetCacheState(*transaction_)) {
-    case HCS_FRESH:
-      // Cache content is good, read from cache
-      break;
-    case HCS_STALE:
-      // Cache content may be acceptable.  Issue a validation request.
-      if (PrepareValidate()) {
-        return false;
-      }
-      // Couldn't validate, fall through.
-    case HCS_NONE:
-      // Cache content is not useable.  Issue a regular request.
-      response().clear(false);
-      return false;
-    }
-  }
-
-  if (HE_NONE == error) {
-    error = ReadCacheBody(id);
-    cache_state_ = CS_READY;
-  }
-
-  if (HE_CACHE == error) {
-    LOG_F(LS_WARNING) << "Cache failure, continuing with normal request";
-    response().clear(false);
-    return false;
-  }
-
-  SignalHttpClientComplete(this, error);
-  return true;
-}
-
-HttpError HttpClient::ReadCacheHeaders(const std::string& id, bool override) {
-  scoped_ptr<StreamInterface> stream(cache_->ReadResource(id, kCacheHeader));
-  if (!stream.get()) {
-    return HE_CACHE;
-  }
-
-  HttpData::HeaderCombine combine =
-    override ? HttpData::HC_REPLACE : HttpData::HC_AUTO;
-
-  if (!HttpReadCacheHeaders(stream.get(), &transaction_->response, combine)) {
-    LOG_F(LS_ERROR) << "Error reading cache headers";
-    return HE_CACHE;
-  }
-
-  response().scode = HC_OK;
-  return HE_NONE;
-}
-
-HttpError HttpClient::ReadCacheBody(const std::string& id) {
-  cache_state_ = CS_READING;
-
-  HttpError error = HE_NONE;
-
-  size_t data_size;
-  scoped_ptr<StreamInterface> stream(cache_->ReadResource(id, kCacheBody));
-  if (!stream.get() || !stream->GetAvailable(&data_size)) {
-    LOG_F(LS_ERROR) << "Unavailable cache body";
-    error = HE_CACHE;
-  } else {
-    error = OnHeaderAvailable(false, false, data_size);
-  }
-
-  if ((HE_NONE == error)
-      && (HV_HEAD != request().verb)
-      && (NULL != response().document.get())) {
-    char buffer[1024 * 64];
-    StreamResult result = Flow(stream.get(), buffer, ARRAY_SIZE(buffer),
-                               response().document.get());
-    if (SR_SUCCESS != result) {
-      error = HE_STREAM;
-    }
-  }
-
-  return error;
-}
-
-bool HttpClient::PrepareValidate() {
-  ASSERT(CS_READY == cache_state_);
-  // At this point, request() contains the pending request, and response()
-  // contains the cached response headers.  Reformat the request to validate
-  // the cached content.
-  HttpValidatorStrength vs_required = HttpRequestValidatorLevel(request());
-  HttpValidatorStrength vs_available = HttpResponseValidatorLevel(response());
-  if (vs_available < vs_required) {
-    return false;
-  }
-  std::string value;
-  if (response().hasHeader(HH_ETAG, &value)) {
-    request().addHeader(HH_IF_NONE_MATCH, value);
-  }
-  if (response().hasHeader(HH_LAST_MODIFIED, &value)) {
-    request().addHeader(HH_IF_MODIFIED_SINCE, value);
-  }
-  response().clear(false);
-  cache_state_ = CS_VALIDATING;
-  return true;
-}
-
-HttpError HttpClient::CompleteValidate() {
-  ASSERT(CS_VALIDATING == cache_state_);
-
-  std::string id = GetCacheID(request());
-
-  // Merge cached headers with new headers
-  HttpError error = ReadCacheHeaders(id, false);
-  if (HE_NONE != error) {
-    // Rewrite merged headers to cache
-    CacheLock lock(cache_, id);
-    error = WriteCacheHeaders(id);
-  }
-  if (HE_NONE != error) {
-    error = ReadCacheBody(id);
-  }
-  return error;
-}
-
-HttpError HttpClient::OnHeaderAvailable(bool ignore_data, bool chunked,
-                                        size_t data_size) {
-  // If we are ignoring the data, this is an intermediate header.
-  // TODO: don't signal intermediate headers.  Instead, do all header-dependent
-  // processing now, and either set up the next request, or fail outright.
-  // TODO: by default, only write response documents with a success code.
-  SignalHeaderAvailable(this, !ignore_data, ignore_data ? 0 : data_size);
-  if (!ignore_data && !chunked && (data_size != SIZE_UNKNOWN)
-      && response().document.get()) {
-    // Attempt to pre-allocate space for the downloaded data.
-    if (!response().document->ReserveSize(data_size)) {
-      return HE_OVERFLOW;
-    }
-  }
-  return HE_NONE;
-}
-
-//
-// HttpBase Implementation
-//
-
-HttpError HttpClient::onHttpHeaderComplete(bool chunked, size_t& data_size) {
-  if (CS_VALIDATING == cache_state_) {
-    if (HC_NOT_MODIFIED == response().scode) {
-      return CompleteValidate();
-    }
-    // Should we remove conditional headers from request?
-    cache_state_ = CS_READY;
-    cache_->DeleteResource(GetCacheID(request()));
-    // Continue processing response as normal
-  }
-
-  ASSERT(!IsCacheActive());
-  if ((request().verb == HV_HEAD) || !HttpCodeHasBody(response().scode)) {
-    // HEAD requests and certain response codes contain no body
-    data_size = 0;
-  }
-  if (ShouldRedirect(NULL)
-      || ((HC_PROXY_AUTHENTICATION_REQUIRED == response().scode)
-          && (PROXY_HTTPS == proxy_.type))) {
-    // We're going to issue another request, so ignore the incoming data.
-    base_.set_ignore_data(true);
-  }
-
-  HttpError error = OnHeaderAvailable(base_.ignore_data(), chunked, data_size);
-  if (HE_NONE != error) {
-    return error;
-  }
-
-  if ((NULL != cache_)
-      && !base_.ignore_data()
-      && HttpShouldCache(*transaction_)) {
-    if (BeginCacheFile()) {
-      cache_state_ = CS_WRITING;
-    }
-  }
-  return HE_NONE;
-}
-
-void HttpClient::onHttpComplete(HttpMode mode, HttpError err) {
-  if (((HE_DISCONNECTED == err) || (HE_CONNECT_FAILED == err)
-       || (HE_SOCKET_ERROR == err))
-      && (HC_INTERNAL_SERVER_ERROR == response().scode)
-      && (attempt_ < retries_)) {
-    // If the response code has not changed from the default, then we haven't
-    // received anything meaningful from the server, so we are eligible for a
-    // retry.
-    ++attempt_;
-    if (request().document.get() && !request().document->Rewind()) {
-      // Unable to replay the request document.
-      err = HE_STREAM;
-    } else {
-      release();
-      connect();
-      return;
-    }
-  } else if (err != HE_NONE) {
-    // fall through
-  } else if (mode == HM_CONNECT) {
-    base_.send(&transaction_->request);
-    return;
-  } else if ((mode == HM_SEND) || HttpCodeIsInformational(response().scode)) {
-    // If you're interested in informational headers, catch
-    // SignalHeaderAvailable.
-    base_.recv(&transaction_->response);
-    return;
-  } else {
-    if (!HttpShouldKeepAlive(response())) {
-      LOG(LS_VERBOSE) << "HttpClient: closing socket";
-      base_.stream()->Close();
-    }
-    std::string location;
-    if (ShouldRedirect(&location)) {
-      Url<char> purl(location);
-      set_server(SocketAddress(purl.host(), purl.port()));
-      request().path = purl.full_path();
-      if (response().scode == HC_SEE_OTHER) {
-        request().verb = HV_GET;
-        request().clearHeader(HH_CONTENT_TYPE);
-        request().clearHeader(HH_CONTENT_LENGTH);
-        request().document.reset();
-      } else if (request().document.get() && !request().document->Rewind()) {
-        // Unable to replay the request document.
-        ASSERT(REDIRECT_ALWAYS == redirect_action_);
-        err = HE_STREAM;
-      }
-      if (err == HE_NONE) {
-        ++redirects_;
-        context_.reset();
-        response().clear(false);
-        release();
-        start();
-        return;
-      }
-    } else if ((HC_PROXY_AUTHENTICATION_REQUIRED == response().scode)
-               && (PROXY_HTTPS == proxy_.type)) {
-      std::string authorization, auth_method;
-      HttpData::const_iterator begin = response().begin(HH_PROXY_AUTHENTICATE);
-      HttpData::const_iterator end = response().end(HH_PROXY_AUTHENTICATE);
-      for (HttpData::const_iterator it = begin; it != end; ++it) {
-        HttpAuthContext *context = context_.get();
-        HttpAuthResult res = HttpAuthenticate(
-          it->second.data(), it->second.size(),
-          proxy_.address,
-          ToString(request().verb), request().path,
-          proxy_.username, proxy_.password,
-          context, authorization, auth_method);
-        context_.reset(context);
-        if (res == HAR_RESPONSE) {
-          request().setHeader(HH_PROXY_AUTHORIZATION, authorization);
-          if (request().document.get() && !request().document->Rewind()) {
-            err = HE_STREAM;
-          } else {
-            // Explicitly do not reset the HttpAuthContext
-            response().clear(false);
-            // TODO: Reuse socket when authenticating?
-            release();
-            start();
-            return;
-          }
-        } else if (res == HAR_IGNORE) {
-          LOG(INFO) << "Ignoring Proxy-Authenticate: " << auth_method;
-          continue;
-        } else {
-          break;
-        }
-      }
-    }
-  }
-  if (CS_WRITING == cache_state_) {
-    CompleteCacheFile();
-    cache_state_ = CS_READY;
-  } else if (CS_READING == cache_state_) {
-    cache_state_ = CS_READY;
-  }
-  release();
-  SignalHttpClientComplete(this, err);
-}
-
-void HttpClient::onHttpClosed(HttpError err) {
-  // This shouldn't occur, since we return the stream to the pool upon command
-  // completion.
-  ASSERT(false);
-}
-
-//////////////////////////////////////////////////////////////////////
-// HttpClientDefault
-//////////////////////////////////////////////////////////////////////
-
-HttpClientDefault::HttpClientDefault(SocketFactory* factory,
-                                     const std::string& agent,
-                                     HttpTransaction* transaction)
-    : ReuseSocketPool(factory ? factory : Thread::Current()->socketserver()),
-      HttpClient(agent, NULL, transaction) {
-  set_pool(this);
-}
-
-//////////////////////////////////////////////////////////////////////
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/httpclient.h b/third_party/libjingle/source/talk/base/httpclient.h
deleted file mode 100644
index b64e55f..0000000
--- a/third_party/libjingle/source/talk/base/httpclient.h
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_HTTPCLIENT_H__
-#define TALK_BASE_HTTPCLIENT_H__
-
-#include "talk/base/common.h"
-#include "talk/base/httpbase.h"
-#include "talk/base/proxyinfo.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/base/sigslot.h"
-#include "talk/base/socketaddress.h"
-#include "talk/base/socketpool.h"
-
-namespace talk_base {
-
-//////////////////////////////////////////////////////////////////////
-// Client-specific http utilities
-//////////////////////////////////////////////////////////////////////
-
-// Write cache-relevant response headers to output stream.  If size is non-null,
-// it contains the length of the output in bytes.  output may be null if only
-// the length is desired.
-bool HttpWriteCacheHeaders(const HttpResponseData* response,
-                           StreamInterface* output, size_t* size);
-// Read cached headers from a stream, and them merge them into the response
-// object using the specified combine operation.
-bool HttpReadCacheHeaders(StreamInterface* input,
-                          HttpResponseData* response,
-                          HttpData::HeaderCombine combine);
-
-//////////////////////////////////////////////////////////////////////
-// HttpClient
-// Implements an HTTP 1.1 client.
-//////////////////////////////////////////////////////////////////////
-
-class DiskCache;
-class HttpClient;
-class IPNetPool;
-
-// What to do:  Define STRICT_HTTP_ERROR=1 in your makefile.  Use HttpError in
-// your code (HttpErrorType should only be used for code that is shared
-// with groups which have not yet migrated).
-#if STRICT_HTTP_ERROR
-typedef HttpError HttpErrorType;
-#else  // !STRICT_HTTP_ERROR
-typedef int HttpErrorType;
-#endif  // !STRICT_HTTP_ERROR
-
-class HttpClient : private IHttpNotify {
-public:
-  // If HttpRequestData and HttpResponseData objects are provided, they must
-  // be freed by the caller.  Otherwise, an internal object is allocated.
-  HttpClient(const std::string& agent, StreamPool* pool,
-             HttpTransaction* transaction = NULL);
-  virtual ~HttpClient();
-
-  void set_pool(StreamPool* pool) { pool_ = pool; }
-
-  void set_agent(const std::string& agent) { agent_ = agent; }
-  const std::string& agent() const { return agent_; }
-  
-  void set_proxy(const ProxyInfo& proxy) { proxy_ = proxy; }
-  const ProxyInfo& proxy() const { return proxy_; }
-
-  // Request retries occur when the connection closes before the beginning of
-  // an http response is received.  In these cases, the http server may have
-  // timed out the keepalive connection before it received our request.  Note
-  // that if a request document cannot be rewound, no retry is made.  The
-  // default is 1.
-  void set_request_retries(size_t retries) { retries_ = retries; }
-  size_t request_retries() const { return retries_; }
-
-  enum RedirectAction { REDIRECT_DEFAULT, REDIRECT_ALWAYS, REDIRECT_NEVER };
-  void set_redirect_action(RedirectAction action) { redirect_action_ = action; }
-  RedirectAction redirect_action() const { return redirect_action_; }
-  // Deprecated
-  void set_fail_redirect(bool fail_redirect) {
-    redirect_action_ = REDIRECT_NEVER;
-  }
-  bool fail_redirect() const { return (REDIRECT_NEVER == redirect_action_); }
-
-  enum UriForm { URI_DEFAULT, URI_ABSOLUTE, URI_RELATIVE };
-  void set_uri_form(UriForm form) { uri_form_ = form; }
-  UriForm uri_form() const { return uri_form_; }
-
-  void set_cache(DiskCache* cache) { ASSERT(!IsCacheActive()); cache_ = cache; }
-  bool cache_enabled() const { return (NULL != cache_); }
-
-  // reset clears the server, request, and response structures.  It will also
-  // abort an active request.
-  void reset();
-  
-  void set_server(const SocketAddress& address);
-  const SocketAddress& server() const { return server_; }
-
-  // Note: in order for HttpClient to retry a POST in response to
-  // an authentication challenge, a redirect response, or socket disconnection,
-  // the request document must support 'replaying' by calling Rewind() on it.
-  // In the case where just a subset of a stream should be used as the request
-  // document, the stream may be wrapped with the StreamSegment adapter.
-  HttpTransaction* transaction() { return transaction_; }
-  const HttpTransaction* transaction() const { return transaction_; }
-  HttpRequestData& request() { return transaction_->request; }
-  const HttpRequestData& request() const { return transaction_->request; }
-  HttpResponseData& response() { return transaction_->response; }
-  const HttpResponseData& response() const { return transaction_->response; }
-  
-  // convenience methods
-  void prepare_get(const std::string& url);
-  void prepare_post(const std::string& url, const std::string& content_type,
-                    StreamInterface* request_doc);
-
-  // Convert HttpClient to a pull-based I/O model.
-  StreamInterface* GetDocumentStream();
-
-  // After you finish setting up your request, call start.
-  void start();
-  
-  // Signalled when the header has finished downloading, before the document
-  // content is processed.  You may change the response document in response
-  // to this signal.  The second parameter indicates whether this is an
-  // intermediate (false) or final (true) header.  An intermediate header is
-  // one that generates another request, such as a redirect or authentication
-  // challenge.  The third parameter indicates the length of the response
-  // document, or else SIZE_UNKNOWN.  Note: Do NOT abort the request in response
-  // to this signal.
-  sigslot::signal3<HttpClient*,bool,size_t> SignalHeaderAvailable;
-  // Signalled when the current request finishes.  On success, err is 0.
-  sigslot::signal2<HttpClient*,HttpErrorType> SignalHttpClientComplete;
-
-protected:
-  void connect();
-  void release();
-
-  bool ShouldRedirect(std::string* location) const;
-
-  bool BeginCacheFile();
-  HttpError WriteCacheHeaders(const std::string& id);
-  void CompleteCacheFile();
-
-  bool CheckCache();
-  HttpError ReadCacheHeaders(const std::string& id, bool override);
-  HttpError ReadCacheBody(const std::string& id);
-
-  bool PrepareValidate();
-  HttpError CompleteValidate();
-
-  HttpError OnHeaderAvailable(bool ignore_data, bool chunked, size_t data_size);
-
-  // IHttpNotify Interface
-  virtual HttpError onHttpHeaderComplete(bool chunked, size_t& data_size);
-  virtual void onHttpComplete(HttpMode mode, HttpError err);
-  virtual void onHttpClosed(HttpError err);
-  
-private:
-  enum CacheState { CS_READY, CS_WRITING, CS_READING, CS_VALIDATING };
-  bool IsCacheActive() const { return (cache_state_ > CS_READY); }
-
-  std::string agent_;
-  StreamPool* pool_;
-  HttpBase base_;
-  SocketAddress server_;
-  ProxyInfo proxy_;
-  HttpTransaction* transaction_;
-  bool free_transaction_;
-  size_t retries_, attempt_, redirects_;
-  RedirectAction redirect_action_;
-  UriForm uri_form_;
-  scoped_ptr<HttpAuthContext> context_;
-  DiskCache* cache_;
-  CacheState cache_state_;
-};
-
-//////////////////////////////////////////////////////////////////////
-// HttpClientDefault - Default implementation of HttpClient
-//////////////////////////////////////////////////////////////////////
-
-class HttpClientDefault : public ReuseSocketPool, public HttpClient {
-public:
-  HttpClientDefault(SocketFactory* factory, const std::string& agent,
-                    HttpTransaction* transaction = NULL);
-};
-
-//////////////////////////////////////////////////////////////////////
-
-}  // namespace talk_base
-
-#endif // TALK_BASE_HTTPCLIENT_H__
diff --git a/third_party/libjingle/source/talk/base/httpcommon-inl.h b/third_party/libjingle/source/talk/base/httpcommon-inl.h
deleted file mode 100644
index a33a643..0000000
--- a/third_party/libjingle/source/talk/base/httpcommon-inl.h
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_HTTPCOMMON_INL_H__
-#define TALK_BASE_HTTPCOMMON_INL_H__
-
-#include "talk/base/common.h"
-#include "talk/base/httpcommon.h"
-
-namespace talk_base {
-
-///////////////////////////////////////////////////////////////////////////////
-// Url
-///////////////////////////////////////////////////////////////////////////////
-
-template<class CTYPE>
-void Url<CTYPE>::do_set_url(const CTYPE* val, size_t len) {
-  if (ascnicmp(val, "http://", 7) == 0) {
-    val += 7; len -= 7;
-    secure_ = false;
-  } else if (ascnicmp(val, "https://", 8) == 0) {
-    val += 8; len -= 8;
-    secure_ = true;
-  } else {
-    clear();
-    return;
-  }
-  const CTYPE* path = strchrn(val, len, static_cast<CTYPE>('/'));
-  if (!path) {
-    path = val + len;
-  }
-  size_t address_length = (path - val);
-  do_set_address(val, address_length);
-  do_set_full_path(path, len - address_length);
-}
-
-template<class CTYPE>
-void Url<CTYPE>::do_set_address(const CTYPE* val, size_t len) {
-  if (const CTYPE* colon = strchrn(val, len, static_cast<CTYPE>(':'))) {
-    host_.assign(val, colon - val);
-    // Note: In every case, we're guaranteed that colon is followed by a null,
-    // or non-numeric character.
-    port_ = static_cast<uint16>(::strtoul(colon + 1, NULL, 10));
-    // TODO: Consider checking for invalid data following port number.
-  } else {
-    host_.assign(val, len);
-    port_ = HttpDefaultPort(secure_);
-  }
-}
-
-template<class CTYPE>
-void Url<CTYPE>::do_set_full_path(const CTYPE* val, size_t len) {
-  const CTYPE* query = strchrn(val, len, static_cast<CTYPE>('?'));
-  if (!query) {
-    query = val + len;
-  }
-  size_t path_length = (query - val);
-  if (0 == path_length) {
-    // TODO: consider failing in this case.
-    path_.assign(1, static_cast<CTYPE>('/'));
-  } else {
-    ASSERT(val[0] == static_cast<CTYPE>('/'));
-    path_.assign(val, path_length);
-  }
-  query_.assign(query, len - path_length);
-}
-
-template<class CTYPE>
-void Url<CTYPE>::do_get_url(string* val) const {
-  CTYPE protocol[9];
-  asccpyn(protocol, ARRAY_SIZE(protocol), secure_ ? "https://" : "http://");
-  val->append(protocol);
-  do_get_address(val);
-  do_get_full_path(val);
-}
-
-template<class CTYPE>
-void Url<CTYPE>::do_get_address(string* val) const {
-  val->append(host_);
-  if (port_ != HttpDefaultPort(secure_)) {
-    CTYPE format[5], port[32];
-    asccpyn(format, ARRAY_SIZE(format), ":%hu");
-    sprintfn(port, ARRAY_SIZE(port), format, port_);
-    val->append(port);
-  }
-}
-
-template<class CTYPE>
-void Url<CTYPE>::do_get_full_path(string* val) const {
-  val->append(path_);
-  val->append(query_);
-}
-
-template<class CTYPE>
-bool Url<CTYPE>::get_attribute(const string& name, string* value) const {
-  if (query_.empty())
-    return false;
-  
-  std::string::size_type pos = query_.find(name, 1);
-  if (std::string::npos == pos)
-    return false;
-
-  pos += name.length() + 1;
-  if ((pos > query_.length()) || (static_cast<CTYPE>('=') != query_[pos-1]))
-    return false;
-
-  std::string::size_type end = query_.find(static_cast<CTYPE>('&'), pos);
-  if (std::string::npos == end) {
-    end = query_.length();
-  }
-  value->assign(query_.substr(pos, end - pos));
-  return true;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_HTTPCOMMON_INL_H__
diff --git a/third_party/libjingle/source/talk/base/httpcommon.cc b/third_party/libjingle/source/talk/base/httpcommon.cc
deleted file mode 100644
index 229aef9..0000000
--- a/third_party/libjingle/source/talk/base/httpcommon.cc
+++ /dev/null
@@ -1,1054 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <time.h>
-
-#ifdef WIN32
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#define SECURITY_WIN32
-#include <security.h>
-#endif
-
-#include "talk/base/httpcommon-inl.h"
-
-#include "talk/base/base64.h"
-#include "talk/base/common.h"
-#include "talk/base/cryptstring.h"
-#include "talk/base/httpcommon.h"
-#include "talk/base/socketaddress.h"
-#include "talk/base/stringdigest.h"
-#include "talk/base/stringencode.h"
-#include "talk/base/stringutils.h"
-
-namespace talk_base {
-
-#ifdef WIN32
-extern const ConstantLabel SECURITY_ERRORS[];
-#endif
-
-//////////////////////////////////////////////////////////////////////
-// Enum - TODO: expose globally later?
-//////////////////////////////////////////////////////////////////////
-
-bool find_string(size_t& index, const std::string& needle,
-                 const char* const haystack[], size_t max_index) {
-  for (index=0; index<max_index; ++index) {
-	if (_stricmp(needle.c_str(), haystack[index]) == 0) {
-	  return true;
-	}
-  }
-  return false;
-}
-
-template<class E>
-struct Enum {
-  static const char** Names;
-  static size_t Size;
-
-  static inline const char* Name(E val) { return Names[val]; }
-  static inline bool Parse(E& val, const std::string& name) {
-	size_t index;
-	if (!find_string(index, name, Names, Size))
-	  return false;
-	val = static_cast<E>(index);
-	return true;
-  }
-
-  E val;
-
-  inline operator E&() { return val; }
-  inline Enum& operator=(E rhs) { val = rhs; return *this; }
-
-  inline const char* name() const { return Name(val); }
-  inline bool assign(const std::string& name) { return Parse(val, name); }
-  inline Enum& operator=(const std::string& rhs) { assign(rhs); return *this; }
-};
-
-#define ENUM(e,n) \
-  template<> const char** Enum<e>::Names = n; \
-  template<> size_t Enum<e>::Size = sizeof(n)/sizeof(n[0])
-
-//////////////////////////////////////////////////////////////////////
-// HttpCommon
-//////////////////////////////////////////////////////////////////////
-
-static const char* kHttpVersions[HVER_LAST+1] = {
-  "1.0", "1.1", "Unknown"
-};
-ENUM(HttpVersion, kHttpVersions);
-
-static const char* kHttpVerbs[HV_LAST+1] = {
-  "GET", "POST", "PUT", "DELETE", "CONNECT", "HEAD"
-};
-ENUM(HttpVerb, kHttpVerbs);
-
-static const char* kHttpHeaders[HH_LAST+1] = {
-  "Age",
-  "Cache-Control",
-  "Connection",
-  "Content-Disposition",
-  "Content-Length",
-  "Content-Range",
-  "Content-Type",
-  "Cookie",
-  "Date",
-  "ETag",
-  "Expires",
-  "Host",
-  "If-Modified-Since",
-  "If-None-Match",
-  "Keep-Alive",
-  "Last-Modified",
-  "Location",
-  "Proxy-Authenticate",
-  "Proxy-Authorization",
-  "Proxy-Connection",
-  "Range",
-  "Set-Cookie",
-  "TE",
-  "Trailers",
-  "Transfer-Encoding",
-  "Upgrade",
-  "User-Agent",
-  "WWW-Authenticate",
-};
-ENUM(HttpHeader, kHttpHeaders);
-
-const char* ToString(HttpVersion version) {
-  return Enum<HttpVersion>::Name(version);
-}
-
-bool FromString(HttpVersion& version, const std::string& str) {
-  return Enum<HttpVersion>::Parse(version, str);
-}
-
-const char* ToString(HttpVerb verb) {
-  return Enum<HttpVerb>::Name(verb);
-}
-
-bool FromString(HttpVerb& verb, const std::string& str) {
-  return Enum<HttpVerb>::Parse(verb, str);
-}
-
-const char* ToString(HttpHeader header) {
-  return Enum<HttpHeader>::Name(header);
-}
-
-bool FromString(HttpHeader& header, const std::string& str) {
-  return Enum<HttpHeader>::Parse(header, str);
-}
-
-bool HttpCodeHasBody(uint32 code) {
-  return !HttpCodeIsInformational(code)
-         && (code != HC_NO_CONTENT) && (code != HC_NOT_MODIFIED);
-}
-
-bool HttpCodeIsCacheable(uint32 code) {
-  switch (code) {
-  case HC_OK:
-  case HC_NON_AUTHORITATIVE:
-  case HC_PARTIAL_CONTENT:
-  case HC_MULTIPLE_CHOICES:
-  case HC_MOVED_PERMANENTLY:
-  case HC_GONE:
-    return true;
-  default:
-    return false;
-  }
-}
-
-bool HttpHeaderIsEndToEnd(HttpHeader header) {
-  switch (header) {
-  case HH_CONNECTION:
-  case HH_KEEP_ALIVE:
-  case HH_PROXY_AUTHENTICATE:
-  case HH_PROXY_AUTHORIZATION:
-  case HH_PROXY_CONNECTION:  // Note part of RFC... this is non-standard header
-  case HH_TE:
-  case HH_TRAILERS:
-  case HH_TRANSFER_ENCODING:
-  case HH_UPGRADE:
-    return false;
-  default:
-    return true;
-  }
-}
-
-bool HttpHeaderIsCollapsible(HttpHeader header) {
-  switch (header) {
-  case HH_SET_COOKIE:
-  case HH_PROXY_AUTHENTICATE:
-  case HH_WWW_AUTHENTICATE:
-    return false;
-  default:
-    return true;
-  }
-}
-
-bool HttpShouldKeepAlive(const HttpData& data) {
-  std::string connection;
-  if ((data.hasHeader(HH_PROXY_CONNECTION, &connection)
-      || data.hasHeader(HH_CONNECTION, &connection))) {
-    return (_stricmp(connection.c_str(), "Keep-Alive") == 0);
-  }
-  return (data.version >= HVER_1_1);
-}
-
-namespace {
-
-inline bool IsEndOfAttributeName(size_t pos, size_t len, const char * data) {
-  if (pos >= len)
-    return true;
-  if (isspace(static_cast<unsigned char>(data[pos])))
-    return true;
-  // The reason for this complexity is that some attributes may contain trailing
-  // equal signs (like base64 tokens in Negotiate auth headers)
-  if ((pos+1 < len) && (data[pos] == '=') &&
-      !isspace(static_cast<unsigned char>(data[pos+1])) &&
-      (data[pos+1] != '=')) {
-    return true;
-  }
-  return false;
-}
-
-// TODO: unittest for EscapeAttribute and HttpComposeAttributes.
-
-std::string EscapeAttribute(const std::string& attribute) {
-  const size_t kMaxLength = attribute.length() * 2 + 1;
-  char* buffer = STACK_ARRAY(char, kMaxLength);
-  size_t len = escape(buffer, kMaxLength, attribute.data(), attribute.length(),
-                      "\"", '\\');
-  return std::string(buffer, len);
-}
-
-}  // anonymous namespace
-
-void HttpComposeAttributes(const HttpAttributeList& attributes, char separator,
-                           std::string* composed) {
-  std::stringstream ss;
-  for (size_t i=0; i<attributes.size(); ++i) {
-    if (i > 0) {
-      ss << separator << " ";
-    }
-    ss << attributes[i].first;
-    if (!attributes[i].second.empty()) {
-      ss << "=\"" << EscapeAttribute(attributes[i].second) << "\"";
-    }
-  }
-  *composed = ss.str();
-}
-
-void HttpParseAttributes(const char * data, size_t len,
-                         HttpAttributeList& attributes) {
-  size_t pos = 0;
-  while (true) {
-    // Skip leading whitespace
-    while ((pos < len) && isspace(static_cast<unsigned char>(data[pos]))) {
-      ++pos;
-    }
-
-    // End of attributes?
-    if (pos >= len)
-      return;
-
-    // Find end of attribute name
-    size_t start = pos;
-    while (!IsEndOfAttributeName(pos, len, data)) {
-      ++pos;
-    }
-
-    HttpAttribute attribute;
-    attribute.first.assign(data + start, data + pos);
-
-    // Attribute has value?
-    if ((pos < len) && (data[pos] == '=')) {
-      ++pos; // Skip '='
-      // Check if quoted value
-      if ((pos < len) && (data[pos] == '"')) {
-        while (++pos < len) {
-          if (data[pos] == '"') {
-            ++pos;
-            break;
-          }
-          if ((data[pos] == '\\') && (pos + 1 < len))
-            ++pos;
-          attribute.second.append(1, data[pos]);
-        }
-      } else {
-        while ((pos < len) &&
-            !isspace(static_cast<unsigned char>(data[pos])) &&
-            (data[pos] != ',')) {
-          attribute.second.append(1, data[pos++]);
-        }
-      }
-    }
-
-    attributes.push_back(attribute);
-    if ((pos < len) && (data[pos] == ',')) ++pos; // Skip ','
-  }
-}
-
-bool HttpHasAttribute(const HttpAttributeList& attributes,
-                      const std::string& name,
-                      std::string* value) {
-  for (HttpAttributeList::const_iterator it = attributes.begin();
-       it != attributes.end(); ++it) {
-    if (it->first == name) {
-      if (value) {
-        *value = it->second;
-      }
-      return true;
-    }
-  }
-  return false;
-}
-
-bool HttpHasNthAttribute(HttpAttributeList& attributes,
-                         size_t index,
-                         std::string* name,
-                         std::string* value) {
-  if (index >= attributes.size())
-    return false;
-
-  if (name)
-    *name = attributes[index].first;
-  if (value)
-    *value = attributes[index].second;
-  return true;
-}
-
-bool HttpDateToSeconds(const std::string& date, unsigned long* seconds) {
-  const char* const kTimeZones[] = {
-    "UT", "GMT", "EST", "EDT", "CST", "CDT", "MST", "MDT", "PST", "PDT",
-    "A", "B", "C", "D", "E", "F", "G", "H", "I", "K", "L", "M",
-    "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y"
-  };
-  const int kTimeZoneOffsets[] = {
-     0,  0, -5, -4, -6, -5, -7, -6, -8, -7,
-    -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12,
-     1,  2,  3,  4,  5,  6,  7,  8,  9,  10,  11,  12
-  };
-
-  ASSERT(NULL != seconds);
-  struct tm tval;
-  memset(&tval, 0, sizeof(tval));
-  char month[4], zone[6];
-  memset(month, 0, sizeof(month));
-  memset(zone, 0, sizeof(zone));
-
-  if (7 != sscanf(date.c_str(), "%*3s, %d %3s %d %d:%d:%d %5c",
-                  &tval.tm_mday, month, &tval.tm_year,
-                  &tval.tm_hour, &tval.tm_min, &tval.tm_sec, zone)) {
-    return false;
-  }
-  switch (toupper(month[2])) {
-  case 'N': tval.tm_mon = (month[1] == 'A') ? 0 : 5; break;
-  case 'B': tval.tm_mon = 1; break;
-  case 'R': tval.tm_mon = (month[0] == 'M') ? 2 : 3; break;
-  case 'Y': tval.tm_mon = 4; break;
-  case 'L': tval.tm_mon = 6; break;
-  case 'G': tval.tm_mon = 7; break;
-  case 'P': tval.tm_mon = 8; break;
-  case 'T': tval.tm_mon = 9; break;
-  case 'V': tval.tm_mon = 10; break;
-  case 'C': tval.tm_mon = 11; break;
-  }
-  tval.tm_year -= 1900;
-  unsigned long gmt, non_gmt = mktime(&tval);
-  if ((zone[0] == '+') || (zone[0] == '-')) {
-    if (!isdigit(zone[1]) || !isdigit(zone[2])
-        || !isdigit(zone[3]) || !isdigit(zone[4])) {
-      return false;
-    }
-    int hours = (zone[1] - '0') * 10 + (zone[2] - '0');
-    int minutes = (zone[3] - '0') * 10 + (zone[4] - '0');
-    int offset = (hours * 60 + minutes) * 60;
-    gmt = non_gmt + ((zone[0] == '+') ? offset : -offset);
-  } else {
-    size_t zindex;
-    if (!find_string(zindex, zone, kTimeZones, ARRAY_SIZE(kTimeZones))) {
-      return false;
-    }
-    gmt = non_gmt + kTimeZoneOffsets[zindex] * 60 * 60;
-  }
-  // TODO: Android should support timezone, see b/2441195
-#if defined(OSX) || defined(ANDROID) || defined(BSD)
-  tm *tm_for_timezone = localtime((time_t *)&gmt);
-  *seconds = gmt + tm_for_timezone->tm_gmtoff;
-#else
-  *seconds = gmt - timezone;
-#endif
-  return true;
-}
-
-std::string HttpAddress(const SocketAddress& address, bool secure) {
-  return (address.port() == HttpDefaultPort(secure))
-          ? address.hostname() : address.ToString();
-}
-
-//////////////////////////////////////////////////////////////////////
-// HttpData
-//////////////////////////////////////////////////////////////////////
-
-void
-HttpData::clear(bool release_document) {
-  // Clear headers first, since releasing a document may have far-reaching
-  // effects.
-  headers_.clear();
-  if (release_document) {
-    document.reset();
-  }
-}
-
-void
-HttpData::copy(const HttpData& src) {
-  headers_ = src.headers_;
-}
-
-void
-HttpData::changeHeader(const std::string& name, const std::string& value,
-                       HeaderCombine combine) {
-  if (combine == HC_AUTO) {
-    HttpHeader header;
-    // Unrecognized headers are collapsible
-    combine = !FromString(header, name) || HttpHeaderIsCollapsible(header)
-              ? HC_YES : HC_NO;
-  } else if (combine == HC_REPLACE) {
-    headers_.erase(name);
-    combine = HC_NO;
-  }
-  // At this point, combine is one of (YES, NO, NEW)
-  if (combine != HC_NO) {
-    HeaderMap::iterator it = headers_.find(name);
-    if (it != headers_.end()) {
-      if (combine == HC_YES) {
-        it->second.append(",");
-        it->second.append(value);
-	  }
-      return;
-	}
-  }
-  headers_.insert(HeaderMap::value_type(name, value));
-}
-
-size_t HttpData::clearHeader(const std::string& name) {
-  return headers_.erase(name);
-}
-
-HttpData::iterator HttpData::clearHeader(iterator header) {
-  iterator deprecated = header++;
-  headers_.erase(deprecated);
-  return header;
-}
-
-bool
-HttpData::hasHeader(const std::string& name, std::string* value) const {
-  HeaderMap::const_iterator it = headers_.find(name);
-  if (it == headers_.end()) {
-    return false;
-  } else if (value) {
-    *value = it->second;
-  }
-  return true;
-}
-
-void HttpData::setContent(const std::string& content_type,
-                          StreamInterface* document) {
-  setHeader(HH_CONTENT_TYPE, content_type);
-  setDocumentAndLength(document);
-}
-
-void HttpData::setDocumentAndLength(StreamInterface* document) {
-  // TODO: Consider calling Rewind() here?
-  ASSERT(!hasHeader(HH_CONTENT_LENGTH, NULL));
-  ASSERT(!hasHeader(HH_TRANSFER_ENCODING, NULL));
-  ASSERT(document != NULL);
-  this->document.reset(document);
-  size_t content_length = 0;
-  if (this->document->GetAvailable(&content_length)) {
-    char buffer[32];
-    sprintfn(buffer, sizeof(buffer), "%d", content_length);
-    setHeader(HH_CONTENT_LENGTH, buffer);
-  } else {
-    setHeader(HH_TRANSFER_ENCODING, "chunked");
-  }
-}
-
-//
-// HttpRequestData
-//
-
-void
-HttpRequestData::clear(bool release_document) {
-  verb = HV_GET;
-  path.clear();
-  HttpData::clear(release_document);
-}
-
-void
-HttpRequestData::copy(const HttpRequestData& src) {
-  verb = src.verb;
-  path = src.path;
-  HttpData::copy(src);
-}
-
-size_t
-HttpRequestData::formatLeader(char* buffer, size_t size) const {
-  ASSERT(path.find(' ') == std::string::npos);
-  return sprintfn(buffer, size, "%s %.*s HTTP/%s", ToString(verb), path.size(),
-                  path.data(), ToString(version));
-}
-
-HttpError
-HttpRequestData::parseLeader(const char* line, size_t len) {
-  UNUSED(len);
-  unsigned int vmajor, vminor;
-  int vend, dstart, dend;
-  if ((sscanf(line, "%*s%n %n%*s%n HTTP/%u.%u", &vend, &dstart, &dend,
-              &vmajor, &vminor) != 2)
-      || (vmajor != 1)) {
-    return HE_PROTOCOL;
-  }
-  if (vminor == 0) {
-    version = HVER_1_0;
-  } else if (vminor == 1) {
-    version = HVER_1_1;
-  } else {
-    return HE_PROTOCOL;
-  }
-  std::string sverb(line, vend);
-  if (!FromString(verb, sverb.c_str())) {
-    return HE_PROTOCOL; // !?! HC_METHOD_NOT_SUPPORTED?
-  }
-  path.assign(line + dstart, line + dend);
-  return HE_NONE;
-}
-
-bool HttpRequestData::getAbsoluteUri(std::string* uri) const {
-  if (HV_CONNECT == verb)
-    return false;
-  Url<char> url(path);
-  if (url.valid()) {
-    uri->assign(path);
-    return true;
-  }
-  std::string host;
-  if (!hasHeader(HH_HOST, &host))
-    return false;
-  url.set_address(host);
-  url.set_full_path(path);
-  uri->assign(url.url());
-  return url.valid();
-}
-
-bool HttpRequestData::getRelativeUri(std::string* host,
-                                     std::string* path) const
-{
-  if (HV_CONNECT == verb)
-    return false;
-  Url<char> url(this->path);
-  if (url.valid()) {
-    host->assign(url.address());
-    path->assign(url.full_path());
-    return true;
-  }
-  if (!hasHeader(HH_HOST, host))
-    return false;
-  path->assign(this->path);
-  return true;
-}
-
-//
-// HttpResponseData
-//
-
-void
-HttpResponseData::clear(bool release_document) {
-  scode = HC_INTERNAL_SERVER_ERROR;
-  message.clear();
-  HttpData::clear(release_document);
-}
-
-void
-HttpResponseData::copy(const HttpResponseData& src) {
-  scode = src.scode;
-  message = src.message;
-  HttpData::copy(src);
-}
-
-void
-HttpResponseData::set_success(uint32 scode) {
-  this->scode = scode;
-  message.clear();
-  setHeader(HH_CONTENT_LENGTH, "0", false);
-}
-
-void
-HttpResponseData::set_success(const std::string& content_type,
-                              StreamInterface* document,
-                              uint32 scode) {
-  this->scode = scode;
-  message.erase(message.begin(), message.end());
-  setContent(content_type, document);
-}
-
-void
-HttpResponseData::set_redirect(const std::string& location, uint32 scode) {
-  this->scode = scode;
-  message.clear();
-  setHeader(HH_LOCATION, location);
-  setHeader(HH_CONTENT_LENGTH, "0", false);
-}
-
-void
-HttpResponseData::set_error(uint32 scode) {
-  this->scode = scode;
-  message.clear();
-  setHeader(HH_CONTENT_LENGTH, "0", false);
-}
-
-size_t
-HttpResponseData::formatLeader(char* buffer, size_t size) const {
-  size_t len = sprintfn(buffer, size, "HTTP/%s %lu", ToString(version), scode);
-  if (!message.empty()) {
-    len += sprintfn(buffer + len, size - len, " %.*s",
-                    message.size(), message.data());
-  }
-  return len;
-}
-
-HttpError
-HttpResponseData::parseLeader(const char* line, size_t len) {
-  size_t pos = 0;
-  unsigned int vmajor, vminor, temp_scode;
-  int temp_pos;
-  if (sscanf(line, "HTTP %u%n",
-             &temp_scode, &temp_pos) == 1) {
-    // This server's response has no version. :( NOTE: This happens for every
-    // response to requests made from Chrome plugins, regardless of the server's
-    // behaviour.
-    LOG(LS_VERBOSE) << "HTTP version missing from response";
-    version = HVER_UNKNOWN;
-  } else if ((sscanf(line, "HTTP/%u.%u %u%n",
-                     &vmajor, &vminor, &temp_scode, &temp_pos) == 3)
-             && (vmajor == 1)) {
-    // This server's response does have a version.
-    if (vminor == 0) {
-      version = HVER_1_0;
-    } else if (vminor == 1) {
-      version = HVER_1_1;
-    } else {
-      return HE_PROTOCOL;
-    }
-  } else {
-    return HE_PROTOCOL;
-  }
-  scode = temp_scode;
-  pos = static_cast<size_t>(temp_pos);
-  while ((pos < len) && isspace(static_cast<unsigned char>(line[pos]))) ++pos;
-  message.assign(line + pos, len - pos);
-  return HE_NONE;
-}
-
-//////////////////////////////////////////////////////////////////////
-// Http Authentication
-//////////////////////////////////////////////////////////////////////
-
-#define TEST_DIGEST 0
-#if TEST_DIGEST
-/*
-const char * const DIGEST_CHALLENGE =
-  "Digest realm=\"testrealm@host.com\","
-  " qop=\"auth,auth-int\","
-  " nonce=\"dcd98b7102dd2f0e8b11d0f600bfb0c093\","
-  " opaque=\"5ccc069c403ebaf9f0171e9517f40e41\"";
-const char * const DIGEST_METHOD = "GET";
-const char * const DIGEST_URI =
-  "/dir/index.html";;
-const char * const DIGEST_CNONCE =
-  "0a4f113b";
-const char * const DIGEST_RESPONSE =
-  "6629fae49393a05397450978507c4ef1";
-//user_ = "Mufasa";
-//pass_ = "Circle Of Life";
-*/
-const char * const DIGEST_CHALLENGE =
-  "Digest realm=\"Squid proxy-caching web server\","
-  " nonce=\"Nny4QuC5PwiSDixJ\","
-  " qop=\"auth\","
-  " stale=false";
-const char * const DIGEST_URI =
-  "/";
-const char * const DIGEST_CNONCE =
-  "6501d58e9a21cee1e7b5fec894ded024";
-const char * const DIGEST_RESPONSE =
-  "edffcb0829e755838b073a4a42de06bc";
-#endif
-
-std::string quote(const std::string& str) {
-  std::string result;
-  result.push_back('"');
-  for (size_t i=0; i<str.size(); ++i) {
-    if ((str[i] == '"') || (str[i] == '\\'))
-      result.push_back('\\');
-    result.push_back(str[i]);
-  }
-  result.push_back('"');
-  return result;
-}
-
-#ifdef WIN32
-struct NegotiateAuthContext : public HttpAuthContext {
-  CredHandle cred;
-  CtxtHandle ctx;
-  size_t steps;
-  bool specified_credentials;
-
-  NegotiateAuthContext(const std::string& auth, CredHandle c1, CtxtHandle c2)
-  : HttpAuthContext(auth), cred(c1), ctx(c2), steps(0),
-    specified_credentials(false)
-  { }
-
-  virtual ~NegotiateAuthContext() {
-    DeleteSecurityContext(&ctx);
-    FreeCredentialsHandle(&cred);
-  }
-};
-#endif // WIN32
-
-HttpAuthResult HttpAuthenticate(
-  const char * challenge, size_t len,
-  const SocketAddress& server,
-  const std::string& method, const std::string& uri,
-  const std::string& username, const CryptString& password,
-  HttpAuthContext *& context, std::string& response, std::string& auth_method)
-{
-#if TEST_DIGEST
-  challenge = DIGEST_CHALLENGE;
-  len = strlen(challenge);
-#endif
-
-  HttpAttributeList args;
-  HttpParseAttributes(challenge, len, args);
-  HttpHasNthAttribute(args, 0, &auth_method, NULL);
-
-  if (context && (context->auth_method != auth_method))
-    return HAR_IGNORE;
-
-  // BASIC
-  if (_stricmp(auth_method.c_str(), "basic") == 0) {
-    if (context)
-      return HAR_CREDENTIALS; // Bad credentials
-    if (username.empty())
-      return HAR_CREDENTIALS; // Missing credentials
-
-    context = new HttpAuthContext(auth_method);
-
-    // TODO: convert sensitive to a secure buffer that gets securely deleted
-    //std::string decoded = username + ":" + password;
-    size_t len = username.size() + password.GetLength() + 2;
-    char * sensitive = new char[len];
-    size_t pos = strcpyn(sensitive, len, username.data(), username.size());
-    pos += strcpyn(sensitive + pos, len - pos, ":");
-    password.CopyTo(sensitive + pos, true);
-
-    response = auth_method;
-    response.append(" ");
-    // TODO: create a sensitive-source version of Base64::encode
-    response.append(Base64::Encode(sensitive));
-    memset(sensitive, 0, len);
-    delete [] sensitive;
-    return HAR_RESPONSE;
-  }
-
-  // DIGEST
-  if (_stricmp(auth_method.c_str(), "digest") == 0) {
-    if (context)
-      return HAR_CREDENTIALS; // Bad credentials
-    if (username.empty())
-      return HAR_CREDENTIALS; // Missing credentials
-
-    context = new HttpAuthContext(auth_method);
-
-    std::string cnonce, ncount;
-#if TEST_DIGEST
-    method = DIGEST_METHOD;
-    uri    = DIGEST_URI;
-    cnonce = DIGEST_CNONCE;
-#else
-    char buffer[256];
-    sprintf(buffer, "%d", static_cast<int>(time(0)));
-    cnonce = MD5(buffer);
-#endif
-    ncount = "00000001";
-
-    std::string realm, nonce, qop, opaque;
-    HttpHasAttribute(args, "realm", &realm);
-    HttpHasAttribute(args, "nonce", &nonce);
-    bool has_qop = HttpHasAttribute(args, "qop", &qop);
-    bool has_opaque = HttpHasAttribute(args, "opaque", &opaque);
-
-    // TODO: convert sensitive to be secure buffer
-    //std::string A1 = username + ":" + realm + ":" + password;
-    size_t len = username.size() + realm.size() + password.GetLength() + 3;
-    char * sensitive = new char[len];  // A1
-    size_t pos = strcpyn(sensitive, len, username.data(), username.size());
-    pos += strcpyn(sensitive + pos, len - pos, ":");
-    pos += strcpyn(sensitive + pos, len - pos, realm.c_str());
-    pos += strcpyn(sensitive + pos, len - pos, ":");
-    password.CopyTo(sensitive + pos, true);
-
-    std::string A2 = method + ":" + uri;
-    std::string middle;
-    if (has_qop) {
-      qop = "auth";
-      middle = nonce + ":" + ncount + ":" + cnonce + ":" + qop;
-    } else {
-      middle = nonce;
-    }
-    std::string HA1 = MD5(sensitive);
-    memset(sensitive, 0, len);
-    delete [] sensitive;
-    std::string HA2 = MD5(A2);
-    std::string dig_response = MD5(HA1 + ":" + middle + ":" + HA2);
-
-#if TEST_DIGEST
-    ASSERT(strcmp(dig_response.c_str(), DIGEST_RESPONSE) == 0);
-#endif
-
-    std::stringstream ss;
-    ss << auth_method;
-    ss << " username=" << quote(username);
-    ss << ", realm=" << quote(realm);
-    ss << ", nonce=" << quote(nonce);
-    ss << ", uri=" << quote(uri);
-    if (has_qop) {
-      ss << ", qop=" << qop;
-      ss << ", nc="  << ncount;
-      ss << ", cnonce=" << quote(cnonce);
-    }
-    ss << ", response=\"" << dig_response << "\"";
-    if (has_opaque) {
-      ss << ", opaque=" << quote(opaque);
-    }
-    response = ss.str();
-    return HAR_RESPONSE;
-  }
-
-#ifdef WIN32
-#if 1
-  bool want_negotiate = (_stricmp(auth_method.c_str(), "negotiate") == 0);
-  bool want_ntlm = (_stricmp(auth_method.c_str(), "ntlm") == 0);
-  // SPNEGO & NTLM
-  if (want_negotiate || want_ntlm) {
-    const size_t MAX_MESSAGE = 12000, MAX_SPN = 256;
-    char out_buf[MAX_MESSAGE], spn[MAX_SPN];
-
-#if 0 // Requires funky windows versions
-    DWORD len = MAX_SPN;
-    if (DsMakeSpn("HTTP", server.IPAsString().c_str(), NULL, server.port(),
-                  0, &len, spn) != ERROR_SUCCESS) {
-      LOG_F(WARNING) << "(Negotiate) - DsMakeSpn failed";
-      return HAR_IGNORE;
-    }
-#else
-    sprintfn(spn, MAX_SPN, "HTTP/%s", server.ToString().c_str());
-#endif
-
-    SecBuffer out_sec;
-    out_sec.pvBuffer   = out_buf;
-    out_sec.cbBuffer   = sizeof(out_buf);
-    out_sec.BufferType = SECBUFFER_TOKEN;
-
-    SecBufferDesc out_buf_desc;
-    out_buf_desc.ulVersion = 0;
-    out_buf_desc.cBuffers  = 1;
-    out_buf_desc.pBuffers  = &out_sec;
-
-    const ULONG NEG_FLAGS_DEFAULT =
-      //ISC_REQ_ALLOCATE_MEMORY
-      ISC_REQ_CONFIDENTIALITY
-      //| ISC_REQ_EXTENDED_ERROR
-      //| ISC_REQ_INTEGRITY
-      | ISC_REQ_REPLAY_DETECT
-      | ISC_REQ_SEQUENCE_DETECT
-      //| ISC_REQ_STREAM
-      //| ISC_REQ_USE_SUPPLIED_CREDS
-      ;
-
-    ::TimeStamp lifetime;
-    SECURITY_STATUS ret = S_OK;
-    ULONG ret_flags = 0, flags = NEG_FLAGS_DEFAULT;
-
-    bool specify_credentials = !username.empty();
-    size_t steps = 0;
-
-    //uint32 now = Time();
-
-    NegotiateAuthContext * neg = static_cast<NegotiateAuthContext *>(context);
-    if (neg) {
-      const size_t max_steps = 10;
-      if (++neg->steps >= max_steps) {
-        LOG(WARNING) << "AsyncHttpsProxySocket::Authenticate(Negotiate) too many retries";
-        return HAR_ERROR;
-      }
-      steps = neg->steps;
-
-      std::string challenge, decoded_challenge;
-      if (HttpHasNthAttribute(args, 1, &challenge, NULL)
-          && Base64::Decode(challenge, Base64::DO_STRICT,
-                            &decoded_challenge, NULL)) {
-        SecBuffer in_sec;
-        in_sec.pvBuffer   = const_cast<char *>(decoded_challenge.data());
-        in_sec.cbBuffer   = static_cast<unsigned long>(decoded_challenge.size());
-        in_sec.BufferType = SECBUFFER_TOKEN;
-
-        SecBufferDesc in_buf_desc;
-        in_buf_desc.ulVersion = 0;
-        in_buf_desc.cBuffers  = 1;
-        in_buf_desc.pBuffers  = &in_sec;
-
-        ret = InitializeSecurityContextA(&neg->cred, &neg->ctx, spn, flags, 0, SECURITY_NATIVE_DREP, &in_buf_desc, 0, &neg->ctx, &out_buf_desc, &ret_flags, &lifetime);
-        //LOG(INFO) << "$$$ InitializeSecurityContext @ " << TimeSince(now);
-        if (FAILED(ret)) {
-          LOG(LS_ERROR) << "InitializeSecurityContext returned: "
-                      << ErrorName(ret, SECURITY_ERRORS);
-          return HAR_ERROR;
-        }
-      } else if (neg->specified_credentials) {
-        // Try again with default credentials
-        specify_credentials = false;
-        delete context;
-        context = neg = 0;
-      } else {
-        return HAR_CREDENTIALS;
-      }
-    }
-
-    if (!neg) {
-      unsigned char userbuf[256], passbuf[256], domainbuf[16];
-      SEC_WINNT_AUTH_IDENTITY_A auth_id, * pauth_id = 0;
-      if (specify_credentials) {
-        memset(&auth_id, 0, sizeof(auth_id));
-        size_t len = password.GetLength()+1;
-        char * sensitive = new char[len];
-        password.CopyTo(sensitive, true);
-        std::string::size_type pos = username.find('\\');
-        if (pos == std::string::npos) {
-          auth_id.UserLength = static_cast<unsigned long>(
-            _min(sizeof(userbuf) - 1, username.size()));
-          memcpy(userbuf, username.c_str(), auth_id.UserLength);
-          userbuf[auth_id.UserLength] = 0;
-          auth_id.DomainLength = 0;
-          domainbuf[auth_id.DomainLength] = 0;
-          auth_id.PasswordLength = static_cast<unsigned long>(
-            _min(sizeof(passbuf) - 1, password.GetLength()));
-          memcpy(passbuf, sensitive, auth_id.PasswordLength);
-          passbuf[auth_id.PasswordLength] = 0;
-        } else {
-          auth_id.UserLength = static_cast<unsigned long>(
-            _min(sizeof(userbuf) - 1, username.size() - pos - 1));
-          memcpy(userbuf, username.c_str() + pos + 1, auth_id.UserLength);
-          userbuf[auth_id.UserLength] = 0;
-          auth_id.DomainLength = static_cast<unsigned long>(
-            _min(sizeof(domainbuf) - 1, pos));
-          memcpy(domainbuf, username.c_str(), auth_id.DomainLength);
-          domainbuf[auth_id.DomainLength] = 0;
-          auth_id.PasswordLength = static_cast<unsigned long>(
-            _min(sizeof(passbuf) - 1, password.GetLength()));
-          memcpy(passbuf, sensitive, auth_id.PasswordLength);
-          passbuf[auth_id.PasswordLength] = 0;
-        }
-        memset(sensitive, 0, len);
-        delete [] sensitive;
-        auth_id.User = userbuf;
-        auth_id.Domain = domainbuf;
-        auth_id.Password = passbuf;
-        auth_id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
-        pauth_id = &auth_id;
-        LOG(LS_VERBOSE) << "Negotiate protocol: Using specified credentials";
-      } else {
-        LOG(LS_VERBOSE) << "Negotiate protocol: Using default credentials";
-      }
-
-      CredHandle cred;
-      ret = AcquireCredentialsHandleA(0, want_negotiate ? NEGOSSP_NAME_A : NTLMSP_NAME_A, SECPKG_CRED_OUTBOUND, 0, pauth_id, 0, 0, &cred, &lifetime);
-      //LOG(INFO) << "$$$ AcquireCredentialsHandle @ " << TimeSince(now);
-      if (ret != SEC_E_OK) {
-        LOG(LS_ERROR) << "AcquireCredentialsHandle error: "
-                    << ErrorName(ret, SECURITY_ERRORS);
-        return HAR_IGNORE;
-      }
-
-      //CSecBufferBundle<5, CSecBufferBase::FreeSSPI> sb_out;
-
-      CtxtHandle ctx;
-      ret = InitializeSecurityContextA(&cred, 0, spn, flags, 0, SECURITY_NATIVE_DREP, 0, 0, &ctx, &out_buf_desc, &ret_flags, &lifetime);
-      //LOG(INFO) << "$$$ InitializeSecurityContext @ " << TimeSince(now);
-      if (FAILED(ret)) {
-        LOG(LS_ERROR) << "InitializeSecurityContext returned: "
-                    << ErrorName(ret, SECURITY_ERRORS);
-        FreeCredentialsHandle(&cred);
-        return HAR_IGNORE;
-      }
-
-      ASSERT(!context);
-      context = neg = new NegotiateAuthContext(auth_method, cred, ctx);
-      neg->specified_credentials = specify_credentials;
-      neg->steps = steps;
-    }
-
-    if ((ret == SEC_I_COMPLETE_NEEDED) || (ret == SEC_I_COMPLETE_AND_CONTINUE)) {
-      ret = CompleteAuthToken(&neg->ctx, &out_buf_desc);
-      //LOG(INFO) << "$$$ CompleteAuthToken @ " << TimeSince(now);
-      LOG(LS_VERBOSE) << "CompleteAuthToken returned: "
-                      << ErrorName(ret, SECURITY_ERRORS);
-      if (FAILED(ret)) {
-        return HAR_ERROR;
-      }
-    }
-
-    //LOG(INFO) << "$$$ NEGOTIATE took " << TimeSince(now) << "ms";
-
-    std::string decoded(out_buf, out_buf + out_sec.cbBuffer);
-    response = auth_method;
-    response.append(" ");
-    response.append(Base64::Encode(decoded));
-    return HAR_RESPONSE;
-  }
-#endif
-#endif // WIN32
-
-  return HAR_IGNORE;
-}
-
-//////////////////////////////////////////////////////////////////////
-
-} // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/httpcommon.h b/third_party/libjingle/source/talk/base/httpcommon.h
deleted file mode 100644
index 7e0b9cf..0000000
--- a/third_party/libjingle/source/talk/base/httpcommon.h
+++ /dev/null
@@ -1,463 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_HTTPCOMMON_H__
-#define TALK_BASE_HTTPCOMMON_H__
-
-#include <map>
-#include <string>
-#include <vector>
-#include "talk/base/basictypes.h"
-#include "talk/base/common.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/base/stringutils.h"
-#include "talk/base/stream.h"
-
-namespace talk_base {
-
-class CryptString;
-class SocketAddress;
-
-//////////////////////////////////////////////////////////////////////
-// Constants
-//////////////////////////////////////////////////////////////////////
-
-enum HttpCode { 
-  HC_OK = 200,
-  HC_NON_AUTHORITATIVE = 203,
-  HC_NO_CONTENT = 204,
-  HC_PARTIAL_CONTENT = 206,
-
-  HC_MULTIPLE_CHOICES = 300,
-  HC_MOVED_PERMANENTLY = 301,
-  HC_FOUND = 302,
-  HC_SEE_OTHER = 303,
-  HC_NOT_MODIFIED = 304,
-  HC_MOVED_TEMPORARILY = 307,
-
-  HC_BAD_REQUEST = 400,
-  HC_UNAUTHORIZED = 401,
-  HC_FORBIDDEN = 403,
-  HC_NOT_FOUND = 404,
-  HC_PROXY_AUTHENTICATION_REQUIRED = 407,
-  HC_GONE = 410,
-
-  HC_INTERNAL_SERVER_ERROR = 500,
-  HC_NOT_IMPLEMENTED = 501,
-  HC_SERVICE_UNAVAILABLE = 503,
-};
-
-enum HttpVersion {
-  HVER_1_0, HVER_1_1, HVER_UNKNOWN,
-  HVER_LAST = HVER_UNKNOWN
-};
-
-enum HttpVerb {
-  HV_GET, HV_POST, HV_PUT, HV_DELETE, HV_CONNECT, HV_HEAD,
-  HV_LAST = HV_HEAD
-};
-
-enum HttpError {
-  HE_NONE,
-  HE_PROTOCOL,            // Received non-valid HTTP data
-  HE_DISCONNECTED,        // Connection closed unexpectedly
-  HE_OVERFLOW,            // Received too much data for internal buffers
-  HE_CONNECT_FAILED,      // The socket failed to connect.
-  HE_SOCKET_ERROR,        // An error occurred on a connected socket
-  HE_SHUTDOWN,            // Http object is being destroyed
-  HE_OPERATION_CANCELLED, // Connection aborted locally
-  HE_AUTH,                // Proxy Authentication Required
-  HE_CERTIFICATE_EXPIRED, // During SSL negotiation
-  HE_STREAM,              // Problem reading or writing to the document
-  HE_CACHE,               // Problem reading from cache
-  HE_DEFAULT
-};
-
-enum HttpHeader {
-  HH_AGE,
-  HH_CACHE_CONTROL,
-  HH_CONNECTION,
-  HH_CONTENT_DISPOSITION,
-  HH_CONTENT_LENGTH,
-  HH_CONTENT_RANGE,
-  HH_CONTENT_TYPE,
-  HH_COOKIE,
-  HH_DATE,
-  HH_ETAG,
-  HH_EXPIRES,
-  HH_HOST,
-  HH_IF_MODIFIED_SINCE,
-  HH_IF_NONE_MATCH,
-  HH_KEEP_ALIVE,
-  HH_LAST_MODIFIED,
-  HH_LOCATION,
-  HH_PROXY_AUTHENTICATE,
-  HH_PROXY_AUTHORIZATION,
-  HH_PROXY_CONNECTION,
-  HH_RANGE,
-  HH_SET_COOKIE,
-  HH_TE,
-  HH_TRAILERS,
-  HH_TRANSFER_ENCODING,
-  HH_UPGRADE,
-  HH_USER_AGENT,
-  HH_WWW_AUTHENTICATE,
-  HH_LAST = HH_WWW_AUTHENTICATE
-};
-
-const uint16 HTTP_DEFAULT_PORT = 80;
-const uint16 HTTP_SECURE_PORT = 443;
-
-//////////////////////////////////////////////////////////////////////
-// Utility Functions
-//////////////////////////////////////////////////////////////////////
-
-inline HttpError mkerr(HttpError err, HttpError def_err = HE_DEFAULT) {
-  return (err != HE_NONE) ? err : def_err;
-}
-
-const char* ToString(HttpVersion version);
-bool FromString(HttpVersion& version, const std::string& str);
-
-const char* ToString(HttpVerb verb);
-bool FromString(HttpVerb& verb, const std::string& str);
-
-const char* ToString(HttpHeader header);
-bool FromString(HttpHeader& header, const std::string& str);
-
-inline bool HttpCodeIsInformational(uint32 code) { return ((code / 100) == 1); }
-inline bool HttpCodeIsSuccessful(uint32 code)    { return ((code / 100) == 2); }
-inline bool HttpCodeIsRedirection(uint32 code)   { return ((code / 100) == 3); }
-inline bool HttpCodeIsClientError(uint32 code)   { return ((code / 100) == 4); }
-inline bool HttpCodeIsServerError(uint32 code)   { return ((code / 100) == 5); }
-
-bool HttpCodeHasBody(uint32 code);
-bool HttpCodeIsCacheable(uint32 code);
-bool HttpHeaderIsEndToEnd(HttpHeader header);
-bool HttpHeaderIsCollapsible(HttpHeader header);
-
-struct HttpData;
-bool HttpShouldKeepAlive(const HttpData& data);
-
-typedef std::pair<std::string, std::string> HttpAttribute;
-typedef std::vector<HttpAttribute> HttpAttributeList;
-void HttpComposeAttributes(const HttpAttributeList& attributes, char separator,
-                           std::string* composed);
-void HttpParseAttributes(const char * data, size_t len, 
-                         HttpAttributeList& attributes);
-bool HttpHasAttribute(const HttpAttributeList& attributes,
-                      const std::string& name,
-                      std::string* value);
-bool HttpHasNthAttribute(HttpAttributeList& attributes,
-                         size_t index, 
-                         std::string* name,
-                         std::string* value);
-
-// Convert RFC1123 date (DoW, DD Mon YYYY HH:MM:SS TZ) to unix timestamp
-bool HttpDateToSeconds(const std::string& date, unsigned long* seconds);
-
-inline uint16 HttpDefaultPort(bool secure) {
-  return secure ? HTTP_SECURE_PORT : HTTP_DEFAULT_PORT;
-}
-
-// Returns the http server notation for a given address
-std::string HttpAddress(const SocketAddress& address, bool secure);
-
-// functional for insensitive std::string compare
-struct iless {
-  bool operator()(const std::string& lhs, const std::string& rhs) const {
-    return (::_stricmp(lhs.c_str(), rhs.c_str()) < 0);
-  }
-};
-
-// put quotes around a string and escape any quotes inside it
-std::string quote(const std::string& str);
-
-//////////////////////////////////////////////////////////////////////
-// Url
-//////////////////////////////////////////////////////////////////////
-
-template<class CTYPE>
-class Url {
-public:
-  typedef typename Traits<CTYPE>::string string;
-
-  // TODO: Implement Encode/Decode
-  static int Encode(const CTYPE* source, CTYPE* destination, size_t len);
-  static int Encode(const string& source, string& destination);
-  static int Decode(const CTYPE* source, CTYPE* destination, size_t len);
-  static int Decode(const string& source, string& destination);
-
-  Url(const string& url) { do_set_url(url.c_str(), url.size()); }
-  Url(const string& path, const string& host, uint16 port = HTTP_DEFAULT_PORT)
-  : host_(host), port_(port), secure_(HTTP_SECURE_PORT == port)
-  { set_full_path(path); }
-
-  bool valid() const { return !host_.empty(); }
-  void clear() {
-    host_.clear();
-    port_ = HTTP_DEFAULT_PORT;
-    secure_ = false;
-    path_.assign(1, static_cast<CTYPE>('/'));
-    query_.clear();
-  }
-
-  void set_url(const string& val) {
-    do_set_url(val.c_str(), val.size());
-  }
-  string url() const {
-    string val; do_get_url(&val); return val;
-  }
-
-  void set_address(const string& val) {
-    do_set_address(val.c_str(), val.size());
-  }
-  string address() const {
-    string val; do_get_address(&val); return val;
-  }
-
-  void set_full_path(const string& val) {
-    do_set_full_path(val.c_str(), val.size());
-  }
-  string full_path() const {
-    string val; do_get_full_path(&val); return val;
-  }
-
-  void set_host(const string& val) { host_ = val; }
-  const string& host() const { return host_; }
-
-  void set_port(uint16 val) { port_ = val; }
-  uint16 port() const { return port_; }
-
-  void set_secure(bool val) { secure_ = val; }
-  bool secure() const { return secure_; }
-
-  void set_path(const string& val) {
-    if (val.empty()) {
-      path_.assign(1, static_cast<CTYPE>('/'));
-    } else {
-      ASSERT(val[0] == static_cast<CTYPE>('/'));
-      path_ = val;
-    }
-  }
-  const string& path() const { return path_; }
-
-  void set_query(const string& val) {
-    ASSERT(val.empty() || (val[0] == static_cast<CTYPE>('?')));
-    query_ = val;
-  }
-  const string& query() const { return query_; }
-
-  bool get_attribute(const string& name, string* value) const;
-
-private:
-  void do_set_url(const CTYPE* val, size_t len);
-  void do_set_address(const CTYPE* val, size_t len);
-  void do_set_full_path(const CTYPE* val, size_t len);
-
-  void do_get_url(string* val) const;
-  void do_get_address(string* val) const;
-  void do_get_full_path(string* val) const;
-
-  string host_, path_, query_;
-  uint16 port_;
-  bool secure_;
-};
-
-//////////////////////////////////////////////////////////////////////
-// HttpData
-//////////////////////////////////////////////////////////////////////
-
-struct HttpData {
-  typedef std::multimap<std::string, std::string, iless> HeaderMap;
-  typedef HeaderMap::const_iterator const_iterator;
-  typedef HeaderMap::iterator iterator;
-
-  HttpVersion version;
-  scoped_ptr<StreamInterface> document;
-
-  HttpData() : version(HVER_1_1) { }
-
-  enum HeaderCombine { HC_YES, HC_NO, HC_AUTO, HC_REPLACE, HC_NEW };
-  void changeHeader(const std::string& name, const std::string& value,
-                    HeaderCombine combine);
-  inline void addHeader(const std::string& name, const std::string& value,
-                        bool append = true) {
-    changeHeader(name, value, append ? HC_AUTO : HC_NO);
-  }
-  inline void setHeader(const std::string& name, const std::string& value,
-                        bool overwrite = true) {
-    changeHeader(name, value, overwrite ? HC_REPLACE : HC_NEW);
-  }
-  // Returns count of erased headers
-  size_t clearHeader(const std::string& name);
-  // Returns iterator to next header
-  iterator clearHeader(iterator header);
-
-  // keep in mind, this may not do what you want in the face of multiple headers
-  bool hasHeader(const std::string& name, std::string* value) const;
-
-  inline const_iterator begin() const {
-    return headers_.begin();
-  }
-  inline const_iterator end() const {
-    return headers_.end();
-  }
-  inline iterator begin() {
-    return headers_.begin();
-  }
-  inline iterator end() {
-    return headers_.end();
-  }
-  inline const_iterator begin(const std::string& name) const {
-    return headers_.lower_bound(name);
-  }
-  inline const_iterator end(const std::string& name) const {
-    return headers_.upper_bound(name);
-  }
-  inline iterator begin(const std::string& name) {
-    return headers_.lower_bound(name);
-  }
-  inline iterator end(const std::string& name) {
-    return headers_.upper_bound(name);
-  }
-
-  // Convenience methods using HttpHeader
-  inline void changeHeader(HttpHeader header, const std::string& value,
-                           HeaderCombine combine) {
-    changeHeader(ToString(header), value, combine);
-  }
-  inline void addHeader(HttpHeader header, const std::string& value,
-                        bool append = true) {
-    addHeader(ToString(header), value, append);
-  }
-  inline void setHeader(HttpHeader header, const std::string& value,
-                        bool overwrite = true) {
-    setHeader(ToString(header), value, overwrite);
-  }
-  inline void clearHeader(HttpHeader header) {
-    clearHeader(ToString(header));
-  }
-  inline bool hasHeader(HttpHeader header, std::string* value) const {
-    return hasHeader(ToString(header), value);
-  }
-  inline const_iterator begin(HttpHeader header) const {
-    return headers_.lower_bound(ToString(header));
-  }
-  inline const_iterator end(HttpHeader header) const {
-    return headers_.upper_bound(ToString(header));
-  }
-  inline iterator begin(HttpHeader header) {
-    return headers_.lower_bound(ToString(header));
-  }
-  inline iterator end(HttpHeader header) {
-    return headers_.upper_bound(ToString(header));
-  }
-
-  void setContent(const std::string& content_type, StreamInterface* document);
-  void setDocumentAndLength(StreamInterface* document);
-
-  virtual size_t formatLeader(char* buffer, size_t size) const = 0;
-  virtual HttpError parseLeader(const char* line, size_t len) = 0;
-
-protected:  
-  virtual ~HttpData() { }
-  void clear(bool release_document);
-  void copy(const HttpData& src);
-
-private:
-  HeaderMap headers_;
-};
-
-struct HttpRequestData : public HttpData {
-  HttpVerb verb;
-  std::string path;
-
-  HttpRequestData() : verb(HV_GET) { }
-
-  void clear(bool release_document);
-  void copy(const HttpRequestData& src);
-
-  virtual size_t formatLeader(char* buffer, size_t size) const;
-  virtual HttpError parseLeader(const char* line, size_t len);
-
-  bool getAbsoluteUri(std::string* uri) const;
-  bool getRelativeUri(std::string* host, std::string* path) const;
-};
-
-struct HttpResponseData : public HttpData {
-  uint32 scode;
-  std::string message;
-
-  HttpResponseData() : scode(HC_INTERNAL_SERVER_ERROR) { }
-  void clear(bool release_document);
-  void copy(const HttpResponseData& src);
-
-  // Convenience methods
-  void set_success(uint32 scode = HC_OK);
-  void set_success(const std::string& content_type, StreamInterface* document,
-                   uint32 scode = HC_OK);
-  void set_redirect(const std::string& location,
-                    uint32 scode = HC_MOVED_TEMPORARILY);
-  void set_error(uint32 scode);
-
-  virtual size_t formatLeader(char* buffer, size_t size) const;
-  virtual HttpError parseLeader(const char* line, size_t len);
-};
-
-struct HttpTransaction {
-  HttpRequestData request;
-  HttpResponseData response;
-};
-
-//////////////////////////////////////////////////////////////////////
-// Http Authentication
-//////////////////////////////////////////////////////////////////////
-
-struct HttpAuthContext {
-  std::string auth_method;
-  HttpAuthContext(const std::string& auth) : auth_method(auth) { }
-  virtual ~HttpAuthContext() { }
-};
-
-enum HttpAuthResult { HAR_RESPONSE, HAR_IGNORE, HAR_CREDENTIALS, HAR_ERROR };
-
-// 'context' is used by this function to record information between calls.
-// Start by passing a null pointer, then pass the same pointer each additional
-// call.  When the authentication attempt is finished, delete the context.
-HttpAuthResult HttpAuthenticate(
-  const char * challenge, size_t len,
-  const SocketAddress& server,
-  const std::string& method, const std::string& uri,
-  const std::string& username, const CryptString& password,
-  HttpAuthContext *& context, std::string& response, std::string& auth_method);
-
-//////////////////////////////////////////////////////////////////////
-
-} // namespace talk_base
-
-#endif // TALK_BASE_HTTPCOMMON_H__
diff --git a/third_party/libjingle/source/talk/base/httpcommon_unittest.cc b/third_party/libjingle/source/talk/base/httpcommon_unittest.cc
deleted file mode 100644
index 37d77ed..0000000
--- a/third_party/libjingle/source/talk/base/httpcommon_unittest.cc
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/gunit.h"
-#include "talk/base/httpcommon-inl.h"
-#include "talk/base/httpcommon.h"
-
-namespace talk_base {
-
-#define TEST_PROTOCOL "http://"
-#define TEST_HOST "www.google.com"
-#define TEST_PATH "/folder/file.html"
-#define TEST_QUERY "?query=x&attr=y"
-#define TEST_URL TEST_PROTOCOL TEST_HOST TEST_PATH TEST_QUERY
-
-TEST(Url, DecomposesUrls) {
-  Url<char> url(TEST_URL);
-  EXPECT_TRUE(url.valid());
-  EXPECT_FALSE(url.secure());
-  EXPECT_STREQ(TEST_HOST, url.host().c_str());
-  EXPECT_EQ(80, url.port());
-  EXPECT_STREQ(TEST_PATH, url.path().c_str());
-  EXPECT_STREQ(TEST_QUERY, url.query().c_str());
-  EXPECT_STREQ(TEST_HOST, url.address().c_str());
-  EXPECT_STREQ(TEST_PATH TEST_QUERY, url.full_path().c_str());
-  EXPECT_STREQ(TEST_URL, url.url().c_str());
-}
-
-TEST(Url, ComposesUrls) {
-  // Set in constructor
-  Url<char> url(TEST_PATH TEST_QUERY, TEST_HOST, 80);
-  EXPECT_TRUE(url.valid());
-  EXPECT_FALSE(url.secure());
-  EXPECT_STREQ(TEST_HOST, url.host().c_str());
-  EXPECT_EQ(80, url.port());
-  EXPECT_STREQ(TEST_PATH, url.path().c_str());
-  EXPECT_STREQ(TEST_QUERY, url.query().c_str());
-  EXPECT_STREQ(TEST_HOST, url.address().c_str());
-  EXPECT_STREQ(TEST_PATH TEST_QUERY, url.full_path().c_str());
-  EXPECT_STREQ(TEST_URL, url.url().c_str());
-
-  url.clear();
-  EXPECT_FALSE(url.valid());
-  EXPECT_FALSE(url.secure());
-  EXPECT_STREQ("", url.host().c_str());
-  EXPECT_EQ(80, url.port());
-  EXPECT_STREQ("/", url.path().c_str());
-  EXPECT_STREQ("", url.query().c_str());
-
-  // Set component-wise
-  url.set_host(TEST_HOST);
-  url.set_port(80);
-  url.set_path(TEST_PATH);
-  url.set_query(TEST_QUERY);
-  EXPECT_TRUE(url.valid());
-  EXPECT_FALSE(url.secure());
-  EXPECT_STREQ(TEST_HOST, url.host().c_str());
-  EXPECT_EQ(80, url.port());
-  EXPECT_STREQ(TEST_PATH, url.path().c_str());
-  EXPECT_STREQ(TEST_QUERY, url.query().c_str());
-  EXPECT_STREQ(TEST_HOST, url.address().c_str());
-  EXPECT_STREQ(TEST_PATH TEST_QUERY, url.full_path().c_str());
-  EXPECT_STREQ(TEST_URL, url.url().c_str());
-}
-
-TEST(Url, EnsuresNonEmptyPath) {
-  Url<char> url(TEST_PROTOCOL TEST_HOST);
-  EXPECT_TRUE(url.valid());
-  EXPECT_STREQ("/", url.path().c_str());
-  
-  url.clear();
-  EXPECT_STREQ("/", url.path().c_str());
-  url.set_path("");
-  EXPECT_STREQ("/", url.path().c_str());
-
-  url.clear();
-  EXPECT_STREQ("/", url.path().c_str());
-  url.set_full_path("");
-  EXPECT_STREQ("/", url.path().c_str());
-}
-
-TEST(Url, GetQueryAttributes) {
-  Url<char> url(TEST_URL);
-  std::string value;
-  EXPECT_TRUE(url.get_attribute("query", &value));
-  EXPECT_STREQ("x", value.c_str());
-  value.clear();
-  EXPECT_TRUE(url.get_attribute("attr", &value));
-  EXPECT_STREQ("y", value.c_str());
-  value.clear();
-  EXPECT_FALSE(url.get_attribute("Query", &value));
-  EXPECT_TRUE(value.empty());
-}
-
-TEST(HttpResponseData, parseLeaderHttp1_0) {
-  static const char kResponseString[] = "HTTP/1.0 200 OK";
-  HttpResponseData response;
-  EXPECT_EQ(HE_NONE, response.parseLeader(kResponseString,
-                                          sizeof(kResponseString) - 1));
-  EXPECT_EQ(HVER_1_0, response.version);
-  EXPECT_EQ(200U, response.scode);
-}
-
-TEST(HttpResponseData, parseLeaderHttp1_1) {
-  static const char kResponseString[] = "HTTP/1.1 200 OK";
-  HttpResponseData response;
-  EXPECT_EQ(HE_NONE, response.parseLeader(kResponseString,
-                                          sizeof(kResponseString) - 1));
-  EXPECT_EQ(HVER_1_1, response.version);
-  EXPECT_EQ(200U, response.scode);
-}
-
-TEST(HttpResponseData, parseLeaderHttpUnknown) {
-  static const char kResponseString[] = "HTTP 200 OK";
-  HttpResponseData response;
-  EXPECT_EQ(HE_NONE, response.parseLeader(kResponseString,
-                                          sizeof(kResponseString) - 1));
-  EXPECT_EQ(HVER_UNKNOWN, response.version);
-  EXPECT_EQ(200U, response.scode);
-}
-
-TEST(HttpResponseData, parseLeaderHttpFailure) {
-  static const char kResponseString[] = "HTTP/1.1 503 Service Unavailable";
-  HttpResponseData response;
-  EXPECT_EQ(HE_NONE, response.parseLeader(kResponseString,
-                                          sizeof(kResponseString) - 1));
-  EXPECT_EQ(HVER_1_1, response.version);
-  EXPECT_EQ(503U, response.scode);
-}
-
-TEST(HttpResponseData, parseLeaderHttpInvalid) {
-  static const char kResponseString[] = "Durrrrr, what's HTTP?";
-  HttpResponseData response;
-  EXPECT_EQ(HE_PROTOCOL, response.parseLeader(kResponseString,
-                                              sizeof(kResponseString) - 1));
-}
-
-} // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/httprequest.cc b/third_party/libjingle/source/talk/base/httprequest.cc
deleted file mode 100644
index 48c924e..0000000
--- a/third_party/libjingle/source/talk/base/httprequest.cc
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * libjingle
- * Copyright 2006, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/httprequest.h"
-
-#include "talk/base/common.h"
-#include "talk/base/firewallsocketserver.h"
-#include "talk/base/httpclient.h"
-#include "talk/base/logging.h"
-#include "talk/base/physicalsocketserver.h"
-#include "talk/base/socketadapters.h"
-#include "talk/base/socketpool.h"
-#include "talk/base/ssladapter.h"
-
-using namespace talk_base;
-
-///////////////////////////////////////////////////////////////////////////////
-// HttpMonitor
-///////////////////////////////////////////////////////////////////////////////
-
-HttpMonitor::HttpMonitor(SocketServer *ss) {
-  ASSERT(Thread::Current() != NULL);
-  ss_ = ss;
-  reset();
-}
-
-void HttpMonitor::Connect(HttpClient *http) {
-  http->SignalHttpClientComplete.connect(this,
-    &HttpMonitor::OnHttpClientComplete);
-}
-
-void HttpMonitor::OnHttpClientComplete(HttpClient * http, HttpErrorType error) {
-  complete_ = true;
-  error_ = error;
-  ss_->WakeUp();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// HttpRequest
-///////////////////////////////////////////////////////////////////////////////
-
-const int kDefaultHTTPTimeout = 30 * 1000; // 30 sec
-
-HttpRequest::HttpRequest(const std::string &user_agent)
-    : firewall_(0), port_(80), secure_(false),
-      timeout_(kDefaultHTTPTimeout), fail_redirect_(false),
-      client_(user_agent.c_str(), NULL), error_(HE_NONE) {
-}
-
-void HttpRequest::Send() {
-  // TODO: Rewrite this to use the thread's native socket server, and a more
-  // natural flow?
-
-  PhysicalSocketServer physical;
-  SocketServer * ss = &physical;
-  if (firewall_) {
-    ss = new FirewallSocketServer(ss, firewall_);
-  }
-
-  SslSocketFactory factory(ss, client_.agent());
-  factory.SetProxy(proxy_);
-  if (secure_)
-    factory.UseSSL(host_.c_str());
-
-  //factory.SetLogging("HttpRequest");
-
-  ReuseSocketPool pool(&factory);
-  client_.set_pool(&pool);
-
-  bool transparent_proxy = (port_ == 80) && ((proxy_.type == PROXY_HTTPS) ||
-                           (proxy_.type == PROXY_UNKNOWN));
-
-  if (transparent_proxy) {
-    client_.set_proxy(proxy_);
-  }
-  client_.set_fail_redirect(fail_redirect_);
-
-  SocketAddress server(host_, port_);
-  client_.set_server(server);
-
-  LOG(LS_INFO) << "HttpRequest start: " << host_ + client_.request().path;
-
-  HttpMonitor monitor(ss);
-  monitor.Connect(&client_);
-  client_.start();
-  ss->Wait(timeout_, true);
-  if (!monitor.done()) {
-    LOG(LS_INFO) << "HttpRequest request timed out";
-    client_.reset();
-    return;
-  }
-
-  set_error(monitor.error());
-  if (error_) {
-    LOG(LS_INFO) << "HttpRequest request error: " << error_;
-    return;
-  }
-
-  std::string value;
-  if (client_.response().hasHeader(HH_LOCATION, &value)) {
-    response_redirect_ = value.c_str();
-  }
-}
diff --git a/third_party/libjingle/source/talk/base/httprequest.h b/third_party/libjingle/source/talk/base/httprequest.h
deleted file mode 100644
index 2e13c32..0000000
--- a/third_party/libjingle/source/talk/base/httprequest.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * libjingle
- * Copyright 2006, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _HTTPREQUEST_H_
-#define _HTTPREQUEST_H_
-
-#include "talk/base/httpclient.h"
-#include "talk/base/logging.h"
-#include "talk/base/proxyinfo.h"
-#include "talk/base/socketserver.h"
-#include "talk/base/thread.h"
-#include "talk/base/sslsocketfactory.h"  // Deprecated include
-
-namespace talk_base {
-
-///////////////////////////////////////////////////////////////////////////////
-// HttpRequest
-///////////////////////////////////////////////////////////////////////////////
-
-class FirewallManager;
-class MemoryStream;
-
-class HttpRequest {
-public:
-  HttpRequest(const std::string &user_agent);
-
-  void Send();
-
-  void set_proxy(const ProxyInfo& proxy) {
-    proxy_ = proxy;
-  }
-  void set_firewall(FirewallManager * firewall) {
-    firewall_ = firewall;
-  }
-
-  // The DNS name of the host to connect to.
-  const std::string& host() { return host_; }
-  void set_host(const std::string& host) { host_ = host; }
-
-  // The port to connect to on the target host.
-  int port() { return port_; }
-  void set_port(int port) { port_ = port; }
-
-   // Whether the request should use SSL.
-  bool secure() { return secure_; }
-  void set_secure(bool secure) { secure_ = secure; }
-
-  // Returns the redirect when redirection occurs
-  const std::string& response_redirect() { return response_redirect_; }
-
-  // Time to wait on the download, in ms.  Default is 5000 (5s)
-  int timeout() { return timeout_; }
-  void set_timeout(int timeout) { timeout_ = timeout; }
-
-  // Fail redirects to allow analysis of redirect urls, etc.
-  bool fail_redirect() const { return fail_redirect_; }
-  void set_fail_redirect(bool fail_redirect) { fail_redirect_ = fail_redirect; }
-
-  HttpRequestData& request() { return client_.request(); }
-  HttpResponseData& response() { return client_.response(); }
-  HttpErrorType error() { return error_; }
-
-protected:
-  void set_error(HttpErrorType error) { error_ = error; }
-
-private:
-  ProxyInfo proxy_;
-  FirewallManager * firewall_;
-  std::string host_;
-  int port_;
-  bool secure_;
-  int timeout_;
-  bool fail_redirect_;
-  HttpClient client_;
-  HttpErrorType error_;
-  std::string response_redirect_;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// HttpMonitor
-///////////////////////////////////////////////////////////////////////////////
-
-class HttpMonitor : public sigslot::has_slots<> {
-public:
-  HttpMonitor(SocketServer *ss);
-
-  void reset() {
-    complete_ = false;
-    error_ = HE_DEFAULT;
-  }
-
-  bool done() const { return complete_; }
-  HttpErrorType error() const { return error_; }
-
-  void Connect(HttpClient* http);
-  void OnHttpClientComplete(HttpClient * http, HttpErrorType error);
-
-private:
-  bool complete_;
-  HttpErrorType error_;
-  SocketServer *ss_;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-
-}  // namespace talk_base_
-
-#endif  // _HTTPREQUEST_H_
diff --git a/third_party/libjingle/source/talk/base/httpserver.cc b/third_party/libjingle/source/talk/base/httpserver.cc
deleted file mode 100644
index dd4898f..0000000
--- a/third_party/libjingle/source/talk/base/httpserver.cc
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <algorithm>
-
-#include "talk/base/httpcommon-inl.h"
-
-#include "talk/base/asyncsocket.h"
-#include "talk/base/common.h"
-#include "talk/base/httpserver.h"
-#include "talk/base/logging.h"
-#include "talk/base/socketstream.h"
-#include "talk/base/thread.h"
-
-namespace talk_base {
-
-///////////////////////////////////////////////////////////////////////////////
-// HttpServer
-///////////////////////////////////////////////////////////////////////////////
-
-HttpServer::HttpServer() : next_connection_id_(1), closing_(false) {
-}
-
-HttpServer::~HttpServer() {
-  if (closing_) {
-    LOG(LS_WARNING) << "HttpServer::CloseAll has not completed";
-  }
-  for (ConnectionMap::iterator it = connections_.begin();
-       it != connections_.end();
-       ++it) {
-    StreamInterface* stream = it->second->EndProcess();
-    delete stream;
-    delete it->second;
-  }
-}
-
-int
-HttpServer::HandleConnection(StreamInterface* stream) {
-  int connection_id = next_connection_id_++;
-  ASSERT(connection_id != HTTP_INVALID_CONNECTION_ID);
-  Connection* connection = new Connection(connection_id, this);
-  connections_.insert(ConnectionMap::value_type(connection_id, connection));
-  connection->BeginProcess(stream);
-  return connection_id;
-}
-
-void
-HttpServer::Respond(HttpServerTransaction* transaction) {
-  int connection_id = transaction->connection_id();
-  if (Connection* connection = Find(connection_id)) {
-    connection->Respond(transaction);
-  } else {
-    delete transaction;
-    // We may be tempted to SignalHttpComplete, but that implies that a
-    // connection still exists.
-  }
-}
-
-void
-HttpServer::Close(int connection_id, bool force) {
-  if (Connection* connection = Find(connection_id)) {
-    connection->InitiateClose(force);
-  }
-}
-
-void
-HttpServer::CloseAll(bool force) {
-  if (connections_.empty()) {
-    SignalCloseAllComplete(this);
-    return;
-  }
-  closing_ = true;
-  std::list<Connection*> connections;
-  for (ConnectionMap::const_iterator it = connections_.begin();
-       it != connections_.end(); ++it) {
-    connections.push_back(it->second);
-  }
-  for (std::list<Connection*>::const_iterator it = connections.begin();
-      it != connections.end(); ++it) {
-    (*it)->InitiateClose(force);
-  }
-}
-
-HttpServer::Connection*
-HttpServer::Find(int connection_id) {
-  ConnectionMap::iterator it = connections_.find(connection_id);
-  if (it == connections_.end())
-    return NULL;
-  return it->second;
-}
-
-void
-HttpServer::Remove(int connection_id) {
-  ConnectionMap::iterator it = connections_.find(connection_id);
-  if (it == connections_.end()) {
-    ASSERT(false);
-    return;
-  }
-  Connection* connection = it->second;
-  connections_.erase(it);
-  SignalConnectionClosed(this, connection_id, connection->EndProcess());
-  delete connection;
-  if (closing_ && connections_.empty()) {
-    closing_ = false;
-    SignalCloseAllComplete(this);
-  }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// HttpServer::Connection
-///////////////////////////////////////////////////////////////////////////////
-
-HttpServer::Connection::Connection(int connection_id, HttpServer* server) 
-  : connection_id_(connection_id), server_(server),
-    current_(NULL), signalling_(false), close_(false) { 
-}
-
-HttpServer::Connection::~Connection() {
-  // It's possible that an object hosted inside this transaction signalled
-  // an event which caused the connection to close.
-  Thread::Current()->Dispose(current_);
-}
-
-void
-HttpServer::Connection::BeginProcess(StreamInterface* stream) {
-  base_.notify(this); 
-  base_.attach(stream);
-  current_ = new HttpServerTransaction(connection_id_);
-  if (base_.mode() != HM_CONNECT)
-    base_.recv(&current_->request);
-}
-
-StreamInterface*
-HttpServer::Connection::EndProcess() {
-  base_.notify(NULL);
-  base_.abort(HE_DISCONNECTED);
-  return base_.detach();
-}
-
-void
-HttpServer::Connection::Respond(HttpServerTransaction* transaction) {
-  ASSERT(current_ == NULL);
-  current_ = transaction;
-  if (current_->response.begin() == current_->response.end()) {
-    current_->response.set_error(HC_INTERNAL_SERVER_ERROR);
-  }
-  bool keep_alive = HttpShouldKeepAlive(current_->request);
-  current_->response.setHeader(HH_CONNECTION,
-                               keep_alive ? "Keep-Alive" : "Close",
-                               false);
-  close_ = !HttpShouldKeepAlive(current_->response);
-  base_.send(&current_->response);
-}
-
-void
-HttpServer::Connection::InitiateClose(bool force) {
-  bool request_in_progress = (HM_SEND == base_.mode()) || (NULL == current_);
-  if (!signalling_ && (force || !request_in_progress)) {
-    server_->Remove(connection_id_);
-  } else {
-    close_ = true;
-  }
-}
-
-//
-// IHttpNotify Implementation
-//
-  
-HttpError
-HttpServer::Connection::onHttpHeaderComplete(bool chunked, size_t& data_size) {
-  if (data_size == SIZE_UNKNOWN) {
-    data_size = 0;
-  }
-  ASSERT(current_ != NULL);
-  bool custom_document = false;
-  server_->SignalHttpRequestHeader(server_, current_, &custom_document);
-  if (!custom_document) {
-    current_->request.document.reset(new MemoryStream);
-  }
-  return HE_NONE;
-}
-
-void
-HttpServer::Connection::onHttpComplete(HttpMode mode, HttpError err) {
-  if (mode == HM_SEND) {
-    ASSERT(current_ != NULL);
-    signalling_ = true;
-    server_->SignalHttpRequestComplete(server_, current_, err);
-    signalling_ = false;
-    if (close_) {
-      // Force a close
-      err = HE_DISCONNECTED;
-    }
-  }
-  if (err != HE_NONE) {
-    server_->Remove(connection_id_);
-  } else if (mode == HM_CONNECT) {
-    base_.recv(&current_->request);
-  } else if (mode == HM_RECV) {
-    ASSERT(current_ != NULL);
-    // TODO: do we need this?
-    //request_.document_->rewind();
-    HttpServerTransaction* transaction = current_;
-    current_ = NULL;
-    server_->SignalHttpRequest(server_, transaction);
-  } else if (mode == HM_SEND) {
-    Thread::Current()->Dispose(current_->response.document.release());
-    current_->request.clear(true);
-    current_->response.clear(true);
-    base_.recv(&current_->request);
-  } else {
-    ASSERT(false);
-  }
-}
-
-void
-HttpServer::Connection::onHttpClosed(HttpError err) {
-  UNUSED(err);
-  server_->Remove(connection_id_);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// HttpListenServer
-///////////////////////////////////////////////////////////////////////////////
-
-HttpListenServer::HttpListenServer()
-: listener_(Thread::Current()->socketserver()->CreateAsyncSocket(SOCK_STREAM)) {
-  listener_->SignalReadEvent.connect(this, &HttpListenServer::OnReadEvent);
-  SignalConnectionClosed.connect(this, &HttpListenServer::OnConnectionClosed);
-}
-
-HttpListenServer::~HttpListenServer() {
-}
-
-int HttpListenServer::Listen(const SocketAddress& address) {
-  if ((listener_->Bind(address) != SOCKET_ERROR) &&
-      (listener_->Listen(5) != SOCKET_ERROR))
-    return 0;
-  return listener_->GetError();
-}
-
-bool HttpListenServer::GetAddress(SocketAddress* address) const {
-  *address = listener_->GetLocalAddress();
-  return !address->IsNil();
-}
-
-void HttpListenServer::StopListening() {
-  listener_->Close();
-}
-
-void HttpListenServer::OnReadEvent(AsyncSocket* socket) {
-  ASSERT(socket == listener_.get());
-  AsyncSocket* incoming = listener_->Accept(NULL);
-  if (incoming) {
-    StreamInterface* stream = new SocketStream(incoming);
-    //stream = new LoggingAdapter(stream, LS_VERBOSE, "HttpServer", false);
-    HandleConnection(stream);
-  }
-}
-
-void HttpListenServer::OnConnectionClosed(HttpServer* server,
-                                          int connection_id,
-                                          StreamInterface* stream) {
-  Thread::Current()->Dispose(stream);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/httpserver.h b/third_party/libjingle/source/talk/base/httpserver.h
deleted file mode 100644
index 67061ee..0000000
--- a/third_party/libjingle/source/talk/base/httpserver.h
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_HTTPSERVER_H__
-#define TALK_BASE_HTTPSERVER_H__
-
-#include <map>
-#include "talk/base/httpbase.h"
-
-namespace talk_base {
-
-class AsyncSocket;
-class HttpServer;
-class SocketAddress;
-
-//////////////////////////////////////////////////////////////////////
-// HttpServer
-//////////////////////////////////////////////////////////////////////
-
-const int HTTP_INVALID_CONNECTION_ID = 0;
-
-struct HttpServerTransaction : public HttpTransaction {
-public:
-  HttpServerTransaction(int id) : connection_id_(id) { }
-  int connection_id() const { return connection_id_; }
-
-private:
-  int connection_id_;
-};
-
-class HttpServer {
-public:
-  HttpServer();
-  virtual ~HttpServer();
-
-  int HandleConnection(StreamInterface* stream);
-  // Due to sigslot issues, we can't destroy some streams at an arbitrary time.
-  sigslot::signal3<HttpServer*, int, StreamInterface*> SignalConnectionClosed;
-
-  // This signal occurs when the HTTP request headers have been received, but
-  // before the request body is written to the request document.  By default,
-  // the request document is a MemoryStream.  By handling this signal, the
-  // document can be overridden, in which case the third signal argument should
-  // be set to true.  In the case where the request body should be ignored,
-  // the document can be set to NULL.  Note that the transaction object is still
-  // owened by the HttpServer at this point.  
-  sigslot::signal3<HttpServer*, HttpServerTransaction*, bool*>
-    SignalHttpRequestHeader;
-
-  // An HTTP request has been made, and is available in the transaction object.
-  // Populate the transaction's response, and then return the object via the
-  // Respond method.  Note that during this time, ownership of the transaction
-  // object is transferred, so it may be passed between threads, although
-  // respond must be called on the server's active thread.
-  sigslot::signal2<HttpServer*, HttpServerTransaction*> SignalHttpRequest;
-  void Respond(HttpServerTransaction* transaction);
-
-  // If you want to know when a request completes, listen to this event.
-  sigslot::signal3<HttpServer*, HttpServerTransaction*, int>
-    SignalHttpRequestComplete;
-
-  // Stop processing the connection indicated by connection_id.
-  // Unless force is true, the server will complete sending a response that is
-  // in progress.
-  void Close(int connection_id, bool force);
-  void CloseAll(bool force);
-
-  // After calling CloseAll, this event is signalled to indicate that all
-  // outstanding connections have closed.
-  sigslot::signal1<HttpServer*> SignalCloseAllComplete;
-
-private:
-  class Connection : private IHttpNotify {
-  public:
-    Connection(int connection_id, HttpServer* server);
-    virtual ~Connection();
-
-    void BeginProcess(StreamInterface* stream);
-    StreamInterface* EndProcess();
-    
-    void Respond(HttpServerTransaction* transaction);
-    void InitiateClose(bool force);
-
-    // IHttpNotify Interface
-    virtual HttpError onHttpHeaderComplete(bool chunked, size_t& data_size);
-    virtual void onHttpComplete(HttpMode mode, HttpError err);
-    virtual void onHttpClosed(HttpError err);
-  
-    int connection_id_;
-    HttpServer* server_;
-    HttpBase base_;
-    HttpServerTransaction* current_;
-    bool signalling_, close_;
-  };
-
-  Connection* Find(int connection_id);
-  void Remove(int connection_id);
-
-  friend class Connection;
-  typedef std::map<int,Connection*> ConnectionMap;
-
-  ConnectionMap connections_;
-  int next_connection_id_;
-  bool closing_;
-};
-
-//////////////////////////////////////////////////////////////////////
-
-class HttpListenServer : public HttpServer, public sigslot::has_slots<> {
-public:
-  HttpListenServer();
-  virtual ~HttpListenServer();
-
-  int Listen(const SocketAddress& address);
-  bool GetAddress(SocketAddress* address) const;
-  void StopListening();
-
-private:
-  void OnReadEvent(AsyncSocket* socket);
-  void OnConnectionClosed(HttpServer* server, int connection_id,
-                          StreamInterface* stream);
-
-  scoped_ptr<AsyncSocket> listener_;
-};
-
-//////////////////////////////////////////////////////////////////////
-
-}  // namespace talk_base
-
-#endif // TALK_BASE_HTTPSERVER_H__
diff --git a/third_party/libjingle/source/talk/base/httpserver_unittest.cc b/third_party/libjingle/source/talk/base/httpserver_unittest.cc
deleted file mode 100644
index d0e0760..0000000
--- a/third_party/libjingle/source/talk/base/httpserver_unittest.cc
+++ /dev/null
@@ -1,130 +0,0 @@
-// Copyright 2007 Google Inc.
-// All Rights Reserved.
-
-
-#include "talk/base/gunit.h"
-#include "talk/base/httpserver.h"
-#include "talk/base/testutils.h"
-
-using namespace testing;
-
-namespace talk_base {
-
-namespace {
-  const char* const kRequest =
-    "GET /index.html HTTP/1.1\r\n"
-    "Host: localhost\r\n"
-    "\r\n";
-
-  const char* const kResponse =
-    "HTTP/1.1 200\r\n"
-    "Connection: Close\r\n"
-    "Content-Length: 0\r\n"
-    "\r\n";
-
-  struct HttpServerMonitor : public sigslot::has_slots<> {
-    HttpServerTransaction* transaction;
-    bool server_closed, connection_closed;
-
-    HttpServerMonitor(HttpServer* server)
-    : transaction(NULL), server_closed(false), connection_closed(false) {
-      server->SignalCloseAllComplete.connect(this,
-        &HttpServerMonitor::OnClosed);
-      server->SignalHttpRequest.connect(this, &HttpServerMonitor::OnRequest);
-      server->SignalHttpRequestComplete.connect(this,
-        &HttpServerMonitor::OnRequestComplete);
-      server->SignalConnectionClosed.connect(this,
-        &HttpServerMonitor::OnConnectionClosed);
-    }
-    void OnRequest(HttpServer*, HttpServerTransaction* t) {
-      ASSERT_FALSE(transaction);
-      transaction = t;
-      transaction->response.set_success();
-      transaction->response.setHeader(HH_CONNECTION, "Close");
-    }
-    void OnRequestComplete(HttpServer*, HttpServerTransaction* t, int) {
-      ASSERT_EQ(transaction, t);
-      transaction = NULL;
-    }
-    void OnClosed(HttpServer*) {
-      server_closed = true;
-    }
-    void OnConnectionClosed(HttpServer*, int, StreamInterface* stream) {
-      connection_closed = true;
-      delete stream;
-    }
-  };
-
-  void CreateClientConnection(HttpServer& server,
-                              HttpServerMonitor& monitor,
-                              bool send_request) {
-    StreamSource* client = new StreamSource;
-    client->SetState(SS_OPEN);
-    server.HandleConnection(client);
-    EXPECT_FALSE(monitor.server_closed);
-    EXPECT_FALSE(monitor.transaction);
-
-    if (send_request) {
-      // Simulate a request
-      client->QueueString(kRequest);
-      EXPECT_FALSE(monitor.server_closed);
-    }
-  }
-}  // anonymous namespace
-
-TEST(HttpServer, DoesNotSignalCloseUnlessCloseAllIsCalled) {
-  HttpServer server;
-  HttpServerMonitor monitor(&server);
-  // Add an active client connection
-  CreateClientConnection(server, monitor, true);
-  // Simulate a response
-  ASSERT_TRUE(NULL != monitor.transaction);
-  server.Respond(monitor.transaction);
-  EXPECT_FALSE(monitor.transaction);
-  // Connection has closed, but no server close signal
-  EXPECT_FALSE(monitor.server_closed);
-  EXPECT_TRUE(monitor.connection_closed);
-}
-
-TEST(HttpServer, SignalsCloseWhenNoConnectionsAreActive) {
-  HttpServer server;
-  HttpServerMonitor monitor(&server);
-  // Add an idle client connection
-  CreateClientConnection(server, monitor, false);
-  // Perform graceful close
-  server.CloseAll(false);
-  // Connections have all closed
-  EXPECT_TRUE(monitor.server_closed);
-  EXPECT_TRUE(monitor.connection_closed);
-}
-
-TEST(HttpServer, SignalsCloseAfterGracefulCloseAll) {
-  HttpServer server;
-  HttpServerMonitor monitor(&server);
-  // Add an active client connection
-  CreateClientConnection(server, monitor, true);
-  // Initiate a graceful close
-  server.CloseAll(false);
-  EXPECT_FALSE(monitor.server_closed);
-  // Simulate a response
-  ASSERT_TRUE(NULL != monitor.transaction);
-  server.Respond(monitor.transaction);
-  EXPECT_FALSE(monitor.transaction);
-  // Connections have all closed
-  EXPECT_TRUE(monitor.server_closed);
-  EXPECT_TRUE(monitor.connection_closed);
-}
-
-TEST(HttpServer, SignalsCloseAfterForcedCloseAll) {
-  HttpServer server;
-  HttpServerMonitor monitor(&server);
-  // Add an active client connection
-  CreateClientConnection(server, monitor, true);
-  // Initiate a forceful close
-  server.CloseAll(true);
-  // Connections have all closed
-  EXPECT_TRUE(monitor.server_closed);
-  EXPECT_TRUE(monitor.connection_closed);
-}
-
-} // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/ipaddress.cc b/third_party/libjingle/source/talk/base/ipaddress.cc
deleted file mode 100644
index 9069269..0000000
--- a/third_party/libjingle/source/talk/base/ipaddress.cc
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifdef POSIX
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#ifdef OPENBSD
-#include <netinet/in_systm.h>
-#endif
-#include <netinet/ip.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <unistd.h>
-#endif
-
-#include <stdio.h>
-
-#include "talk/base/ipaddress.h"
-#include "talk/base/nethelpers.h"
-#include "talk/base/logging.h"
-#include "talk/base/win32.h"
-
-namespace talk_base {
-
-static const unsigned char kMappedPrefix[] = {0x00, 0x00, 0x00, 0x00,
-                                              0x00, 0x00, 0x00, 0x00,
-                                              0x00, 0x00, 0xFF, 0xFF};
-static bool IsPrivateV4(uint32 ip);
-static bool IsMappedAddress(const in6_addr& addr);
-static in_addr ExtractMappedAddress(const in6_addr& addr);
-
-uint32 IPAddress::v4AddressAsHostOrderInteger() const {
-  if (family_ == AF_INET) {
-    return ntohl(u_.ip4.s_addr);
-  } else {
-    return 0;
-  }
-}
-
-size_t IPAddress::Size() const {
-  switch (family_) {
-    case AF_INET:
-      return sizeof(in_addr);
-    case AF_INET6:
-      return sizeof(in6_addr);
-  }
-  return 0;
-}
-
-
-bool IPAddress::operator==(const IPAddress &other) const {
-  if (family_ != other.family_) {
-    return false;
-  }
-  if (family_ == AF_INET) {
-    return memcmp(&u_.ip4, &other.u_.ip4, sizeof(u_.ip4)) == 0;
-  }
-  if (family_ == AF_INET6) {
-    return memcmp(&u_.ip6, &other.u_.ip6, sizeof(u_.ip6)) == 0;
-  }
-  return family_ == AF_UNSPEC;
-}
-
-bool IPAddress::operator!=(const IPAddress &other) const {
-  return !((*this) == other);
-}
-
-bool IPAddress::operator >(const IPAddress &other) const {
-  return (*this) != other && !((*this) < other);
-}
-
-bool IPAddress::operator <(const IPAddress &other) const {
-  // IPv4 is 'less than' IPv6
-  if (family_ != other.family_) {
-    if (family_ == AF_UNSPEC) {
-      return true;
-    }
-    if (family_ == AF_INET && other.family_ == AF_INET6) {
-      return true;
-    }
-    return false;
-  }
-  // Comparing addresses of the same family.
-  switch (family_) {
-    case AF_INET: {
-      return ntohl(u_.ip4.s_addr) < ntohl(other.u_.ip4.s_addr);
-    }
-    case AF_INET6: {
-      return memcmp(&u_.ip6.s6_addr, &other.u_.ip6.s6_addr, 16) < 0;
-    }
-  }
-  // Catches AF_UNSPEC and invalid addresses.
-  return false;
-}
-
-std::ostream& operator<<(std::ostream& os, const IPAddress& ip) {
-  os << ip.ToString();
-  return os;
-}
-
-in6_addr IPAddress::ipv6_address() const {
-  return u_.ip6;
-}
-
-in_addr IPAddress::ipv4_address() const {
-  return u_.ip4;
-}
-
-std::string IPAddress::ToString() const {
-  if (family_ != AF_INET && family_ != AF_INET6) {
-    return std::string();
-  }
-  char buf[INET6_ADDRSTRLEN] = {0};
-  const void* src = &u_.ip4;
-  if (family_ == AF_INET6) {
-    src = &u_.ip6;
-  }
-  if (!talk_base::inet_ntop(family_, src, buf, sizeof(buf))) {
-    return std::string();
-  }
-  return std::string(buf);
-}
-
-IPAddress IPAddress::Normalized() const {
-  if (family_ != AF_INET6) {
-    return *this;
-  }
-  if (!IsMappedAddress(u_.ip6)) {
-    return *this;
-  }
-  in_addr addr = ExtractMappedAddress(u_.ip6);
-  return IPAddress(addr);
-}
-
-IPAddress IPAddress::AsIPv6Address() const {
-  if (family_ != AF_INET) {
-    return *this;
-  }
-  //  uint32 v4 = (u_.ip4.s_addr);
-  in6_addr v6addr;
-  ::memcpy(&v6addr.s6_addr, kMappedPrefix, sizeof(kMappedPrefix));
-  ::memcpy(&v6addr.s6_addr[12], &u_.ip4.s_addr, sizeof(u_.ip4.s_addr));
-  return IPAddress(v6addr);
-}
-
-bool IsPrivateV4(uint32 ip_in_host_order) {
-  return ((ip_in_host_order >> 24) == 127) ||
-      ((ip_in_host_order >> 24) == 10) ||
-      ((ip_in_host_order >> 20) == ((172 << 4) | 1)) ||
-      ((ip_in_host_order >> 16) == ((192 << 8) | 168)) ||
-      ((ip_in_host_order >> 16) == ((169 << 8) | 254));
-}
-
-bool IsMappedAddress(const in6_addr& addr) {
-  return memcmp(&(addr.s6_addr), kMappedPrefix, sizeof(kMappedPrefix)) == 0;
-}
-
-in_addr ExtractMappedAddress(const in6_addr& in6) {
-  in_addr ipv4;
-  ::memcpy(&ipv4.s_addr, &in6.s6_addr[12], sizeof(ipv4.s_addr));
-  return ipv4;
-}
-
-bool IPFromHostEnt(hostent* host_ent, IPAddress* out) {
-  return IPFromHostEnt(host_ent, 0, out);
-}
-
-bool IPFromHostEnt(hostent* host_ent, int idx, IPAddress* out) {
-  if (!out || (idx < 0)) {
-    return false;
-  }
-  char** requested_address = host_ent->h_addr_list;
-  // Find the idx-th element (while checking for null, which terminates the
-  // list of addresses).
-  while (*requested_address && idx) {
-    idx--;
-    requested_address++;
-  }
-  if (!(*requested_address)) {
-    return false;
-  }
-
-  if (host_ent->h_addrtype == AF_INET) {
-    in_addr ip;
-    ip.s_addr = *reinterpret_cast<uint32*>(*requested_address);
-    *out = IPAddress(ip);
-    return true;
-  } else if (host_ent->h_addrtype == AF_INET6) {
-    in6_addr ip;
-    ::memcpy(&ip.s6_addr, *requested_address, host_ent->h_length);
-    *out = IPAddress(ip);
-    return true;
-  }
-  return false;
-}
-
-bool IPFromString(const std::string& str, IPAddress* out) {
-  if (!out) {
-    return false;
-  }
-  in_addr addr;
-  if (talk_base::inet_pton(AF_INET, str.c_str(), &addr) == 0) {
-    in6_addr addr6;
-    if (talk_base::inet_pton(AF_INET6, str.c_str(), &addr6) == 0) {
-      *out = IPAddress();
-      return false;
-    }
-    *out = IPAddress(addr6);
-  } else {
-    *out = IPAddress(addr);
-  }
-  return true;
-}
-
-bool IPIsAny(const IPAddress& ip) {
-  static const IPAddress kIPv4Any(INADDR_ANY);
-  static const IPAddress kIPv6Any(in6addr_any);
-  switch (ip.family()) {
-    case AF_INET:
-      return ip == kIPv4Any;
-    case AF_INET6:
-      return ip == kIPv6Any;
-    case AF_UNSPEC:
-      return false;
-  }
-  return false;
-}
-
-bool IPIsLoopback(const IPAddress& ip) {
-  static const IPAddress kIPv4Loopback(INADDR_LOOPBACK);
-  static const IPAddress kIPv6Loopback(in6addr_loopback);
-  switch (ip.family()) {
-    case AF_INET: {
-      return ip == kIPv4Loopback;
-    }
-    case AF_INET6: {
-      return ip == kIPv6Loopback;
-    }
-  }
-  return false;
-}
-
-bool IPIsPrivate(const IPAddress& ip) {
-  switch (ip.family()) {
-    case AF_INET: {
-      return IsPrivateV4(ip.v4AddressAsHostOrderInteger());
-    }
-    case AF_INET6: {
-      in6_addr v6 = ip.ipv6_address();
-      return (v6.s6_addr[0] == 0xFE && v6.s6_addr[1] == 0x80) ||
-          IPIsLoopback(ip);
-    }
-  }
-  return false;
-}
-
-size_t HashIP(const IPAddress& ip) {
-  switch (ip.family()) {
-    case AF_INET: {
-      return ip.ipv4_address().s_addr;
-    }
-    case AF_INET6: {
-      in6_addr v6addr = ip.ipv6_address();
-      const uint32* v6_as_ints =
-          reinterpret_cast<const uint32*>(&v6addr.s6_addr);
-      return v6_as_ints[0] ^ v6_as_ints[1] ^ v6_as_ints[2] ^ v6_as_ints[3];
-    }
-  }
-  return 0;
-}
-}  // Namespace talk base
diff --git a/third_party/libjingle/source/talk/base/ipaddress.h b/third_party/libjingle/source/talk/base/ipaddress.h
deleted file mode 100644
index a421f16..0000000
--- a/third_party/libjingle/source/talk/base/ipaddress.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * libjingle
- * Copyright 2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_IPADDRESS_H_
-#define TALK_BASE_IPADDRESS_H_
-
-#ifdef POSIX
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#endif
-#ifdef WIN32
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#endif
-#include <string.h>
-#include <string>
-#include <vector>
-
-#include "talk/base/basictypes.h"
-#ifdef WIN32
-#include "talk/base/win32.h"
-#endif
-
-namespace talk_base {
-
-// Version-agnostic IP address class, wraps a union of in_addr and in6_addr.
-class IPAddress {
- public:
-  IPAddress() : family_(AF_UNSPEC) {
-    ::memset(&u_, 0, sizeof(u_));
-  }
-
-  explicit IPAddress(const in_addr &ip4) : family_(AF_INET) {
-    memset(&u_, 0, sizeof(u_));
-    u_.ip4 = ip4;
-  }
-
-  explicit IPAddress(const in6_addr &ip6) : family_(AF_INET6) {
-    u_.ip6 = ip6;
-  }
-
-  explicit IPAddress(uint32 ip_in_host_byte_order) : family_(AF_INET) {
-    memset(&u_, 0, sizeof(u_));
-    u_.ip4.s_addr = htonl(ip_in_host_byte_order);
-  }
-
-  IPAddress(const IPAddress &other) : family_(other.family_) {
-    ::memcpy(&u_, &other.u_, sizeof(u_));
-  }
-
-  ~IPAddress() {}
-
-  const IPAddress & operator=(const IPAddress &other) {
-    family_ = other.family_;
-    ::memcpy(&u_, &other.u_, sizeof(u_));
-    return *this;
-  }
-
-  bool operator==(const IPAddress &other) const;
-  bool operator!=(const IPAddress &other) const;
-  bool operator <(const IPAddress &other) const;
-  bool operator >(const IPAddress &other) const;
-  friend std::ostream& operator<<(std::ostream& os, const IPAddress& addr);
-
-  int family() const { return family_; }
-  in_addr ipv4_address() const;
-  in6_addr ipv6_address() const;
-
-  // Returns the number of bytes needed to store the raw address.
-  size_t Size() const;
-
-  // Wraps inet_ntop.
-  std::string ToString() const;
-
-  // Returns an unmapped address from a possibly-mapped address.
-  // Returns the same address if this isn't a mapped address.
-  IPAddress Normalized() const;
-
-  // Returns this address as an IPv6 address.
-  // Maps v4 addresses (as ::ffff:a.b.c.d), returns v6 addresses unchanged.
-  IPAddress AsIPv6Address() const;
-
-  // For socketaddress' benefit. Returns the IP in host byte order.
-  uint32 v4AddressAsHostOrderInteger() const;
-
- private:
-  int family_;
-  union {
-    in_addr ip4;
-    in6_addr ip6;
-  } u_;
-};
-
-bool IPFromHostEnt(hostent* hostEnt, IPAddress* out);
-bool IPFromHostEnt(hostent* hostEnt, int idx, IPAddress* out);
-bool IPFromString(const std::string& str, IPAddress* out);
-bool IPIsAny(const IPAddress& ip);
-bool IPIsLoopback(const IPAddress& ip);
-bool IPIsPrivate(const IPAddress& ip);
-size_t HashIP(const IPAddress& ip);
-}  // namespace talk_base
-
-#endif  // TALK_BASE_IPADDRESS_H_
diff --git a/third_party/libjingle/source/talk/base/ipaddress_unittest.cc b/third_party/libjingle/source/talk/base/ipaddress_unittest.cc
deleted file mode 100644
index 38a50f9..0000000
--- a/third_party/libjingle/source/talk/base/ipaddress_unittest.cc
+++ /dev/null
@@ -1,632 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/gunit.h"
-#include "talk/base/ipaddress.h"
-
-
-namespace talk_base {
-
-static const unsigned int kIPv4AddrSize = 4;
-static const unsigned int kIPv6AddrSize = 16;
-static const unsigned int kIPv4RFC1918Addr = 0xC0A80701;
-static const unsigned int kIPv4PublicAddr = 0x01020304;
-static const in6_addr kIPv6LinkLocalAddr = {{{0xfe, 0x80, 0x00, 0x00,
-                                              0x00, 0x00, 0x00, 0x00,
-                                              0xbe, 0x30, 0x5b, 0xff,
-                                              0xfe, 0xe5, 0x00, 0xc3}}};
-static const in6_addr kIPv6PublicAddr = {{{0x24, 0x01, 0xfa, 0x00,
-                                           0x00, 0x04, 0x10, 0x00,
-                                           0xbe, 0x30, 0x5b, 0xff,
-                                           0xfe, 0xe5, 0x00, 0xc3}}};
-static const in6_addr kIPv6CompatAddr = {{{0x00, 0x00, 0x00, 0x00,
-                                           0x00, 0x00, 0x00, 0x00,
-                                           0x00, 0x00, 0x00, 0x00,
-                                           0xfe, 0xe5, 0x00, 0xc3}}};
-static const in6_addr kIPv4MappedAnyAddr = {{{0x00, 0x00, 0x00, 0x00,
-                                              0x00, 0x00, 0x00, 0x00,
-                                              0x00, 0x00, 0xff, 0xff,
-                                              0x00, 0x00, 0x00, 0x00}}};
-static const in6_addr kIPv4MappedLoopbackAddr = {{{0x00, 0x00, 0x00, 0x00,
-                                                   0x00, 0x00, 0x00, 0x00,
-                                                   0x00, 0x00, 0xff, 0xff,
-                                                   0x7f, 0x00, 0x00, 0x01}}};
-static const in6_addr kIPv4MappedRFC1918Addr = {{{0x00, 0x00, 0x00, 0x00,
-                                                  0x00, 0x00, 0x00, 0x00,
-                                                  0x00, 0x00, 0xff, 0xff,
-                                                  0xc0, 0xa8, 0x07, 0x01}}};
-static const in6_addr kIPv4MappedPublicAddr = {{{0x00, 0x00, 0x00, 0x00,
-                                                 0x00, 0x00, 0x00, 0x00,
-                                                 0x00, 0x00, 0xff, 0xff,
-                                                 0x01, 0x02, 0x03, 0x04}}};
-static const in6_addr kIPv6AllNodes = {{{0xff, 0x02, 0x00, 0x00,
-                                         0x00, 0x00, 0x00, 0x00,
-                                         0x00, 0x00, 0x00, 0x00,
-                                         0x00, 0x00, 0x00, 0x01}}};
-
-static const std::string kIPv4AnyAddrString = "0.0.0.0";
-static const std::string kIPv4LoopbackAddrString = "127.0.0.1";
-static const std::string kIPv4RFC1918AddrString = "192.168.7.1";
-static const std::string kIPv4PublicAddrString = "1.2.3.4";
-static const std::string kIPv6AnyAddrString = "::";
-static const std::string kIPv6LoopbackAddrString = "::1";
-static const std::string kIPv6LinkLocalAddrString = "fe80::be30:5bff:fee5:c3";
-static const std::string kIPv6PublicAddrString =
-    "2401:fa00:4:1000:be30:5bff:fee5:c3";
-static const std::string kIPv4MappedAnyAddrString = "::ffff:0:0";
-static const std::string kIPv4MappedRFC1918AddrString = "::ffff:c0a8:701";
-static const std::string kIPv4MappedLoopbackAddrString = "::ffff:7f00:1";
-static const std::string kIPv4MappedPublicAddrString = "::ffff:102:0304";
-static const std::string kIPv4MappedV4StyleAddrString = "::ffff:192.168.7.1";
-
-static const std::string kIPv4BrokenString1 = "192.168.7.";
-static const std::string kIPv4BrokenString2 = "192.168.7.1.1";
-static const std::string kIPv4BrokenString3 = "192.168.7.1:80";
-static const std::string kIPv4BrokenString4 = "192.168.7.ONE";
-static const std::string kIPv4BrokenString5 = "-192.168.7.1";
-static const std::string kIPv4BrokenString6 = "256.168.7.1";
-static const std::string kIPv6BrokenString1 = "2401:fa00:4:1000:be30";
-static const std::string kIPv6BrokenString2 =
-    "2401:fa00:4:1000:be30:5bff:fee5:c3:1";
-static const std::string kIPv6BrokenString3 =
-    "[2401:fa00:4:1000:be30:5bff:fee5:c3]:1";
-static const std::string kIPv6BrokenString4 =
-    "2401::4::be30";
-static const std::string kIPv6BrokenString5 =
-    "2401:::4:fee5:be30";
-static const std::string kIPv6BrokenString6 =
-    "2401f:fa00:4:1000:be30:5bff:fee5:c3";
-static const std::string kIPv6BrokenString7 =
-    "2401:ga00:4:1000:be30:5bff:fee5:c3";
-static const std::string kIPv6BrokenString8 =
-    "2401:fa000:4:1000:be30:5bff:fee5:c3";
-static const std::string kIPv6BrokenString9 =
-    "2401:fal0:4:1000:be30:5bff:fee5:c3";
-static const std::string kIPv6BrokenString10 =
-    "::ffff:192.168.7.";
-static const std::string kIPv6BrokenString11 =
-    "::ffff:192.168.7.1.1.1";
-static const std::string kIPv6BrokenString12 =
-    "::fffe:192.168.7.1";
-static const std::string kIPv6BrokenString13 =
-    "::ffff:192.168.7.ff";
-static const std::string kIPv6BrokenString14 =
-    "0x2401:fa00:4:1000:be30:5bff:fee5:c3";
-
-bool IPFromHostEntWorks(const std::string& name, int expected_family,
-                        IPAddress expected_addr) {
-  struct hostent* ent = gethostbyname(name.c_str());
-  if (ent) {
-    IPAddress addr;
-    if (!IPFromHostEnt(ent, &addr)) {
-      return false;
-    }
-    return addr == expected_addr;
-  }
-  return true;
-}
-
-bool AreEqual(const IPAddress& addr,
-              const IPAddress& addr2) {
-  if ((IPIsAny(addr) != IPIsAny(addr2)) ||
-      (IPIsLoopback(addr) != IPIsLoopback(addr2)) ||
-      (IPIsPrivate(addr) != IPIsPrivate(addr2)) ||
-      (HashIP(addr) != HashIP(addr2)) ||
-      (addr.Size() != addr2.Size()) ||
-      (addr.family() != addr2.family()) ||
-      (addr.ToString() != addr2.ToString())) {
-    return false;
-  }
-  in_addr v4addr, v4addr2;
-  v4addr = addr.ipv4_address();
-  v4addr2 = addr2.ipv4_address();
-  if (0 != memcmp(&v4addr, &v4addr2, sizeof(v4addr))) {
-    return false;
-  }
-  in6_addr v6addr, v6addr2;
-  v6addr = addr.ipv6_address();
-  v6addr2 = addr2.ipv6_address();
-  if (0 != memcmp(&v6addr, &v6addr2, sizeof(v6addr))) {
-    return false;
-  }
-  return true;
-}
-
-bool BrokenIPStringFails(const std::string& broken) {
-  IPAddress addr(0);   // Intentionally make it v4.
-  if (IPFromString(kIPv4BrokenString1, &addr)) {
-    return false;
-  }
-  return addr.family() == AF_UNSPEC;
-}
-
-TEST(IPAddressTest, TestDefaultCtor) {
-  IPAddress addr;
-  EXPECT_FALSE(IPIsAny(addr));
-  EXPECT_FALSE(IPIsLoopback(addr));
-  EXPECT_FALSE(IPIsPrivate(addr));
-
-  EXPECT_EQ(0U, addr.Size());
-  EXPECT_EQ(AF_UNSPEC, addr.family());
-  EXPECT_EQ("", addr.ToString());
-}
-
-TEST(IPAddressTest, TestInAddrCtor) {
-  in_addr v4addr;
-
-  // Test V4 Any address.
-  v4addr.s_addr = INADDR_ANY;
-  IPAddress addr(v4addr);
-  EXPECT_TRUE(IPIsAny(addr));
-  EXPECT_FALSE(IPIsLoopback(addr));
-  EXPECT_FALSE(IPIsPrivate(addr));
-  EXPECT_EQ(kIPv4AddrSize, addr.Size());
-  EXPECT_EQ(kIPv4AnyAddrString, addr.ToString());
-
-  // Test a V4 loopback address.
-  v4addr.s_addr = htonl(INADDR_LOOPBACK);
-  addr = IPAddress(v4addr);
-  EXPECT_FALSE(IPIsAny(addr));
-  EXPECT_TRUE(IPIsLoopback(addr));
-  EXPECT_TRUE(IPIsPrivate(addr));
-  EXPECT_EQ(kIPv4AddrSize, addr.Size());
-  EXPECT_EQ(kIPv4LoopbackAddrString, addr.ToString());
-
-  // Test an RFC1918 address.
-  v4addr.s_addr = htonl(kIPv4RFC1918Addr);
-  addr = IPAddress(v4addr);
-  EXPECT_FALSE(IPIsAny(addr));
-  EXPECT_FALSE(IPIsLoopback(addr));
-  EXPECT_TRUE(IPIsPrivate(addr));
-  EXPECT_EQ(kIPv4AddrSize, addr.Size());
-  EXPECT_EQ(kIPv4RFC1918AddrString, addr.ToString());
-
-  // Test a 'normal' v4 address.
-  v4addr.s_addr = htonl(kIPv4PublicAddr);
-  addr = IPAddress(v4addr);
-  EXPECT_FALSE(IPIsAny(addr));
-  EXPECT_FALSE(IPIsLoopback(addr));
-  EXPECT_FALSE(IPIsPrivate(addr));
-  EXPECT_EQ(kIPv4AddrSize, addr.Size());
-  EXPECT_EQ(kIPv4PublicAddrString, addr.ToString());
-}
-
-TEST(IPAddressTest, TestInAddr6Ctor) {
-  // Test v6 empty.
-  IPAddress addr(in6addr_any);
-  EXPECT_TRUE(IPIsAny(addr));
-  EXPECT_FALSE(IPIsLoopback(addr));
-  EXPECT_FALSE(IPIsPrivate(addr));
-  EXPECT_EQ(kIPv6AddrSize, addr.Size());
-  EXPECT_EQ(kIPv6AnyAddrString, addr.ToString());
-
-  // Test v6 loopback.
-  addr = IPAddress(in6addr_loopback);
-  EXPECT_FALSE(IPIsAny(addr));
-  EXPECT_TRUE(IPIsLoopback(addr));
-  EXPECT_TRUE(IPIsPrivate(addr));
-  EXPECT_EQ(kIPv6AddrSize, addr.Size());
-  EXPECT_EQ(kIPv6LoopbackAddrString, addr.ToString());
-
-  // Test v6 link-local.
-  addr = IPAddress(kIPv6LinkLocalAddr);
-  EXPECT_FALSE(IPIsAny(addr));
-  EXPECT_FALSE(IPIsLoopback(addr));
-  EXPECT_TRUE(IPIsPrivate(addr));
-  EXPECT_EQ(kIPv6AddrSize, addr.Size());
-  EXPECT_EQ(kIPv6LinkLocalAddrString, addr.ToString());
-
-  // Test v6 global address.
-  addr = IPAddress(kIPv6PublicAddr);
-  EXPECT_FALSE(IPIsAny(addr));
-  EXPECT_FALSE(IPIsLoopback(addr));
-  EXPECT_FALSE(IPIsPrivate(addr));
-  EXPECT_EQ(kIPv6AddrSize, addr.Size());
-  EXPECT_EQ(kIPv6PublicAddrString, addr.ToString());
-}
-
-TEST(IPAddressTest, TestUint32Ctor) {
-  // Test V4 Any address.
-  IPAddress addr(0);
-  EXPECT_TRUE(IPIsAny(addr));
-  EXPECT_FALSE(IPIsLoopback(addr));
-  EXPECT_FALSE(IPIsPrivate(addr));
-  EXPECT_EQ(kIPv4AddrSize, addr.Size());
-  EXPECT_EQ(kIPv4AnyAddrString, addr.ToString());
-
-  // Test a V4 loopback address.
-  addr = IPAddress(INADDR_LOOPBACK);
-  EXPECT_FALSE(IPIsAny(addr));
-  EXPECT_TRUE(IPIsLoopback(addr));
-  EXPECT_TRUE(IPIsPrivate(addr));
-  EXPECT_EQ(kIPv4AddrSize, addr.Size());
-  EXPECT_EQ(kIPv4LoopbackAddrString, addr.ToString());
-
-  // Test an RFC1918 address.
-  addr = IPAddress(kIPv4RFC1918Addr);
-  EXPECT_FALSE(IPIsAny(addr));
-  EXPECT_FALSE(IPIsLoopback(addr));
-  EXPECT_TRUE(IPIsPrivate(addr));
-  EXPECT_EQ(kIPv4AddrSize, addr.Size());
-  EXPECT_EQ(kIPv4RFC1918AddrString, addr.ToString());
-
-  // Test a 'normal' v4 address.
-  addr = IPAddress(kIPv4PublicAddr);
-  EXPECT_FALSE(IPIsAny(addr));
-  EXPECT_FALSE(IPIsLoopback(addr));
-  EXPECT_FALSE(IPIsPrivate(addr));
-  EXPECT_EQ(kIPv4AddrSize, addr.Size());
-  EXPECT_EQ(kIPv4PublicAddrString, addr.ToString());
-}
-
-TEST(IPAddressTest, TestHostEntCtor) {
-  IPAddress addr(INADDR_LOOPBACK);
-  EXPECT_PRED3(IPFromHostEntWorks, "localhost", AF_INET, addr);
-
-  addr = IPAddress(kIPv6AllNodes);
-  EXPECT_PRED3(IPFromHostEntWorks, "ip6-allnodes", AF_INET6, addr);
-
-  //  gethostbyname works for literal addresses too
-  addr = IPAddress(INADDR_ANY);
-  EXPECT_PRED3(IPFromHostEntWorks,
-               kIPv4AnyAddrString, AF_INET, addr);
-  addr = IPAddress(kIPv4RFC1918Addr);
-  EXPECT_PRED3(IPFromHostEntWorks,
-               kIPv4RFC1918AddrString, AF_INET, addr);
-  addr = IPAddress(kIPv4PublicAddr);
-  EXPECT_PRED3(IPFromHostEntWorks,
-               kIPv4PublicAddrString, AF_INET, addr);
-
-  addr = IPAddress(in6addr_any);
-  EXPECT_PRED3(IPFromHostEntWorks,
-               kIPv6AnyAddrString, AF_INET6, addr);
-  addr = IPAddress(in6addr_loopback);
-  EXPECT_PRED3(IPFromHostEntWorks,
-               kIPv6LoopbackAddrString, AF_INET6, addr);
-  addr = IPAddress(kIPv6LinkLocalAddr);
-  EXPECT_PRED3(IPFromHostEntWorks,
-               kIPv6LinkLocalAddrString, AF_INET6, addr);
-  addr = IPAddress(kIPv6PublicAddr);
-  EXPECT_PRED3(IPFromHostEntWorks,
-               kIPv6PublicAddrString, AF_INET6, addr);
-}
-
-TEST(IPAddressTest, TestCopyCtor) {
-  in_addr v4addr;
-  v4addr.s_addr = htonl(kIPv4PublicAddr);
-  IPAddress addr(v4addr);
-  IPAddress addr2(addr);
-
-  EXPECT_PRED2(AreEqual, addr, addr2);
-
-  addr = IPAddress(INADDR_ANY);
-  addr2 = IPAddress(addr);
-  EXPECT_PRED2(AreEqual, addr, addr2);
-
-  addr = IPAddress(INADDR_LOOPBACK);
-  addr2 = IPAddress(addr);
-  EXPECT_PRED2(AreEqual, addr, addr2);
-
-  addr = IPAddress(kIPv4PublicAddr);
-  addr2 = IPAddress(addr);
-  EXPECT_PRED2(AreEqual, addr, addr2);
-
-  addr = IPAddress(kIPv4RFC1918Addr);
-  addr2 = IPAddress(addr);
-  EXPECT_PRED2(AreEqual, addr, addr2);
-
-  addr = IPAddress(in6addr_any);
-  addr2 = IPAddress(addr);
-  EXPECT_PRED2(AreEqual, addr, addr2);
-
-  addr = IPAddress(in6addr_loopback);
-  addr2 = IPAddress(addr);
-  EXPECT_PRED2(AreEqual, addr, addr2);
-
-  addr = IPAddress(kIPv6LinkLocalAddr);
-  addr2 = IPAddress(addr);
-  EXPECT_PRED2(AreEqual, addr, addr2);
-
-  addr = IPAddress(kIPv6PublicAddr);
-  addr2 = IPAddress(addr);
-  EXPECT_PRED2(AreEqual, addr, addr2);
-}
-
-TEST(IPAddressTest, TestEquality) {
-  // Check v4 equality
-  in_addr v4addr, v4addr2;
-  v4addr.s_addr = htonl(kIPv4PublicAddr);
-  v4addr2.s_addr = htonl(kIPv4PublicAddr + 1);
-  IPAddress addr(v4addr);
-  IPAddress addr2(v4addr2);
-  IPAddress addr3(v4addr);
-
-  EXPECT_TRUE(addr == addr);
-  EXPECT_TRUE(addr2 == addr2);
-  EXPECT_TRUE(addr3 == addr3);
-  EXPECT_TRUE(addr == addr3);
-  EXPECT_TRUE(addr3 == addr);
-  EXPECT_FALSE(addr2 == addr);
-  EXPECT_FALSE(addr2 == addr3);
-  EXPECT_FALSE(addr == addr2);
-  EXPECT_FALSE(addr3 == addr2);
-
-  // Check v6 equality
-  IPAddress addr4(kIPv6PublicAddr);
-  IPAddress addr5(kIPv6LinkLocalAddr);
-  IPAddress addr6(kIPv6PublicAddr);
-
-  EXPECT_TRUE(addr4 == addr4);
-  EXPECT_TRUE(addr5 == addr5);
-  EXPECT_TRUE(addr4 == addr6);
-  EXPECT_TRUE(addr6 == addr4);
-  EXPECT_FALSE(addr4 == addr5);
-  EXPECT_FALSE(addr5 == addr4);
-  EXPECT_FALSE(addr6 == addr5);
-  EXPECT_FALSE(addr5 == addr6);
-
-  // Check v4/v6 cross-equality
-  EXPECT_FALSE(addr == addr4);
-  EXPECT_FALSE(addr == addr5);
-  EXPECT_FALSE(addr == addr6);
-  EXPECT_FALSE(addr4 == addr);
-  EXPECT_FALSE(addr5 == addr);
-  EXPECT_FALSE(addr6 == addr);
-  EXPECT_FALSE(addr2 == addr4);
-  EXPECT_FALSE(addr2 == addr5);
-  EXPECT_FALSE(addr2 == addr6);
-  EXPECT_FALSE(addr4 == addr2);
-  EXPECT_FALSE(addr5 == addr2);
-  EXPECT_FALSE(addr6 == addr2);
-  EXPECT_FALSE(addr3 == addr4);
-  EXPECT_FALSE(addr3 == addr5);
-  EXPECT_FALSE(addr3 == addr6);
-  EXPECT_FALSE(addr4 == addr3);
-  EXPECT_FALSE(addr5 == addr3);
-  EXPECT_FALSE(addr6 == addr3);
-
-  // Special cases: loopback and any.
-  // They're special but they're still not equal.
-  IPAddress v4loopback(htonl(INADDR_LOOPBACK));
-  IPAddress v6loopback(in6addr_loopback);
-  EXPECT_FALSE(v4loopback == v6loopback);
-
-  IPAddress v4any(0);
-  IPAddress v6any(in6addr_any);
-  EXPECT_FALSE(v4any == v6any);
-}
-
-TEST(IPAddressTest, TestComparison) {
-  // Defined in 'ascending' order.
-  // v6 > v4, and intra-family sorting is purely numerical
-  IPAddress addr0;  // AF_UNSPEC
-  IPAddress addr1(INADDR_ANY);  // 0.0.0.0
-  IPAddress addr2(kIPv4PublicAddr);  // 1.2.3.4
-  IPAddress addr3(INADDR_LOOPBACK);  // 127.0.0.1
-  IPAddress addr4(kIPv4RFC1918Addr);  // 192.168.7.1.
-  IPAddress addr5(in6addr_any);  // ::
-  IPAddress addr6(in6addr_loopback);  // ::1
-  IPAddress addr7(kIPv6PublicAddr);  // 2401....
-  IPAddress addr8(kIPv6LinkLocalAddr);  // fe80....
-
-  EXPECT_TRUE(addr0 < addr1);
-  EXPECT_TRUE(addr1 < addr2);
-  EXPECT_TRUE(addr2 < addr3);
-  EXPECT_TRUE(addr3 < addr4);
-  EXPECT_TRUE(addr4 < addr5);
-  EXPECT_TRUE(addr5 < addr6);
-  EXPECT_TRUE(addr6 < addr7);
-  EXPECT_TRUE(addr7 < addr8);
-
-  EXPECT_FALSE(addr0 > addr1);
-  EXPECT_FALSE(addr1 > addr2);
-  EXPECT_FALSE(addr2 > addr3);
-  EXPECT_FALSE(addr3 > addr4);
-  EXPECT_FALSE(addr4 > addr5);
-  EXPECT_FALSE(addr5 > addr6);
-  EXPECT_FALSE(addr6 > addr7);
-  EXPECT_FALSE(addr7 > addr8);
-
-  EXPECT_FALSE(addr0 > addr0);
-  EXPECT_FALSE(addr1 > addr1);
-  EXPECT_FALSE(addr2 > addr2);
-  EXPECT_FALSE(addr3 > addr3);
-  EXPECT_FALSE(addr4 > addr4);
-  EXPECT_FALSE(addr5 > addr5);
-  EXPECT_FALSE(addr6 > addr6);
-  EXPECT_FALSE(addr7 > addr7);
-  EXPECT_FALSE(addr8 > addr8);
-
-  EXPECT_FALSE(addr0 < addr0);
-  EXPECT_FALSE(addr1 < addr1);
-  EXPECT_FALSE(addr2 < addr2);
-  EXPECT_FALSE(addr3 < addr3);
-  EXPECT_FALSE(addr4 < addr4);
-  EXPECT_FALSE(addr5 < addr5);
-  EXPECT_FALSE(addr6 < addr6);
-  EXPECT_FALSE(addr7 < addr7);
-  EXPECT_FALSE(addr8 < addr8);
-}
-
-TEST(IPAddressTest, TestFromString) {
-  IPAddress addr;
-  IPAddress addr2;
-  addr2 = IPAddress(INADDR_ANY);
-
-  EXPECT_TRUE(IPFromString(kIPv4AnyAddrString, &addr));
-  EXPECT_EQ(addr.ToString(), kIPv4AnyAddrString);
-  EXPECT_PRED2(AreEqual, addr, addr2);
-
-  addr2 = IPAddress(INADDR_LOOPBACK);
-  EXPECT_TRUE(IPFromString(kIPv4LoopbackAddrString, &addr));
-  EXPECT_EQ(addr.ToString(), kIPv4LoopbackAddrString);
-  EXPECT_PRED2(AreEqual, addr, addr2);
-
-  addr2 = IPAddress(kIPv4RFC1918Addr);
-  EXPECT_TRUE(IPFromString(kIPv4RFC1918AddrString, &addr));
-  EXPECT_EQ(addr.ToString(), kIPv4RFC1918AddrString);
-  EXPECT_PRED2(AreEqual, addr, addr2);
-
-  addr2 = IPAddress(kIPv4PublicAddr);
-  EXPECT_TRUE(IPFromString(kIPv4PublicAddrString, &addr));
-  EXPECT_EQ(addr.ToString(), kIPv4PublicAddrString);
-  EXPECT_PRED2(AreEqual, addr, addr2);
-
-  addr2 = IPAddress(in6addr_any);
-  EXPECT_TRUE(IPFromString(kIPv6AnyAddrString, &addr));
-  EXPECT_EQ(addr.ToString(), kIPv6AnyAddrString);
-  EXPECT_PRED2(AreEqual, addr, addr2);
-
-  addr2 = IPAddress(in6addr_loopback);
-  EXPECT_TRUE(IPFromString(kIPv6LoopbackAddrString, &addr));
-  EXPECT_EQ(addr.ToString(), kIPv6LoopbackAddrString);
-  EXPECT_PRED2(AreEqual, addr, addr2);
-
-  addr2 = IPAddress(kIPv6LinkLocalAddr);
-  EXPECT_TRUE(IPFromString(kIPv6LinkLocalAddrString, &addr));
-  EXPECT_EQ(addr.ToString(), kIPv6LinkLocalAddrString);
-  EXPECT_PRED2(AreEqual, addr, addr2);
-
-  addr2 = IPAddress(kIPv6PublicAddr);
-  EXPECT_TRUE(IPFromString(kIPv6PublicAddrString, &addr));
-  EXPECT_EQ(addr.ToString(), kIPv6PublicAddrString);
-  EXPECT_PRED2(AreEqual, addr, addr2);
-
-  addr2 = IPAddress(kIPv4MappedRFC1918Addr);
-  EXPECT_TRUE(IPFromString(kIPv4MappedV4StyleAddrString, &addr));
-  EXPECT_PRED2(AreEqual, addr, addr2);
-
-  // Broken cases, should set addr to AF_UNSPEC.
-  EXPECT_PRED1(BrokenIPStringFails, kIPv4BrokenString1);
-  EXPECT_PRED1(BrokenIPStringFails, kIPv4BrokenString2);
-  EXPECT_PRED1(BrokenIPStringFails, kIPv4BrokenString3);
-  EXPECT_PRED1(BrokenIPStringFails, kIPv4BrokenString4);
-  EXPECT_PRED1(BrokenIPStringFails, kIPv4BrokenString5);
-  EXPECT_PRED1(BrokenIPStringFails, kIPv4BrokenString6);
-  EXPECT_PRED1(BrokenIPStringFails, kIPv6BrokenString1);
-  EXPECT_PRED1(BrokenIPStringFails, kIPv6BrokenString2);
-  EXPECT_PRED1(BrokenIPStringFails, kIPv6BrokenString3);
-  EXPECT_PRED1(BrokenIPStringFails, kIPv6BrokenString4);
-  EXPECT_PRED1(BrokenIPStringFails, kIPv6BrokenString5);
-  EXPECT_PRED1(BrokenIPStringFails, kIPv6BrokenString6);
-  EXPECT_PRED1(BrokenIPStringFails, kIPv6BrokenString7);
-  EXPECT_PRED1(BrokenIPStringFails, kIPv6BrokenString8);
-  EXPECT_PRED1(BrokenIPStringFails, kIPv6BrokenString9);
-  EXPECT_PRED1(BrokenIPStringFails, kIPv6BrokenString10);
-  EXPECT_PRED1(BrokenIPStringFails, kIPv6BrokenString11);
-  EXPECT_PRED1(BrokenIPStringFails, kIPv6BrokenString12);
-  EXPECT_PRED1(BrokenIPStringFails, kIPv6BrokenString13);
-  EXPECT_PRED1(BrokenIPStringFails, kIPv6BrokenString14);
-}
-
-TEST(IPAddressTest, TestIsPrivate) {
-  EXPECT_FALSE(IPIsPrivate(IPAddress(INADDR_ANY)));
-  EXPECT_FALSE(IPIsPrivate(IPAddress(kIPv4PublicAddr)));
-  EXPECT_FALSE(IPIsPrivate(IPAddress(in6addr_any)));
-  EXPECT_FALSE(IPIsPrivate(IPAddress(kIPv6PublicAddr)));
-  EXPECT_FALSE(IPIsPrivate(IPAddress(kIPv4MappedAnyAddr)));
-  EXPECT_FALSE(IPIsPrivate(IPAddress(kIPv4MappedPublicAddr)));
-
-  EXPECT_TRUE(IPIsPrivate(IPAddress(kIPv4RFC1918Addr)));
-  EXPECT_TRUE(IPIsPrivate(IPAddress(INADDR_LOOPBACK)));
-  EXPECT_TRUE(IPIsPrivate(IPAddress(in6addr_loopback)));
-  EXPECT_TRUE(IPIsPrivate(IPAddress(kIPv6LinkLocalAddr)));
-}
-
-TEST(IPAddressTest, TestIsLoopback) {
-  EXPECT_FALSE(IPIsLoopback(IPAddress(INADDR_ANY)));
-  EXPECT_FALSE(IPIsLoopback(IPAddress(kIPv4PublicAddr)));
-  EXPECT_FALSE(IPIsLoopback(IPAddress(in6addr_any)));
-  EXPECT_FALSE(IPIsLoopback(IPAddress(kIPv6PublicAddr)));
-  EXPECT_FALSE(IPIsLoopback(IPAddress(kIPv4MappedAnyAddr)));
-  EXPECT_FALSE(IPIsLoopback(IPAddress(kIPv4MappedPublicAddr)));
-
-  EXPECT_TRUE(IPIsLoopback(IPAddress(INADDR_LOOPBACK)));
-  EXPECT_TRUE(IPIsLoopback(IPAddress(in6addr_loopback)));
-}
-
-TEST(IPAddressTest, TestNormalized) {
-  // Check normalizing a ::ffff:a.b.c.d address.
-  IPAddress addr;
-  EXPECT_TRUE(IPFromString(kIPv4MappedV4StyleAddrString, &addr));
-  IPAddress addr2(kIPv4RFC1918Addr);
-  addr = addr.Normalized();
-  EXPECT_EQ(addr2, addr);
-
-  // Check normalizing a ::ffff:aabb:ccdd address.
-  addr = IPAddress(kIPv4MappedPublicAddr);
-  addr2 = IPAddress(kIPv4PublicAddr);
-  addr = addr.Normalized();
-  EXPECT_EQ(addr, addr2);
-
-  // Check that a non-mapped v6 addresses isn't altered.
-  addr = IPAddress(kIPv6PublicAddr);
-  addr2 = IPAddress(kIPv6PublicAddr);
-  addr = addr.Normalized();
-  EXPECT_EQ(addr, addr2);
-
-  // Check that addresses that look a bit like mapped addresses aren't altered
-  EXPECT_TRUE(IPFromString("fe80::ffff:0102:0304", &addr));
-  addr2 = addr;
-  addr = addr.Normalized();
-  EXPECT_EQ(addr, addr2);
-  EXPECT_TRUE(IPFromString("::0102:0304", &addr));
-  addr2 = addr;
-  addr = addr.Normalized();
-  EXPECT_EQ(addr, addr2);
-  // This string should 'work' as an IP address but is not a mapped address,
-  // so it shouldn't change on normalization.
-  EXPECT_TRUE(IPFromString("::192.168.7.1", &addr));
-  addr2 = addr;
-  addr = addr.Normalized();
-  EXPECT_EQ(addr, addr2);
-
-  // Check that v4 addresses aren't altered.
-  addr = IPAddress(htonl(kIPv4PublicAddr));
-  addr2 = IPAddress(htonl(kIPv4PublicAddr));
-  addr = addr.Normalized();
-  EXPECT_EQ(addr, addr2);
-}
-
-TEST(IPAddressTest, TestAsIPv6Address) {
-  IPAddress addr(kIPv4PublicAddr);
-  IPAddress addr2(kIPv4MappedPublicAddr);
-  addr = addr.AsIPv6Address();
-  EXPECT_EQ(addr, addr2);
-
-  addr = IPAddress(kIPv4MappedPublicAddr);
-  addr2 = IPAddress(kIPv4MappedPublicAddr);
-  addr = addr.AsIPv6Address();
-  EXPECT_EQ(addr, addr2);
-
-  addr = IPAddress(kIPv6PublicAddr);
-  addr2 = IPAddress(kIPv6PublicAddr);
-  addr = addr.AsIPv6Address();
-  EXPECT_EQ(addr, addr2);
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/json.cc b/third_party/libjingle/source/talk/base/json.cc
deleted file mode 100644
index 721fb94..0000000
--- a/third_party/libjingle/source/talk/base/json.cc
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/json.h"
-
-#include <errno.h>
-
-#include <climits>
-#include <cstdlib>
-#include <sstream>
-
-bool GetStringFromJson(const Json::Value& in, std::string* out) {
-  if (!in.isString()) {
-    std::ostringstream s;
-    if (in.isBool()) {
-      s << std::boolalpha << in.asBool();
-    } else if (in.isInt()) {
-      s << in.asInt();
-    } else if (in.isUInt()) {
-      s << in.asUInt();
-    } else if (in.isDouble()) {
-      s << in.asDouble();
-    } else {
-      return false;
-    }
-    *out = s.str();
-  } else {
-    *out = in.asString();
-  }
-  return true;
-}
-
-bool GetIntFromJson(const Json::Value& in, int* out) {
-  bool ret;
-  if (!in.isString()) {
-    ret = in.isConvertibleTo(Json::intValue);
-    if (ret) {
-      *out = in.asInt();
-    }
-  } else {
-    long val;  // NOLINT
-    const char* c_str = in.asCString();
-    char* end_ptr;
-    errno = 0;
-    val = strtol(c_str, &end_ptr, 10);  // NOLINT
-    ret = (end_ptr != c_str && *end_ptr == '\0' && !errno &&
-           val >= INT_MIN && val <= INT_MAX);
-    *out = val;
-  }
-  return ret;
-}
-
-bool GetUIntFromJson(const Json::Value& in, unsigned int* out) {
-  bool ret;
-  if (!in.isString()) {
-    ret = in.isConvertibleTo(Json::uintValue);
-    if (ret) {
-      *out = in.asUInt();
-    }
-  } else {
-    unsigned long val;  // NOLINT
-    const char* c_str = in.asCString();
-    char* end_ptr;
-    errno = 0;
-    val = strtoul(c_str, &end_ptr, 10);  // NOLINT
-    ret = (end_ptr != c_str && *end_ptr == '\0' && !errno &&
-           val <= UINT_MAX);
-    *out = val;
-  }
-  return ret;
-}
-
-bool GetBoolFromJson(const Json::Value& in, bool* out) {
-  bool ret;
-  if (!in.isString()) {
-    ret = in.isConvertibleTo(Json::booleanValue);
-    if (ret) {
-      *out = in.asBool();
-    }
-  } else {
-    if (in.asString() == "true") {
-      *out = true;
-      ret = true;
-    } else if (in.asString() == "false") {
-      *out = false;
-      ret = true;
-    } else {
-      ret = false;
-    }
-  }
-  return ret;
-}
-
-bool GetDoubleFromJson(const Json::Value& in, double* out) {
-  bool ret;
-  if (!in.isString()) {
-    ret = in.isConvertibleTo(Json::realValue);
-    if (ret) {
-      *out = in.asDouble();
-    }
-  } else {
-    double val;
-    const char* c_str = in.asCString();
-    char* end_ptr;
-    errno = 0;
-    val = strtod(c_str, &end_ptr);
-    ret = (end_ptr != c_str && *end_ptr == '\0' && !errno);
-    *out = val;
-  }
-  return ret;
-}
-
-bool GetValueFromJsonArray(const Json::Value& in, size_t n,
-                           Json::Value* out) {
-  if (!in.isArray() || !in.isValidIndex(n)) {
-    return false;
-  }
-
-  *out = in[static_cast<Json::Value::ArrayIndex>(n)];
-  return true;
-}
-
-bool GetIntFromJsonArray(const Json::Value& in, size_t n,
-                         int* out) {
-  Json::Value x;
-  return GetValueFromJsonArray(in, n, &x) && GetIntFromJson(x, out);
-}
-
-bool GetUIntFromJsonArray(const Json::Value& in, size_t n,
-                          unsigned int* out)  {
-  Json::Value x;
-  return GetValueFromJsonArray(in, n, &x) && GetUIntFromJson(x, out);
-}
-
-bool GetStringFromJsonArray(const Json::Value& in, size_t n,
-                            std::string* out) {
-  Json::Value x;
-  return GetValueFromJsonArray(in, n, &x) && GetStringFromJson(x, out);
-}
-
-bool GetBoolFromJsonArray(const Json::Value& in, size_t n,
-                          bool* out) {
-  Json::Value x;
-  return GetValueFromJsonArray(in, n, &x) && GetBoolFromJson(x, out);
-}
-
-bool GetDoubleFromJsonArray(const Json::Value& in, size_t n,
-                            double* out) {
-  Json::Value x;
-  return GetValueFromJsonArray(in, n, &x) && GetDoubleFromJson(x, out);
-}
-
-bool GetValueFromJsonObject(const Json::Value& in, const std::string& k,
-                            Json::Value* out) {
-  if (!in.isObject() || !in.isMember(k)) {
-    return false;
-  }
-
-  *out = in[k];
-  return true;
-}
-
-bool GetIntFromJsonObject(const Json::Value& in, const std::string& k,
-                          int* out) {
-  Json::Value x;
-  return GetValueFromJsonObject(in, k, &x) && GetIntFromJson(x, out);
-}
-
-bool GetUIntFromJsonObject(const Json::Value& in, const std::string& k,
-                           unsigned int* out)  {
-  Json::Value x;
-  return GetValueFromJsonObject(in, k, &x) && GetUIntFromJson(x, out);
-}
-
-bool GetStringFromJsonObject(const Json::Value& in, const std::string& k,
-                             std::string* out)  {
-  Json::Value x;
-  return GetValueFromJsonObject(in, k, &x) && GetStringFromJson(x, out);
-}
-
-bool GetBoolFromJsonObject(const Json::Value& in, const std::string& k,
-                           bool* out) {
-  Json::Value x;
-  return GetValueFromJsonObject(in, k, &x) && GetBoolFromJson(x, out);
-}
-
-bool GetDoubleFromJsonObject(const Json::Value& in, const std::string& k,
-                             double* out) {
-  Json::Value x;
-  return GetValueFromJsonObject(in, k, &x) && GetDoubleFromJson(x, out);
-}
-
-Json::Value StringVectorToJsonValue(const std::vector<std::string>& strings) {
-  Json::Value result(Json::arrayValue);
-  for (size_t i = 0; i < strings.size(); ++i) {
-    result.append(Json::Value(strings[i]));
-  }
-  return result;
-}
-
-bool JsonValueToStringVector(const Json::Value& value,
-                             std::vector<std::string> *strings) {
-  strings->clear();
-  if (!value.isArray()) {
-    return false;
-  }
-
-  for (Json::Value::ArrayIndex i = 0; i < value.size(); ++i) {
-    if (value[i].isString()) {
-      strings->push_back(value[i].asString());
-    } else {
-      return false;
-    }
-  }
-
-  return true;
-}
-
-std::string JsonValueToString(const Json::Value& json) {
-  Json::FastWriter w;
-  std::string value = w.write(json);
-  return value.substr(0, value.size() - 1);  // trim trailing newline
-}
diff --git a/third_party/libjingle/source/talk/base/json.h b/third_party/libjingle/source/talk/base/json.h
deleted file mode 100644
index d8cee35..0000000
--- a/third_party/libjingle/source/talk/base/json.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_JSON_H_
-#define TALK_BASE_JSON_H_
-
-#include <string>
-#include <vector>
-
-#ifdef JSONCPP_RELATIVE_PATH
-#include "json/json.h"
-#else
-#include "third_party/jsoncpp/json.h"
-#endif
-
-// TODO: Move to talk_base namespace
-
-///////////////////////////////////////////////////////////////////////////////
-// JSON Helpers
-///////////////////////////////////////////////////////////////////////////////
-
-// Robust conversion operators, better than the ones in JsonCpp.
-bool GetIntFromJson(const Json::Value& in, int* out);
-bool GetUIntFromJson(const Json::Value& in, unsigned int* out);
-bool GetStringFromJson(const Json::Value& in, std::string* out);
-bool GetBoolFromJson(const Json::Value& in, bool* out);
-bool GetDoubleFromJson(const Json::Value& in, double* out);
-
-// Pull values out of a JSON array.
-bool GetValueFromJsonArray(const Json::Value& in, size_t n,
-                           Json::Value* out);
-bool GetIntFromJsonArray(const Json::Value& in, size_t n,
-                         int* out);
-bool GetUIntFromJsonArray(const Json::Value& in, size_t n,
-                          unsigned int* out);
-bool GetStringFromJsonArray(const Json::Value& in, size_t n,
-                            std::string* out);
-bool GetBoolFromJsonArray(const Json::Value& in, size_t n,
-                          bool* out);
-bool GetDoubleFromJsonArray(const Json::Value& in, size_t n,
-                            double* out);
-
-// Pull values out of a JSON object.
-bool GetValueFromJsonObject(const Json::Value& in, const std::string& k,
-                            Json::Value* out);
-bool GetIntFromJsonObject(const Json::Value& in, const std::string& k,
-                          int* out);
-bool GetUIntFromJsonObject(const Json::Value& in, const std::string& k,
-                           unsigned int* out);
-bool GetStringFromJsonObject(const Json::Value& in, const std::string& k,
-                             std::string* out);
-bool GetBoolFromJsonObject(const Json::Value& in, const std::string& k,
-                           bool* out);
-bool GetDoubleFromJsonObject(const Json::Value& in, const std::string& k,
-                             double* out);
-
-// Converts vectors of strings to/from JSON arrays.
-Json::Value StringVectorToJsonValue(const std::vector<std::string>& strings);
-bool JsonValueToStringVector(const Json::Value& value,
-                             std::vector<std::string> *strings);
-
-// Writes out a Json value as a string.
-std::string JsonValueToString(const Json::Value& json);
-
-#endif  // TALK_BASE_JSON_H_
diff --git a/third_party/libjingle/source/talk/base/latebindingsymboltable.cc b/third_party/libjingle/source/talk/base/latebindingsymboltable.cc
deleted file mode 100644
index f9d59ab..0000000
--- a/third_party/libjingle/source/talk/base/latebindingsymboltable.cc
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/latebindingsymboltable.h"
-
-#ifdef LINUX
-#include <dlfcn.h>
-#endif
-
-#include "talk/base/logging.h"
-
-namespace talk_base {
-
-inline static const char *GetDllError() {
-#ifdef LINUX
-  char *err = dlerror();
-  if (err) {
-    return err;
-  } else {
-    return "No error";
-  }
-#else
-#error Not implemented
-#endif
-}
-
-DllHandle InternalLoadDll(const char dll_name[]) {
-#ifdef LINUX
-  DllHandle handle = dlopen(dll_name, RTLD_NOW);
-#else
-#error Not implemented
-#endif
-  if (handle == kInvalidDllHandle) {
-    LOG(LS_WARNING) << "Can't load " << dll_name << ": " << GetDllError();
-  }
-  return handle;
-}
-
-void InternalUnloadDll(DllHandle handle) {
-#ifdef LINUX
-  if (dlclose(handle) != 0) {
-    LOG(LS_ERROR) << GetDllError();
-  }
-#else
-#error Not implemented
-#endif
-}
-
-static bool LoadSymbol(DllHandle handle,
-                       const char *symbol_name,
-                       void **symbol) {
-#ifdef LINUX
-  *symbol = dlsym(handle, symbol_name);
-  char *err = dlerror();
-  if (err) {
-    LOG(LS_ERROR) << "Error loading symbol " << symbol_name << ": " << err;
-    return false;
-  } else if (!*symbol) {
-    LOG(LS_ERROR) << "Symbol " << symbol_name << " is NULL";
-    return false;
-  }
-  return true;
-#else
-#error Not implemented
-#endif
-}
-
-// This routine MUST assign SOME value for every symbol, even if that value is
-// NULL, or else some symbols may be left with uninitialized data that the
-// caller may later interpret as a valid address.
-bool InternalLoadSymbols(DllHandle handle,
-                         int num_symbols,
-                         const char *const symbol_names[],
-                         void *symbols[]) {
-#ifdef LINUX
-  // Clear any old errors.
-  dlerror();
-#endif
-  for (int i = 0; i < num_symbols; ++i) {
-    if (!LoadSymbol(handle, symbol_names[i], &symbols[i])) {
-      return false;
-    }
-  }
-  return true;
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/latebindingsymboltable.h b/third_party/libjingle/source/talk/base/latebindingsymboltable.h
deleted file mode 100644
index 3a9544f..0000000
--- a/third_party/libjingle/source/talk/base/latebindingsymboltable.h
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_LATEBINDINGSYMBOLTABLE_H_
-#define TALK_BASE_LATEBINDINGSYMBOLTABLE_H_
-
-#include <string.h>
-
-#include "talk/base/common.h"
-#include "talk/base/logging.h"
-
-// This file provides macros for creating "symbol table" classes to simplify the
-// dynamic loading of symbols from DLLs. Currently the implementation only
-// supports Linux and pure C symbols.
-// See talk/sound/pulseaudiosymboltable.(h|cc) for an example.
-
-namespace talk_base {
-
-#ifdef LINUX
-typedef void *DllHandle;
-
-const DllHandle kInvalidDllHandle = NULL;
-#else
-#error Not implemented
-#endif
-
-// These are helpers for use only by the class below.
-DllHandle InternalLoadDll(const char dll_name[]);
-
-void InternalUnloadDll(DllHandle handle);
-
-bool InternalLoadSymbols(DllHandle handle,
-                         int num_symbols,
-                         const char *const symbol_names[],
-                         void *symbols[]);
-
-template <int SYMBOL_TABLE_SIZE,
-          const char kDllName[],
-          const char *const kSymbolNames[]>
-class LateBindingSymbolTable {
- public:
-  LateBindingSymbolTable()
-      : handle_(kInvalidDllHandle),
-        undefined_symbols_(false) {
-    memset(symbols_, 0, sizeof(symbols_));
-  }
-
-  ~LateBindingSymbolTable() {
-    Unload();
-  }
-
-  static int NumSymbols() {
-    return SYMBOL_TABLE_SIZE;
-  }
-
-  // We do not use this, but we offer it for theoretical convenience.
-  static const char *GetSymbolName(int index) {
-    ASSERT(index < NumSymbols());
-    return kSymbolNames[index];
-  }
-
-  bool IsLoaded() const {
-    return handle_ != kInvalidDllHandle;
-  }
-
-  // Loads the DLL and the symbol table. Returns true iff the DLL and symbol
-  // table loaded successfully.
-  bool Load() {
-    if (IsLoaded()) {
-      return true;
-    }
-    if (undefined_symbols_) {
-      // We do not attempt to load again because repeated attempts are not
-      // likely to succeed and DLL loading is costly.
-      LOG(LS_ERROR) << "We know there are undefined symbols";
-      return false;
-    }
-    handle_ = InternalLoadDll(kDllName);
-    if (!IsLoaded()) {
-      return false;
-    }
-    if (!InternalLoadSymbols(handle_, NumSymbols(), kSymbolNames, symbols_)) {
-      undefined_symbols_ = true;
-      Unload();
-      return false;
-    }
-    return true;
-  }
-
-  void Unload() {
-    if (!IsLoaded()) {
-      return;
-    }
-    InternalUnloadDll(handle_);
-    handle_ = kInvalidDllHandle;
-    memset(symbols_, 0, sizeof(symbols_));
-  }
-
-  // Retrieves the given symbol. NOTE: Recommended to use LATESYM_GET below
-  // instead of this.
-  void *GetSymbol(int index) const {
-    ASSERT(IsLoaded());
-    ASSERT(index < NumSymbols());
-    return symbols_[index];
-  }
-
- private:
-  DllHandle handle_;
-  bool undefined_symbols_;
-  void *symbols_[SYMBOL_TABLE_SIZE];
-
-  DISALLOW_COPY_AND_ASSIGN(LateBindingSymbolTable);
-};
-
-// This macro must be invoked in a header to declare a symbol table class.
-#define LATE_BINDING_SYMBOL_TABLE_DECLARE_BEGIN(ClassName) \
-enum {
-
-// This macro must be invoked in the header declaration once for each symbol
-// (recommended to use an X-Macro to avoid duplication).
-// This macro defines an enum with names built from the symbols, which
-// essentially creates a hash table in the compiler from symbol names to their
-// indices in the symbol table class.
-#define LATE_BINDING_SYMBOL_TABLE_DECLARE_ENTRY(ClassName, sym) \
-  ClassName##_SYMBOL_TABLE_INDEX_##sym,
-
-// This macro completes the header declaration.
-#define LATE_BINDING_SYMBOL_TABLE_DECLARE_END(ClassName) \
-  ClassName##_SYMBOL_TABLE_SIZE \
-}; \
-\
-extern const char ClassName##_kDllName[]; \
-extern const char *const \
-    ClassName##_kSymbolNames[ClassName##_SYMBOL_TABLE_SIZE]; \
-\
-typedef ::talk_base::LateBindingSymbolTable<ClassName##_SYMBOL_TABLE_SIZE, \
-                                            ClassName##_kDllName, \
-                                            ClassName##_kSymbolNames> \
-    ClassName;
-
-// This macro must be invoked in a .cc file to define a previously-declared
-// symbol table class.
-#define LATE_BINDING_SYMBOL_TABLE_DEFINE_BEGIN(ClassName, dllName) \
-const char ClassName##_kDllName[] = dllName; \
-const char *const ClassName##_kSymbolNames[ClassName##_SYMBOL_TABLE_SIZE] = {
-
-// This macro must be invoked in the .cc definition once for each symbol
-// (recommended to use an X-Macro to avoid duplication).
-// This would have to use the mangled name if we were to ever support C++
-// symbols.
-#define LATE_BINDING_SYMBOL_TABLE_DEFINE_ENTRY(ClassName, sym) \
-  #sym,
-
-#define LATE_BINDING_SYMBOL_TABLE_DEFINE_END(ClassName) \
-};
-
-// Index of a given symbol in the given symbol table class.
-#define LATESYM_INDEXOF(ClassName, sym) \
-  (ClassName##_SYMBOL_TABLE_INDEX_##sym)
-
-// Returns a reference to the given late-binded symbol, with the correct type.
-#define LATESYM_GET(ClassName, inst, sym) \
-  (*reinterpret_cast<typeof(&sym)>( \
-      (inst)->GetSymbol(LATESYM_INDEXOF(ClassName, sym))))
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_LATEBINDINGSYMBOLTABLE_H_
diff --git a/third_party/libjingle/source/talk/base/linked_ptr.h b/third_party/libjingle/source/talk/base/linked_ptr.h
deleted file mode 100644
index a98a367..0000000
--- a/third_party/libjingle/source/talk/base/linked_ptr.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * linked_ptr - simple reference linked pointer
- * (like reference counting, just using a linked list of the references
- * instead of their count.)
- *
- * The implementation stores three pointers for every linked_ptr, but
- * does not allocate anything on the free store.
- */
-
-#ifndef TALK_BASE_LINKED_PTR_H__
-#define TALK_BASE_LINKED_PTR_H__
-
-namespace talk_base {
-
-/* For ANSI-challenged compilers, you may want to #define
- * NO_MEMBER_TEMPLATES, explicit or mutable */
-#define NO_MEMBER_TEMPLATES
-
-template <class X> class linked_ptr
-{
-public:
-
-#ifndef NO_MEMBER_TEMPLATES
-#   define TEMPLATE_FUNCTION template <class Y>
-    TEMPLATE_FUNCTION friend class linked_ptr<Y>;
-#else
-#   define TEMPLATE_FUNCTION
-    typedef X Y;
-#endif
-
-    typedef X element_type;
-
-    explicit linked_ptr(X* p = 0) throw()
-        : itsPtr(p) {itsPrev = itsNext = this;}
-    ~linked_ptr()
-        {release();}
-    linked_ptr(const linked_ptr& r) throw()
-        {acquire(r);}
-    linked_ptr& operator=(const linked_ptr& r)
-    {
-        if (this != &r) {
-            release();
-            acquire(r);
-        }
-        return *this;
-    }
-
-#ifndef NO_MEMBER_TEMPLATES
-    template <class Y> friend class linked_ptr<Y>;
-    template <class Y> linked_ptr(const linked_ptr<Y>& r) throw()
-        {acquire(r);}
-    template <class Y> linked_ptr& operator=(const linked_ptr<Y>& r)
-    {
-        if (this != &r) {
-            release();
-            acquire(r);
-        }
-        return *this;
-    }
-#endif // NO_MEMBER_TEMPLATES
-
-    X& operator*()  const throw()   {return *itsPtr;}
-    X* operator->() const throw()   {return itsPtr;}
-    X* get()        const throw()   {return itsPtr;}
-    bool unique()   const throw()   {return itsPrev ? itsPrev==this : true;}
-
-private:
-    X*                          itsPtr;
-    mutable const linked_ptr*   itsPrev;
-    mutable const linked_ptr*   itsNext;
-
-    void acquire(const linked_ptr& r) throw()
-    { // insert this to the list
-        itsPtr = r.itsPtr;
-        itsNext = r.itsNext;
-        itsNext->itsPrev = this;
-        itsPrev = &r;
-#ifndef mutable
-        r.itsNext = this;
-#else // for ANSI-challenged compilers
-        (const_cast<linked_ptr<X>*>(&r))->itsNext = this;
-#endif
-    }
-
-#ifndef NO_MEMBER_TEMPLATES
-    template <class Y> void acquire(const linked_ptr<Y>& r) throw()
-    { // insert this to the list
-        itsPtr = r.itsPtr;
-        itsNext = r.itsNext;
-        itsNext->itsPrev = this;
-        itsPrev = &r;
-#ifndef mutable
-        r.itsNext = this;
-#else // for ANSI-challenged compilers
-        (const_cast<linked_ptr<X>*>(&r))->itsNext = this;
-#endif
-    }
-#endif // NO_MEMBER_TEMPLATES
-
-    void release()
-    { // erase this from the list, delete if unique
-        if (unique()) delete itsPtr;
-        else {
-            itsPrev->itsNext = itsNext;
-            itsNext->itsPrev = itsPrev;
-            itsPrev = itsNext = 0;
-        }
-        itsPtr = 0;
-    }
-};
-
-} // namespace talk_base
-
-#endif // TALK_BASE_LINKED_PTR_H__
-
diff --git a/third_party/libjingle/source/talk/base/linux.cc b/third_party/libjingle/source/talk/base/linux.cc
deleted file mode 100644
index a4434f5..0000000
--- a/third_party/libjingle/source/talk/base/linux.cc
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * libjingle
- * Copyright 2008 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#if defined(LINUX) || defined(ANDROID)
-#include "talk/base/linux.h"
-
-#include <ctype.h>
-
-#include <errno.h>
-#include <sys/utsname.h>
-#include <sys/wait.h>
-
-#include <cstdio>
-#include <set>
-
-#include "talk/base/stringencode.h"
-
-namespace talk_base {
-
-static const char kCpuInfoFile[] = "/proc/cpuinfo";
-static const char kCpuMaxFreqFile[] =
-    "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq";
-
-ProcCpuInfo::ProcCpuInfo() {
-}
-
-ProcCpuInfo::~ProcCpuInfo() {
-}
-
-bool ProcCpuInfo::LoadFromSystem() {
-  ConfigParser procfs;
-  if (!procfs.Open(kCpuInfoFile)) {
-    return false;
-  }
-  return procfs.Parse(&sections_);
-};
-
-bool ProcCpuInfo::GetSectionCount(size_t* count) {
-  if (sections_.empty()) {
-    return false;
-  }
-  if (count) {
-    *count = sections_.size();
-  }
-  return true;
-}
-
-bool ProcCpuInfo::GetNumCpus(int* num) {
-  if (sections_.empty()) {
-    return false;
-  }
-  int total_cpus = 0;
-#if defined(__arm__)
-  // Count the number of blocks that have a "processor" key defined. On ARM,
-  // there may be extra blocks of information that aren't per-processor.
-  size_t section_count = sections_.size();
-  for (size_t i = 0; i < section_count; ++i) {
-    int processor_id;
-    if (GetSectionIntValue(i, "processor", &processor_id)) {
-      ++total_cpus;
-    }
-  }
-  // Single core ARM systems don't include "processor" keys at all, so return
-  // that we have a single core if we didn't find any explicitly above.
-  if (total_cpus == 0) {
-    total_cpus = 1;
-  }
-#else
-  // On X86, there is exactly one info section per processor.
-  total_cpus = static_cast<int>(sections_.size());
-#endif
-  if (num) {
-    *num = total_cpus;
-  }
-  return true;
-}
-
-bool ProcCpuInfo::GetNumPhysicalCpus(int* num) {
-  if (sections_.empty()) {
-    return false;
-  }
-  // TODO: /proc/cpuinfo only reports cores that are currently
-  // _online_, so this may underreport the number of physical cores.
-#if defined(__arm__)
-  // ARM (currently) has no hyperthreading, so just return the same value
-  // as GetNumCpus.
-  return GetNumCpus(num);
-#else
-  int total_cores = 0;
-  std::set<int> physical_ids;
-  size_t section_count = sections_.size();
-  for (size_t i = 0; i < section_count; ++i) {
-    int physical_id;
-    int cores;
-    // Count the cores for the physical id only if we have not counted the id.
-    if (GetSectionIntValue(i, "physical id", &physical_id) &&
-        GetSectionIntValue(i, "cpu cores", &cores) &&
-        physical_ids.find(physical_id) == physical_ids.end()) {
-      physical_ids.insert(physical_id);
-      total_cores += cores;
-    }
-  }
-
-  if (num) {
-    *num = total_cores;
-  }
-  return true;
-#endif
-}
-
-bool ProcCpuInfo::GetCpuFamily(int* id) {
-  int cpu_family = 0;
-
-#if defined(__arm__)
-  // On some ARM platforms, there is no 'cpu family' in '/proc/cpuinfo'. But
-  // there is 'CPU Architecture' which can be used as 'cpu family'.
-  // See http://en.wikipedia.org/wiki/ARM_architecture for a good list of
-  // ARM cpu families, architectures, and their mappings.
-  // There may be multiple sessions that aren't per-processor. We need to scan
-  // through each session until we find the first 'CPU architecture'.
-  size_t section_count = sections_.size();
-  for (size_t i = 0; i < section_count; ++i) {
-    if (GetSectionIntValue(i, "CPU architecture", &cpu_family)) {
-      // We returns the first one (if there are multiple entries).
-      break;
-    };
-  }
-#else
-  GetSectionIntValue(0, "cpu family", &cpu_family);
-#endif
-  if (id) {
-    *id = cpu_family;
-  }
-  return true;
-}
-
-bool ProcCpuInfo::GetSectionStringValue(size_t section_num,
-                                        const std::string& key,
-                                        std::string* result) {
-  if (section_num >= sections_.size()) {
-    return false;
-  }
-  ConfigParser::SimpleMap::iterator iter = sections_[section_num].find(key);
-  if (iter == sections_[section_num].end()) {
-    return false;
-  }
-  *result = iter->second;
-  return true;
-}
-
-bool ProcCpuInfo::GetSectionIntValue(size_t section_num,
-                                     const std::string& key,
-                                     int* result) {
-  if (section_num >= sections_.size()) {
-    return false;
-  }
-  ConfigParser::SimpleMap::iterator iter = sections_[section_num].find(key);
-  if (iter == sections_[section_num].end()) {
-    return false;
-  }
-  return FromString(iter->second, result);
-}
-
-ConfigParser::ConfigParser() {}
-
-ConfigParser::~ConfigParser() {}
-
-bool ConfigParser::Open(const std::string& filename) {
-  FileStream* fs = new FileStream();
-  if (!fs->Open(filename, "r", NULL)) {
-    return false;
-  }
-  instream_.reset(fs);
-  return true;
-}
-
-void ConfigParser::Attach(StreamInterface* stream) {
-  instream_.reset(stream);
-}
-
-bool ConfigParser::Parse(MapVector* key_val_pairs) {
-  // Parses the file and places the found key-value pairs into key_val_pairs.
-  SimpleMap section;
-  while (ParseSection(&section)) {
-    key_val_pairs->push_back(section);
-    section.clear();
-  }
-  return (!key_val_pairs->empty());
-}
-
-bool ConfigParser::ParseSection(SimpleMap* key_val_pair) {
-  // Parses the next section in the filestream and places the found key-value
-  // pairs into key_val_pair.
-  std::string key, value;
-  while (ParseLine(&key, &value)) {
-    (*key_val_pair)[key] = value;
-  }
-  return (!key_val_pair->empty());
-}
-
-bool ConfigParser::ParseLine(std::string* key, std::string* value) {
-  // Parses the next line in the filestream and places the found key-value
-  // pair into key and val.
-  std::string line;
-  if ((instream_->ReadLine(&line)) == EOF) {
-    return false;
-  }
-  std::vector<std::string> tokens;
-  if (2 != split(line, ':', &tokens)) {
-    return false;
-  }
-  // Removes whitespace at the end of Key name
-  size_t pos = tokens[0].length() - 1;
-  while ((pos > 0) && isspace(tokens[0][pos])) {
-    pos--;
-  }
-  tokens[0].erase(pos + 1);
-  // Removes whitespace at the start of value
-  pos = 0;
-  while (pos < tokens[1].length() && isspace(tokens[1][pos])) {
-    pos++;
-  }
-  tokens[1].erase(0, pos);
-  *key = tokens[0];
-  *value = tokens[1];
-  return true;
-}
-
-static bool ExpectLineFromStream(FileStream* stream,
-                                 std::string* out) {
-  StreamResult res = stream->ReadLine(out);
-  if (res != SR_SUCCESS) {
-    if (res != SR_EOS) {
-      LOG(LS_ERROR) << "Error when reading from stream";
-    } else {
-      LOG(LS_ERROR) << "Incorrect number of lines in stream";
-    }
-    return false;
-  }
-  return true;
-}
-
-static void ExpectEofFromStream(FileStream* stream) {
-  std::string unused;
-  StreamResult res = stream->ReadLine(&unused);
-  if (res == SR_SUCCESS) {
-    LOG(LS_WARNING) << "Ignoring unexpected extra lines from stream";
-  } else if (res != SR_EOS) {
-    LOG(LS_WARNING) << "Error when checking for extra lines from stream";
-  }
-}
-
-// For caching the lsb_release output (reading it invokes a sub-process and
-// hence is somewhat expensive).
-static std::string lsb_release_string;
-static CriticalSection lsb_release_string_critsec;
-
-std::string ReadLinuxLsbRelease() {
-  CritScope cs(&lsb_release_string_critsec);
-  if (!lsb_release_string.empty()) {
-    // Have cached result from previous call.
-    return lsb_release_string;
-  }
-  // No cached result. Run lsb_release and parse output.
-  POpenStream lsb_release_output;
-  if (!lsb_release_output.Open("lsb_release -idrcs", "r", NULL)) {
-    LOG_ERR(LS_ERROR) << "Can't run lsb_release";
-    return lsb_release_string;  // empty
-  }
-  // Read in the command's output and build the string.
-  std::ostringstream sstr;
-  std::string line;
-  int wait_status;
-
-  if (!ExpectLineFromStream(&lsb_release_output, &line)) {
-    return lsb_release_string;  // empty
-  }
-  sstr << "DISTRIB_ID=" << line;
-
-  if (!ExpectLineFromStream(&lsb_release_output, &line)) {
-    return lsb_release_string;  // empty
-  }
-  sstr << " DISTRIB_DESCRIPTION=\"" << line << '"';
-
-  if (!ExpectLineFromStream(&lsb_release_output, &line)) {
-    return lsb_release_string;  // empty
-  }
-  sstr << " DISTRIB_RELEASE=" << line;
-
-  if (!ExpectLineFromStream(&lsb_release_output, &line)) {
-    return lsb_release_string;  // empty
-  }
-  sstr << " DISTRIB_CODENAME=" << line;
-
-  // Should not be anything left.
-  ExpectEofFromStream(&lsb_release_output);
-
-  lsb_release_output.Close();
-  wait_status = lsb_release_output.GetWaitStatus();
-  if (wait_status == -1 ||
-      !WIFEXITED(wait_status) ||
-      WEXITSTATUS(wait_status) != 0) {
-    LOG(LS_WARNING) << "Unexpected exit status from lsb_release";
-  }
-
-  lsb_release_string = sstr.str();
-
-  return lsb_release_string;
-}
-
-std::string ReadLinuxUname() {
-  struct utsname buf;
-  if (uname(&buf) < 0) {
-    LOG_ERR(LS_ERROR) << "Can't call uname()";
-    return std::string();
-  }
-  std::ostringstream sstr;
-  sstr << buf.sysname << " "
-       << buf.release << " "
-       << buf.version << " "
-       << buf.machine;
-  return sstr.str();
-}
-
-int ReadCpuMaxFreq() {
-  FileStream fs;
-  std::string str;
-  int freq = -1;
-  if (!fs.Open(kCpuMaxFreqFile, "r", NULL) ||
-      SR_SUCCESS != fs.ReadLine(&str) ||
-      !FromString(str, &freq)) {
-    return -1;
-  }
-  return freq;
-}
-
-}  // namespace talk_base
-
-#endif  // defined(LINUX) || defined(ANDROID)
diff --git a/third_party/libjingle/source/talk/base/linux.h b/third_party/libjingle/source/talk/base/linux.h
deleted file mode 100644
index ee028c7..0000000
--- a/third_party/libjingle/source/talk/base/linux.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * libjingle
- * Copyright 2008, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_LINUX_H_
-#define TALK_BASE_LINUX_H_
-
-#if defined(LINUX) || defined(ANDROID)
-#include <string>
-#include <map>
-#include <vector>
-
-#include "talk/base/scoped_ptr.h"
-#include "talk/base/stream.h"
-
-namespace talk_base {
-
-//////////////////////////////////////////////////////////////////////////////
-// ConfigParser parses a FileStream of an ".ini."-type format into a map.
-//////////////////////////////////////////////////////////////////////////////
-
-// Sample Usage:
-//   ConfigParser parser;
-//   ConfigParser::MapVector key_val_pairs;
-//   if (parser.Open(inifile) && parser.Parse(&key_val_pairs)) {
-//     for (int section_num=0; i < key_val_pairs.size(); ++section_num) {
-//       std::string val1 = key_val_pairs[section_num][key1];
-//       std::string val2 = key_val_pairs[section_num][key2];
-//       // Do something with valn;
-//     }
-//   }
-
-class ConfigParser {
- public:
-  typedef std::map<std::string, std::string> SimpleMap;
-  typedef std::vector<SimpleMap> MapVector;
-
-  ConfigParser();
-  virtual ~ConfigParser();
-
-  virtual bool Open(const std::string& filename);
-  virtual void Attach(StreamInterface* stream);
-  virtual bool Parse(MapVector* key_val_pairs);
-  virtual bool ParseSection(SimpleMap* key_val_pair);
-  virtual bool ParseLine(std::string* key, std::string* value);
-
- private:
-  scoped_ptr<StreamInterface> instream_;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-// ProcCpuInfo reads CPU info from the /proc subsystem on any *NIX platform.
-//////////////////////////////////////////////////////////////////////////////
-
-// Sample Usage:
-//   ProcCpuInfo proc_info;
-//   int no_of_cpu;
-//   if (proc_info.LoadFromSystem()) {
-//      std::string out_str;
-//      proc_info.GetNumCpus(&no_of_cpu);
-//      proc_info.GetCpuStringValue(0, "vendor_id", &out_str);
-//      }
-//   }
-
-class ProcCpuInfo {
- public:
-  ProcCpuInfo();
-  virtual ~ProcCpuInfo();
-
-  // Reads the proc subsystem's cpu info into memory. If this fails, this
-  // returns false; if it succeeds, it returns true.
-  virtual bool LoadFromSystem();
-
-  // Obtains the number of logical CPU threads and places the value num.
-  virtual bool GetNumCpus(int* num);
-
-  // Obtains the number of physical CPU cores and places the value num.
-  virtual bool GetNumPhysicalCpus(int* num);
-
-  // Obtains the CPU family id.
-  virtual bool GetCpuFamily(int* id);
-
-  // Obtains the number of sections in /proc/cpuinfo, which may be greater
-  // than the number of CPUs (e.g. on ARM)
-  virtual bool GetSectionCount(size_t* count);
-
-  // Looks for the CPU proc item with the given name for the given section
-  // number and places the string value in result.
-  virtual bool GetSectionStringValue(size_t section_num, const std::string& key,
-                                     std::string* result);
-
-  // Looks for the CPU proc item with the given name for the given section
-  // number and places the int value in result.
-  virtual bool GetSectionIntValue(size_t section_num, const std::string& key,
-                                  int* result);
-
- private:
-  ConfigParser::MapVector sections_;
-};
-
-// Builds a string containing the info from lsb_release on a single line.
-std::string ReadLinuxLsbRelease();
-
-// Returns the output of "uname".
-std::string ReadLinuxUname();
-
-// Returns the content (int) of
-// /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq
-// Returns -1 on error.
-int ReadCpuMaxFreq();
-
-}  // namespace talk_base
-
-#endif  // defined(LINUX) || defined(ANDROID)
-#endif  // TALK_BASE_LINUX_H_
diff --git a/third_party/libjingle/source/talk/base/logging.cc b/third_party/libjingle/source/talk/base/logging.cc
deleted file mode 100644
index f094042..0000000
--- a/third_party/libjingle/source/talk/base/logging.cc
+++ /dev/null
@@ -1,612 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifdef WIN32
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#define snprintf _snprintf
-#undef ERROR  // wingdi.h
-#endif
-
-#ifdef OSX
-#include <CoreServices/CoreServices.h>
-#elif defined(ANDROID)
-#include <android/log.h>
-static const char kLibjingle[] = "libjingle";
-// Android has a 1024 limit on log inputs. We use 60 chars as an
-// approx for the header/tag portion.
-// See android/system/core/liblog/logd_write.c
-static const int kMaxLogLineSize = 1024 - 60;
-#endif  // OSX || ANDROID
-
-#include <iostream>
-#include <iomanip>
-#include <vector>
-
-#include "talk/base/logging.h"
-#include "talk/base/stream.h"
-#include "talk/base/stringencode.h"
-#include "talk/base/stringutils.h"
-#include "talk/base/timeutils.h"
-
-namespace talk_base {
-
-/////////////////////////////////////////////////////////////////////////////
-// Constant Labels
-/////////////////////////////////////////////////////////////////////////////
-
-const char * FindLabel(int value, const ConstantLabel entries[]) {
-  for (int i = 0; entries[i].label; ++i) {
-    if (value == entries[i].value) {
-      return entries[i].label;
-    }
-  }
-  return 0;
-}
-
-std::string ErrorName(int err, const ConstantLabel * err_table) {
-  if (err == 0)
-    return "No error";
-
-  if (err_table != 0) {
-    if (const char * value = FindLabel(err, err_table))
-      return value;
-  }
-
-  char buffer[16];
-  snprintf(buffer, sizeof(buffer), "0x%08x", err);
-  return buffer;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-// LogMessage
-/////////////////////////////////////////////////////////////////////////////
-
-const int LogMessage::NO_LOGGING = LS_ERROR + 1;
-
-#if _DEBUG
-static const int LOG_DEFAULT = LS_INFO;
-#else  // !_DEBUG
-static const int LOG_DEFAULT = LogMessage::NO_LOGGING;
-#endif  // !_DEBUG
-
-// Global lock for log subsystem, only needed to serialize access to streams_.
-CriticalSection LogMessage::crit_;
-
-// By default, release builds don't log, debug builds at info level
-int LogMessage::min_sev_ = LOG_DEFAULT;
-int LogMessage::dbg_sev_ = LOG_DEFAULT;
-
-// Don't bother printing context for the ubiquitous INFO log messages
-int LogMessage::ctx_sev_ = LS_WARNING;
-
-// The list of logging streams currently configured.
-// Note: we explicitly do not clean this up, because of the uncertain ordering
-// of destructors at program exit.  Let the person who sets the stream trigger
-// cleanup by setting to NULL, or let it leak (safe at program exit).
-LogMessage::StreamList LogMessage::streams_;
-
-// Boolean options default to false (0)
-bool LogMessage::thread_, LogMessage::timestamp_;
-
-// Program start time
-uint32 LogMessage::start_ = StartTime();
-
-// If we're in diagnostic mode, we'll be explicitly set that way; default=false.
-bool LogMessage::is_diagnostic_mode_ = false;
-
-LogMessage::LogMessage(const char* file, int line, LoggingSeverity sev,
-                       LogErrorContext err_ctx, int err, const char* module)
-    : severity_(sev) {
-  // Android's logging facility keeps track of timestamp and thread.
-#ifndef ANDROID
-  if (timestamp_) {
-    uint32 time = TimeSince(start_);
-    print_stream_ << "[" << std::setfill('0') << std::setw(3) << (time / 1000)
-                  << ":" << std::setw(3) << (time % 1000) << std::setfill(' ')
-                  << "] ";
-  }
-
-  if (thread_) {
-#ifdef WIN32
-    DWORD id = GetCurrentThreadId();
-    print_stream_ << "[" << std::hex << id << std::dec << "] ";
-#endif  // WIN32
-  }
-#endif  // !ANDROID
-
-  if (severity_ >= ctx_sev_) {
-    print_stream_ << Describe(sev) << "(" << DescribeFile(file)
-                  << ":" << line << "): ";
-  }
-
-  if (err_ctx != ERRCTX_NONE) {
-    std::ostringstream tmp;
-    tmp << "[0x" << std::setfill('0') << std::hex << std::setw(8) << err << "]";
-    switch (err_ctx) {
-      case ERRCTX_ERRNO:
-        tmp << " " << strerror(err);
-        break;
-#if WIN32
-      case ERRCTX_HRESULT: {
-        char msgbuf[256];
-        DWORD flags = FORMAT_MESSAGE_FROM_SYSTEM;
-        HMODULE hmod = GetModuleHandleA(module);
-        if (hmod)
-          flags |= FORMAT_MESSAGE_FROM_HMODULE;
-        if (DWORD len = FormatMessageA(
-            flags, hmod, err,
-            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
-            msgbuf, sizeof(msgbuf) / sizeof(msgbuf[0]), NULL)) {
-          while ((len > 0) &&
-              isspace(static_cast<unsigned char>(msgbuf[len-1]))) {
-            msgbuf[--len] = 0;
-          }
-          tmp << " " << msgbuf;
-        }
-        break;
-      }
-#endif  // WIN32
-#if OSX
-      case ERRCTX_OSSTATUS: {
-        tmp << " " << nonnull(GetMacOSStatusErrorString(err), "Unknown error");
-        if (const char* desc = GetMacOSStatusCommentString(err)) {
-          tmp << ": " << desc;
-        }
-        break;
-      }
-#endif  // OSX
-      default:
-        break;
-    }
-    extra_ = tmp.str();
-  }
-}
-
-LogMessage::~LogMessage() {
-  if (!extra_.empty())
-    print_stream_ << " : " << extra_;
-  print_stream_ << std::endl;
-
-  const std::string& str = print_stream_.str();
-  if (severity_ >= dbg_sev_) {
-    OutputToDebug(str, severity_);
-  }
-
-  // Must lock streams_ before accessing
-  CritScope cs(&crit_);
-  for (StreamList::iterator it = streams_.begin(); it != streams_.end(); ++it) {
-    if (severity_ >= it->second) {
-      OutputToStream(it->first, str);
-    }
-  }
-}
-
-void LogMessage::LogContext(int min_sev) {
-  ctx_sev_ = min_sev;
-}
-
-void LogMessage::LogThreads(bool on) {
-  thread_ = on;
-}
-
-void LogMessage::LogTimestamps(bool on) {
-  timestamp_ = on;
-}
-
-void LogMessage::ResetTimestamps() {
-  start_ = Time();
-}
-
-void LogMessage::LogToDebug(int min_sev) {
-  dbg_sev_ = min_sev;
-  UpdateMinLogSeverity();
-}
-
-void LogMessage::LogToStream(StreamInterface* stream, int min_sev) {
-  CritScope cs(&crit_);
-  // Discard and delete all previously installed streams
-  for (StreamList::iterator it = streams_.begin(); it != streams_.end(); ++it) {
-    delete it->first;
-  }
-  streams_.clear();
-  // Install the new stream, if specified
-  if (stream) {
-    AddLogToStream(stream, min_sev);
-  }
-}
-
-int LogMessage::GetLogToStream(StreamInterface* stream) {
-  CritScope cs(&crit_);
-  int sev = NO_LOGGING;
-  for (StreamList::iterator it = streams_.begin(); it != streams_.end(); ++it) {
-    if (!stream || stream == it->first) {
-      sev = _min(sev, it->second);
-    }
-  }
-  return sev;
-}
-
-void LogMessage::AddLogToStream(StreamInterface* stream, int min_sev) {
-  CritScope cs(&crit_);
-  streams_.push_back(std::make_pair(stream, min_sev));
-  UpdateMinLogSeverity();
-}
-
-void LogMessage::RemoveLogToStream(StreamInterface* stream) {
-  CritScope cs(&crit_);
-  for (StreamList::iterator it = streams_.begin(); it != streams_.end(); ++it) {
-    if (stream == it->first) {
-      streams_.erase(it);
-      break;
-    }
-  }
-  UpdateMinLogSeverity();
-}
-
-void LogMessage::ConfigureLogging(const char* params, const char* filename) {
-  int current_level = LS_VERBOSE;
-  int debug_level = GetLogToDebug();
-  int file_level = GetLogToStream();
-
-  std::vector<std::string> tokens;
-  tokenize(params, ' ', &tokens);
-
-  for (size_t i = 0; i < tokens.size(); ++i) {
-    if (tokens[i].empty())
-      continue;
-
-    // Logging features
-    if (tokens[i] == "tstamp") {
-      LogTimestamps();
-    } else if (tokens[i] == "thread") {
-      LogThreads();
-
-    // Logging levels
-    } else if (tokens[i] == "sensitive") {
-      current_level = LS_SENSITIVE;
-    } else if (tokens[i] == "verbose") {
-      current_level = LS_VERBOSE;
-    } else if (tokens[i] == "info") {
-      current_level = LS_INFO;
-    } else if (tokens[i] == "warning") {
-      current_level = LS_WARNING;
-    } else if (tokens[i] == "error") {
-      current_level = LS_ERROR;
-    } else if (tokens[i] == "none") {
-      current_level = NO_LOGGING;
-
-    // Logging targets
-    } else if (tokens[i] == "file") {
-      file_level = current_level;
-    } else if (tokens[i] == "debug") {
-      debug_level = current_level;
-    }
-  }
-
-#ifdef WIN32
-  if ((NO_LOGGING != debug_level) && !::IsDebuggerPresent()) {
-    // First, attempt to attach to our parent's console... so if you invoke
-    // from the command line, we'll see the output there.  Otherwise, create
-    // our own console window.
-    // Note: These methods fail if a console already exists, which is fine.
-    bool success = false;
-    typedef BOOL (WINAPI* PFN_AttachConsole)(DWORD);
-    if (HINSTANCE kernel32 = ::LoadLibrary(L"kernel32.dll")) {
-      // AttachConsole is defined on WinXP+.
-      if (PFN_AttachConsole attach_console = reinterpret_cast<PFN_AttachConsole>
-            (::GetProcAddress(kernel32, "AttachConsole"))) {
-        success = (FALSE != attach_console(ATTACH_PARENT_PROCESS));
-      }
-      ::FreeLibrary(kernel32);
-    }
-    if (!success) {
-      ::AllocConsole();
-    }
-  }
-#endif  // WIN32
-
-  scoped_ptr<FileStream> stream;
-  if (NO_LOGGING != file_level) {
-    stream.reset(new FileStream);
-    if (!stream->Open(filename, "wb", NULL) || !stream->DisableBuffering()) {
-      stream.reset();
-    }
-  }
-
-  LogToDebug(debug_level);
-  LogToStream(stream.release(), file_level);
-}
-
-int LogMessage::ParseLogSeverity(const std::string& value) {
-  int level = NO_LOGGING;
-  if (value == "LS_SENSITIVE") {
-    level = LS_SENSITIVE;
-  } else if (value == "LS_VERBOSE") {
-    level = LS_VERBOSE;
-  } else if (value == "LS_INFO") {
-    level = LS_INFO;
-  } else if (value == "LS_WARNING") {
-    level = LS_WARNING;
-  } else if (value == "LS_ERROR") {
-    level = LS_ERROR;
-  } else if (isdigit(value[0])) {
-    level = atoi(value.c_str());  // NOLINT
-  }
-  return level;
-}
-
-void LogMessage::UpdateMinLogSeverity() {
-  int min_sev = dbg_sev_;
-  for (StreamList::iterator it = streams_.begin(); it != streams_.end(); ++it) {
-    min_sev = _min(dbg_sev_, it->second);
-  }
-  min_sev_ = min_sev;
-}
-
-const char* LogMessage::Describe(LoggingSeverity sev) {
-  switch (sev) {
-  case LS_SENSITIVE: return "Sensitive";
-  case LS_VERBOSE:   return "Verbose";
-  case LS_INFO:      return "Info";
-  case LS_WARNING:   return "Warning";
-  case LS_ERROR:     return "Error";
-  default:           return "<unknown>";
-  }
-}
-
-const char* LogMessage::DescribeFile(const char* file) {
-  const char* end1 = ::strrchr(file, '/');
-  const char* end2 = ::strrchr(file, '\\');
-  if (!end1 && !end2)
-    return file;
-  else
-    return (end1 > end2) ? end1 + 1 : end2 + 1;
-}
-
-void LogMessage::OutputToDebug(const std::string& str,
-                               LoggingSeverity severity) {
-  bool log_to_stderr = true;
-#if defined(OSX) && (!defined(DEBUG) || defined(NDEBUG))
-  // On the Mac, all stderr output goes to the Console log and causes clutter.
-  // So in opt builds, don't log to stderr unless the user specifically sets
-  // a preference to do so.
-  CFStringRef key = CFStringCreateWithCString(kCFAllocatorDefault,
-                                              "logToStdErr",
-                                              kCFStringEncodingUTF8);
-  CFStringRef domain = CFBundleGetIdentifier(CFBundleGetMainBundle());
-  if (key != NULL && domain != NULL) {
-    Boolean exists_and_is_valid;
-    Boolean should_log =
-        CFPreferencesGetAppBooleanValue(key, domain, &exists_and_is_valid);
-    // If the key doesn't exist or is invalid or is false, we will not log to
-    // stderr.
-    log_to_stderr = exists_and_is_valid && should_log;
-  }
-  if (key != NULL) {
-    CFRelease(key);
-  }
-#endif
-#ifdef WIN32
-  // Always log to the debugger.
-  // Perhaps stderr should be controlled by a preference, as on Mac?
-  OutputDebugStringA(str.c_str());
-  if (log_to_stderr) {
-    // This handles dynamically allocated consoles, too.
-    if (HANDLE error_handle = ::GetStdHandle(STD_ERROR_HANDLE)) {
-      log_to_stderr = false;
-      unsigned long written;  // NOLINT
-      ::WriteFile(error_handle, str.data(), str.size(), &written, 0);
-    }
-  }
-#endif  // WIN32
-#ifdef ANDROID
-  // Android's logging facility uses severity to log messages but we
-  // need to map libjingle's severity levels to Android ones first.
-  // Also write to stderr which maybe available to executable started
-  // from the shell.
-  int prio;
-  switch (severity) {
-    case LS_SENSITIVE:
-      __android_log_write(ANDROID_LOG_INFO, kLibjingle, "SENSITIVE");
-      if (log_to_stderr) {
-        std::cerr << "SENSITIVE";
-        std::cerr.flush();
-      }
-      return;
-    case LS_VERBOSE:
-      prio = ANDROID_LOG_VERBOSE;
-      break;
-    case LS_INFO:
-      prio = ANDROID_LOG_INFO;
-      break;
-    case LS_WARNING:
-      prio = ANDROID_LOG_WARN;
-      break;
-    case LS_ERROR:
-      prio = ANDROID_LOG_ERROR;
-      break;
-    default:
-      prio = ANDROID_LOG_UNKNOWN;
-  }
-
-  int size = str.size();
-  int line = 0;
-  int idx = 0;
-  const int max_lines = size / kMaxLogLineSize + 1;
-  if (max_lines == 1) {
-    __android_log_print(prio, kLibjingle, "%.*s", size, str.c_str());
-  } else {
-    while (size > 0) {
-      const int len = std::min(size, kMaxLogLineSize);
-      // Use the size of the string in the format (str may have \0 in the
-      // middle).
-      __android_log_print(prio, kLibjingle, "[%d/%d] %.*s",
-                          line + 1, max_lines,
-                          len, str.c_str() + idx);
-      idx += len;
-      size -= len;
-      ++line;
-    }
-  }
-#endif  // ANDROID
-  if (log_to_stderr) {
-    std::cerr << str;
-    std::cerr.flush();
-  }
-}
-
-void LogMessage::OutputToStream(StreamInterface* stream,
-                                const std::string& str) {
-  // If write isn't fully successful, what are we going to do, log it? :)
-  stream->WriteAll(str.data(), str.size(), NULL, NULL);
-}
-
-//////////////////////////////////////////////////////////////////////
-// Logging Helpers
-//////////////////////////////////////////////////////////////////////
-
-void LogMultiline(LoggingSeverity level, const char* label, bool input,
-                  const void* data, size_t len, bool hex_mode,
-                  LogMultilineState* state) {
-  if (!LOG_CHECK_LEVEL_V(level))
-    return;
-
-  const char * direction = (input ? " << " : " >> ");
-
-  // NULL data means to flush our count of unprintable characters.
-  if (!data) {
-    if (state && state->unprintable_count_[input]) {
-      LOG_V(level) << label << direction << "## "
-                   << state->unprintable_count_[input]
-                   << " consecutive unprintable ##";
-      state->unprintable_count_[input] = 0;
-    }
-    return;
-  }
-
-  // The ctype classification functions want unsigned chars.
-  const unsigned char* udata = static_cast<const unsigned char*>(data);
-
-  if (hex_mode) {
-    const size_t LINE_SIZE = 24;
-    char hex_line[LINE_SIZE * 9 / 4 + 2], asc_line[LINE_SIZE + 1];
-    while (len > 0) {
-      memset(asc_line, ' ', sizeof(asc_line));
-      memset(hex_line, ' ', sizeof(hex_line));
-      size_t line_len = _min(len, LINE_SIZE);
-      for (size_t i = 0; i < line_len; ++i) {
-        unsigned char ch = udata[i];
-        asc_line[i] = isprint(ch) ? ch : '.';
-        hex_line[i*2 + i/4] = hex_encode(ch >> 4);
-        hex_line[i*2 + i/4 + 1] = hex_encode(ch & 0xf);
-      }
-      asc_line[sizeof(asc_line)-1] = 0;
-      hex_line[sizeof(hex_line)-1] = 0;
-      LOG_V(level) << label << direction
-                   << asc_line << " " << hex_line << " ";
-      udata += line_len;
-      len -= line_len;
-    }
-    return;
-  }
-
-  size_t consecutive_unprintable = state ? state->unprintable_count_[input] : 0;
-
-  const unsigned char* end = udata + len;
-  while (udata < end) {
-    const unsigned char* line = udata;
-    const unsigned char* end_of_line = strchrn<unsigned char>(udata,
-                                                              end - udata,
-                                                              '\n');
-    if (!end_of_line) {
-      udata = end_of_line = end;
-    } else {
-      udata = end_of_line + 1;
-    }
-
-    bool is_printable = true;
-
-    // If we are in unprintable mode, we need to see a line of at least
-    // kMinPrintableLine characters before we'll switch back.
-    const ptrdiff_t kMinPrintableLine = 4;
-    if (consecutive_unprintable && ((end_of_line - line) < kMinPrintableLine)) {
-      is_printable = false;
-    } else {
-      // Determine if the line contains only whitespace and printable
-      // characters.
-      bool is_entirely_whitespace = true;
-      for (const unsigned char* pos = line; pos < end_of_line; ++pos) {
-        if (isspace(*pos))
-          continue;
-        is_entirely_whitespace = false;
-        if (!isprint(*pos)) {
-          is_printable = false;
-          break;
-        }
-      }
-      // Treat an empty line following unprintable data as unprintable.
-      if (consecutive_unprintable && is_entirely_whitespace) {
-        is_printable = false;
-      }
-    }
-    if (!is_printable) {
-      consecutive_unprintable += (udata - line);
-      continue;
-    }
-    // Print out the current line, but prefix with a count of prior unprintable
-    // characters.
-    if (consecutive_unprintable) {
-      LOG_V(level) << label << direction << "## " << consecutive_unprintable
-                  << " consecutive unprintable ##";
-      consecutive_unprintable = 0;
-    }
-    // Strip off trailing whitespace.
-    while ((end_of_line > line) && isspace(*(end_of_line-1))) {
-      --end_of_line;
-    }
-    // Filter out any private data
-    std::string substr(reinterpret_cast<const char*>(line), end_of_line - line);
-    std::string::size_type pos_private = substr.find("Email");
-    if (pos_private == std::string::npos) {
-      pos_private = substr.find("Passwd");
-    }
-    if (pos_private == std::string::npos) {
-      LOG_V(level) << label << direction << substr;
-    } else {
-      LOG_V(level) << label << direction << "## omitted for privacy ##";
-    }
-  }
-
-  if (state) {
-    state->unprintable_count_[input] = consecutive_unprintable;
-  }
-}
-
-//////////////////////////////////////////////////////////////////////
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/logging.h b/third_party/libjingle/source/talk/base/logging.h
deleted file mode 100644
index ac69b7b..0000000
--- a/third_party/libjingle/source/talk/base/logging.h
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-//   LOG(...) an ostream target that can be used to send formatted
-// output to a variety of logging targets, such as debugger console, stderr,
-// file, or any StreamInterface.
-//   The severity level passed as the first argument to the LOGging
-// functions is used as a filter, to limit the verbosity of the logging.
-//   Static members of LogMessage documented below are used to control the
-// verbosity and target of the output.
-//   There are several variations on the LOG macro which facilitate logging
-// of common error conditions, detailed below.
-
-// LOG(sev) logs the given stream at severity "sev", which must be a
-//     compile-time constant of the LoggingSeverity type, without the namespace
-//     prefix.
-// LOG_V(sev) Like LOG(), but sev is a run-time variable of the LoggingSeverity
-//     type (basically, it just doesn't prepend the namespace).
-// LOG_F(sev) Like LOG(), but includes the name of the current function.
-// LOG_GLE(M)(sev [, mod]) attempt to add a string description of the
-//     HRESULT returned by GetLastError.  The "M" variant allows searching of a
-//     DLL's string table for the error description.
-// LOG_ERRNO(sev) attempts to add a string description of an errno-derived
-//     error. errno and associated facilities exist on both Windows and POSIX,
-//     but on Windows they only apply to the C/C++ runtime.
-// LOG_ERR(sev) is an alias for the platform's normal error system, i.e. _GLE on
-//     Windows and _ERRNO on POSIX.
-// (The above three also all have _EX versions that let you specify the error
-// code, rather than using the last one.)
-// LOG_E(sev, ctx, err, ...) logs a detailed error interpreted using the
-//     specified context.
-// LOG_CHECK_LEVEL(sev) (and LOG_CHECK_LEVEL_V(sev)) can be used as a test
-//     before performing expensive or sensitive operations whose sole purpose is
-//     to output logging data at the desired level.
-// Lastly, PLOG(sev, err) is an alias for LOG_ERR_EX.
-
-#ifndef TALK_BASE_LOGGING_H_
-#define TALK_BASE_LOGGING_H_
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"  // NOLINT
-#endif
-
-#include <list>
-#include <sstream>
-#include <string>
-#include <utility>
-#include "talk/base/basictypes.h"
-#include "talk/base/criticalsection.h"
-
-namespace talk_base {
-
-class StreamInterface;
-
-///////////////////////////////////////////////////////////////////////////////
-// ConstantLabel can be used to easily generate string names from constant
-// values.  This can be useful for logging descriptive names of error messages.
-// Usage:
-//   const ConstantLabel LIBRARY_ERRORS[] = {
-//     KLABEL(SOME_ERROR),
-//     KLABEL(SOME_OTHER_ERROR),
-//     ...
-//     LASTLABEL
-//   }
-//
-//   int err = LibraryFunc();
-//   LOG(LS_ERROR) << "LibraryFunc returned: "
-//                 << ErrorName(err, LIBRARY_ERRORS);
-
-struct ConstantLabel { int value; const char * label; };
-#define KLABEL(x) { x, #x }
-#define TLABEL(x, y) { x, y }
-#define LASTLABEL { 0, 0 }
-
-const char * FindLabel(int value, const ConstantLabel entries[]);
-std::string ErrorName(int err, const ConstantLabel* err_table);
-
-//////////////////////////////////////////////////////////////////////
-
-// Note that the non-standard LoggingSeverity aliases exist because they are
-// still in broad use.  The meanings of the levels are:
-//  LS_SENSITIVE: Information which should only be logged with the consent
-//   of the user, due to privacy concerns.
-//  LS_VERBOSE: This level is for data which we do not want to appear in the
-//   normal debug log, but should appear in diagnostic logs.
-//  LS_INFO: Chatty level used in debugging for all sorts of things, the default
-//   in debug builds.
-//  LS_WARNING: Something that may warrant investigation.
-//  LS_ERROR: Something that should not have occurred.
-enum LoggingSeverity { LS_SENSITIVE, LS_VERBOSE, LS_INFO, LS_WARNING, LS_ERROR,
-                       INFO = LS_INFO,
-                       WARNING = LS_WARNING,
-                       LERROR = LS_ERROR };
-
-// LogErrorContext assists in interpreting the meaning of an error value.
-enum LogErrorContext {
-  ERRCTX_NONE,
-  ERRCTX_ERRNO,     // System-local errno
-  ERRCTX_HRESULT,   // Windows HRESULT
-  ERRCTX_OSSTATUS,  // MacOS OSStatus
-
-  // Abbreviations for LOG_E macro
-  ERRCTX_EN = ERRCTX_ERRNO,     // LOG_E(sev, EN, x)
-  ERRCTX_HR = ERRCTX_HRESULT,   // LOG_E(sev, HR, x)
-  ERRCTX_OS = ERRCTX_OSSTATUS,  // LOG_E(sev, OS, x)
-};
-
-class LogMessage {
- public:
-  static const int NO_LOGGING;
-
-  LogMessage(const char* file, int line, LoggingSeverity sev,
-             LogErrorContext err_ctx = ERRCTX_NONE, int err = 0,
-             const char* module = NULL);
-  ~LogMessage();
-
-  static inline bool Loggable(LoggingSeverity sev) { return (sev >= min_sev_); }
-  std::ostream& stream() { return print_stream_; }
-
-  // These are attributes which apply to all logging channels
-  //  LogContext: Display the file and line number of the message
-  static void LogContext(int min_sev);
-  //  LogThreads: Display the thread identifier of the current thread
-  static void LogThreads(bool on = true);
-  //  LogTimestamps: Display the elapsed time of the program
-  static void LogTimestamps(bool on = true);
-
-  // Timestamps begin with program execution, but can be reset with this
-  // function for measuring the duration of an activity, or to synchronize
-  // timestamps between multiple instances.
-  static void ResetTimestamps();
-
-  // These are the available logging channels
-  //  Debug: Debug console on Windows, otherwise stderr
-  static void LogToDebug(int min_sev);
-  static int GetLogToDebug() { return dbg_sev_; }
-
-  //  Stream: Any non-blocking stream interface.  LogMessage takes ownership of
-  //   the stream. Multiple streams may be specified by using AddLogToStream.
-  //   LogToStream is retained for backwards compatibility; when invoked, it
-  //   will discard any previously set streams and install the specified stream.
-  //   GetLogToStream gets the severity for the specified stream, of if none
-  //   is specified, the minimum stream severity.
-  //   RemoveLogToStream removes the specified stream, without destroying it.
-  static void LogToStream(StreamInterface* stream, int min_sev);
-  static int GetLogToStream(StreamInterface* stream = NULL);
-  static void AddLogToStream(StreamInterface* stream, int min_sev);
-  static void RemoveLogToStream(StreamInterface* stream);
-
-  // Testing against MinLogSeverity allows code to avoid potentially expensive
-  // logging operations by pre-checking the logging level.
-  static int GetMinLogSeverity() { return min_sev_; }
-
-  static void SetDiagnosticMode(bool f) { is_diagnostic_mode_ = f; }
-  static bool IsDiagnosticMode() { return is_diagnostic_mode_; }
-
-  // Parses the provided parameter stream to configure the options above.
-  // Useful for configuring logging from the command line.  If file logging
-  // is enabled, it is output to the specified filename.
-  static void ConfigureLogging(const char* params, const char* filename);
-
-  // Convert the string to a LS_ value; also accept numeric values.
-  static int ParseLogSeverity(const std::string& value);
-
- private:
-  typedef std::list<std::pair<StreamInterface*, int> > StreamList;
-
-  // Updates min_sev_ appropriately when debug sinks change.
-  static void UpdateMinLogSeverity();
-
-  // These assist in formatting some parts of the debug output.
-  static const char* Describe(LoggingSeverity sev);
-  static const char* DescribeFile(const char* file);
-
-  // These write out the actual log messages.
-  static void OutputToDebug(const std::string& msg, LoggingSeverity severity_);
-  static void OutputToStream(StreamInterface* stream, const std::string& msg);
-
-  // The ostream that buffers the formatted message before output
-  std::ostringstream print_stream_;
-
-  // The severity level of this message
-  LoggingSeverity severity_;
-
-  // String data generated in the constructor, that should be appended to
-  // the message before output.
-  std::string extra_;
-
-  // Global lock for the logging subsystem
-  static CriticalSection crit_;
-
-  // dbg_sev_ is the thresholds for those output targets
-  // min_sev_ is the minimum (most verbose) of those levels, and is used
-  //  as a short-circuit in the logging macros to identify messages that won't
-  //  be logged.
-  // ctx_sev_ is the minimum level at which file context is displayed
-  static int min_sev_, dbg_sev_, ctx_sev_;
-
-  // The output streams and their associated severities
-  static StreamList streams_;
-
-  // Flags for formatting options
-  static bool thread_, timestamp_;
-
-  // The timestamp at which logging started.
-  static uint32 start_;
-
-  // are we in diagnostic mode (as defined by the app)?
-  static bool is_diagnostic_mode_;
-
-  DISALLOW_EVIL_CONSTRUCTORS(LogMessage);
-};
-
-//////////////////////////////////////////////////////////////////////
-// Logging Helpers
-//////////////////////////////////////////////////////////////////////
-
-class LogMultilineState {
- public:
-  size_t unprintable_count_[2];
-  LogMultilineState() {
-    unprintable_count_[0] = unprintable_count_[1] = 0;
-  }
-};
-
-// When possible, pass optional state variable to track various data across
-// multiple calls to LogMultiline.  Otherwise, pass NULL.
-void LogMultiline(LoggingSeverity level, const char* label, bool input,
-                  const void* data, size_t len, bool hex_mode,
-                  LogMultilineState* state);
-
-//////////////////////////////////////////////////////////////////////
-// Macros which automatically disable logging when LOGGING == 0
-//////////////////////////////////////////////////////////////////////
-
-// If LOGGING is not explicitly defined, default to enabled in debug mode
-#if !defined(LOGGING)
-#if defined(_DEBUG) && !defined(NDEBUG)
-#define LOGGING 1
-#else
-#define LOGGING 0
-#endif
-#endif  // !defined(LOGGING)
-
-#ifndef LOG
-#if LOGGING
-
-// The following non-obvious technique for implementation of a
-// conditional log stream was stolen from google3/base/logging.h.
-
-// This class is used to explicitly ignore values in the conditional
-// logging macros.  This avoids compiler warnings like "value computed
-// is not used" and "statement has no effect".
-
-class LogMessageVoidify {
- public:
-  LogMessageVoidify() { }
-  // This has to be an operator with a precedence lower than << but
-  // higher than ?:
-  void operator&(std::ostream&) { }
-};
-
-#define LOG_SEVERITY_PRECONDITION(sev) \
-  !(talk_base::LogMessage::Loggable(sev)) \
-    ? (void) 0 \
-    : talk_base::LogMessageVoidify() &
-
-#define LOG(sev) \
-  LOG_SEVERITY_PRECONDITION(talk_base::sev) \
-    talk_base::LogMessage(__FILE__, __LINE__, talk_base::sev).stream()
-
-// The _V version is for when a variable is passed in.  It doesn't do the
-// namespace concatination.
-#define LOG_V(sev) \
-  LOG_SEVERITY_PRECONDITION(sev) \
-    talk_base::LogMessage(__FILE__, __LINE__, sev).stream()
-
-// The _F version prefixes the message with the current function name.
-#if defined(__GNUC__) && defined(_DEBUG)
-#define LOG_F(sev) LOG(sev) << __PRETTY_FUNCTION__ << ": "
-#else
-#define LOG_F(sev) LOG(sev) << __FUNCTION__ << ": "
-#endif
-
-#define LOG_CHECK_LEVEL(sev) \
-  talk_base::LogCheckLevel(talk_base::sev)
-#define LOG_CHECK_LEVEL_V(sev) \
-  talk_base::LogCheckLevel(sev)
-inline bool LogCheckLevel(LoggingSeverity sev) {
-  return (LogMessage::GetMinLogSeverity() <= sev);
-}
-
-#define LOG_E(sev, ctx, err, ...) \
-  LOG_SEVERITY_PRECONDITION(talk_base::sev) \
-    talk_base::LogMessage(__FILE__, __LINE__, talk_base::sev, \
-                          talk_base::ERRCTX_ ## ctx, err , ##__VA_ARGS__) \
-        .stream()
-
-#else  // !LOGGING
-
-// Hopefully, the compiler will optimize away some of this code.
-// Note: syntax of "1 ? (void)0 : LogMessage" was causing errors in g++,
-//   converted to "while (false)"
-#define LOG(sev) \
-  while (false)talk_base:: LogMessage(NULL, 0, talk_base::sev).stream()
-#define LOG_V(sev) \
-  while (false) talk_base::LogMessage(NULL, 0, sev).stream()
-#define LOG_F(sev) LOG(sev) << __FUNCTION__ << ": "
-#define LOG_CHECK_LEVEL(sev) \
-  false
-#define LOG_CHECK_LEVEL_V(sev) \
-  false
-
-#define LOG_E(sev, ctx, err, ...) \
-  while (false) talk_base::LogMessage(__FILE__, __LINE__, talk_base::sev, \
-                          talk_base::ERRCTX_ ## ctx, err , ##__VA_ARGS__) \
-      .stream()
-
-#endif  // !LOGGING
-
-#define LOG_ERRNO_EX(sev, err) \
-  LOG_E(sev, ERRNO, err)
-#define LOG_ERRNO(sev) \
-  LOG_ERRNO_EX(sev, errno)
-
-#ifdef WIN32
-#define LOG_GLE_EX(sev, err) \
-  LOG_E(sev, HRESULT, err)
-#define LOG_GLE(sev) \
-  LOG_GLE_EX(sev, GetLastError())
-#define LOG_GLEM(sev, mod) \
-  LOG_E(sev, HRESULT, GetLastError(), mod)
-#define LOG_ERR_EX(sev, err) \
-  LOG_GLE_EX(sev, err)
-#define LOG_ERR(sev) \
-  LOG_GLE(sev)
-#define LAST_SYSTEM_ERROR \
-  (::GetLastError())
-#elif POSIX
-#define LOG_ERR_EX(sev, err) \
-  LOG_ERRNO_EX(sev, err)
-#define LOG_ERR(sev) \
-  LOG_ERRNO(sev)
-#define LAST_SYSTEM_ERROR \
-  (errno)
-#endif  // WIN32
-
-#define PLOG(sev, err) \
-  LOG_ERR_EX(sev, err)
-
-// TODO(?): Add an "assert" wrapper that logs in the same manner.
-
-#endif  // LOG
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_LOGGING_H_
diff --git a/third_party/libjingle/source/talk/base/logging_unittest.cc b/third_party/libjingle/source/talk/base/logging_unittest.cc
deleted file mode 100644
index 18de822..0000000
--- a/third_party/libjingle/source/talk/base/logging_unittest.cc
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/fileutils.h"
-#include "talk/base/gunit.h"
-#include "talk/base/logging.h"
-#include "talk/base/pathutils.h"
-#include "talk/base/stream.h"
-#include "talk/base/thread.h"
-
-namespace talk_base {
-
-// Test basic logging operation. We should get the INFO log but not the VERBOSE.
-// We should restore the correct global state at the end.
-TEST(LogTest, SingleStream) {
-  int sev = LogMessage::GetLogToStream(NULL);
-
-  std::string str;
-  StringStream stream(str);
-  LogMessage::AddLogToStream(&stream, LS_INFO);
-  EXPECT_EQ(LS_INFO, LogMessage::GetLogToStream(&stream));
-
-  LOG(LS_INFO) << "INFO";
-  LOG(LS_VERBOSE) << "VERBOSE";
-  EXPECT_NE(std::string::npos, str.find("INFO"));
-  EXPECT_EQ(std::string::npos, str.find("VERBOSE"));
-
-  LogMessage::RemoveLogToStream(&stream);
-  EXPECT_EQ(LogMessage::NO_LOGGING, LogMessage::GetLogToStream(&stream));
-
-  EXPECT_EQ(sev, LogMessage::GetLogToStream(NULL));
-}
-
-// Test using multiple log streams. The INFO stream should get the INFO message,
-// the VERBOSE stream should get the INFO and the VERBOSE.
-// We should restore the correct global state at the end.
-TEST(LogTest, MultipleStreams) {
-  int sev = LogMessage::GetLogToStream(NULL);
-
-  std::string str1, str2;
-  StringStream stream1(str1), stream2(str2);
-  LogMessage::AddLogToStream(&stream1, LS_INFO);
-  LogMessage::AddLogToStream(&stream2, LS_VERBOSE);
-  EXPECT_EQ(LS_INFO, LogMessage::GetLogToStream(&stream1));
-  EXPECT_EQ(LS_VERBOSE, LogMessage::GetLogToStream(&stream2));
-
-  LOG(LS_INFO) << "INFO";
-  LOG(LS_VERBOSE) << "VERBOSE";
-
-  EXPECT_NE(std::string::npos, str1.find("INFO"));
-  EXPECT_EQ(std::string::npos, str1.find("VERBOSE"));
-  EXPECT_NE(std::string::npos, str2.find("INFO"));
-  EXPECT_NE(std::string::npos, str2.find("VERBOSE"));
-
-  LogMessage::RemoveLogToStream(&stream2);
-  LogMessage::RemoveLogToStream(&stream1);
-  EXPECT_EQ(LogMessage::NO_LOGGING, LogMessage::GetLogToStream(&stream2));
-  EXPECT_EQ(LogMessage::NO_LOGGING, LogMessage::GetLogToStream(&stream1));
-
-  EXPECT_EQ(sev, LogMessage::GetLogToStream(NULL));
-}
-
-// Ensure we don't crash when adding/removing streams while threads are going.
-// We should restore the correct global state at the end.
-class LogThread : public Thread {
-  void Run() {
-    // LS_SENSITIVE to avoid cluttering up any real logging going on
-    LOG(LS_SENSITIVE) << "LOG";
-  }
-};
-
-TEST(LogTest, MultipleThreads) {
-  int sev = LogMessage::GetLogToStream(NULL);
-
-  LogThread thread1, thread2, thread3;
-  thread1.Start();
-  thread2.Start();
-  thread3.Start();
-
-  NullStream stream1, stream2, stream3;
-  for (int i = 0; i < 1000; ++i) {
-    LogMessage::AddLogToStream(&stream1, LS_INFO);
-    LogMessage::AddLogToStream(&stream2, LS_VERBOSE);
-    LogMessage::AddLogToStream(&stream3, LS_SENSITIVE);
-    LogMessage::RemoveLogToStream(&stream1);
-    LogMessage::RemoveLogToStream(&stream2);
-    LogMessage::RemoveLogToStream(&stream3);
-  }
-
-  EXPECT_EQ(sev, LogMessage::GetLogToStream(NULL));
-}
-
-// Test the time required to write 1000 80-character logs to an unbuffered file.
-TEST(LogTest, Perf) {
-  Pathname path;
-  EXPECT_TRUE(Filesystem::GetTemporaryFolder(path, true, NULL));
-  path.SetPathname(Filesystem::TempFilename(path, "ut"));
-
-  FileStream stream;
-  EXPECT_TRUE(stream.Open(path.pathname(), "wb", NULL));
-  stream.DisableBuffering();
-  LogMessage::AddLogToStream(&stream, LS_SENSITIVE);
-
-  uint32 start = Time(), finish;
-  std::string message('X', 80);
-  for (int i = 0; i < 1000; ++i) {
-    LOG(LS_SENSITIVE) << message;
-  }
-  finish = Time();
-
-  LogMessage::RemoveLogToStream(&stream);
-  stream.Close();
-  Filesystem::DeleteFile(path);
-
-  LOG(LS_INFO) << "Average log time: " << TimeDiff(finish, start) << " us";
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/macasyncsocket.cc b/third_party/libjingle/source/talk/base/macasyncsocket.cc
deleted file mode 100644
index 4924333..0000000
--- a/third_party/libjingle/source/talk/base/macasyncsocket.cc
+++ /dev/null
@@ -1,439 +0,0 @@
-// Copyright 2010 Google Inc. All Rights Reserved.
-
-//         thaloun@google.com (Tim Haloun)
-//
-// MacAsyncSocket is a kind of AsyncSocket. It does not support the SOCK_DGRAM
-// type (yet). It works asynchronously, which means that users of this socket
-// should connect to the various events declared in asyncsocket.h to receive
-// notifications about this socket.  It uses CFSockets for signals, but prefers
-// the basic bsd socket operations rather than their CFSocket wrappers when
-// possible.
-
-#include <CoreFoundation/CoreFoundation.h>
-#include <fcntl.h>
-
-#include "talk/base/macasyncsocket.h"
-
-#include "talk/base/logging.h"
-#include "talk/base/macsocketserver.h"
-
-namespace talk_base {
-
-static const int kCallbackFlags = kCFSocketReadCallBack |
-                                  kCFSocketConnectCallBack |
-                                  kCFSocketWriteCallBack;
-
-MacAsyncSocket::MacAsyncSocket(MacBaseSocketServer* ss)
-    : ss_(ss),
-      socket_(NULL),
-      native_socket_(INVALID_SOCKET),
-      source_(NULL),
-      current_callbacks_(0),
-      disabled_(false),
-      error_(0),
-      state_(CS_CLOSED) {
-  Initialize();
-}
-
-MacAsyncSocket::~MacAsyncSocket() {
-  Close();
-}
-
-// Returns the address to which the socket is bound.  If the socket is not
-// bound, then the any-address is returned.
-SocketAddress MacAsyncSocket::GetLocalAddress() const {
-  SocketAddress address;
-
-  // The CFSocket doesn't pick up on implicit binds from the connect call.
-  // Calling bind in before connect explicitly causes errors, so just query
-  // the underlying bsd socket.
-  sockaddr_in addr;
-  socklen_t addrlen = sizeof(addr);
-  int result = ::getsockname(native_socket_,
-                             reinterpret_cast<sockaddr*>(&addr), &addrlen);
-  if (result >= 0) {
-    ASSERT(addrlen == sizeof(addr));
-    address.FromSockAddr(addr);
-  }
-  return address;
-}
-
-// Returns the address to which the socket is connected.  If the socket is not
-// connected, then the any-address is returned.
-SocketAddress MacAsyncSocket::GetRemoteAddress() const {
-  SocketAddress address;
-
-  // Use native_socket for consistency with GetLocalAddress.
-  sockaddr_in addr;
-  socklen_t addrlen = sizeof(addr);
-  int result = ::getpeername(native_socket_,
-                             reinterpret_cast<sockaddr*>(&addr), &addrlen);
-  if (result >= 0) {
-    ASSERT(addrlen == sizeof(addr));
-    address.FromSockAddr(addr);
-  }
-  return address;
-}
-
-// Bind the socket to a local address.
-int MacAsyncSocket::Bind(const SocketAddress& address) {
-  sockaddr_in saddr;
-  address.ToSockAddr(&saddr);
-  int err = ::bind(native_socket_, reinterpret_cast<sockaddr*>(&saddr),
-                   sizeof(saddr));
-  if (err == SOCKET_ERROR) error_ = errno;
-  return err;
-}
-
-// Connect to a remote address.
-int MacAsyncSocket::Connect(const SocketAddress& address) {
-  if (!valid()) {
-    Initialize();
-    if (!valid())
-      return SOCKET_ERROR;
-  }
-
-  SocketAddress addr2(address);
-  if (addr2.IsUnresolved()) {
-    LOG(LS_VERBOSE) << "Resolving addr in MacAsyncSocket::Connect";
-    // TODO: Convert to using AsyncResolver
-    if (!addr2.ResolveIP(false, &error_)) {
-      return SOCKET_ERROR;
-    }
-  }
-
-  sockaddr_in saddr;
-  addr2.ToSockAddr(&saddr);
-  int result = ::connect(native_socket_, reinterpret_cast<sockaddr*>(&saddr),
-                         sizeof(saddr));
-
-  if (result != SOCKET_ERROR) {
-    state_ = CS_CONNECTED;
-  } else {
-    error_ = errno;
-    if (error_ == EINPROGRESS) {
-      state_ = CS_CONNECTING;
-      result = 0;
-    }
-  }
-  return result;
-}
-
-// Send to the remote end we're connected to.
-int MacAsyncSocket::Send(const void* pv, size_t cb) {
-  if (!valid()) {
-    return SOCKET_ERROR;
-  }
-
-  int sent = ::send(native_socket_, pv, cb, 0);
-
-  if (sent == SOCKET_ERROR) {
-    error_ = errno;
-
-    if (IsBlocking()) {
-      // Reenable the writable callback (once), since we are flow controlled.
-      LOG(LS_VERBOSE) << "Enabling flow control callback.";
-      CFSocketEnableCallBacks(socket_, kCallbackFlags);
-      current_callbacks_ = kCallbackFlags;
-    }
-  }
-  return sent;
-}
-
-// Send to the given address. We may or may not be connected to anyone.
-int MacAsyncSocket::SendTo(const void* pv, size_t cb,
-                           const SocketAddress& address) {
-  if (!valid()) {
-    return SOCKET_ERROR;
-  }
-
-  sockaddr_in saddr;
-  address.ToSockAddr(&saddr);
-  int sent = ::sendto(native_socket_, pv, cb, 0,
-                      reinterpret_cast<sockaddr*>(&saddr), sizeof(saddr));
-
-  if (sent == SOCKET_ERROR) {
-    error_ = errno;
-  }
-
-  return sent;
-}
-
-// Read data received from the remote end we're connected to.
-int MacAsyncSocket::Recv(void* pv, size_t cb) {
-  int received = ::recv(native_socket_, reinterpret_cast<char*>(pv), cb, 0);
-  if (received == SOCKET_ERROR) error_ = errno;
-
-  // Recv should only be called when there is data to read
-  ASSERT((received != 0) || (cb == 0));
-  return received;
-}
-
-// Read data received from any remote party
-int MacAsyncSocket::RecvFrom(void* pv, size_t cb, SocketAddress* paddr) {
-  sockaddr_in saddr;
-  socklen_t cbAddr = sizeof(saddr);
-  int received = ::recvfrom(native_socket_, reinterpret_cast<char*>(pv), cb, 0,
-                          reinterpret_cast<sockaddr*>(&saddr), &cbAddr);
-  if (received >= 0 && paddr != NULL) {
-    paddr->FromSockAddr(saddr);
-  } else if (received == SOCKET_ERROR) {
-    error_ = errno;
-  }
-  return received;
-}
-
-int MacAsyncSocket::Listen(int backlog) {
-  if (!valid()) {
-    return SOCKET_ERROR;
-  }
-
-  int res = ::listen(native_socket_, backlog);
-  if (res != SOCKET_ERROR)
-    state_ = CS_CONNECTING;
-  else
-    error_ = errno;
-
-  return res;
-}
-
-MacAsyncSocket* MacAsyncSocket::Accept(SocketAddress* paddr) {
-  sockaddr_in saddr;
-  socklen_t cbAddr = sizeof(saddr);
-
-  int socket_fd = ::accept(native_socket_, reinterpret_cast<sockaddr*>(&saddr),
-                           &cbAddr);
-  if (socket_fd == INVALID_SOCKET) {
-    error_ = errno;
-    return NULL;
-  }
-
-  MacAsyncSocket* s = new MacAsyncSocket(ss_, socket_fd);
-  if (s && s->valid()) {
-    s->state_ = CS_CONNECTED;
-    if (paddr)
-      paddr->FromSockAddr(saddr);
-  } else {
-    delete s;
-    s = NULL;
-  }
-  return s;
-}
-
-int MacAsyncSocket::Close() {
-  if (source_ != NULL) {
-    CFRunLoopSourceInvalidate(source_);
-    CFRelease(source_);
-    if (ss_) ss_->UnregisterSocket(this);
-    source_ = NULL;
-  }
-
-  if (socket_ != NULL) {
-    CFSocketInvalidate(socket_);
-    CFRelease(socket_);
-    socket_ = NULL;
-  }
-
-  native_socket_ = INVALID_SOCKET;  // invalidates the socket
-  error_ = 0;
-  state_ = CS_CLOSED;
-  return 0;
-}
-
-int MacAsyncSocket::EstimateMTU(uint16* mtu) {
-  ASSERT(false && "NYI");
-  return -1;
-}
-
-int MacAsyncSocket::GetError() const {
-  return error_;
-}
-
-void MacAsyncSocket::SetError(int error) {
-  error_ = error;
-}
-
-Socket::ConnState MacAsyncSocket::GetState() const {
-  return state_;
-}
-
-int MacAsyncSocket::GetOption(Option opt, int* value) {
-  ASSERT(false && "NYI");
-  return -1;
-}
-
-int MacAsyncSocket::SetOption(Option opt, int value) {
-  ASSERT(false && "NYI");
-  return -1;
-}
-
-void MacAsyncSocket::EnableCallbacks() {
-  if (valid()) {
-    disabled_ = false;
-    CFSocketEnableCallBacks(socket_, current_callbacks_);
-  }
-}
-
-void MacAsyncSocket::DisableCallbacks() {
-  if (valid()) {
-    disabled_ = true;
-    CFSocketDisableCallBacks(socket_, kCallbackFlags);
-  }
-}
-
-MacAsyncSocket::MacAsyncSocket(MacBaseSocketServer* ss, int native_socket)
-    : ss_(ss),
-      socket_(NULL),
-      native_socket_(native_socket),
-      source_(NULL),
-      current_callbacks_(0),
-      disabled_(false),
-      error_(0),
-      state_(CS_CLOSED) {
-  Initialize();
-}
-
-// Create a new socket, wrapping the native socket if provided or creating one
-// otherwise. In case of any failure, consume the native socket.  We assume the
-// wrapped socket is in the closed state.  If this is not the case you must
-// update the state_ field for this socket yourself.
-void MacAsyncSocket::Initialize() {
-  CFSocketContext ctx = { 0 };
-  ctx.info = this;
-
-  // First create the CFSocket
-  CFSocketRef cf_socket = NULL;
-  bool res = false;
-  if (native_socket_ == INVALID_SOCKET) {
-    cf_socket = CFSocketCreate(kCFAllocatorDefault,
-                               PF_INET, SOCK_STREAM, IPPROTO_TCP,
-                               kCallbackFlags, MacAsyncSocketCallBack, &ctx);
-  } else {
-    cf_socket = CFSocketCreateWithNative(kCFAllocatorDefault,
-                                         native_socket_, kCallbackFlags,
-                                         MacAsyncSocketCallBack, &ctx);
-  }
-
-  if (cf_socket) {
-    res = true;
-    socket_ = cf_socket;
-    native_socket_ = CFSocketGetNative(cf_socket);
-    current_callbacks_ = kCallbackFlags;
-  }
-
-  if (res) {
-    // Make the underlying socket asynchronous
-    res = (-1 != ::fcntl(native_socket_, F_SETFL,
-                         ::fcntl(native_socket_, F_GETFL, 0) | O_NONBLOCK));
-  }
-
-  if (res) {
-    // Add this socket to the run loop, at priority 1 so that it will be
-    // queued behind any pending signals.
-    source_ = CFSocketCreateRunLoopSource(kCFAllocatorDefault, socket_, 1);
-    res = (source_ != NULL);
-    if (!res) errno = EINVAL;
-  }
-
-  if (res) {
-    if (ss_) ss_->RegisterSocket(this);
-    CFRunLoopAddSource(CFRunLoopGetCurrent(), source_, kCFRunLoopCommonModes);
-  }
-
-  if (!res) {
-    int error = errno;
-    Close();  //  Clears error_.
-    error_ = error;
-  }
-}
-
-// Call CFRelease on the result when done using it
-CFDataRef MacAsyncSocket::CopyCFAddress(const SocketAddress& address) {
-  sockaddr_in saddr;
-  address.ToSockAddr(&saddr);
-
-  const UInt8* bytes = reinterpret_cast<UInt8*>(&saddr);
-
-  CFDataRef cf_address = CFDataCreate(kCFAllocatorDefault,
-                                      bytes, sizeof(saddr));
-
-  ASSERT(cf_address != NULL);
-  return cf_address;
-}
-
-void MacAsyncSocket::MacAsyncSocketCallBack(CFSocketRef s,
-                                            CFSocketCallBackType callbackType,
-                                            CFDataRef address,
-                                            const void* data,
-                                            void* info) {
-  MacAsyncSocket* this_socket =
-      reinterpret_cast<MacAsyncSocket*>(info);
-  ASSERT(this_socket != NULL && this_socket->socket_ == s);
-
-  // Don't signal any socket messages if the socketserver is not listening on
-  // them.  When we are reenabled they will be requeued and will fire again.
-  if (this_socket->disabled_)
-    return;
-
-  switch (callbackType) {
-    case kCFSocketReadCallBack:
-      // This callback is invoked in one of 3 situations:
-      // 1. A new connection is waiting to be accepted.
-      // 2. The remote end closed the connection (a recv will return 0).
-      // 3. Data is available to read.
-      // 4. The connection closed unhappily (recv will return -1).
-      if (this_socket->state_ == CS_CONNECTING) {
-        // Case 1.
-        this_socket->SignalReadEvent(this_socket);
-      } else {
-        char ch, amt;
-        amt = ::recv(this_socket->native_socket_, &ch, 1, MSG_PEEK);
-        if (amt == 0) {
-          // Case 2.
-          this_socket->state_ = CS_CLOSED;
-
-          // Disable additional callbacks or we will signal close twice.
-          CFSocketDisableCallBacks(this_socket->socket_, kCFSocketReadCallBack);
-          this_socket->current_callbacks_ &= ~kCFSocketReadCallBack;
-          this_socket->SignalCloseEvent(this_socket, 0);
-        } else if (amt > 0) {
-          // Case 3.
-          this_socket->SignalReadEvent(this_socket);
-        } else {
-          // Case 4.
-          int error = errno;
-          if (error == EAGAIN) {
-            // Observed in practice.  Let's hope it's a spurious or out of date
-            // signal, since we just eat it.
-          } else {
-            this_socket->error_ = error;
-            this_socket->SignalCloseEvent(this_socket, error);
-          }
-        }
-      }
-      break;
-
-    case kCFSocketConnectCallBack:
-      if (data != NULL) {
-        // An error occured in the background while connecting
-        this_socket->error_ = errno;
-        this_socket->state_ = CS_CLOSED;
-        this_socket->SignalCloseEvent(this_socket, this_socket->error_);
-      } else {
-        this_socket->state_ = CS_CONNECTED;
-        this_socket->SignalConnectEvent(this_socket);
-      }
-      break;
-
-    case kCFSocketWriteCallBack:
-      // Update our callback tracking.  Write doesn't reenable, so it's off now.
-      this_socket->current_callbacks_ &= ~kCFSocketWriteCallBack;
-      this_socket->SignalWriteEvent(this_socket);
-      break;
-
-    default:
-      ASSERT(false && "Invalid callback type for socket");
-  }
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/macasyncsocket.h b/third_party/libjingle/source/talk/base/macasyncsocket.h
deleted file mode 100644
index 10a1c10..0000000
--- a/third_party/libjingle/source/talk/base/macasyncsocket.h
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright 2008 Google Inc. All Rights Reserved.
-
-//
-// MacAsyncSocket is a kind of AsyncSocket. It only creates sockets
-// of the TCP type, and does not (yet) support listen and accept. It works
-// asynchronously, which means that users of this socket should connect to
-// the various events declared in asyncsocket.h to receive notifications about
-// this socket.
-
-#ifndef TALK_BASE_MACASYNCSOCKET_H__
-#define TALK_BASE_MACASYNCSOCKET_H__
-
-#include <CoreFoundation/CoreFoundation.h>
-
-#include "talk/base/asyncsocket.h"
-
-namespace talk_base {
-
-class MacBaseSocketServer;
-
-class MacAsyncSocket : public AsyncSocket {
- public:
-  MacAsyncSocket(MacBaseSocketServer* ss);
-  virtual ~MacAsyncSocket();
-
-  bool valid() const { return source_ != NULL; }
-
-  // Socket interface
-  virtual SocketAddress GetLocalAddress() const;
-  virtual SocketAddress GetRemoteAddress() const;
-  virtual int Bind(const SocketAddress& addr);
-  virtual int Connect(const SocketAddress& addr);
-  virtual int Send(const void* pv, size_t cb);
-  virtual int SendTo(const void* pv, size_t cb, const SocketAddress& addr);
-  virtual int Recv(void* pv, size_t cb);
-  virtual int RecvFrom(void* pv, size_t cb, SocketAddress* paddr);
-  virtual int Listen(int backlog);
-  virtual MacAsyncSocket* Accept(SocketAddress* paddr);
-  virtual int Close();
-  virtual int GetError() const;
-  virtual void SetError(int error);
-  virtual ConnState GetState() const;
-  virtual int EstimateMTU(uint16* mtu);
-  virtual int GetOption(Option opt, int* value);
-  virtual int SetOption(Option opt, int value);
-
-  // For the MacBaseSocketServer to disable callbacks when process_io is false.
-  void EnableCallbacks();
-  void DisableCallbacks();
-
- private:
-  // Creates an async socket from an existing bsd socket
-  explicit MacAsyncSocket(MacBaseSocketServer* ss, int native_socket);
-
-   // Attaches the socket to the CFRunloop and sets the wrapped bsd socket
-  // to async mode
-  void Initialize();
-
-  // Translate the SocketAddress into a CFDataRef to pass to CF socket
-  // functions. Caller must call CFRelease on the result when done.
-  static CFDataRef CopyCFAddress(const SocketAddress& address);
-
-  // Callback for the underlying CFSocketRef.
-  static void MacAsyncSocketCallBack(CFSocketRef s,
-                                     CFSocketCallBackType callbackType,
-                                     CFDataRef address,
-                                     const void* data,
-                                     void* info);
-
-  MacBaseSocketServer* ss_;
-  CFSocketRef socket_;
-  int native_socket_;
-  CFRunLoopSourceRef source_;
-  int current_callbacks_;
-  bool disabled_;
-  int error_;
-  ConnState state_;
-
-  DISALLOW_EVIL_CONSTRUCTORS(MacAsyncSocket);
-};
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_MACASYNCSOCKET_H__
diff --git a/third_party/libjingle/source/talk/base/maccocoathreadhelper.h b/third_party/libjingle/source/talk/base/maccocoathreadhelper.h
deleted file mode 100644
index a3cb3a8..0000000
--- a/third_party/libjingle/source/talk/base/maccocoathreadhelper.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * libjingle
- * Copyright 2008 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// Helper function for using Cocoa with Posix threads. This header should be
-// included from C/C++ files that want to use some Cocoa functionality without
-// using the .mm extension (mostly for files that are compiled on multiple
-// platforms).
-
-#ifndef TALK_BASE_MACCOCOATHREADHELPER_H__
-#define TALK_BASE_MACCOCOATHREADHELPER_H__
-
-#if !defined(USE_COCOA_THREADING) || (!defined(OSX) && !defined(IOS))
-#error You can only include this file on OSX or IOS, and must also define
-#error USE_COCOA_THREADING.
-#endif
-
-namespace talk_base {
-
-// Cocoa must be "put into multithreading mode" before Cocoa functionality can
-// be used on POSIX threads. This function does that.
-void InitCocoaMultiThreading();
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_MACCOCOATHREADHELPER_H__
diff --git a/third_party/libjingle/source/talk/base/macconversion.cc b/third_party/libjingle/source/talk/base/macconversion.cc
deleted file mode 100644
index 4654e53..0000000
--- a/third_party/libjingle/source/talk/base/macconversion.cc
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2009, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifdef OSX
-
-#include <CoreFoundation/CoreFoundation.h>
-
-#include "talk/base/logging.h"
-#include "talk/base/macconversion.h"
-
-bool p_convertHostCFStringRefToCPPString(
-  const CFStringRef cfstr, std::string& cppstr) {
-  bool result = false;
-
-  // First this must be non-null,
-  if (NULL != cfstr) {
-    // it must actually *be* a CFString, and not something just masquerading
-    // as one,
-    if (CFGetTypeID(cfstr) == CFStringGetTypeID()) {
-      // and we must be able to get the characters out of it.
-      // (The cfstr owns this buffer; it came from somewhere else,
-      // so someone else gets to take care of getting rid of the cfstr,
-      // and then this buffer will go away automatically.)
-      unsigned length = CFStringGetLength(cfstr);
-      char* buf = new char[1 + length];
-      if (CFStringGetCString(cfstr, buf, 1 + length, kCFStringEncodingASCII)) {
-        if (strlen(buf) == length) {
-          cppstr.assign(buf);
-          result = true;
-        }
-      }
-      delete [] buf;
-    }
-  }
-
-  return result;
-}
-
-bool p_convertCFNumberToInt(CFNumberRef cfn, int* i) {
-  bool converted = false;
-
-  // It must not be null.
-  if (NULL != cfn) {
-    // It must actually *be* a CFNumber and not something just masquerading
-    // as one.
-    if (CFGetTypeID(cfn) == CFNumberGetTypeID()) {
-      CFNumberType ntype = CFNumberGetType(cfn);
-      switch (ntype) {
-        case kCFNumberSInt8Type:
-          SInt8 sint8;
-          converted = CFNumberGetValue(cfn, ntype, static_cast<void*>(&sint8));
-          if (converted) *i = static_cast<int>(sint8);
-          break;
-        case kCFNumberSInt16Type:
-          SInt16 sint16;
-          converted = CFNumberGetValue(cfn, ntype, static_cast<void*>(&sint16));
-          if (converted) *i = static_cast<int>(sint16);
-          break;
-        case kCFNumberSInt32Type:
-          SInt32 sint32;
-          converted = CFNumberGetValue(cfn, ntype, static_cast<void*>(&sint32));
-          if (converted) *i = static_cast<int>(sint32);
-          break;
-        case kCFNumberSInt64Type:
-          SInt64 sint64;
-          converted = CFNumberGetValue(cfn, ntype, static_cast<void*>(&sint64));
-          if (converted) *i = static_cast<int>(sint64);
-          break;
-        case kCFNumberFloat32Type:
-          Float32 float32;
-          converted = CFNumberGetValue(cfn, ntype,
-                                       static_cast<void*>(&float32));
-          if (converted) *i = static_cast<int>(float32);
-          break;
-        case kCFNumberFloat64Type:
-          Float64 float64;
-          converted = CFNumberGetValue(cfn, ntype,
-                                       static_cast<void*>(&float64));
-          if (converted) *i = static_cast<int>(float64);
-          break;
-        case kCFNumberCharType:
-          char charvalue;
-          converted = CFNumberGetValue(cfn, ntype,
-                                       static_cast<void*>(&charvalue));
-          if (converted) *i = static_cast<int>(charvalue);
-          break;
-        case kCFNumberShortType:
-          short shortvalue;
-          converted = CFNumberGetValue(cfn, ntype,
-                                       static_cast<void*>(&shortvalue));
-          if (converted) *i = static_cast<int>(shortvalue);
-          break;
-        case kCFNumberIntType:
-          int intvalue;
-          converted = CFNumberGetValue(cfn, ntype,
-                                       static_cast<void*>(&intvalue));
-          if (converted) *i = static_cast<int>(intvalue);
-          break;
-        case kCFNumberLongType:
-          long longvalue;
-          converted = CFNumberGetValue(cfn, ntype,
-                     static_cast<void*>(&longvalue));
-          if (converted) *i = static_cast<int>(longvalue);
-          break;
-        case kCFNumberLongLongType:
-          long long llvalue;
-          converted = CFNumberGetValue(cfn, ntype,
-                                       static_cast<void*>(&llvalue));
-          if (converted) *i = static_cast<int>(llvalue);
-          break;
-        case kCFNumberFloatType:
-          float floatvalue;
-          converted = CFNumberGetValue(cfn, ntype,
-                                       static_cast<void*>(&floatvalue));
-          if (converted) *i = static_cast<int>(floatvalue);
-          break;
-        case kCFNumberDoubleType:
-          double doublevalue;
-          converted = CFNumberGetValue(cfn, ntype,
-                                       static_cast<void*>(&doublevalue));
-          if (converted) *i = static_cast<int>(doublevalue);
-          break;
-        case kCFNumberCFIndexType:
-          CFIndex cfindex;
-          converted = CFNumberGetValue(cfn, ntype,
-                                       static_cast<void*>(&cfindex));
-          if (converted) *i = static_cast<int>(cfindex);
-          break;
-        default:
-          LOG(LS_ERROR) << "got unknown type.";
-          break;
-      }
-    }
-  }
-
-  return converted;
-}
-
-bool p_isCFNumberTrue(CFNumberRef cfn) {
-  // We assume it's false until proven otherwise.
-  bool result = false;
-  int asInt;
-  bool converted = p_convertCFNumberToInt(cfn, &asInt);
-
-  if (converted && (0 != asInt)) {
-    result = true;
-  }
-
-  return result;
-}
-
-#endif  // OSX
diff --git a/third_party/libjingle/source/talk/base/macconversion.h b/third_party/libjingle/source/talk/base/macconversion.h
deleted file mode 100644
index a401cab..0000000
--- a/third_party/libjingle/source/talk/base/macconversion.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2009, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_MACCONVERSION_H_
-#define TALK_BASE_MACCONVERSION_H_
-
-#ifdef OSX
-
-#include <CoreFoundation/CoreFoundation.h>
-
-#include <string>
-
-// given a CFStringRef, attempt to convert it to a C++ string.
-// returns true if it succeeds, false otherwise.
-// We can safely assume, given our context, that the string is
-// going to be in ASCII, because it will either be an IP address,
-// or a domain name, which is guaranteed to be ASCII-representable.
-bool p_convertHostCFStringRefToCPPString(const CFStringRef cfstr,
-                                         std::string& cppstr);
-
-// Convert the CFNumber to an integer, putting the integer in the location
-// given, and returhing true, if the conversion succeeds.
-// If given a NULL or a non-CFNumber, returns false.
-// This is pretty aggresive about trying to convert to int.
-bool p_convertCFNumberToInt(CFNumberRef cfn, int* i);
-
-// given a CFNumberRef, determine if it represents a true value.
-bool p_isCFNumberTrue(CFNumberRef cfn);
-
-#endif  // OSX
-
-#endif  // TALK_BASE_MACCONVERSION_H_
diff --git a/third_party/libjingle/source/talk/base/macsocketserver.cc b/third_party/libjingle/source/talk/base/macsocketserver.cc
deleted file mode 100644
index 5b2ec03..0000000
--- a/third_party/libjingle/source/talk/base/macsocketserver.cc
+++ /dev/null
@@ -1,419 +0,0 @@
-
-
-#include "talk/base/macsocketserver.h"
-
-#include "talk/base/common.h"
-#include "talk/base/logging.h"
-#include "talk/base/macasyncsocket.h"
-#include "talk/base/macutils.h"
-#include "talk/base/thread.h"
-
-namespace talk_base {
-
-///////////////////////////////////////////////////////////////////////////////
-// MacBaseSocketServer
-///////////////////////////////////////////////////////////////////////////////
-
-MacBaseSocketServer::MacBaseSocketServer() {
-}
-
-MacBaseSocketServer::~MacBaseSocketServer() {
-}
-
-AsyncSocket* MacBaseSocketServer::CreateAsyncSocket(int type) {
-  if (SOCK_STREAM != type)
-    return NULL;
-
-  MacAsyncSocket* socket = new MacAsyncSocket(this);
-  if (!socket->valid()) {
-    delete socket;
-    return NULL;
-  }
-  return socket;
-}
-
-void MacBaseSocketServer::RegisterSocket(MacAsyncSocket* s) {
-  sockets_.insert(s);
-}
-
-void MacBaseSocketServer::UnregisterSocket(MacAsyncSocket* s) {
-  size_t found = sockets_.erase(s);
-  ASSERT(found == 1);
-}
-
-bool MacBaseSocketServer::SetPosixSignalHandler(int signum,
-                                                void (*handler)(int)) {
-  Dispatcher* dispatcher = signal_dispatcher();
-  if (!PhysicalSocketServer::SetPosixSignalHandler(signum, handler)) {
-    return false;
-  }
-
-  // Only register the FD once, when the first custom handler is installed.
-  if (!dispatcher && (dispatcher = signal_dispatcher())) {
-    CFFileDescriptorContext ctx = { 0 };
-    ctx.info = this;
-
-    CFFileDescriptorRef desc = CFFileDescriptorCreate(
-        kCFAllocatorDefault,
-        dispatcher->GetDescriptor(),
-        false,
-        &MacBaseSocketServer::FileDescriptorCallback,
-        &ctx);
-    if (!desc) {
-      return false;
-    }
-
-    CFFileDescriptorEnableCallBacks(desc, kCFFileDescriptorReadCallBack);
-    CFRunLoopSourceRef ref =
-        CFFileDescriptorCreateRunLoopSource(kCFAllocatorDefault, desc, 0);
-
-    if (!ref) {
-      CFRelease(desc);
-      return false;
-    }
-
-    CFRunLoopAddSource(CFRunLoopGetCurrent(), ref, kCFRunLoopCommonModes);
-    CFRelease(desc);
-    CFRelease(ref);
-  }
-
-  return true;
-}
-
-// Used to disable socket events from waking our message queue when
-// process_io is false.  Does not disable signal event handling though.
-void MacBaseSocketServer::EnableSocketCallbacks(bool enable) {
-  for (std::set<MacAsyncSocket*>::iterator it = sockets().begin();
-       it != sockets().end(); ++it) {
-    if (enable) {
-      (*it)->EnableCallbacks();
-    } else {
-      (*it)->DisableCallbacks();
-    }
-  }
-}
-
-void MacBaseSocketServer::FileDescriptorCallback(CFFileDescriptorRef fd,
-                                                 CFOptionFlags flags,
-                                                 void* context) {
-  MacBaseSocketServer* this_ss =
-      reinterpret_cast<MacBaseSocketServer*>(context);
-  ASSERT(this_ss);
-  Dispatcher* signal_dispatcher = this_ss->signal_dispatcher();
-  ASSERT(signal_dispatcher);
-
-  signal_dispatcher->OnPreEvent(DE_READ);
-  signal_dispatcher->OnEvent(DE_READ, 0);
-  CFFileDescriptorEnableCallBacks(fd, kCFFileDescriptorReadCallBack);
-}
-
-
-///////////////////////////////////////////////////////////////////////////////
-// MacCFSocketServer
-///////////////////////////////////////////////////////////////////////////////
-
-void WakeUpCallback(void* info) {
-  MacCFSocketServer* server = static_cast<MacCFSocketServer*>(info);
-  ASSERT(NULL != server);
-  server->OnWakeUpCallback();
-}
-
-MacCFSocketServer::MacCFSocketServer()
-    : run_loop_(CFRunLoopGetCurrent()),
-      wake_up_(NULL) {
-  CFRunLoopSourceContext ctx;
-  memset(&ctx, 0, sizeof(ctx));
-  ctx.info = this;
-  ctx.perform = &WakeUpCallback;
-  wake_up_ = CFRunLoopSourceCreate(NULL, 0, &ctx);
-  ASSERT(NULL != wake_up_);
-  if (wake_up_) {
-    CFRunLoopAddSource(run_loop_, wake_up_, kCFRunLoopCommonModes);
-  }
-}
-
-MacCFSocketServer::~MacCFSocketServer() {
-  if (wake_up_) {
-    CFRunLoopSourceInvalidate(wake_up_);
-    CFRelease(wake_up_);
-  }
-}
-
-bool MacCFSocketServer::Wait(int cms, bool process_io) {
-  ASSERT(CFRunLoopGetCurrent() == run_loop_);
-
-  if (!process_io && cms == 0) {
-    // No op.
-    return true;
-  }
-
-  if (!process_io) {
-    // No way to listen to common modes and not get socket events, unless
-    // we disable each one's callbacks.
-    EnableSocketCallbacks(false);
-  }
-
-  SInt32 result;
-  if (kForever == cms) {
-    do {
-      // Would prefer to run in a custom mode that only listens to wake_up,
-      // but we have qtkit sending work to the main thread which is effectively
-      // blocked here, causing deadlock.  Thus listen to the common modes.
-      // TODO: If QTKit becomes thread safe, do the above.
-      result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 10000000, false);
-    } while (result != kCFRunLoopRunFinished && result != kCFRunLoopRunStopped);
-  } else {
-    // TODO: In the case of 0ms wait, this will only process one event, so we
-    // may want to loop until it returns TimedOut.
-    CFTimeInterval seconds = cms / 1000.0;
-    result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, seconds, false);
-  }
-
-  if (!process_io) {
-    // Reenable them.  Hopefully this won't cause spurious callbacks or
-    // missing ones while they were disabled.
-    EnableSocketCallbacks(true);
-  }
-
-  if (kCFRunLoopRunFinished == result) {
-    return false;
-  }
-  return true;
-}
-
-void MacCFSocketServer::WakeUp() {
-  if (wake_up_) {
-    CFRunLoopSourceSignal(wake_up_);
-    CFRunLoopWakeUp(run_loop_);
-  }
-}
-
-void MacCFSocketServer::OnWakeUpCallback() {
-  ASSERT(run_loop_ == CFRunLoopGetCurrent());
-  CFRunLoopStop(run_loop_);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// MacCarbonSocketServer
-///////////////////////////////////////////////////////////////////////////////
-
-const UInt32 kEventClassSocketServer = 'MCSS';
-const UInt32 kEventWakeUp = 'WAKE';
-const EventTypeSpec kEventWakeUpSpec[] = {
-  { kEventClassSocketServer, kEventWakeUp }
-};
-
-MacCarbonSocketServer::MacCarbonSocketServer()
-    : event_queue_(GetCurrentEventQueue()), wake_up_(NULL) {
-  VERIFY(noErr == CreateEvent(NULL, kEventClassSocketServer, kEventWakeUp, 0,
-                              kEventAttributeUserEvent, &wake_up_));
-}
-
-MacCarbonSocketServer::~MacCarbonSocketServer() {
-  if (wake_up_) {
-    ReleaseEvent(wake_up_);
-  }
-}
-
-bool MacCarbonSocketServer::Wait(int cms, bool process_io) {
-  ASSERT(GetCurrentEventQueue() == event_queue_);
-
-  // Listen to all events if we're processing I/O.
-  // Only listen for our wakeup event if we're not.
-  UInt32 num_types = 0;
-  const EventTypeSpec* events = NULL;
-  if (!process_io) {
-    num_types = GetEventTypeCount(kEventWakeUpSpec);
-    events = kEventWakeUpSpec;
-  }
-
-  EventTargetRef target = GetEventDispatcherTarget();
-  EventTimeout timeout =
-      (kForever == cms) ? kEventDurationForever : cms / 1000.0;
-  EventTimeout end_time = GetCurrentEventTime() + timeout;
-
-  bool done = false;
-  while (!done) {
-    EventRef event;
-    OSStatus result = ReceiveNextEvent(num_types, events, timeout, true,
-                                       &event);
-    if (noErr == result) {
-      if (wake_up_ != event) {
-        LOG_F(LS_VERBOSE) << "Dispatching event: " << DecodeEvent(event);
-        result = SendEventToEventTarget(event, target);
-        if ((noErr != result) && (eventNotHandledErr != result)) {
-          LOG_E(LS_ERROR, OS, result) << "SendEventToEventTarget";
-        }
-      } else {
-        done = true;
-      }
-      ReleaseEvent(event);
-    } else if (eventLoopTimedOutErr == result) {
-      ASSERT(cms != kForever);
-      done = true;
-    } else if (eventLoopQuitErr == result) {
-      // Ignore this... we get spurious quits for a variety of reasons.
-      LOG_E(LS_VERBOSE, OS, result) << "ReceiveNextEvent";
-    } else {
-      // Some strange error occurred. Log it.
-      LOG_E(LS_WARNING, OS, result) << "ReceiveNextEvent";
-      return false;
-    }
-    if (kForever != cms) {
-      timeout = end_time - GetCurrentEventTime();
-    }
-  }
-  return true;
-}
-
-void MacCarbonSocketServer::WakeUp() {
-  if (!IsEventInQueue(event_queue_, wake_up_)) {
-    RetainEvent(wake_up_);
-    OSStatus result = PostEventToQueue(event_queue_, wake_up_,
-                                       kEventPriorityStandard);
-    if (noErr != result) {
-      LOG_E(LS_ERROR, OS, result) << "PostEventToQueue";
-    }
-  }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// MacCarbonAppSocketServer
-///////////////////////////////////////////////////////////////////////////////
-
-// Carbon is deprecated for x64.  Switch to Cocoa
-#if !defined(__x86_64__)
-
-MacCarbonAppSocketServer::MacCarbonAppSocketServer()
-    : event_queue_(GetCurrentEventQueue()) {
-  // Install event handler
-  VERIFY(noErr == InstallApplicationEventHandler(
-      NewEventHandlerUPP(WakeUpEventHandler), 1, kEventWakeUpSpec, this,
-      &event_handler_));
-
-  // Install a timer and set it idle to begin with.
-  VERIFY(noErr == InstallEventLoopTimer(GetMainEventLoop(),
-                                        kEventDurationForever,
-                                        kEventDurationForever,
-                                        NewEventLoopTimerUPP(TimerHandler),
-                                        this,
-                                        &timer_));
-}
-
-MacCarbonAppSocketServer::~MacCarbonAppSocketServer() {
-  RemoveEventLoopTimer(timer_);
-  RemoveEventHandler(event_handler_);
-}
-
-OSStatus MacCarbonAppSocketServer::WakeUpEventHandler(
-    EventHandlerCallRef next, EventRef event, void *data) {
-  QuitApplicationEventLoop();
-  return noErr;
-}
-
-void MacCarbonAppSocketServer::TimerHandler(
-    EventLoopTimerRef timer, void *data) {
-  QuitApplicationEventLoop();
-}
-
-bool MacCarbonAppSocketServer::Wait(int cms, bool process_io) {
-  if (!process_io && cms == 0) {
-    // No op.
-    return true;
-  }
-  if (kForever != cms) {
-    // Start a timer.
-    OSStatus error =
-        SetEventLoopTimerNextFireTime(timer_, cms / 1000.0);
-    if (error != noErr) {
-      LOG(LS_ERROR) << "Failed setting next fire time.";
-    }
-  }
-  if (!process_io) {
-    // No way to listen to common modes and not get socket events, unless
-    // we disable each one's callbacks.
-    EnableSocketCallbacks(false);
-  }
-  RunApplicationEventLoop();
-  if (!process_io) {
-    // Reenable them.  Hopefully this won't cause spurious callbacks or
-    // missing ones while they were disabled.
-    EnableSocketCallbacks(true);
-  }
-  return true;
-}
-
-void MacCarbonAppSocketServer::WakeUp() {
-  // TODO: No-op if there's already a WakeUp in flight.
-  EventRef wake_up;
-  VERIFY(noErr == CreateEvent(NULL, kEventClassSocketServer, kEventWakeUp, 0,
-                              kEventAttributeUserEvent, &wake_up));
-  OSStatus result = PostEventToQueue(event_queue_, wake_up,
-                                       kEventPriorityStandard);
-  if (noErr != result) {
-    LOG_E(LS_ERROR, OS, result) << "PostEventToQueue";
-  }
-  ReleaseEvent(wake_up);
-}
-#endif
-
-///////////////////////////////////////////////////////////////////////////////
-// MacNotificationsSocketServer
-///////////////////////////////////////////////////////////////////////////////
-
-static const CFStringRef kNotificationName =
-  CFSTR("MacNotificationsSocketServer");
-
-MacNotificationsSocketServer::MacNotificationsSocketServer()
-    : sent_notification_(false) {
-  CFNotificationCenterRef nc = CFNotificationCenterGetLocalCenter();
-
-  // Passing NULL for the observed object
-  CFNotificationCenterAddObserver(
-      nc, this, NotificationCallBack, kNotificationName, NULL,
-      CFNotificationSuspensionBehaviorDeliverImmediately);
-}
-
-MacNotificationsSocketServer::~MacNotificationsSocketServer() {
-  CFNotificationCenterRef nc = CFNotificationCenterGetLocalCenter();
-  CFNotificationCenterRemoveObserver(nc, this, kNotificationName, NULL);
-}
-
-bool MacNotificationsSocketServer::Wait(int cms, bool process_io) {
-  return cms == 0;
-}
-
-void MacNotificationsSocketServer::WakeUp() {
-  // We could be invoked recursively, so this stops the infinite loop
-  if (!sent_notification_) {
-    sent_notification_ = true;
-    CFNotificationCenterRef nc = CFNotificationCenterGetLocalCenter();
-    CFNotificationCenterPostNotification(nc, kNotificationName, this, NULL,
-                                         true);
-    sent_notification_ = false;
-  }
-}
-
-void MacNotificationsSocketServer::NotificationCallBack(
-    CFNotificationCenterRef center, void* observer, CFStringRef name,
-    const void* object, CFDictionaryRef userInfo) {
-
-  ASSERT(CFStringCompare(name, kNotificationName, 0) == kCFCompareEqualTo);
-  ASSERT(userInfo == NULL);
-
-  // We have thread messages to process.
-  Thread* thread = Thread::Current();
-  if (thread == NULL) {
-    // We're shutting down
-    return;
-  }
-
-  Message msg;
-  while (thread->Get(&msg, 0)) {
-    thread->Dispatch(&msg);
-  }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-} // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/macsocketserver.h b/third_party/libjingle/source/talk/base/macsocketserver.h
deleted file mode 100644
index 53118b8..0000000
--- a/third_party/libjingle/source/talk/base/macsocketserver.h
+++ /dev/null
@@ -1,166 +0,0 @@
-// Copyright 2007, Google Inc.
-
-
-#ifndef TALK_BASE_MACSOCKETSERVER_H__
-#define TALK_BASE_MACSOCKETSERVER_H__
-
-#include <set>
-#ifdef OSX // Invalid on IOS
-#include <Carbon/Carbon.h>
-#endif
-#include "talk/base/physicalsocketserver.h"
-
-namespace talk_base {
-
-///////////////////////////////////////////////////////////////////////////////
-// MacBaseSocketServer
-///////////////////////////////////////////////////////////////////////////////
-class MacAsyncSocket;
-
-class MacBaseSocketServer : public PhysicalSocketServer {
- public:
-  MacBaseSocketServer();
-  virtual ~MacBaseSocketServer();
-
-  // SocketServer Interface
-  virtual Socket* CreateSocket(int type) { return NULL; }
-  virtual AsyncSocket* CreateAsyncSocket(int type);
-  virtual bool Wait(int cms, bool process_io) = 0;
-  virtual void WakeUp() = 0;
-
-  void RegisterSocket(MacAsyncSocket* socket);
-  void UnregisterSocket(MacAsyncSocket* socket);
-
-  // PhysicalSocketServer Overrides
-  virtual bool SetPosixSignalHandler(int signum, void (*handler)(int));
-
- protected:
-  void EnableSocketCallbacks(bool enable);
-  const std::set<MacAsyncSocket*>& sockets() {
-    return sockets_;
-  }
-
- private:
-  static void FileDescriptorCallback(CFFileDescriptorRef ref,
-                                     CFOptionFlags flags,
-                                     void* context);
-
-  std::set<MacAsyncSocket*> sockets_;
-};
-
-// Core Foundation implementation of the socket server. While idle it
-// will run the current CF run loop. When the socket server has work
-// to do the run loop will be paused. Does not support Carbon or Cocoa
-// UI interaction.
-class MacCFSocketServer : public MacBaseSocketServer {
- public:
-  MacCFSocketServer();
-  virtual ~MacCFSocketServer();
-
-  // SocketServer Interface
-  virtual bool Wait(int cms, bool process_io);
-  virtual void WakeUp();
-  void OnWakeUpCallback();
-
- private:
-  CFRunLoopRef run_loop_;
-  CFRunLoopSourceRef wake_up_;
-};
-
-#ifdef OSX
-
-///////////////////////////////////////////////////////////////////////////////
-// MacCarbonSocketServer
-///////////////////////////////////////////////////////////////////////////////
-
-// Interacts with the Carbon event queue. While idle it will block,
-// waiting for events. When the socket server has work to do, it will
-// post a 'wake up' event to the queue, causing the thread to exit the
-// event loop until the next call to Wait. Other events are dispatched
-// to their target. Supports Carbon and Cocoa UI interaction.
-class MacCarbonSocketServer : public MacBaseSocketServer {
- public:
-  MacCarbonSocketServer();
-  virtual ~MacCarbonSocketServer();
-
-  // SocketServer Interface
-  virtual bool Wait(int cms, bool process_io);
-  virtual void WakeUp();
-
- private:
-  EventQueueRef event_queue_;
-  EventRef wake_up_;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// MacCarbonAppSocketServer
-///////////////////////////////////////////////////////////////////////////////
-
-// Runs the Carbon application event loop on the current thread while
-// idle. When the socket server has work to do, it will post an event
-// to the queue, causing the thread to exit the event loop until the
-// next call to Wait. Other events are automatically dispatched to
-// their target.
-class MacCarbonAppSocketServer : public MacBaseSocketServer {
- public:
-  MacCarbonAppSocketServer();
-  virtual ~MacCarbonAppSocketServer();
-
-  // SocketServer Interface
-  virtual bool Wait(int cms, bool process_io);
-  virtual void WakeUp();
-
- private:
-  static OSStatus WakeUpEventHandler(EventHandlerCallRef next, EventRef event,
-                                     void *data);
-  static void TimerHandler(EventLoopTimerRef timer, void *data);
-
-  EventQueueRef event_queue_;
-  EventHandlerRef event_handler_;
-  EventLoopTimerRef timer_;
-};
-
-#endif
-
-///////////////////////////////////////////////////////////////////////////////
-// MacNotificationsSocketServer
-///////////////////////////////////////////////////////////////////////////////
-
-// The name "SocketServer" is misleading for this class. This class inherits
-// from SocketServer, some variants of which create/use physical sockets
-// (specifically, PhysicalSocketServer). But generally, this class is a way for
-// a thread to schedule tasks (see task.h, thread.h and taskrunner.h).
-//
-// Since we don't want to write a custom Cocoa event loop, we will use this
-// in a non-standard way. The "Wait" method will never actually wait - it will
-// return false if cms > 0. Whenever a task needs to be woken up, the WakeUp
-// method here will get called, and will cause the thread to cycle through all
-// messages currently available.
-
-class MacNotificationsSocketServer : public SocketServer {
- public:
-  MacNotificationsSocketServer();
-  virtual ~MacNotificationsSocketServer();
-
-  // SocketServer Interface
-  virtual Socket* CreateSocket(int type) { return NULL; }
-  virtual AsyncSocket* CreateAsyncSocket(int type) { return NULL; }
-  // process_io argument is ignored.
-  virtual bool Wait(int cms, bool process_io);
-  virtual void WakeUp();
-
- private:
-  static void NotificationCallBack(CFNotificationCenterRef center,
-                                   void* observer,
-                                   CFStringRef name,
-                                   const void* object,
-                                   CFDictionaryRef userInfo);
-
-  bool sent_notification_;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-
-} // namespace talk_base
-
-#endif  // TALK_BASE_MACSOCKETSERVER_H__
diff --git a/third_party/libjingle/source/talk/base/macutils.cc b/third_party/libjingle/source/talk/base/macutils.cc
deleted file mode 100644
index 21d31ff..0000000
--- a/third_party/libjingle/source/talk/base/macutils.cc
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * libjingle
- * Copyright 2007--2009, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sstream>
-
-#include "talk/base/common.h"
-#include "talk/base/logging.h"
-#include "talk/base/macutils.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/base/stringutils.h"
-
-namespace talk_base {
-
-///////////////////////////////////////////////////////////////////////////////
-
-bool ToUtf8(const CFStringRef str16, std::string* str8) {
-  if ((NULL == str16) || (NULL == str8))
-    return false;
-  size_t maxlen = CFStringGetMaximumSizeForEncoding(CFStringGetLength(str16),
-                                                    kCFStringEncodingUTF8)
-                  + 1;
-  scoped_array<char> buffer(new char[maxlen]);
-  if (!buffer.get()
-      || !CFStringGetCString(str16, buffer.get(), maxlen,
-                             kCFStringEncodingUTF8))
-    return false;
-  str8->assign(buffer.get());
-  return true;
-}
-
-bool ToUtf16(const std::string& str8, CFStringRef* str16) {
-  if (NULL == str16)
-    return false;
-  *str16 = CFStringCreateWithBytes(kCFAllocatorDefault,
-                                   reinterpret_cast<const UInt8*>(str8.data()),
-                                   str8.length(), kCFStringEncodingUTF8,
-                                   false);
-  return (NULL != *str16);
-}
-
-#ifdef OSX
-void DecodeFourChar(UInt32 fc, std::string* out) {
-  std::stringstream ss;
-  ss << '\'';
-  bool printable = true;
-  for (int i = 3; i >= 0; --i) {
-    char ch = (fc >> (8 * i)) & 0xFF;
-    if (isprint(static_cast<unsigned char>(ch))) {
-      ss << ch;
-    } else {
-      printable = false;
-      break;
-    }
-  }
-  if (printable) {
-    ss << '\'';
-  } else {
-    ss.str("");
-    ss << "0x" << std::hex << fc;
-  }
-  out->append(ss.str());
-}
-
-std::string DecodeEvent(EventRef event) {
-  std::string str;
-  DecodeFourChar(::GetEventClass(event), &str);
-  str.push_back(':');
-  DecodeFourChar(::GetEventKind(event), &str);
-  return str;
-}
-
-static bool GetGestalt(OSType ostype, int* value) {
-  ASSERT(NULL != value);
-  SInt32 native_value;
-  OSStatus result = Gestalt(ostype, &native_value);
-  if (noErr == result) {
-    *value = native_value;
-    return true;
-  }
-  std::string str;
-  DecodeFourChar(ostype, &str);
-  LOG_E(LS_ERROR, OS, result) << "Gestalt(" << str << ")";
-  return false;
-}
-
-bool GetOSVersion(int* major, int* minor, int* bugfix) {
-  ASSERT(major && minor && bugfix);
-  if (!GetGestalt(gestaltSystemVersion, major))
-    return false;
-  if (*major < 0x1040) {
-    *bugfix = *major & 0xF;
-    *minor = (*major >> 4) & 0xF;
-    *major = (*major >> 8);
-    return true;
-  }
-  return GetGestalt(gestaltSystemVersionMajor, major)
-      && GetGestalt(gestaltSystemVersionMinor, minor)
-      && GetGestalt(gestaltSystemVersionBugFix, bugfix);
-}
-
-MacOSVersionName GetOSVersionName() {
-  int major = 0, minor = 0, bugfix = 0;
-  if (!GetOSVersion(&major, &minor, &bugfix))
-    return kMacOSUnknown;
-  if (major > 10)
-    return kMacOSNewer;
-  if ((major < 10) || (minor < 3))
-    return kMacOSOlder;
-  switch (minor) {
-    case 3:
-      return kMacOSPanther;
-    case 4:
-      return kMacOSTiger;
-    case 5:
-      return kMacOSLeopard;
-  }
-  return kMacOSNewer;
-}
-
-bool GetQuickTimeVersion(std::string* out) {
-  int ver;
-  if (!GetGestalt(gestaltQuickTimeVersion, &ver))
-    return false;
-
-  std::stringstream ss;
-  ss << std::hex << ver;
-  *out = ss.str();
-  return true;
-}
-
-bool RunAppleScript(const std::string& script) {
-  ComponentInstance component = NULL;
-  AEDesc script_desc;
-  AEDesc result_data;
-  OSStatus err;
-  OSAID script_id, result_id;
-
-  AECreateDesc(typeNull, NULL, 0, &script_desc);
-  AECreateDesc(typeNull, NULL, 0, &result_data);
-  script_id = kOSANullScript;
-  result_id = kOSANullScript;
-
-  component = OpenDefaultComponent(kOSAComponentType, typeAppleScript);
-  if (component == NULL) {
-    LOG(LS_ERROR) << "Failed opening Apple Script component";
-    return false;
-  }
-  err = AECreateDesc(typeUTF8Text, script.data(), script.size(), &script_desc);
-  if (err != noErr) {
-    CloseComponent(component);
-    LOG(LS_ERROR) << "Failed creating Apple Script description";
-    return false;
-  }
-
-  err = OSACompile(component, &script_desc, kOSAModeCanInteract, &script_id);
-  if (err != noErr) {
-    AEDisposeDesc(&script_desc);
-    if (script_id != kOSANullScript) {
-      OSADispose(component, script_id);
-    }
-    CloseComponent(component);
-    LOG(LS_ERROR) << "Error compiling Apple Script";
-    return false;
-  }
-
-  err = OSAExecute(component, script_id, kOSANullScript, kOSAModeCanInteract,
-                   &result_id);
-
-  if (err == errOSAScriptError) {
-    LOG(LS_ERROR) << "Error when executing Apple Script: " << script;
-    AECreateDesc(typeNull, NULL, 0, &result_data);
-    OSAScriptError(component, kOSAErrorMessage, typeChar, &result_data);
-    int len = AEGetDescDataSize(&result_data);
-    char* data = (char*) malloc(len);
-    if (data != NULL) {
-      err = AEGetDescData(&result_data, data, len);
-      LOG(LS_ERROR) << "Script error: " << data;
-    }
-    AEDisposeDesc(&script_desc);
-    AEDisposeDesc(&result_data);
-    return false;
-  }
-  AEDisposeDesc(&script_desc);
-  if (script_id != kOSANullScript) {
-    OSADispose(component, script_id);
-  }
-  if (result_id != kOSANullScript) {
-    OSADispose(component, result_id);
-  }
-  CloseComponent(component);
-  return true;
-}
-#endif
-
-///////////////////////////////////////////////////////////////////////////////
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/macutils.h b/third_party/libjingle/source/talk/base/macutils.h
deleted file mode 100644
index be6e728..0000000
--- a/third_party/libjingle/source/talk/base/macutils.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * libjingle
- * Copyright 2007--2009, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_MACUTILS_H__
-#define TALK_BASE_MACUTILS_H__
-
-#include <CoreFoundation/CoreFoundation.h>
-#ifdef OSX
-#include <Carbon/Carbon.h>
-#endif
-#include <string>
-
-namespace talk_base {
-
-///////////////////////////////////////////////////////////////////////////////
-
-// Note that some of these functions work for both iOS and Mac OS X.  The ones
-// that are specific to Mac are #ifdef'ed as such.
-
-bool ToUtf8(const CFStringRef str16, std::string* str8);
-bool ToUtf16(const std::string& str8, CFStringRef* str16);
-
-#ifdef OSX
-void DecodeFourChar(UInt32 fc, std::string* out);
-std::string DecodeEvent(EventRef event);
-
-enum MacOSVersionName {
-  kMacOSUnknown,  // ???
-  kMacOSOlder,    // 10.2-
-  kMacOSPanther,  // 10.3
-  kMacOSTiger,    // 10.4
-  kMacOSLeopard,  // 10.5
-  kMacOSNewer,    // 10.6+
-};
-
-bool GetOSVersion(int* major, int* minor, int* bugfix);
-MacOSVersionName GetOSVersionName();
-bool GetQuickTimeVersion(std::string* version);
-
-// Runs the given apple script. Only supports scripts that does not
-// require user interaction.
-bool RunAppleScript(const std::string& script);
-#endif
-
-///////////////////////////////////////////////////////////////////////////////
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_MACUTILS_H__
diff --git a/third_party/libjingle/source/talk/base/md5.h b/third_party/libjingle/source/talk/base/md5.h
deleted file mode 100644
index ec458d1..0000000
--- a/third_party/libjingle/source/talk/base/md5.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * This is the header file for the MD5 message-digest algorithm.
- * The algorithm is due to Ron Rivest.  This code was
- * written by Colin Plumb in 1993, no copyright is claimed.
- * This code is in the public domain; do with it what you wish.
- *
- * Equivalent code is available from RSA Data Security, Inc.
- * This code has been tested against that, and is equivalent,
- * except that you don't need to include two pages of legalese
- * with every copy.
- * To compute the message digest of a chunk of bytes, declare an
- * MD5Context structure, pass it to MD5Init, call MD5Update as
- * needed on buffers full of bytes, and then call MD5Final, which
- * will fill a supplied 16-byte array with the digest.
- *
- */
-
-#ifndef TALK_BASE_MD5_H__
-#define TALK_BASE_MD5_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef long unsigned int uint32;
-typedef struct MD5Context MD5_CTX;
-
-#define md5byte unsigned char
-
-struct MD5Context {
-  uint32 buf[4];
-  uint32 bits[2];
-  uint32 in[16];
-};
-
-void MD5Init(struct MD5Context *context);
-void MD5Update(struct MD5Context *context, md5byte const *buf, unsigned len);
-void MD5Final(unsigned char digest[16], struct MD5Context *context);
-void MD5Transform(uint32 buf[4], uint32 const in[16]);
-
-#ifdef __cplusplus
-};
-#endif
-
-#endif // TALK_BASE_MD5_H__
diff --git a/third_party/libjingle/source/talk/base/md5c.c b/third_party/libjingle/source/talk/base/md5c.c
deleted file mode 100644
index ef9f862..0000000
--- a/third_party/libjingle/source/talk/base/md5c.c
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * This code implements the MD5 message-digest algorithm.
- * The algorithm is due to Ron Rivest.  This code was
- * written by Colin Plumb in 1993, no copyright is claimed.
- * This code is in the public domain; do with it what you wish.
- *
- * Equivalent code is available from RSA Data Security, Inc.
- * This code has been tested against that, and is equivalent,
- * except that you don't need to include two pages of legalese
- * with every copy.
- *
- * To compute the message digest of a chunk of bytes, declare an
- * MD5Context structure, pass it to MD5Init, call MD5Update as
- * needed on buffers full of bytes, and then call MD5Final, which
- * will fill a supplied 16-byte array with the digest.
- */
-#include <string.h>	/* for memcpy() */
-#include "md5.h"
-
-#ifndef HIGHFIRST
-#define byteReverse(buf, len)	/* Nothing */
-#else
-void byteReverse(unsigned char *buf, unsigned longs);
-
-#ifndef ASM_MD5
-/*
- * Note: this code is harmless on little-endian machines.
- */
-void byteReverse(unsigned char *buf, unsigned longs)
-{
-	uint32 t;
-	do {
-		t = (uint32)((unsigned)buf[3]<<8 | buf[2]) << 16 |
-		            ((unsigned)buf[1]<<8 | buf[0]);
-		*(uint32 *)buf = t;
-		buf += 4;
-	} while (--longs);
-}
-#endif
-#endif
-
-/*
- * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
- * initialization constants.
- */
-void
-MD5Init(struct MD5Context *ctx)
-{
-	ctx->buf[0] = 0x67452301;
-	ctx->buf[1] = 0xefcdab89;
-	ctx->buf[2] = 0x98badcfe;
-	ctx->buf[3] = 0x10325476;
-
-	ctx->bits[0] = 0;
-	ctx->bits[1] = 0;
-}
-
-/*
- * Update context to reflect the concatenation of another buffer full
- * of bytes.
- */
-void
-MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len)
-{
-	uint32 t;
-
-	/* Update bitcount */
-
-	t = ctx->bits[0];
-	if ((ctx->bits[0] = t + ((uint32)len << 3)) < t)
-		ctx->bits[1]++;	/* Carry from low to high */
-	ctx->bits[1] += len >> 29;
-
-	t = (t >> 3) & 0x3f;	/* Bytes already in shsInfo->data */
-
-	/* Handle any leading odd-sized chunks */
-
-	if ( t ) {
-		unsigned char *p = (unsigned char *)ctx->in + t;
-
-		t = 64-t;
-		if (len < t) {
-			memcpy(p, buf, len);
-			return;
-		}
-		memcpy(p, buf, t);
-		byteReverse(ctx->in, 16);
-		MD5Transform(ctx->buf, (uint32 *)ctx->in);
-		buf += t;
-		len -= t;
-	}
-
-	/* Process data in 64-byte chunks */
-
-	while (len >= 64) {
-		memcpy(ctx->in, buf, 64);
-		byteReverse(ctx->in, 16);
-		MD5Transform(ctx->buf, (uint32 *)ctx->in);
-		buf += 64;
-		len -= 64;
-	}
-
-	/* Handle any remaining bytes of data. */
-
-	memcpy(ctx->in, buf, len);
-}
-
-/*
- * Final wrapup - pad to 64-byte boundary with the bit pattern 
- * 1 0* (64-bit count of bits processed, MSB-first)
- */
-void
-MD5Final(unsigned char digest[16], struct MD5Context *ctx)
-{
-	unsigned count;
-	unsigned char *p;
-
-	/* Compute number of bytes mod 64 */
-	count = (ctx->bits[0] >> 3) & 0x3F;
-
-	/* Set the first char of padding to 0x80.  This is safe since there is
-	   always at least one byte free */
-	p = (unsigned char*)(ctx->in) + count;
-	*p++ = 0x80;
-
-	/* Bytes of padding needed to make 64 bytes */
-	count = 64 - 1 - count;
-
-	/* Pad out to 56 mod 64 */
-	if (count < 8) {
-		/* Two lots of padding:  Pad the first block to 64 bytes */
-		memset(p, 0, count);
-		byteReverse(ctx->in, 16);
-		MD5Transform(ctx->buf, (uint32 *)ctx->in);
-
-		/* Now fill the next block with 56 bytes */
-		memset(ctx->in, 0, 56);
-	} else {
-		/* Pad block to 56 bytes */
-		memset(p, 0, count-8);
-	}
-	byteReverse(ctx->in, 14);
-
-	/* Append length in bits and transform */
-	((uint32 *)ctx->in)[ 14 ] = ctx->bits[0];
-	((uint32 *)ctx->in)[ 15 ] = ctx->bits[1];
-
-	MD5Transform(ctx->buf, (uint32 *)ctx->in);
-	byteReverse((unsigned char *)ctx->buf, 4);
-	memcpy(digest, ctx->buf, 16);
-	memset(ctx, 0, sizeof(*ctx));	/* In case it's sensitive */
-}
-
-#ifndef ASM_MD5
-
-/* The four core functions - F1 is optimized somewhat */
-
-/* #define F1(x, y, z) (x & y | ~x & z) */
-#define F1(x, y, z) (z ^ (x & (y ^ z)))
-#define F2(x, y, z) F1(z, x, y)
-#define F3(x, y, z) (x ^ y ^ z)
-#define F4(x, y, z) (y ^ (x | ~z))
-
-/* This is the central step in the MD5 algorithm. */
-#define MD5STEP(f, w, x, y, z, data, s) \
-	( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
-
-/*
- * The core of the MD5 algorithm, this alters an existing MD5 hash to
- * reflect the addition of 16 longwords of new data.  MD5Update blocks
- * the data and converts bytes into longwords for this routine.
- */
-void
-MD5Transform(uint32 buf[4], uint32 const in[16])
-{
-	register uint32 a, b, c, d;
-
-	a = buf[0];
-	b = buf[1];
-	c = buf[2];
-	d = buf[3];
-
-	MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478,  7);
-	MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12);
-	MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17);
-	MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22);
-	MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf,  7);
-	MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12);
-	MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17);
-	MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22);
-	MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8,  7);
-	MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12);
-	MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17);
-	MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22);
-	MD5STEP(F1, a, b, c, d, in[12]+0x6b901122,  7);
-	MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12);
-	MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17);
-	MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22);
-
-	MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562,  5);
-	MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340,  9);
-	MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14);
-	MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20);
-	MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d,  5);
-	MD5STEP(F2, d, a, b, c, in[10]+0x02441453,  9);
-	MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14);
-	MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20);
-	MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6,  5);
-	MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6,  9);
-	MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14);
-	MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20);
-	MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905,  5);
-	MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8,  9);
-	MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14);
-	MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20);
-
-	MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942,  4);
-	MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11);
-	MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16);
-	MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23);
-	MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44,  4);
-	MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11);
-	MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16);
-	MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23);
-	MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6,  4);
-	MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11);
-	MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16);
-	MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23);
-	MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039,  4);
-	MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11);
-	MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16);
-	MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23);
-
-	MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244,  6);
-	MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10);
-	MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15);
-	MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21);
-	MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3,  6);
-	MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10);
-	MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15);
-	MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21);
-	MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f,  6);
-	MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10);
-	MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15);
-	MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21);
-	MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82,  6);
-	MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10);
-	MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15);
-	MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21);
-
-	buf[0] += a;
-	buf[1] += b;
-	buf[2] += c;
-	buf[3] += d;
-}
-#endif
diff --git a/third_party/libjingle/source/talk/base/messagehandler.cc b/third_party/libjingle/source/talk/base/messagehandler.cc
deleted file mode 100644
index 5b3585b..0000000
--- a/third_party/libjingle/source/talk/base/messagehandler.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/messagehandler.h"
-#include "talk/base/messagequeue.h"
-
-namespace talk_base {
-
-MessageHandler::~MessageHandler() {
-  MessageQueueManager::Instance()->Clear(this);
-}
-
-} // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/messagehandler.h b/third_party/libjingle/source/talk/base/messagehandler.h
deleted file mode 100644
index bf7a4c2..0000000
--- a/third_party/libjingle/source/talk/base/messagehandler.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_MESSAGEHANDLER_H_
-#define TALK_BASE_MESSAGEHANDLER_H_
-
-#include "talk/base/constructormagic.h"
-
-namespace talk_base {
-
-struct Message;
-
-// Messages get dispatched to a MessageHandler
-
-class MessageHandler {
- public:
-  virtual ~MessageHandler();
-
-  virtual void OnMessage(Message* msg) = 0;
-
- protected:
-  MessageHandler() {}
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(MessageHandler);
-};
-
-} // namespace talk_base
-
-#endif // TALK_BASE_MESSAGEHANDLER_H_
diff --git a/third_party/libjingle/source/talk/base/messagequeue.cc b/third_party/libjingle/source/talk/base/messagequeue.cc
deleted file mode 100644
index 8c3a8ce..0000000
--- a/third_party/libjingle/source/talk/base/messagequeue.cc
+++ /dev/null
@@ -1,383 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#if defined(_MSC_VER) && _MSC_VER < 1300
-#pragma warning(disable:4786)
-#endif
-
-#ifdef POSIX
-#include <sys/time.h>
-#endif
-
-#include "talk/base/common.h"
-#include "talk/base/logging.h"
-#include "talk/base/messagequeue.h"
-#include "talk/base/physicalsocketserver.h"
-
-
-namespace talk_base {
-
-const uint32 kMaxMsgLatency = 150;  // 150 ms
-
-//------------------------------------------------------------------
-// MessageQueueManager
-
-MessageQueueManager* MessageQueueManager::instance_;
-
-MessageQueueManager* MessageQueueManager::Instance() {
-  // Note: This is not thread safe, but it is first called before threads are
-  // spawned.
-  if (!instance_)
-    instance_ = new MessageQueueManager;
-  return instance_;
-}
-
-MessageQueueManager::MessageQueueManager() {
-}
-
-MessageQueueManager::~MessageQueueManager() {
-}
-
-void MessageQueueManager::Add(MessageQueue *message_queue) {
-  // MessageQueueManager methods should be non-reentrant, so we
-  // ASSERT that is the case.  If any of these ASSERT, please
-  // contact bpm or jbeda.
-  ASSERT(!crit_.CurrentThreadIsOwner());
-  CritScope cs(&crit_);
-  message_queues_.push_back(message_queue);
-}
-
-void MessageQueueManager::Remove(MessageQueue *message_queue) {
-  ASSERT(!crit_.CurrentThreadIsOwner());  // See note above.
-  // If this is the last MessageQueue, destroy the manager as well so that
-  // we don't leak this object at program shutdown. As mentioned above, this is
-  // not thread-safe, but this should only happen at program termination (when
-  // the ThreadManager is destroyed, and threads are no longer active).
-  bool destroy = false;
-  {
-    CritScope cs(&crit_);
-    std::vector<MessageQueue *>::iterator iter;
-    iter = std::find(message_queues_.begin(), message_queues_.end(),
-                     message_queue);
-    if (iter != message_queues_.end()) {
-      message_queues_.erase(iter);      
-    }
-    destroy = message_queues_.empty();
-  }
-  if (destroy) {
-    instance_ = NULL;
-    delete this;    
-  }
-}
-
-void MessageQueueManager::Clear(MessageHandler *handler) {
-  ASSERT(!crit_.CurrentThreadIsOwner());  // See note above.
-  CritScope cs(&crit_);
-  std::vector<MessageQueue *>::iterator iter;
-  for (iter = message_queues_.begin(); iter != message_queues_.end(); iter++)
-    (*iter)->Clear(handler);
-}
-
-//------------------------------------------------------------------
-// MessageQueue
-
-MessageQueue::MessageQueue(SocketServer* ss)
-    : ss_(ss), fStop_(false), fPeekKeep_(false), active_(false),
-      dmsgq_next_num_(0) {
-  if (!ss_) {
-    // Currently, MessageQueue holds a socket server, and is the base class for
-    // Thread.  It seems like it makes more sense for Thread to hold the socket
-    // server, and provide it to the MessageQueue, since the Thread controls
-    // the I/O model, and MQ is agnostic to those details.  Anyway, this causes
-    // messagequeue_unittest to depend on network libraries... yuck.
-    default_ss_.reset(new PhysicalSocketServer());
-    ss_ = default_ss_.get();
-  }
-  ss_->SetMessageQueue(this);
-}
-
-MessageQueue::~MessageQueue() {
-  // The signal is done from here to ensure
-  // that it always gets called when the queue
-  // is going away.
-  SignalQueueDestroyed();
-  if (active_) {
-    MessageQueueManager::Instance()->Remove(this);
-    Clear(NULL);
-  }
-  if (ss_) {
-    ss_->SetMessageQueue(NULL);
-  }
-}
-
-void MessageQueue::set_socketserver(SocketServer* ss) {
-  ss_ = ss ? ss : default_ss_.get();
-  ss_->SetMessageQueue(this);
-}
-
-void MessageQueue::Quit() {
-  fStop_ = true;
-  ss_->WakeUp();
-}
-
-bool MessageQueue::IsQuitting() {
-  return fStop_;
-}
-
-void MessageQueue::Restart() {
-  fStop_ = false;
-}
-
-bool MessageQueue::Peek(Message *pmsg, int cmsWait) {
-  if (fPeekKeep_) {
-    *pmsg = msgPeek_;
-    return true;
-  }
-  if (!Get(pmsg, cmsWait))
-    return false;
-  msgPeek_ = *pmsg;
-  fPeekKeep_ = true;
-  return true;
-}
-
-bool MessageQueue::Get(Message *pmsg, int cmsWait, bool process_io) {
-  // Return and clear peek if present
-  // Always return the peek if it exists so there is Peek/Get symmetry
-
-  if (fPeekKeep_) {
-    *pmsg = msgPeek_;
-    fPeekKeep_ = false;
-    return true;
-  }
-
-  // Get w/wait + timer scan / dispatch + socket / event multiplexer dispatch
-
-  int cmsTotal = cmsWait;
-  int cmsElapsed = 0;
-  uint32 msStart = Time();
-  uint32 msCurrent = msStart;
-  while (true) {
-    // Check for sent messages
-
-    ReceiveSends();
-
-    // Check queues
-
-    int cmsDelayNext = kForever;
-    {
-      CritScope cs(&crit_);
-
-      // Check for delayed messages that have been triggered
-      // Calc the next trigger too
-
-      while (!dmsgq_.empty()) {
-        if (TimeIsLater(msCurrent, dmsgq_.top().msTrigger_)) {
-          cmsDelayNext = TimeDiff(dmsgq_.top().msTrigger_, msCurrent);
-          break;
-        }
-        msgq_.push_back(dmsgq_.top().msg_);
-        dmsgq_.pop();
-      }
-
-      // Check for posted events
-
-      while (!msgq_.empty()) {
-        *pmsg = msgq_.front();
-        if (pmsg->ts_sensitive) {
-          long delay = TimeDiff(msCurrent, pmsg->ts_sensitive);
-          if (delay > 0) {
-            LOG_F(LS_WARNING) << "id: " << pmsg->message_id << "  delay: "
-                              << (delay + kMaxMsgLatency) << "ms";
-          }
-        }
-        msgq_.pop_front();
-        if (MQID_DISPOSE == pmsg->message_id) {
-          ASSERT(NULL == pmsg->phandler);
-          delete pmsg->pdata;
-          continue;
-        }
-        return true;
-      }
-    }
-
-    if (fStop_)
-      break;
-
-    // Which is shorter, the delay wait or the asked wait?
-
-    int cmsNext;
-    if (cmsWait == kForever) {
-      cmsNext = cmsDelayNext;
-    } else {
-      cmsNext = _max(0, cmsTotal - cmsElapsed);
-      if ((cmsDelayNext != kForever) && (cmsDelayNext < cmsNext))
-        cmsNext = cmsDelayNext;
-    }
-
-    // Wait and multiplex in the meantime
-    if (!ss_->Wait(cmsNext, process_io))
-      return false;
-
-    // If the specified timeout expired, return
-
-    msCurrent = Time();
-    cmsElapsed = TimeDiff(msCurrent, msStart);
-    if (cmsWait != kForever) {
-      if (cmsElapsed >= cmsWait)
-        return false;
-    }
-  }
-  return false;
-}
-
-void MessageQueue::ReceiveSends() {
-}
-
-void MessageQueue::Post(MessageHandler *phandler, uint32 id,
-    MessageData *pdata, bool time_sensitive) {
-  if (fStop_)
-    return;
-
-  // Keep thread safe
-  // Add the message to the end of the queue
-  // Signal for the multiplexer to return
-
-  CritScope cs(&crit_);
-  EnsureActive();
-  Message msg;
-  msg.phandler = phandler;
-  msg.message_id = id;
-  msg.pdata = pdata;
-  if (time_sensitive) {
-    msg.ts_sensitive = Time() + kMaxMsgLatency;
-  }
-  msgq_.push_back(msg);
-  ss_->WakeUp();
-}
-
-void MessageQueue::DoDelayPost(int cmsDelay, uint32 tstamp,
-    MessageHandler *phandler, uint32 id, MessageData* pdata) {
-  if (fStop_)
-    return;
-
-  // Keep thread safe
-  // Add to the priority queue. Gets sorted soonest first.
-  // Signal for the multiplexer to return.
-
-  CritScope cs(&crit_);
-  EnsureActive();
-  Message msg;
-  msg.phandler = phandler;
-  msg.message_id = id;
-  msg.pdata = pdata;
-  DelayedMessage dmsg(cmsDelay, tstamp, dmsgq_next_num_, msg);
-  dmsgq_.push(dmsg);
-  // If this message queue processes 1 message every millisecond for 50 days,
-  // we will wrap this number.  Even then, only messages with identical times
-  // will be misordered, and then only briefly.  This is probably ok.
-  VERIFY(0 != ++dmsgq_next_num_);
-  ss_->WakeUp();
-}
-
-int MessageQueue::GetDelay() {
-  CritScope cs(&crit_);
-
-  if (!msgq_.empty())
-    return 0;
-
-  if (!dmsgq_.empty()) {
-    int delay = TimeUntil(dmsgq_.top().msTrigger_);
-    if (delay < 0)
-      delay = 0;
-    return delay;
-  }
-
-  return kForever;
-}
-
-void MessageQueue::Clear(MessageHandler *phandler, uint32 id,
-                         MessageList* removed) {
-  CritScope cs(&crit_);
-
-  // Remove messages with phandler
-
-  if (fPeekKeep_ && msgPeek_.Match(phandler, id)) {
-    if (removed) {
-      removed->push_back(msgPeek_);
-    } else {
-      delete msgPeek_.pdata;
-    }
-    fPeekKeep_ = false;
-  }
-
-  // Remove from ordered message queue
-
-  for (MessageList::iterator it = msgq_.begin(); it != msgq_.end();) {
-    if (it->Match(phandler, id)) {
-      if (removed) {
-        removed->push_back(*it);
-      } else {
-        delete it->pdata;
-      }
-      it = msgq_.erase(it);
-    } else {
-      ++it;
-    }
-  }
-
-  // Remove from priority queue. Not directly iterable, so use this approach
-
-  PriorityQueue::container_type::iterator new_end = dmsgq_.container().begin();
-  for (PriorityQueue::container_type::iterator it = new_end;
-       it != dmsgq_.container().end(); ++it) {
-    if (it->msg_.Match(phandler, id)) {
-      if (removed) {
-        removed->push_back(it->msg_);
-      } else {
-        delete it->msg_.pdata;
-      }
-    } else {
-      *new_end++ = *it;
-    }
-  }
-  dmsgq_.container().erase(new_end, dmsgq_.container().end());
-  dmsgq_.reheap();
-}
-
-void MessageQueue::Dispatch(Message *pmsg) {
-  pmsg->phandler->OnMessage(pmsg);
-}
-
-void MessageQueue::EnsureActive() {
-  ASSERT(crit_.CurrentThreadIsOwner());
-  if (!active_) {
-    active_ = true;
-    MessageQueueManager::Instance()->Add(this);
-  }
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/messagequeue.h b/third_party/libjingle/source/talk/base/messagequeue.h
deleted file mode 100644
index 2857182..0000000
--- a/third_party/libjingle/source/talk/base/messagequeue.h
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_MESSAGEQUEUE_H_
-#define TALK_BASE_MESSAGEQUEUE_H_
-
-#include <algorithm>
-#include <cstring>
-#include <list>
-#include <queue>
-#include <vector>
-
-#include "talk/base/basictypes.h"
-#include "talk/base/constructormagic.h"
-#include "talk/base/criticalsection.h"
-#include "talk/base/messagehandler.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/base/scoped_ref_ptr.h"
-#include "talk/base/sigslot.h"
-#include "talk/base/socketserver.h"
-#include "talk/base/timeutils.h"
-
-namespace talk_base {
-
-struct Message;
-class MessageQueue;
-
-// MessageQueueManager does cleanup of of message queues
-
-class MessageQueueManager {
- public:
-  static MessageQueueManager* Instance();
-
-  void Add(MessageQueue *message_queue);
-  void Remove(MessageQueue *message_queue);
-  void Clear(MessageHandler *handler);
-
- private:
-  MessageQueueManager();
-  ~MessageQueueManager();
-
-  static MessageQueueManager* instance_;
-  // This list contains 'active' MessageQueues.
-  std::vector<MessageQueue *> message_queues_;
-  CriticalSection crit_;
-};
-
-// Derive from this for specialized data
-// App manages lifetime, except when messages are purged
-
-class MessageData {
- public:
-  MessageData() {}
-  virtual ~MessageData() {}
-};
-
-template <class T>
-class TypedMessageData : public MessageData {
- public:
-  explicit TypedMessageData(const T& data) : data_(data) { }
-  const T& data() const { return data_; }
-  T& data() { return data_; }
- private:
-  T data_;
-};
-
-// Like TypedMessageData, but for pointers that require a delete.
-template <class T>
-class ScopedMessageData : public MessageData {
- public:
-  explicit ScopedMessageData(T* data) : data_(data) { }
-  const scoped_ptr<T>& data() const { return data_; }
-  scoped_ptr<T>& data() { return data_; }
- private:
-  scoped_ptr<T> data_;
-};
-
-// Like ScopedMessageData, but for reference counted pointers.
-template <class T>
-class ScopedRefMessageData : public MessageData {
- public:
-  explicit ScopedRefMessageData(T* data) : data_(data) { }
-  const scoped_refptr<T>& data() const { return data_; }
-  scoped_refptr<T>& data() { return data_; }
- private:
-  scoped_refptr<T> data_;
-};
-
-template<class T>
-inline MessageData* WrapMessageData(const T& data) {
-  return new TypedMessageData<T>(data);
-}
-
-template<class T>
-inline const T& UseMessageData(MessageData* data) {
-  return static_cast< TypedMessageData<T>* >(data)->data();
-}
-
-template<class T>
-class DisposeData : public MessageData {
- public:
-  explicit DisposeData(T* data) : data_(data) { }
-  virtual ~DisposeData() { delete data_; }
- private:
-  T* data_;
-};
-
-const uint32 MQID_ANY = static_cast<uint32>(-1);
-const uint32 MQID_DISPOSE = static_cast<uint32>(-2);
-
-// No destructor
-
-struct Message {
-  Message() {
-    memset(this, 0, sizeof(*this));
-  }
-  inline bool Match(MessageHandler* handler, uint32 id) const {
-    return (handler == NULL || handler == phandler)
-           && (id == MQID_ANY || id == message_id);
-  }
-  MessageHandler *phandler;
-  uint32 message_id;
-  MessageData *pdata;
-  uint32 ts_sensitive;
-};
-
-typedef std::list<Message> MessageList;
-
-// DelayedMessage goes into a priority queue, sorted by trigger time.  Messages
-// with the same trigger time are processed in num_ (FIFO) order.
-
-class DelayedMessage {
- public:
-  DelayedMessage(int delay, uint32 trigger, uint32 num, const Message& msg)
-  : cmsDelay_(delay), msTrigger_(trigger), num_(num), msg_(msg) { }
-
-  bool operator< (const DelayedMessage& dmsg) const {
-    return (dmsg.msTrigger_ < msTrigger_)
-           || ((dmsg.msTrigger_ == msTrigger_) && (dmsg.num_ < num_));
-  }
-
-  int cmsDelay_;  // for debugging
-  uint32 msTrigger_;
-  uint32 num_;
-  Message msg_;
-};
-
-class MessageQueue {
- public:
-  explicit MessageQueue(SocketServer* ss = NULL);
-  virtual ~MessageQueue();
-
-  SocketServer* socketserver() { return ss_; }
-  void set_socketserver(SocketServer* ss);
-
-  // Note: The behavior of MessageQueue has changed.  When a MQ is stopped,
-  // futher Posts and Sends will fail.  However, any pending Sends and *ready*
-  // Posts (as opposed to unexpired delayed Posts) will be delivered before
-  // Get (or Peek) returns false.  By guaranteeing delivery of those messages,
-  // we eliminate the race condition when an MessageHandler and MessageQueue
-  // may be destroyed independently of each other.
-  virtual void Quit();
-  virtual bool IsQuitting();
-  virtual void Restart();
-
-  // Get() will process I/O until:
-  //  1) A message is available (returns true)
-  //  2) cmsWait seconds have elapsed (returns false)
-  //  3) Stop() is called (returns false)
-  virtual bool Get(Message *pmsg, int cmsWait = kForever,
-                   bool process_io = true);
-  virtual bool Peek(Message *pmsg, int cmsWait = 0);
-  virtual void Post(MessageHandler *phandler, uint32 id = 0,
-                    MessageData *pdata = NULL, bool time_sensitive = false);
-  virtual void PostDelayed(int cmsDelay, MessageHandler *phandler,
-                           uint32 id = 0, MessageData *pdata = NULL) {
-    return DoDelayPost(cmsDelay, TimeAfter(cmsDelay), phandler, id, pdata);
-  }
-  virtual void PostAt(uint32 tstamp, MessageHandler *phandler,
-                      uint32 id = 0, MessageData *pdata = NULL) {
-    return DoDelayPost(TimeUntil(tstamp), tstamp, phandler, id, pdata);
-  }
-  virtual void Clear(MessageHandler *phandler, uint32 id = MQID_ANY,
-                     MessageList* removed = NULL);
-  virtual void Dispatch(Message *pmsg);
-  virtual void ReceiveSends();
-
-  // Amount of time until the next message can be retrieved
-  virtual int GetDelay();
-
-  bool empty() const { return msgq_.empty() && dmsgq_.empty() && !fPeekKeep_; }
-  size_t size() const { return msgq_.size() + dmsgq_.size() + fPeekKeep_; }
-
-  // Internally posts a message which causes the doomed object to be deleted
-  template<class T> void Dispose(T* doomed) {
-    if (doomed) {
-      Post(NULL, MQID_DISPOSE, new DisposeData<T>(doomed));
-    }
-  }
-
-  // When this signal is sent out, any references to this queue should
-  // no longer be used.
-  sigslot::signal0<> SignalQueueDestroyed;
-
- protected:
-  class PriorityQueue : public std::priority_queue<DelayedMessage> {
-   public:
-    container_type& container() { return c; }
-    void reheap() { make_heap(c.begin(), c.end(), comp); }
-  };
-
-  void EnsureActive();
-  void DoDelayPost(int cmsDelay, uint32 tstamp, MessageHandler *phandler,
-                   uint32 id, MessageData* pdata);
-
-  // The SocketServer is not owned by MessageQueue.
-  SocketServer* ss_;
-  // If a server isn't supplied in the constructor, use this one.
-  scoped_ptr<SocketServer> default_ss_;
-  bool fStop_;
-  bool fPeekKeep_;
-  Message msgPeek_;
-  // A message queue is active if it has ever had a message posted to it.
-  // This also corresponds to being in MessageQueueManager's global list.
-  bool active_;
-  MessageList msgq_;
-  PriorityQueue dmsgq_;
-  uint32 dmsgq_next_num_;
-  CriticalSection crit_;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(MessageQueue);
-};
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_MESSAGEQUEUE_H_
diff --git a/third_party/libjingle/source/talk/base/messagequeue_unittest.cc b/third_party/libjingle/source/talk/base/messagequeue_unittest.cc
deleted file mode 100644
index 1ca65ea..0000000
--- a/third_party/libjingle/source/talk/base/messagequeue_unittest.cc
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/gunit.h"
-#include "talk/base/logging.h"
-#include "talk/base/timeutils.h"
-#include "talk/base/messagequeue.h"
-
-using namespace talk_base;
-
-TEST(MessageQueue, DelayedPostsWithIdenticalTimesAreProcessedInFifoOrder) {
-  MessageQueue q;
-
-  TimeStamp now = Time();
-  q.PostAt(now, NULL, 3);
-  q.PostAt(now - 2, NULL, 0);
-  q.PostAt(now - 1, NULL, 1);
-  q.PostAt(now, NULL, 4);
-  q.PostAt(now - 1, NULL, 2);
-
-  Message msg;
-  for (size_t i=0; i<5; ++i) {
-    memset(&msg, 0, sizeof(msg));
-    EXPECT_TRUE(q.Get(&msg, 0));
-    EXPECT_EQ(i, msg.message_id);
-  }
-
-  EXPECT_FALSE(q.Get(&msg, 0));  // No more messages
-}
diff --git a/third_party/libjingle/source/talk/base/multipart.cc b/third_party/libjingle/source/talk/base/multipart.cc
deleted file mode 100644
index d280ff3..0000000
--- a/third_party/libjingle/source/talk/base/multipart.cc
+++ /dev/null
@@ -1,268 +0,0 @@
-// libjingle
-// Copyright 2004--2010, Google Inc.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-//  1. Redistributions of source code must retain the above copyright notice,
-//     this list of conditions and the following disclaimer.
-//  2. Redistributions in binary form must reproduce the above copyright notice,
-//     this list of conditions and the following disclaimer in the documentation
-//     and/or other materials provided with the distribution.
-//  3. The name of the author may not be used to endorse or promote products
-//     derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
-#include "talk/base/common.h"
-#include "talk/base/httpcommon.h"
-#include "talk/base/multipart.h"
-
-namespace talk_base {
-
-///////////////////////////////////////////////////////////////////////////////
-// MultipartStream
-///////////////////////////////////////////////////////////////////////////////
-
-MultipartStream::MultipartStream(const std::string& type,
-                                 const std::string& boundary)
-    : type_(type),
-      boundary_(boundary),
-      adding_(true),
-      current_(0),
-      position_(0) {
-  // The content type should be multipart/*.
-  ASSERT(0 == strncmp(type_.c_str(), "multipart/", 10));
-}
-
-MultipartStream::~MultipartStream() {
-  Close();
-}
-
-void MultipartStream::GetContentType(std::string* content_type) {
-  ASSERT(NULL != content_type);
-  content_type->assign(type_);
-  content_type->append("; boundary=");
-  content_type->append(boundary_);
-}
-
-bool MultipartStream::AddPart(StreamInterface* data_stream,
-                              const std::string& content_disposition,
-                              const std::string& content_type) {
-  if (!AddPart("", content_disposition, content_type))
-    return false;
-  parts_.push_back(data_stream);
-  data_stream->SignalEvent.connect(this, &MultipartStream::OnEvent);
-  return true;
-}
-
-bool MultipartStream::AddPart(const std::string& data,
-                              const std::string& content_disposition,
-                              const std::string& content_type) {
-  ASSERT(adding_);
-  if (!adding_)
-    return false;
-  std::stringstream ss;
-  if (!parts_.empty()) {
-    ss << "\r\n";
-  }
-  ss << "--" << boundary_ << "\r\n";
-  if (!content_disposition.empty()) {
-    ss << ToString(HH_CONTENT_DISPOSITION) << ": "
-       << content_disposition << "\r\n";
-  }
-  if (!content_type.empty()) {
-    ss << ToString(HH_CONTENT_TYPE) << ": "
-       << content_type << "\r\n";
-  }
-  ss << "\r\n" << data;
-  parts_.push_back(new MemoryStream(ss.str().data(), ss.str().size()));
-  return true;
-}
-
-void MultipartStream::EndParts() {
-  ASSERT(adding_);
-  if (!adding_)
-    return;
-
-  std::stringstream ss;
-  if (!parts_.empty()) {
-    ss << "\r\n";
-  }
-  ss << "--" << boundary_ << "--" << "\r\n";
-  parts_.push_back(new MemoryStream(ss.str().data(), ss.str().size()));
-
-  ASSERT(0 == current_);
-  ASSERT(0 == position_);
-  adding_ = false;
-  SignalEvent(this, SE_OPEN | SE_READ, 0);
-}
-
-size_t MultipartStream::GetPartSize(const std::string& data,
-                                    const std::string& content_disposition,
-                                    const std::string& content_type) const {
-  size_t size = 0;
-  if (!parts_.empty()) {
-    size += 2;  // for "\r\n";
-  }
-  size += boundary_.size() + 4;  // for "--boundary_\r\n";
-  if (!content_disposition.empty()) {
-    // for ToString(HH_CONTENT_DISPOSITION): content_disposition\r\n
-    size += std::string(ToString(HH_CONTENT_DISPOSITION)).size() + 2 +
-        content_disposition.size() + 2;
-  }
-  if (!content_type.empty()) {
-    // for ToString(HH_CONTENT_TYPE): content_type\r\n
-    size += std::string(ToString(HH_CONTENT_TYPE)).size() + 2 +
-        content_type.size() + 2;
-  }
-  size += 2 + data.size();  // for \r\ndata
-  return size;
-}
-
-size_t MultipartStream::GetEndPartSize() const {
-  size_t size = 0;
-  if (!parts_.empty()) {
-    size += 2;  // for "\r\n";
-  }
-  size += boundary_.size() + 6;  // for "--boundary_--\r\n";
-  return size;
-}
-
-//
-// StreamInterface
-//
-
-StreamState MultipartStream::GetState() const {
-  if (adding_) {
-    return SS_OPENING;
-  }
-  return (current_ < parts_.size()) ? SS_OPEN : SS_CLOSED;
-}
-
-StreamResult MultipartStream::Read(void* buffer, size_t buffer_len,
-                                   size_t* read, int* error) {
-  if (adding_) {
-    return SR_BLOCK;
-  }
-  size_t local_read;
-  if (!read) read = &local_read;
-  while (current_ < parts_.size()) {
-    StreamResult result = parts_[current_]->Read(buffer, buffer_len, read,
-                                                 error);
-    if (SR_EOS != result) {
-      if (SR_SUCCESS == result) {
-        position_ += *read;
-      }
-      return result;
-    }
-    ++current_;
-  }
-  return SR_EOS;
-}
-
-StreamResult MultipartStream::Write(const void* data, size_t data_len,
-                                    size_t* written, int* error) {
-  if (error) {
-    *error = -1;
-  }
-  return SR_ERROR;
-}
-
-void MultipartStream::Close() {
-  for (size_t i = 0; i < parts_.size(); ++i) {
-    delete parts_[i];
-  }
-  parts_.clear();
-  adding_ = false;
-  current_ = 0;
-  position_ = 0;
-}
-
-bool MultipartStream::SetPosition(size_t position) {
-  if (adding_) {
-    return false;
-  }
-  size_t part_size, part_offset = 0;
-  for (size_t i = 0; i < parts_.size(); ++i) {
-    if (!parts_[i]->GetSize(&part_size)) {
-      return false;
-    }
-    if (part_offset + part_size > position) {
-      for (size_t j = i+1; j < _min(parts_.size(), current_+1); ++j) {
-        if (!parts_[j]->Rewind()) {
-          return false;
-        }
-      }
-      if (!parts_[i]->SetPosition(position - part_offset)) {
-        return false;
-      }
-      current_ = i;
-      position_ = position;
-      return true;
-    }
-    part_offset += part_size;
-  }
-  return false;
-}
-
-bool MultipartStream::GetPosition(size_t* position) const {
-  if (position) {
-    *position = position_;
-  }
-  return true;
-}
-
-bool MultipartStream::GetSize(size_t* size) const {
-  size_t part_size, total_size = 0;
-  for (size_t i = 0; i < parts_.size(); ++i) {
-    if (!parts_[i]->GetSize(&part_size)) {
-      return false;
-    }
-    total_size += part_size;
-  }
-  if (size) {
-    *size = total_size;
-  }
-  return true;
-}
-
-bool MultipartStream::GetAvailable(size_t* size) const {
-  if (adding_) {
-    return false;
-  }
-  size_t part_size, total_size = 0;
-  for (size_t i = current_; i < parts_.size(); ++i) {
-    if (!parts_[i]->GetAvailable(&part_size)) {
-      return false;
-    }
-    total_size += part_size;
-  }
-  if (size) {
-    *size = total_size;
-  }
-  return true;
-}
-
-//
-// StreamInterface Slots
-//
-
-void MultipartStream::OnEvent(StreamInterface* stream, int events, int error) {
-  if (adding_ || (current_ >= parts_.size()) || (parts_[current_] != stream)) {
-    return;
-  }
-  SignalEvent(this, events, error);
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/multipart.h b/third_party/libjingle/source/talk/base/multipart.h
deleted file mode 100644
index cce592b..0000000
--- a/third_party/libjingle/source/talk/base/multipart.h
+++ /dev/null
@@ -1,94 +0,0 @@
-// libjingle
-// Copyright 2004--2010, Google Inc.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-//  1. Redistributions of source code must retain the above copyright notice,
-//     this list of conditions and the following disclaimer.
-//  2. Redistributions in binary form must reproduce the above copyright notice,
-//     this list of conditions and the following disclaimer in the documentation
-//     and/or other materials provided with the distribution.
-//  3. The name of the author may not be used to endorse or promote products
-//     derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef TALK_BASE_MULTIPART_H__
-#define TALK_BASE_MULTIPART_H__
-
-#include <string>
-#include <vector>
-
-#include "talk/base/sigslot.h"
-#include "talk/base/stream.h"
-
-namespace talk_base {
-
-///////////////////////////////////////////////////////////////////////////////
-// MultipartStream - Implements an RFC2046 multipart stream by concatenating
-// the supplied parts together, and adding the correct boundaries.
-///////////////////////////////////////////////////////////////////////////////
-
-class MultipartStream : public StreamInterface, public sigslot::has_slots<> {
- public:
-  MultipartStream(const std::string& type, const std::string& boundary);
-  virtual ~MultipartStream();
-
-  void GetContentType(std::string* content_type);
-
-  // Note: If content_disposition and/or content_type are the empty string,
-  // they will be omitted.
-  bool AddPart(StreamInterface* data_stream,
-               const std::string& content_disposition,
-               const std::string& content_type);
-  bool AddPart(const std::string& data,
-               const std::string& content_disposition,
-               const std::string& content_type);
-  void EndParts();
-
-  // Calculates the size of a part before actually adding the part.
-  size_t GetPartSize(const std::string& data,
-                     const std::string& content_disposition,
-                     const std::string& content_type) const;
-  size_t GetEndPartSize() const;
-
-  // StreamInterface
-  virtual StreamState GetState() const;
-  virtual StreamResult Read(void* buffer, size_t buffer_len,
-                            size_t* read, int* error);
-  virtual StreamResult Write(const void* data, size_t data_len,
-                             size_t* written, int* error);
-  virtual void Close();
-  virtual bool SetPosition(size_t position);
-  virtual bool GetPosition(size_t* position) const;
-  virtual bool GetSize(size_t* size) const;
-  virtual bool GetAvailable(size_t* size) const;
-
- private:
-  typedef std::vector<StreamInterface*> PartList;
-
-  // StreamInterface Slots
-  void OnEvent(StreamInterface* stream, int events, int error);
-
-  std::string type_, boundary_;
-  PartList parts_;
-  bool adding_;
-  size_t current_;  // The index into parts_ of the current read position.
-  size_t position_;  // The current read position in bytes.
-
-  DISALLOW_COPY_AND_ASSIGN(MultipartStream);
-};
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_MULTIPART_H__
diff --git a/third_party/libjingle/source/talk/base/multipart_unittest.cc b/third_party/libjingle/source/talk/base/multipart_unittest.cc
deleted file mode 100644
index 18e3cf9..0000000
--- a/third_party/libjingle/source/talk/base/multipart_unittest.cc
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * libjingle
- * Copyright 2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string>
-
-#include "talk/base/gunit.h"
-#include "talk/base/helpers.h"
-#include "talk/base/logging.h"
-#include "talk/base/pathutils.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/base/multipart.h"
-
-namespace talk_base {
-
-static const std::string kTestMultipartBoundary = "123456789987654321";
-static const std::string kTestContentType =
-    "multipart/form-data; boundary=123456789987654321";
-static const char kTestData[] = "This is a test.";
-static const char kTestStreamContent[] = "This is a test stream.";
-
-TEST(MultipartTest, TestBasicOperations) {
-  MultipartStream multipart("multipart/form-data", kTestMultipartBoundary);
-  std::string content_type;
-  multipart.GetContentType(&content_type);
-  EXPECT_EQ(kTestContentType, content_type);
-
-  EXPECT_EQ(talk_base::SS_OPENING, multipart.GetState());
-
-  // The multipart stream contains only --boundary--\r\n
-  size_t end_part_size = multipart.GetEndPartSize();
-  multipart.EndParts();
-  EXPECT_EQ(talk_base::SS_OPEN, multipart.GetState());
-  size_t size;
-  EXPECT_TRUE(multipart.GetSize(&size));
-  EXPECT_EQ(end_part_size, size);
-
-  // Write is not supported.
-  EXPECT_EQ(talk_base::SR_ERROR,
-            multipart.Write(kTestData, sizeof(kTestData), NULL, NULL));
-
-  multipart.Close();
-  EXPECT_EQ(talk_base::SS_CLOSED, multipart.GetState());
-  EXPECT_TRUE(multipart.GetSize(&size));
-  EXPECT_EQ(0U, size);
-}
-
-TEST(MultipartTest, TestAddAndRead) {
-  MultipartStream multipart("multipart/form-data", kTestMultipartBoundary);
-
-  size_t part_size =
-      multipart.GetPartSize(kTestData, "form-data; name=\"text\"", "text");
-  EXPECT_TRUE(multipart.AddPart(kTestData, "form-data; name=\"text\"", "text"));
-  size_t size;
-  EXPECT_TRUE(multipart.GetSize(&size));
-  EXPECT_EQ(part_size, size);
-
-  talk_base::MemoryStream* stream =
-      new talk_base::MemoryStream(kTestStreamContent);
-  size_t stream_size = 0;
-  EXPECT_TRUE(stream->GetSize(&stream_size));
-  part_size +=
-      multipart.GetPartSize("", "form-data; name=\"stream\"", "stream");
-  part_size += stream_size;
-
-  EXPECT_TRUE(multipart.AddPart(
-      new talk_base::MemoryStream(kTestStreamContent),
-      "form-data; name=\"stream\"",
-      "stream"));
-  EXPECT_TRUE(multipart.GetSize(&size));
-  EXPECT_EQ(part_size, size);
-
-  // In adding state, block read.
-  char buffer[1024];
-  EXPECT_EQ(talk_base::SR_BLOCK,
-            multipart.Read(buffer, sizeof(buffer), NULL, NULL));
-  // Write is not supported.
-  EXPECT_EQ(talk_base::SR_ERROR,
-            multipart.Write(buffer, sizeof(buffer), NULL, NULL));
-
-  part_size += multipart.GetEndPartSize();
-  multipart.EndParts();
-  EXPECT_TRUE(multipart.GetSize(&size));
-  EXPECT_EQ(part_size, size);
-
-  // Read the multipart stream into StringStream
-  std::string str;
-  talk_base::StringStream str_stream(str);
-  EXPECT_EQ(talk_base::SR_SUCCESS,
-            Flow(&multipart, buffer, sizeof(buffer), &str_stream));
-  EXPECT_EQ(size, str.length());
-
-  // Search three boundaries and two parts in the order.
-  size_t pos = 0;
-  pos = str.find(kTestMultipartBoundary);
-  EXPECT_NE(std::string::npos, pos);
-  pos += kTestMultipartBoundary.length();
-
-  pos = str.find(kTestData, pos);
-  EXPECT_NE(std::string::npos, pos);
-  pos += sizeof(kTestData);
-
-  pos = str.find(kTestMultipartBoundary, pos);
-  EXPECT_NE(std::string::npos, pos);
-  pos += kTestMultipartBoundary.length();
-
-  pos = str.find(kTestStreamContent, pos);
-  EXPECT_NE(std::string::npos, pos);
-  pos += sizeof(kTestStreamContent);
-
-  pos = str.find(kTestMultipartBoundary, pos);
-  EXPECT_NE(std::string::npos, pos);
-  pos += kTestMultipartBoundary.length();
-
-  pos = str.find(kTestMultipartBoundary, pos);
-  EXPECT_EQ(std::string::npos, pos);
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/nat_unittest.cc b/third_party/libjingle/source/talk/base/nat_unittest.cc
deleted file mode 100644
index a7fc3b1..0000000
--- a/third_party/libjingle/source/talk/base/nat_unittest.cc
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * libjingle
- * Copyright 2004, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string>
-
-#include "talk/base/gunit.h"
-#include "talk/base/host.h"
-#include "talk/base/logging.h"
-#include "talk/base/natserver.h"
-#include "talk/base/natsocketfactory.h"
-#include "talk/base/network.h"
-#include "talk/base/physicalsocketserver.h"
-#include "talk/base/testclient.h"
-#include "talk/base/virtualsocketserver.h"
-
-using namespace talk_base;
-
-bool CheckReceive(
-    TestClient* client, bool should_receive, const char* buf, size_t size) {
-  return (should_receive) ?
-      client->CheckNextPacket(buf, size, 0) :
-      client->CheckNoPacket();
-}
-
-TestClient* CreateTestClient(
-      SocketFactory* factory, const SocketAddress& local_addr) {
-  AsyncUDPSocket* socket = AsyncUDPSocket::Create(factory, local_addr);
-  return new TestClient(socket);
-}
-
-// Tests that when sending from internal_addr to external_addrs through the
-// NAT type specified by nat_type, all external addrs receive the sent packet
-// and, if exp_same is true, all use the same mapped-address on the NAT.
-void TestSend(
-      SocketServer* internal, const SocketAddress& internal_addr,
-      SocketServer* external, const SocketAddress external_addrs[4],
-      NATType nat_type, bool exp_same) {
-  Thread th_int(internal);
-  Thread th_ext(external);
-
-  SocketAddress server_addr = internal_addr;
-  server_addr.SetPort(0);  // Auto-select a port
-  NATServer* nat = new NATServer(
-      nat_type, internal, server_addr, external, external_addrs[0]);
-  NATSocketFactory* natsf = new NATSocketFactory(internal,
-                                                 nat->internal_address());
-
-  TestClient* in = CreateTestClient(natsf, internal_addr);
-  TestClient* out[4];
-  for (int i = 0; i < 4; i++)
-    out[i] = CreateTestClient(external, external_addrs[i]);
-
-  th_int.Start();
-  th_ext.Start();
-
-  const char* buf = "filter_test";
-  size_t len = strlen(buf);
-
-  in->SendTo(buf, len, out[0]->address());
-  SocketAddress trans_addr;
-  EXPECT_TRUE(out[0]->CheckNextPacket(buf, len, &trans_addr));
-
-  for (int i = 1; i < 4; i++) {
-    in->SendTo(buf, len, out[i]->address());
-    SocketAddress trans_addr2;
-    EXPECT_TRUE(out[i]->CheckNextPacket(buf, len, &trans_addr2));
-    bool are_same = (trans_addr == trans_addr2);
-    ASSERT_EQ(are_same, exp_same) << "same translated address";
-  }
-
-  th_int.Stop();
-  th_ext.Stop();
-
-  delete nat;
-  delete natsf;
-  delete in;
-  for (int i = 0; i < 4; i++)
-    delete out[i];
-}
-
-// Tests that when sending from external_addrs to internal_addr, the packet
-// is delivered according to the specified filter_ip and filter_port rules.
-void TestRecv(
-      SocketServer* internal, const SocketAddress& internal_addr,
-      SocketServer* external, const SocketAddress external_addrs[4],
-      NATType nat_type, bool filter_ip, bool filter_port) {
-  Thread th_int(internal);
-  Thread th_ext(external);
-
-  SocketAddress server_addr = internal_addr;
-  server_addr.SetPort(0);  // Auto-select a port
-  NATServer* nat = new NATServer(
-      nat_type, internal, server_addr, external, external_addrs[0]);
-  NATSocketFactory* natsf = new NATSocketFactory(internal,
-                                                 nat->internal_address());
-
-  TestClient* in = CreateTestClient(natsf, internal_addr);
-  TestClient* out[4];
-  for (int i = 0; i < 4; i++)
-    out[i] = CreateTestClient(external, external_addrs[i]);
-
-  th_int.Start();
-  th_ext.Start();
-
-  const char* buf = "filter_test";
-  size_t len = strlen(buf);
-
-  in->SendTo(buf, len, out[0]->address());
-  SocketAddress trans_addr;
-  EXPECT_TRUE(out[0]->CheckNextPacket(buf, len, &trans_addr));
-
-  out[1]->SendTo(buf, len, trans_addr);
-  EXPECT_TRUE(CheckReceive(in, !filter_ip, buf, len));
-
-  out[2]->SendTo(buf, len, trans_addr);
-  EXPECT_TRUE(CheckReceive(in, !filter_port, buf, len));
-
-  out[3]->SendTo(buf, len, trans_addr);
-  EXPECT_TRUE(CheckReceive(in, !filter_ip && !filter_port, buf, len));
-
-  th_int.Stop();
-  th_ext.Stop();
-
-  delete nat;
-  delete natsf;
-  delete in;
-  for (int i = 0; i < 4; i++)
-    delete out[i];
-}
-
-// Tests that NATServer allocates bindings properly.
-void TestBindings(
-    SocketServer* internal, const SocketAddress& internal_addr,
-    SocketServer* external, const SocketAddress external_addrs[4]) {
-  TestSend(internal, internal_addr, external, external_addrs,
-           NAT_OPEN_CONE, true);
-  TestSend(internal, internal_addr, external, external_addrs,
-           NAT_ADDR_RESTRICTED, true);
-  TestSend(internal, internal_addr, external, external_addrs,
-           NAT_PORT_RESTRICTED, true);
-  TestSend(internal, internal_addr, external, external_addrs,
-           NAT_SYMMETRIC, false);
-}
-
-// Tests that NATServer filters packets properly.
-void TestFilters(
-    SocketServer* internal, const SocketAddress& internal_addr,
-    SocketServer* external, const SocketAddress external_addrs[4]) {
-  TestRecv(internal, internal_addr, external, external_addrs,
-           NAT_OPEN_CONE, false, false);
-  TestRecv(internal, internal_addr, external, external_addrs,
-           NAT_ADDR_RESTRICTED, true, false);
-  TestRecv(internal, internal_addr, external, external_addrs,
-           NAT_PORT_RESTRICTED, true, true);
-  TestRecv(internal, internal_addr, external, external_addrs,
-           NAT_SYMMETRIC, true, true);
-}
-
-TEST(NatTest, TestPhysical) {
-  BasicNetworkManager network_manager;
-  network_manager.StartUpdating();
-  // Process pending messages so the network list is updated.
-  Thread::Current()->ProcessMessages(0);
-
-  std::vector<Network*> networks;
-  network_manager.GetNetworks(&networks);
-  if (networks.empty()) {
-    LOG(LS_WARNING) << "Not enough network adapters for test.";
-    return;
-  }
-
-  SocketAddress int_addr("127.0.0.1", 0);
-  std::string ext_ip1 = "127.0.0.1";
-  std::string ext_ip2 = networks[0]->ip().ToString();
-
-  LOG(LS_INFO) << "selected ip " << ext_ip2;
-
-  SocketAddress ext_addrs[4] = {
-      SocketAddress(ext_ip1, 0),
-      SocketAddress(ext_ip2, 0),
-      SocketAddress(ext_ip1, 0),
-      SocketAddress(ext_ip2, 0)
-  };
-
-  PhysicalSocketServer* int_pss = new PhysicalSocketServer();
-  PhysicalSocketServer* ext_pss = new PhysicalSocketServer();
-
-  TestBindings(int_pss, int_addr, ext_pss, ext_addrs);
-  TestFilters(int_pss, int_addr, ext_pss, ext_addrs);
-}
-
-class TestVirtualSocketServer : public VirtualSocketServer {
- public:
-  explicit TestVirtualSocketServer(SocketServer* ss)
-      : VirtualSocketServer(ss) {}
-  // Expose this publicly
-  uint32 GetNextIP() { return VirtualSocketServer::GetNextIP(); }
-};
-
-TEST(NatTest, TestVirtual) {
-  TestVirtualSocketServer* int_vss = new TestVirtualSocketServer(
-      new PhysicalSocketServer());
-  TestVirtualSocketServer* ext_vss = new TestVirtualSocketServer(
-      new PhysicalSocketServer());
-
-  SocketAddress int_addr, ext_addrs[4];
-  int_addr.SetIP(IPAddress(int_vss->GetNextIP()));
-  ext_addrs[0].SetIP(IPAddress(ext_vss->GetNextIP()));
-  ext_addrs[1].SetIP(IPAddress(ext_vss->GetNextIP()));
-  ext_addrs[2].SetIP(ext_addrs[0].ipaddr());
-  ext_addrs[3].SetIP(ext_addrs[1].ipaddr());
-
-  TestBindings(int_vss, int_addr, ext_vss, ext_addrs);
-  TestFilters(int_vss, int_addr, ext_vss, ext_addrs);
-}
-
-
-// TODO: Finish this test
-class NatTcpTest : public testing::Test, public sigslot::has_slots<> {
- public:
-  NatTcpTest() : connected_(false) {}
-  virtual void SetUp() {
-    int_vss_ = new TestVirtualSocketServer(new PhysicalSocketServer());
-    ext_vss_ = new TestVirtualSocketServer(new PhysicalSocketServer());
-    nat_ = new NATServer(NAT_OPEN_CONE, int_vss_, SocketAddress(),
-                         ext_vss_, SocketAddress());
-    natsf_ = new NATSocketFactory(int_vss_, nat_->internal_address());
-  }
-  void OnConnectEvent(AsyncSocket* socket) {
-    connected_ = true;
-  }
-  void OnAcceptEvent(AsyncSocket* socket) {
-    accepted_ = server_->Accept(NULL);
-  }
-  void OnCloseEvent(AsyncSocket* socket, int error) {
-  }
-  void ConnectEvents() {
-    server_->SignalReadEvent.connect(this, &NatTcpTest::OnAcceptEvent);
-    client_->SignalConnectEvent.connect(this, &NatTcpTest::OnConnectEvent);
-  }
-  TestVirtualSocketServer* int_vss_;
-  TestVirtualSocketServer* ext_vss_;
-  NATServer* nat_;
-  NATSocketFactory* natsf_;
-  AsyncSocket* client_;
-  AsyncSocket* server_;
-  AsyncSocket* accepted_;
-  bool connected_;
-};
-
-TEST_F(NatTcpTest, DISABLED_TestConnectOut) {
-  server_ = ext_vss_->CreateAsyncSocket(SOCK_STREAM);
-  server_->Bind(SocketAddress());
-  server_->Listen(5);
-
-  client_ = int_vss_->CreateAsyncSocket(SOCK_STREAM);
-  EXPECT_GE(0, client_->Bind(SocketAddress()));
-  EXPECT_GE(0, client_->Connect(server_->GetLocalAddress()));
-
-
-  ConnectEvents();
-
-  EXPECT_TRUE_WAIT(connected_, 1000);
-  EXPECT_EQ(client_->GetRemoteAddress(), server_->GetLocalAddress());
-  EXPECT_EQ(client_->GetRemoteAddress(), accepted_->GetLocalAddress());
-  EXPECT_EQ(client_->GetLocalAddress(), accepted_->GetRemoteAddress());
-
-  client_->Close();
-}
-//#endif
diff --git a/third_party/libjingle/source/talk/base/natserver.cc b/third_party/libjingle/source/talk/base/natserver.cc
deleted file mode 100644
index 06493ad..0000000
--- a/third_party/libjingle/source/talk/base/natserver.cc
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/natserver.h"
-#include "talk/base/logging.h"
-
-namespace talk_base {
-
-RouteCmp::RouteCmp(NAT* nat) : symmetric(nat->IsSymmetric()) {
-}
-
-size_t RouteCmp::operator()(const SocketAddressPair& r) const {
-  size_t h = r.source().Hash();
-  if (symmetric)
-    h ^= r.destination().Hash();
-  return h;
-}
-
-bool RouteCmp::operator()(
-      const SocketAddressPair& r1, const SocketAddressPair& r2) const {
-  if (r1.source() < r2.source())
-    return true;
-  if (r2.source() < r1.source())
-    return false;
-  if (symmetric && (r1.destination() < r2.destination()))
-    return true;
-  if (symmetric && (r2.destination() < r1.destination()))
-    return false;
-  return false;
-}
-
-AddrCmp::AddrCmp(NAT* nat)
-    : use_ip(nat->FiltersIP()), use_port(nat->FiltersPort()) {
-}
-
-size_t AddrCmp::operator()(const SocketAddress& a) const {
-  size_t h = 0;
-  if (use_ip)
-    h ^= a.ip();
-  if (use_port)
-    h ^= a.port() | (a.port() << 16);
-  return h;
-}
-
-bool AddrCmp::operator()(
-      const SocketAddress& a1, const SocketAddress& a2) const {
-  if (use_ip && (a1.ip() < a2.ip()))
-    return true;
-  if (use_ip && (a2.ip() < a1.ip()))
-    return false;
-  if (use_port && (a1.port() < a2.port()))
-    return true;
-  if (use_port && (a2.port() < a1.port()))
-    return false;
-  return false;
-}
-
-NATServer::NATServer(
-    NATType type, SocketFactory* internal, const SocketAddress& internal_addr,
-    SocketFactory* external, const SocketAddress& external_ip)
-    : external_(external), external_ip_(external_ip.ip(), 0) {
-  nat_ = NAT::Create(type);
-
-  server_socket_ = AsyncUDPSocket::Create(internal, internal_addr);
-  server_socket_->SignalReadPacket.connect(this, &NATServer::OnInternalPacket);
-
-  int_map_ = new InternalMap(RouteCmp(nat_));
-  ext_map_ = new ExternalMap();
-}
-
-NATServer::~NATServer() {
-  for (InternalMap::iterator iter = int_map_->begin();
-       iter != int_map_->end();
-       iter++)
-    delete iter->second;
-
-  delete nat_;
-  delete server_socket_;
-  delete int_map_;
-  delete ext_map_;
-}
-
-void NATServer::OnInternalPacket(
-    AsyncPacketSocket* socket, const char* buf, size_t size,
-    const SocketAddress& addr) {
-
-  // Read the intended destination from the wire.
-  SocketAddress dest_addr;
-  dest_addr.Read_(buf, size);
-
-  // Find the translation for these addresses (allocating one if necessary).
-  SocketAddressPair route(addr, dest_addr);
-  InternalMap::iterator iter = int_map_->find(route);
-  if (iter == int_map_->end()) {
-    Translate(route);
-    iter = int_map_->find(route);
-  }
-  ASSERT(iter != int_map_->end());
-
-  // Allow the destination to send packets back to the source.
-  iter->second->whitelist->insert(dest_addr);
-
-  // Send the packet to its intended destination.
-  iter->second->socket->SendTo(
-      buf + dest_addr.Size_(), size - dest_addr.Size_(), dest_addr);
-}
-
-void NATServer::OnExternalPacket(
-    AsyncPacketSocket* socket, const char* buf, size_t size,
-    const SocketAddress& remote_addr) {
-
-  SocketAddress local_addr = socket->GetLocalAddress();
-
-  // Find the translation for this addresses.
-  ExternalMap::iterator iter = ext_map_->find(local_addr);
-  ASSERT(iter != ext_map_->end());
-
-  // Allow the NAT to reject this packet.
-  if (Filter(iter->second, remote_addr)) {
-    LOG(LS_INFO) << "Packet from " << remote_addr.ToString()
-                 << " was filtered out by the NAT.";
-    return;
-  }
-
-  // Forward this packet to the internal address.
-
-  size_t real_size = size + remote_addr.Size_();
-  char*  real_buf  = new char[real_size];
-
-  remote_addr.Write_(real_buf, real_size);
-  std::memcpy(real_buf + remote_addr.Size_(), buf, size);
-
-  server_socket_->SendTo(real_buf, real_size, iter->second->route.source());
-
-  delete[] real_buf;
-}
-
-void NATServer::Translate(const SocketAddressPair& route) {
-  AsyncUDPSocket* socket = AsyncUDPSocket::Create(external_, external_ip_);
-
-  if (!socket) {
-    LOG(LS_ERROR) << "Couldn't find a free port!";
-    return;
-  }
-
-  TransEntry* entry = new TransEntry(route, socket, nat_);
-  (*int_map_)[route] = entry;
-  (*ext_map_)[socket->GetLocalAddress()] = entry;
-  socket->SignalReadPacket.connect(this, &NATServer::OnExternalPacket);
-}
-
-bool NATServer::Filter(TransEntry* entry, const SocketAddress& ext_addr) {
-  return entry->whitelist->find(ext_addr) == entry->whitelist->end();
-}
-
-NATServer::TransEntry::TransEntry(
-    const SocketAddressPair& r, AsyncUDPSocket* s, NAT* nat)
-    : route(r), socket(s) {
-  whitelist = new AddressSet(AddrCmp(nat));
-}
-
-NATServer::TransEntry::~TransEntry() {
-  delete whitelist;
-  delete socket;
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/natserver.h b/third_party/libjingle/source/talk/base/natserver.h
deleted file mode 100644
index 0a6083c..0000000
--- a/third_party/libjingle/source/talk/base/natserver.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_NATSERVER_H_
-#define TALK_BASE_NATSERVER_H_
-
-#include <map>
-#include <set>
-
-#include "talk/base/asyncudpsocket.h"
-#include "talk/base/socketaddresspair.h"
-#include "talk/base/thread.h"
-#include "talk/base/socketfactory.h"
-#include "talk/base/nattypes.h"
-
-namespace talk_base {
-
-// Change how routes (socketaddress pairs) are compared based on the type of
-// NAT.  The NAT server maintains a hashtable of the routes that it knows
-// about.  So these affect which routes are treated the same.
-struct RouteCmp {
-  explicit RouteCmp(NAT* nat);
-  size_t operator()(const SocketAddressPair& r) const;
-  bool operator()(
-      const SocketAddressPair& r1, const SocketAddressPair& r2) const;
-
-  bool symmetric;
-};
-
-// Changes how addresses are compared based on the filtering rules of the NAT.
-struct AddrCmp {
-  explicit AddrCmp(NAT* nat);
-  size_t operator()(const SocketAddress& r) const;
-  bool operator()(const SocketAddress& r1, const SocketAddress& r2) const;
-
-  bool use_ip;
-  bool use_port;
-};
-
-// Implements the NAT device.  It listens for packets on the internal network,
-// translates them, and sends them out over the external network.
-
-const int NAT_SERVER_PORT = 4237;
-
-class NATServer : public sigslot::has_slots<> {
- public:
-  NATServer(
-      NATType type, SocketFactory* internal, const SocketAddress& internal_addr,
-      SocketFactory* external, const SocketAddress& external_ip);
-  ~NATServer();
-
-  SocketAddress internal_address() const {
-    return server_socket_->GetLocalAddress();
-  }
-
-  // Packets received on one of the networks.
-  void OnInternalPacket(AsyncPacketSocket* socket, const char* buf,
-                        size_t size, const SocketAddress& addr);
-  void OnExternalPacket(AsyncPacketSocket* socket, const char* buf,
-                        size_t size, const SocketAddress& remote_addr);
-
- private:
-  typedef std::set<SocketAddress, AddrCmp> AddressSet;
-
-  /* Records a translation and the associated external socket. */
-  struct TransEntry {
-    TransEntry(const SocketAddressPair& r, AsyncUDPSocket* s, NAT* nat);
-    ~TransEntry();
-
-    SocketAddressPair route;
-    AsyncUDPSocket* socket;
-    AddressSet* whitelist;
-  };
-
-  typedef std::map<SocketAddressPair, TransEntry*, RouteCmp> InternalMap;
-  typedef std::map<SocketAddress, TransEntry*> ExternalMap;
-
-  /* Creates a new entry that translates the given route. */
-  void Translate(const SocketAddressPair& route);
-
-  /* Determines whether the NAT would filter out a packet from this address. */
-  bool Filter(TransEntry* entry, const SocketAddress& ext_addr);
-
-  NAT* nat_;
-  SocketFactory* internal_;
-  SocketFactory* external_;
-  SocketAddress external_ip_;
-  AsyncUDPSocket* server_socket_;
-  AsyncSocket* tcp_server_socket_;
-  InternalMap* int_map_;
-  ExternalMap* ext_map_;
-  DISALLOW_EVIL_CONSTRUCTORS(NATServer);
-};
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_NATSERVER_H_
diff --git a/third_party/libjingle/source/talk/base/natsocketfactory.cc b/third_party/libjingle/source/talk/base/natsocketfactory.cc
deleted file mode 100644
index 846d0e6..0000000
--- a/third_party/libjingle/source/talk/base/natsocketfactory.cc
+++ /dev/null
@@ -1,458 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/natsocketfactory.h"
-
-#include "talk/base/logging.h"
-#include "talk/base/natserver.h"
-#include "talk/base/virtualsocketserver.h"
-
-namespace talk_base {
-
-// NATSocket
-class NATSocket : public AsyncSocket, public sigslot::has_slots<> {
- public:
-  explicit NATSocket(NATInternalSocketFactory* sf, int type)
-      : sf_(sf), type_(type), async_(true), connected_(false),
-        socket_(NULL), buf_(NULL), size_(0) {
-  }
-
-  virtual ~NATSocket() {
-    delete socket_;
-    delete[] buf_;
-  }
-
-  virtual SocketAddress GetLocalAddress() const {
-    return (socket_) ? socket_->GetLocalAddress() : SocketAddress();
-  }
-
-  virtual SocketAddress GetRemoteAddress() const {
-    return remote_addr_;  // will be ANY if not connected
-  }
-
-  virtual int Bind(const SocketAddress& addr) {
-    if (socket_) {  // already bound, bubble up error
-      return -1;
-    }
-
-    int result;
-    socket_ = sf_->CreateInternalSocket(type_, addr, &server_addr_);
-    result = (socket_) ? socket_->Bind(addr) : -1;
-    if (result >= 0) {
-      socket_->SignalConnectEvent.connect(this, &NATSocket::OnConnectEvent);
-      socket_->SignalReadEvent.connect(this, &NATSocket::OnReadEvent);
-      socket_->SignalWriteEvent.connect(this, &NATSocket::OnWriteEvent);
-      socket_->SignalCloseEvent.connect(this, &NATSocket::OnCloseEvent);
-    } else {
-      server_addr_.Clear();
-      delete socket_;
-      socket_ = NULL;
-    }
-
-    return result;
-  }
-
-  virtual int Connect(const SocketAddress& addr) {
-    if (!socket_) {  // socket must be bound, for now
-      return -1;
-    }
-
-    int result = 0;
-    if (type_ == SOCK_STREAM) {
-      result = socket_->Connect(server_addr_.IsAny() ? addr : server_addr_);
-    } else {
-      connected_ = true;
-    }
-
-    if (result >= 0) {
-      remote_addr_ = addr;
-    }
-
-    return result;
-  }
-
-  virtual int Send(const void *pv, size_t cb) {
-    ASSERT(connected_);
-    return SendTo(pv, cb, remote_addr_);
-  }
-
-  virtual int SendTo(const void *pv, size_t cb, const SocketAddress& addr) {
-    ASSERT(!connected_ || addr == remote_addr_);
-    if (server_addr_.IsAny() || type_ == SOCK_STREAM) {
-      return socket_->SendTo(pv, cb, addr);
-    }
-
-    size_t size = cb + addr.Size_();
-    scoped_array<char> buf(new char[size]);
-    Encode(static_cast<const char*>(pv), cb, buf.get(), size, addr);
-
-    int result = socket_->SendTo(buf.get(), size, server_addr_);
-    if (result >= 0) {
-      ASSERT(result == static_cast<int>(size));
-      result = result - static_cast<int>(addr.Size_());
-    }
-    return result;
-  }
-
-  virtual int Recv(void *pv, size_t cb) {
-    SocketAddress addr;
-    return RecvFrom(pv, cb, &addr);
-  }
-
-  virtual int RecvFrom(void *pv, size_t cb, SocketAddress *paddr) {
-    if (server_addr_.IsAny() || type_ == SOCK_STREAM) {
-      return socket_->RecvFrom(pv, cb, paddr);
-    }
-
-    // Make sure we have enough room to read the requested amount plus the
-    // header address.
-    SocketAddress remote_addr;
-    Grow(cb + remote_addr.Size_());
-
-    // Read the packet from the socket.
-    int result = socket_->RecvFrom(buf_, size_, &remote_addr);
-    if (result >= 0) {
-      ASSERT(remote_addr == server_addr_);
-
-      // TODO: we need better framing so we know how many bytes we can
-      // return before we need to read the next address. For UDP, this will be
-      // fine as long as the reader always reads everything in the packet.
-      ASSERT((size_t)result < size_);
-
-      // Decode the wire packet into the actual results.
-      SocketAddress real_remote_addr;
-      size_t real_size = cb;
-      Decode(buf_, result, pv, &real_size, &real_remote_addr);
-
-      // Make sure this packet should be delivered before returning it.
-      if (!connected_ || (real_remote_addr == remote_addr_)) {
-        if (paddr)
-          *paddr = real_remote_addr;
-        result = real_size;
-      } else {
-        LOG(LS_ERROR) << "Dropping packet from unknown remote address: "
-                      << real_remote_addr.ToString();
-        result = 0;  // Tell the caller we didn't read anything
-      }
-    }
-
-    return result;
-  }
-
-  virtual int Close() {
-    int result = 0;
-    if (socket_) {
-      result = socket_->Close();
-      if (result >= 0) {
-        connected_ = false;
-        remote_addr_ = SocketAddress();
-        delete socket_;
-        socket_ = NULL;
-      }
-    }
-    return result;
-  }
-
-  virtual int Listen(int backlog) {
-    return socket_->Listen(backlog);
-  }
-  virtual AsyncSocket* Accept(SocketAddress *paddr) {
-    return socket_->Accept(paddr);
-  }
-  virtual int GetError() const {
-    return socket_->GetError();
-  }
-  virtual void SetError(int error) {
-    socket_->SetError(error);
-  }
-  virtual ConnState GetState() const {
-    return connected_ ? CS_CONNECTED : CS_CLOSED;
-  }
-  virtual int EstimateMTU(uint16* mtu) {
-    return socket_->EstimateMTU(mtu);
-  }
-  virtual int GetOption(Option opt, int* value) {
-    return socket_->GetOption(opt, value);
-  }
-  virtual int SetOption(Option opt, int value) {
-    return socket_->SetOption(opt, value);
-  }
-
-  void OnConnectEvent(AsyncSocket* socket) {
-    // If we're NATed, we need to send a request with the real addr to use.
-    ASSERT(socket == socket_);
-    if (server_addr_.IsAny()) {
-      connected_ = true;
-      SignalConnectEvent(this);
-    } else {
-      SendConnectRequest();
-    }
-  }
-  void OnReadEvent(AsyncSocket* socket) {
-    // If we're NATed, we need to process the connect reply.
-    ASSERT(socket == socket_);
-    if (type_ == SOCK_STREAM && !server_addr_.IsAny() && !connected_) {
-      HandleConnectReply();
-    } else {
-      SignalReadEvent(this);
-    }
-  }
-  void OnWriteEvent(AsyncSocket* socket) {
-    ASSERT(socket == socket_);
-    SignalWriteEvent(this);
-  }
-  void OnCloseEvent(AsyncSocket* socket, int error) {
-    ASSERT(socket == socket_);
-    SignalCloseEvent(this, error);
-  }
-
- private:
-  // Makes sure the buffer is at least the given size.
-  void Grow(size_t new_size) {
-    if (size_ < new_size) {
-      delete[] buf_;
-      size_ = new_size;
-      buf_ = new char[size_];
-    }
-  }
-
-  // Sends the destination address to the server to tell it to connect.
-  void SendConnectRequest() {
-    char buf[256];
-    remote_addr_.Write_(buf, ARRAY_SIZE(buf));
-    socket_->Send(buf, remote_addr_.Size_());
-  }
-
-  // Handles the byte sent back from the server and fires the appropriate event.
-  void HandleConnectReply() {
-    char code;
-    socket_->Recv(&code, sizeof(code));
-    if (code == 0) {
-      SignalConnectEvent(this);
-    } else {
-      Close();
-      SignalCloseEvent(this, code);
-    }
-  }
-
-  // Encodes the given data and intended remote address into a packet to send
-  // to the NAT server.
-  static void Encode(const char* data, size_t data_size, char* buf,
-                     size_t buf_size, const SocketAddress& remote_addr) {
-    ASSERT(buf_size == data_size + remote_addr.Size_());
-    remote_addr.Write_(buf, static_cast<int>(buf_size));
-    std::memcpy(buf + remote_addr.Size_(), data, data_size);
-  }
-
-  // Decodes the given packet from the NAT server into the actual remote
-  // address and data.
-  static void Decode(const char* data, size_t data_size, void* buf,
-                     size_t* buf_size, SocketAddress* remote_addr) {
-    ASSERT(data_size >= remote_addr->Size_());
-    ASSERT(data_size <= *buf_size + remote_addr->Size_());
-    remote_addr->Read_(data, static_cast<int>(data_size));
-    *buf_size = data_size - remote_addr->Size_();
-    std::memcpy(buf, data + remote_addr->Size_(), *buf_size);
-  }
-
-  NATInternalSocketFactory* sf_;
-  int type_;
-  bool async_;
-  bool connected_;
-  SocketAddress remote_addr_;
-  SocketAddress server_addr_;  // address of the NAT server
-  AsyncSocket* socket_;
-  char* buf_;
-  size_t size_;
-};
-
-// NATSocketFactory
-NATSocketFactory::NATSocketFactory(SocketFactory* factory,
-                                   const SocketAddress& nat_addr)
-    : factory_(factory), nat_addr_(nat_addr) {
-}
-
-Socket* NATSocketFactory::CreateSocket(int type) {
-  return new NATSocket(this, type);
-}
-
-AsyncSocket* NATSocketFactory::CreateAsyncSocket(int type) {
-  return new NATSocket(this, type);
-}
-
-AsyncSocket* NATSocketFactory::CreateInternalSocket(int type,
-    const SocketAddress& local_addr, SocketAddress* nat_addr) {
-  *nat_addr = nat_addr_;
-  return factory_->CreateAsyncSocket(type);
-}
-
-// NATSocketServer
-NATSocketServer::NATSocketServer(SocketServer* server)
-    : server_(server), msg_queue_(NULL) {
-}
-
-NATSocketServer::Translator* NATSocketServer::GetTranslator(
-    const SocketAddress& ext_ip) {
-  return nats_.Get(ext_ip);
-}
-
-NATSocketServer::Translator* NATSocketServer::AddTranslator(
-    const SocketAddress& ext_ip, const SocketAddress& int_ip, NATType type) {
-  // Fail if a translator already exists with this extternal address.
-  if (nats_.Get(ext_ip))
-    return NULL;
-
-  return nats_.Add(ext_ip, new Translator(this, type, int_ip, server_, ext_ip));
-}
-
-void NATSocketServer::RemoveTranslator(
-    const SocketAddress& ext_ip) {
-  nats_.Remove(ext_ip);
-}
-
-Socket* NATSocketServer::CreateSocket(int type) {
-  return new NATSocket(this, type);
-}
-
-AsyncSocket* NATSocketServer::CreateAsyncSocket(int type) {
-  return new NATSocket(this, type);
-}
-
-AsyncSocket* NATSocketServer::CreateInternalSocket(int type,
-    const SocketAddress& local_addr, SocketAddress* nat_addr) {
-  AsyncSocket* socket = NULL;
-  Translator* nat = nats_.FindClient(local_addr);
-  if (nat) {
-    socket = nat->internal_factory()->CreateAsyncSocket(type);
-    *nat_addr = (type == SOCK_STREAM) ?
-        nat->internal_tcp_address() : nat->internal_address();
-  } else {
-    socket = server_->CreateAsyncSocket(type);
-  }
-  return socket;
-}
-
-// NATSocketServer::Translator
-NATSocketServer::Translator::Translator(
-    NATSocketServer* server, NATType type, const SocketAddress& int_ip,
-    SocketFactory* ext_factory, const SocketAddress& ext_ip)
-    : server_(server) {
-  // Create a new private network, and a NATServer running on the private
-  // network that bridges to the external network. Also tell the private
-  // network to use the same message queue as us.
-  VirtualSocketServer* internal_server = new VirtualSocketServer(server_);
-  internal_server->SetMessageQueue(server_->queue());
-  internal_factory_.reset(internal_server);
-  nat_server_.reset(new NATServer(type, internal_server, int_ip,
-                                  ext_factory, ext_ip));
-}
-
-
-NATSocketServer::Translator* NATSocketServer::Translator::GetTranslator(
-    const SocketAddress& ext_ip) {
-  return nats_.Get(ext_ip);
-}
-
-NATSocketServer::Translator* NATSocketServer::Translator::AddTranslator(
-    const SocketAddress& ext_ip, const SocketAddress& int_ip, NATType type) {
-  // Fail if a translator already exists with this extternal address.
-  if (nats_.Get(ext_ip))
-    return NULL;
-
-  AddClient(ext_ip);
-  return nats_.Add(ext_ip,
-                   new Translator(server_, type, int_ip, server_, ext_ip));
-}
-void NATSocketServer::Translator::RemoveTranslator(
-    const SocketAddress& ext_ip) {
-  nats_.Remove(ext_ip);
-  RemoveClient(ext_ip);
-}
-
-bool NATSocketServer::Translator::AddClient(
-    const SocketAddress& int_ip) {
-  // Fail if a client already exists with this internal address.
-  if (clients_.find(int_ip) != clients_.end())
-    return false;
-
-  clients_.insert(int_ip);
-  return true;
-}
-
-void NATSocketServer::Translator::RemoveClient(
-    const SocketAddress& int_ip) {
-  std::set<SocketAddress>::iterator it = clients_.find(int_ip);
-  if (it != clients_.end()) {
-    clients_.erase(it);
-  }
-}
-
-NATSocketServer::Translator* NATSocketServer::Translator::FindClient(
-    const SocketAddress& int_ip) {
-  // See if we have the requested IP, or any of our children do.
-  return (clients_.find(int_ip) != clients_.end()) ?
-      this : nats_.FindClient(int_ip);
-}
-
-// NATSocketServer::TranslatorMap
-NATSocketServer::TranslatorMap::~TranslatorMap() {
-  for (TranslatorMap::iterator it = begin(); it != end(); ++it) {
-    delete it->second;
-  }
-}
-
-NATSocketServer::Translator* NATSocketServer::TranslatorMap::Get(
-    const SocketAddress& ext_ip) {
-  TranslatorMap::iterator it = find(ext_ip);
-  return (it != end()) ? it->second : NULL;
-}
-
-NATSocketServer::Translator* NATSocketServer::TranslatorMap::Add(
-    const SocketAddress& ext_ip, Translator* nat) {
-  (*this)[ext_ip] = nat;
-  return nat;
-}
-
-void NATSocketServer::TranslatorMap::Remove(
-    const SocketAddress& ext_ip) {
-  TranslatorMap::iterator it = find(ext_ip);
-  if (it != end()) {
-    delete it->second;
-    erase(it);
-  }
-}
-
-NATSocketServer::Translator* NATSocketServer::TranslatorMap::FindClient(
-    const SocketAddress& int_ip) {
-  Translator* nat = NULL;
-  for (TranslatorMap::iterator it = begin(); it != end() && !nat; ++it) {
-    nat = it->second->FindClient(int_ip);
-  }
-  return nat;
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/natsocketfactory.h b/third_party/libjingle/source/talk/base/natsocketfactory.h
deleted file mode 100644
index bbaaf3e..0000000
--- a/third_party/libjingle/source/talk/base/natsocketfactory.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_NATSOCKETFACTORY_H_
-#define TALK_BASE_NATSOCKETFACTORY_H_
-
-#include <string>
-#include <map>
-#include <set>
-
-#include "talk/base/natserver.h"
-#include "talk/base/socketaddress.h"
-#include "talk/base/socketserver.h"
-
-namespace talk_base {
-
-// Used by the NAT socket implementation.
-class NATInternalSocketFactory {
- public:
-  virtual ~NATInternalSocketFactory() {}
-  virtual AsyncSocket* CreateInternalSocket(int type,
-      const SocketAddress& local_addr, SocketAddress* nat_addr) = 0;
-};
-
-// Creates sockets that will send all traffic through a NAT, using an existing
-// NATServer instance running at nat_addr. The actual data is sent using sockets
-// from a socket factory, given to the constructor.
-class NATSocketFactory : public SocketFactory, public NATInternalSocketFactory {
- public:
-  NATSocketFactory(SocketFactory* factory, const SocketAddress& nat_addr);
-
-  // SocketFactory implementation
-  virtual Socket* CreateSocket(int type);
-  virtual AsyncSocket* CreateAsyncSocket(int type);
-
-  // NATInternalSocketFactory implementation
-  virtual AsyncSocket* CreateInternalSocket(int type,
-      const SocketAddress& local_addr, SocketAddress* nat_addr);
-
- private:
-  SocketFactory* factory_;
-  SocketAddress nat_addr_;
-  DISALLOW_EVIL_CONSTRUCTORS(NATSocketFactory);
-};
-
-// Creates sockets that will send traffic through a NAT depending on what
-// address they bind to. This can be used to simulate a client on a NAT sending
-// to a client that is not behind a NAT.
-// Note that the internal addresses of clients must be unique. This is because
-// there is only one socketserver per thread, and the Bind() address is used to
-// figure out which NAT (if any) the socket should talk to.
-//
-// Example with 3 NATs (2 cascaded), and 3 clients.
-// ss->AddTranslator("1.2.3.4", "192.168.0.1", NAT_ADDR_RESTRICTED);
-// ss->AddTranslator("99.99.99.99", "10.0.0.1", NAT_SYMMETRIC)->
-//     AddTranslator("10.0.0.2", "192.168.1.1", NAT_OPEN_CONE);
-// ss->GetTranslator("1.2.3.4")->AddClient("1.2.3.4", "192.168.0.2");
-// ss->GetTranslator("99.99.99.99")->AddClient("10.0.0.3");
-// ss->GetTranslator("99.99.99.99")->GetTranslator("10.0.0.2")->
-//     AddClient("192.168.1.2");
-class NATSocketServer : public SocketServer, public NATInternalSocketFactory {
- public:
-  class Translator;
-  // holds a list of NATs
-  class TranslatorMap : private std::map<SocketAddress, Translator*> {
-   public:
-    ~TranslatorMap();
-    Translator* Get(const SocketAddress& ext_ip);
-    Translator* Add(const SocketAddress& ext_ip, Translator*);
-    void Remove(const SocketAddress& ext_ip);
-    Translator* FindClient(const SocketAddress& int_ip);
-  };
-
-  // a specific NAT
-  class Translator {
-   public:
-    Translator(NATSocketServer* server, NATType type,
-               const SocketAddress& int_addr, SocketFactory* ext_factory,
-               const SocketAddress& ext_addr);
-
-    SocketFactory* internal_factory() { return internal_factory_.get(); }
-    SocketAddress internal_address() const {
-      return nat_server_->internal_address();
-    }
-    SocketAddress internal_tcp_address() const {
-      return SocketAddress();  // nat_server_->internal_tcp_address();
-    }
-
-    Translator* GetTranslator(const SocketAddress& ext_ip);
-    Translator* AddTranslator(const SocketAddress& ext_ip,
-                              const SocketAddress& int_ip, NATType type);      
-    void RemoveTranslator(const SocketAddress& ext_ip);
-
-    bool AddClient(const SocketAddress& int_ip);
-    void RemoveClient(const SocketAddress& int_ip);
-
-    // Looks for the specified client in this or a child NAT.
-    Translator* FindClient(const SocketAddress& int_ip);
-
-   private:
-    NATSocketServer* server_;
-    scoped_ptr<SocketFactory> internal_factory_;
-    scoped_ptr<NATServer> nat_server_;
-    TranslatorMap nats_;
-    std::set<SocketAddress> clients_;
-  };
-
-  explicit NATSocketServer(SocketServer* ss);
-
-  SocketServer* socketserver() { return server_; }
-  MessageQueue* queue() { return msg_queue_; }
-
-  Translator* GetTranslator(const SocketAddress& ext_ip);
-  Translator* AddTranslator(const SocketAddress& ext_ip,
-                            const SocketAddress& int_ip, NATType type);
-  void RemoveTranslator(const SocketAddress& ext_ip);
-
-  // SocketServer implementation
-  virtual Socket* CreateSocket(int type);
-  virtual AsyncSocket* CreateAsyncSocket(int type);
-  virtual void SetMessageQueue(MessageQueue* queue) {
-    msg_queue_ = queue;
-    server_->SetMessageQueue(queue);
-  }
-  virtual bool Wait(int cms, bool process_io) {
-    return server_->Wait(cms, process_io);
-  }
-  virtual void WakeUp() {
-    server_->WakeUp();
-  }
-
-  // NATInternalSocketFactory implementation
-  virtual AsyncSocket* CreateInternalSocket(int type,
-      const SocketAddress& local_addr, SocketAddress* nat_addr);
-
- private:
-  SocketServer* server_;
-  MessageQueue* msg_queue_;
-  TranslatorMap nats_;
-  DISALLOW_EVIL_CONSTRUCTORS(NATSocketServer);
-};
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_NATSOCKETFACTORY_H_
diff --git a/third_party/libjingle/source/talk/base/nattypes.cc b/third_party/libjingle/source/talk/base/nattypes.cc
deleted file mode 100644
index 290c3ad..0000000
--- a/third_party/libjingle/source/talk/base/nattypes.cc
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <cassert>
-
-#include "talk/base/nattypes.h"
-
-namespace talk_base {
-
-class SymmetricNAT : public NAT {
-public:
-  bool IsSymmetric() { return true; }
-  bool FiltersIP() { return true; }
-  bool FiltersPort() { return true; }
-};
-
-class OpenConeNAT : public NAT {
-public:
-  bool IsSymmetric() { return false; }
-  bool FiltersIP() { return false; }
-  bool FiltersPort() { return false; }
-};
-
-class AddressRestrictedNAT : public NAT {
-public:
-  bool IsSymmetric() { return false; }
-  bool FiltersIP() { return true; }
-  bool FiltersPort() { return false; }
-};
-
-class PortRestrictedNAT : public NAT {
-public:
-  bool IsSymmetric() { return false; }
-  bool FiltersIP() { return true; }
-  bool FiltersPort() { return true; }
-};
-
-NAT* NAT::Create(NATType type) {
-  switch (type) {
-  case NAT_OPEN_CONE:       return new OpenConeNAT();
-  case NAT_ADDR_RESTRICTED: return new AddressRestrictedNAT();
-  case NAT_PORT_RESTRICTED: return new PortRestrictedNAT();
-  case NAT_SYMMETRIC:       return new SymmetricNAT();
-  default: assert(0);       return 0;
-  }
-}
-
-} // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/nattypes.h b/third_party/libjingle/source/talk/base/nattypes.h
deleted file mode 100644
index e9602c7..0000000
--- a/third_party/libjingle/source/talk/base/nattypes.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_NATTYPE_H__
-#define TALK_BASE_NATTYPE_H__
-
-namespace talk_base {
-
-/* Identifies each type of NAT that can be simulated. */
-enum NATType {
-  NAT_OPEN_CONE,
-  NAT_ADDR_RESTRICTED,
-  NAT_PORT_RESTRICTED,
-  NAT_SYMMETRIC
-};
-
-// Implements the rules for each specific type of NAT.
-class NAT {
-public:
-  virtual ~NAT() { }
-
-  // Determines whether this NAT uses both source and destination address when
-  // checking whether a mapping already exists.
-  virtual bool IsSymmetric() = 0;
-
-  // Determines whether this NAT drops packets received from a different IP
-  // the one last sent to.
-  virtual bool FiltersIP() = 0;
-
-  // Determines whether this NAT drops packets received from a different port
-  // the one last sent to.
-  virtual bool FiltersPort() = 0;
-
-  // Returns an implementation of the given type of NAT.
-  static NAT* Create(NATType type);
-};
-
-} // namespace talk_base
-
-#endif // TALK_BASE_NATTYPE_H__
diff --git a/third_party/libjingle/source/talk/base/nethelpers.cc b/third_party/libjingle/source/talk/base/nethelpers.cc
deleted file mode 100644
index 3961fc0..0000000
--- a/third_party/libjingle/source/talk/base/nethelpers.cc
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * libjingle
- * Copyright 2008, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/nethelpers.h"
-
-#include "talk/base/byteorder.h"
-#include "talk/base/signalthread.h"
-
-namespace talk_base {
-
-#if defined(LINUX) || defined(ANDROID)
-static const size_t kInitHostentLen = 1024;
-static const size_t kMaxHostentLen = kInitHostentLen * 8;
-#endif
-
-// AsyncResolver
-
-AsyncResolver::AsyncResolver() : result_(NULL), error_(0) {
-}
-
-AsyncResolver::~AsyncResolver() {
-  FreeHostEnt(result_);
-}
-
-void AsyncResolver::DoWork() {
-  result_ = SafeGetHostByName(addr_.hostname().c_str(), &error_);
-}
-
-void AsyncResolver::OnWorkDone() {
-  if (result_) {
-    addr_.SetIP(NetworkToHost32(
-        *reinterpret_cast<uint32*>(result_->h_addr_list[0])));
-  }
-}
-
-#if defined(WIN32) || defined(ANDROID) || defined(OPENBSD)
-static hostent* DeepCopyHostent(const hostent* ent) {
-  // Get the total number of bytes we need to copy, and allocate our buffer.
-  int num_aliases = 0, num_addrs = 0;
-  int total_len = sizeof(hostent);
-  total_len += strlen(ent->h_name) + 1;
-  while (ent->h_aliases[num_aliases]) {
-    total_len += sizeof(char*) + strlen(ent->h_aliases[num_aliases]) + 1;
-    ++num_aliases;
-  }
-  total_len += sizeof(char*);
-  while (ent->h_addr_list[num_addrs]) {
-    total_len += sizeof(char*) + ent->h_length;
-    ++num_addrs;
-  }
-  total_len += sizeof(char*);
-
-  hostent* result = static_cast<hostent*>(malloc(total_len));
-  if (NULL == result) {
-    return NULL;
-  }
-  char* p = reinterpret_cast<char*>(result) + sizeof(hostent);
-
-  // Copy the hostent into it, along with its embedded pointers.
-  result->h_name = p;
-  memcpy(p, ent->h_name, strlen(ent->h_name) + 1);
-  p += strlen(ent->h_name) + 1;
-
-  result->h_aliases = reinterpret_cast<char**>(p);
-  p += (num_aliases + 1) * sizeof(char*);
-  for (int i = 0; i < num_aliases; ++i) {
-    result->h_aliases[i] = p;
-    memcpy(p, ent->h_aliases[i], strlen(ent->h_aliases[i]) + 1);
-    p += strlen(ent->h_aliases[i]) + 1;
-  }
-  result->h_aliases[num_aliases] = NULL;
-
-  result->h_addrtype = ent->h_addrtype;
-  result->h_length = ent->h_length;
-
-  result->h_addr_list = reinterpret_cast<char**>(p);
-  p += (num_addrs + 1) * sizeof(char*);
-  for (int i = 0; i < num_addrs; ++i) {
-    result->h_addr_list[i] = p;
-    memcpy(p, ent->h_addr_list[i], ent->h_length);
-    p += ent->h_length;
-  }
-  result->h_addr_list[num_addrs] = NULL;
-  
-  return result;
-}
-#endif
-
-// The functions below are used to do gethostbyname, but with an allocated
-// instead of a static buffer.
-hostent* SafeGetHostByName(const char* hostname, int* herrno) {
-  if (NULL == hostname || NULL == herrno) {
-    return NULL;
-  }
-  hostent* result = NULL;
-#if defined(WIN32)
-  // On Windows we have to allocate a buffer, and manually copy the hostent,
-  // along with its embedded pointers.
-  hostent* ent = gethostbyname(hostname);
-  if (!ent) {
-    *herrno = WSAGetLastError();
-    return NULL;
-  }
-  result = DeepCopyHostent(ent);
-  *herrno = 0;
-#elif defined(LINUX) || defined(ANDROID)
-  // gethostbyname() is not thread safe, so we need to call gethostbyname_r()
-  // which is a reentrant version of gethostbyname().
-  ASSERT(kInitHostentLen > sizeof(hostent));
-  size_t size = kInitHostentLen;
-  int ret;
-  void* buf = malloc(size);
-  if (NULL == buf) {
-    return NULL;
-  }
-  char* aux = static_cast<char*>(buf) + sizeof(hostent);
-  size_t aux_len = size - sizeof(hostent);
-  while ((ret = gethostbyname_r(hostname, reinterpret_cast<hostent*>(buf), aux,
-      aux_len, &result, herrno)) == ERANGE) {
-    size *= 2;
-    if (size > kMaxHostentLen) {
-      break;  // Just to be safe.
-    }
-    buf = realloc(buf, size);
-    if (NULL == buf) {
-      return NULL;
-    }
-    aux = static_cast<char*>(buf) + sizeof(hostent);
-    aux_len = size - sizeof(hostent);
-  }
-  if (ret != 0 || buf != result) {
-    free(buf);
-    return NULL;
-  }
-#if defined(ANDROID)
-  // Note that Android's version of gethostbyname_r has a bug such that the
-  // returned hostent contains pointers into thread-local storage.  (See bug
-  // 4383723.)  So we deep copy the result before returning.
-  hostent* deep_copy = DeepCopyHostent(result);
-  FreeHostEnt(result);
-  result = deep_copy;
-#endif
-  *herrno = 0;
-#elif defined(OSX) || defined(IOS) || defined(FREEBSD)
-  // Mac OS returns an object with everything allocated.
-  result = getipnodebyname(hostname, AF_INET, AI_DEFAULT, herrno);
-#elif defined(OPENBSD)
-  hostent* ent = gethostbyname(hostname);
-  if (!ent) {
-    return NULL;
-  }
-  result = DeepCopyHostent(ent);
-  *herrno = 0;
-#else
-#error "I don't know how to do gethostbyname safely on your system."
-#endif
-  return result;
-}
-
-// This function should mirror the above function, and free any resources
-// allocated by the above.
-void FreeHostEnt(hostent* host) {
-#if defined(OSX) || defined(IOS) || defined(FREEBSD)
-  freehostent(host);
-#elif defined(WIN32) || defined(POSIX)
-  free(host);
-#else
-#error "I don't know how to free a hostent on your system."
-#endif
-}
-
-const char* inet_ntop(int af, const void *src, char* dst, socklen_t size) {
-#ifdef WIN32
-  return win32_inet_ntop(af, src, dst, size);
-#else
-  return ::inet_ntop(af, src, dst, size);
-#endif
-}
-
-int inet_pton(int af, const char* src, void *dst) {
-#ifdef WIN32
-  return win32_inet_pton(af, src, dst);
-#else
-  return ::inet_pton(af, src, dst);
-#endif
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/nethelpers.h b/third_party/libjingle/source/talk/base/nethelpers.h
deleted file mode 100644
index ca97738..0000000
--- a/third_party/libjingle/source/talk/base/nethelpers.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * libjingle
- * Copyright 2008, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_NETHELPERS_H_
-#define TALK_BASE_NETHELPERS_H_
-
-#ifdef POSIX
-#include <netdb.h>
-#include <cstddef>
-#elif WIN32
-#include <winsock2.h>  // NOLINT
-#endif
-
-#include <list>
-
-#include "talk/base/signalthread.h"
-#include "talk/base/sigslot.h"
-#include "talk/base/socketaddress.h"
-
-namespace talk_base {
-
-// AsyncResolver will perform async DNS resolution, signaling the result on
-// the inherited SignalWorkDone when the operation completes.
-class AsyncResolver : public SignalThread {
- public:
-  AsyncResolver();
-
-  const SocketAddress& address() const { return addr_; }
-  void set_address(const SocketAddress& addr) { addr_ = addr; }
-  int error() const { return error_; }
-  void set_error(int error) { error_ = error; }
-
- protected:
-  ~AsyncResolver();
-  virtual void DoWork();
-  virtual void OnWorkDone();
-
- private:
-  SocketAddress addr_;
-  hostent* result_;
-  int error_;
-};
-
-// SafeGetHostByName functions allocate and return their result, instead of
-// using a static variable like the normal gethostbyname.
-// FreeHostEnt frees the memory allocated by SafeGetHostByName.
-hostent* SafeGetHostByName(const char* hostname, int* herrno);
-void FreeHostEnt(hostent* host);
-
-// talk_base namespaced wrappers for inet_ntop and inet_pton so we can avoid
-// the windows-native versions of these.
-const char* inet_ntop(int af, const void *src, char* dst, socklen_t size);
-int inet_pton(int af, const char* src, void *dst);
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_NETHELPERS_H_
diff --git a/third_party/libjingle/source/talk/base/network.cc b/third_party/libjingle/source/talk/base/network.cc
deleted file mode 100644
index 9d1a83d..0000000
--- a/third_party/libjingle/source/talk/base/network.cc
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "talk/base/network.h"
-
-#ifdef POSIX
-#include <sys/socket.h>
-#include <sys/utsname.h>
-#include <sys/ioctl.h>
-#include <net/if.h>
-#include <unistd.h>
-#include <errno.h>
-#endif  // POSIX
-
-#ifdef WIN32
-#include "talk/base/win32.h"
-#include <Iphlpapi.h>
-#endif
-
-#include <algorithm>
-#include <cstdio>
-
-#include "talk/base/host.h"
-#include "talk/base/logging.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/base/socket.h"  // includes something that makes windows happy
-#include "talk/base/stream.h"
-#include "talk/base/thread.h"
-
-namespace talk_base {
-
-namespace {
-
-const uint32 kUpdateNetworksMessage = 1;
-
-// Fetch list of networks every two seconds.
-const int kNetworksUpdateIntervalMs = 2000;
-
-bool CompareNetworks(const Network* a, const Network* b) {
-  return a->name() < b->name();
-}
-
-}  // namespace
-
-NetworkManager::NetworkManager() {
-}
-
-NetworkManager::~NetworkManager() {
-}
-
-NetworkManagerBase::NetworkManagerBase() {
-}
-
-NetworkManagerBase::~NetworkManagerBase() {
-  for (NetworkMap::iterator i = networks_map_.begin();
-       i != networks_map_.end(); ++i) {
-    delete i->second;
-  }
-}
-
-void NetworkManagerBase::GetNetworks(NetworkList* result) const {
-  *result = networks_;
-}
-
-void NetworkManagerBase::MergeNetworkList(const NetworkList& new_networks,
-                                          bool force_notification) {
-  // Sort the list so that we can detect when it changes.
-  NetworkList list(new_networks);
-  std::sort(list.begin(), list.end(), CompareNetworks);
-
-  bool changed = false;
-
-  if (networks_.size() != list.size())
-    changed = true;
-
-  networks_.resize(list.size());
-
-  for (uint32 i = 0; i < list.size(); ++i) {
-    NetworkMap::iterator iter = networks_map_.find(list[i]->name());
-
-    Network* network;
-    if (iter == networks_map_.end()) {
-      // That's a new network, add it to the map.
-      network = list[i];
-      networks_map_[network->name()] = network;
-    } else {
-      network = iter->second;
-      if (network->ip() != list[i]->ip()) {
-        changed = true;
-        network->set_ip(list[i]->ip());
-      }
-
-      delete list[i];
-    }
-
-    if (!changed && networks_[i]->name() != network->name())
-      changed = true;
-
-    networks_[i] = network;
-  }
-
-  if (changed || force_notification)
-    SignalNetworksChanged();
-}
-
-BasicNetworkManager::BasicNetworkManager()
-    : thread_(NULL),
-      started_(false) {
-}
-
-BasicNetworkManager::~BasicNetworkManager() {
-}
-
-#ifdef POSIX
-bool BasicNetworkManager::CreateNetworks(bool include_ignored,
-                                         NetworkList* networks) {
-  int fd;
-  if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
-    LOG_ERR(LERROR) << "socket";
-    return false;
-  }
-
-  struct ifconf ifc;
-  ifc.ifc_len = 64 * sizeof(struct ifreq);
-  ifc.ifc_buf = new char[ifc.ifc_len];
-
-  if (ioctl(fd, SIOCGIFCONF, &ifc) < 0) {
-    LOG_ERR(LERROR) << "ioctl";
-    return false;
-  }
-  ASSERT(ifc.ifc_len < static_cast<int>(64 * sizeof(struct ifreq)));
-
-  struct ifreq* ptr = reinterpret_cast<struct ifreq*>(ifc.ifc_buf);
-  struct ifreq* end =
-      reinterpret_cast<struct ifreq*>(ifc.ifc_buf + ifc.ifc_len);
-
-  while (ptr < end) {
-    struct sockaddr_in* inaddr =
-        reinterpret_cast<struct sockaddr_in*>(&ptr->ifr_ifru.ifru_addr);
-    if (inaddr->sin_family == AF_INET) {
-      IPAddress ip(inaddr->sin_addr);
-      scoped_ptr<Network> network(
-          new Network(ptr->ifr_name, ptr->ifr_name, ip));
-      network->set_ignored(IsIgnoredNetwork(*network));
-      if (include_ignored || !network->ignored()) {
-        networks->push_back(network.release());
-      }
-    }
-
-#ifdef _SIZEOF_ADDR_IFREQ
-    ptr = reinterpret_cast<struct ifreq*>(
-        reinterpret_cast<char*>(ptr) + _SIZEOF_ADDR_IFREQ(*ptr));
-#else
-    ptr++;
-#endif
-  }
-
-  delete [] ifc.ifc_buf;
-  close(fd);
-  return true;
-}
-#endif  // POSIX
-
-#ifdef WIN32
-bool BasicNetworkManager::CreateNetworks(bool include_ignored,
-                                         NetworkList* networks) {
-  IP_ADAPTER_INFO info_temp;
-  ULONG len = 0;
-
-  if (GetAdaptersInfo(&info_temp, &len) != ERROR_BUFFER_OVERFLOW)
-    // This just means there's zero networks, which is not an error.
-    return true;
-
-  scoped_array<char> buf(new char[len]);
-  IP_ADAPTER_INFO *infos = reinterpret_cast<IP_ADAPTER_INFO *>(buf.get());
-  // TODO: GetAdaptersInfo is IPv4 only. Replace with GetAddressesInfo when
-  // IPv6 support is needed in Network.
-  DWORD ret = GetAdaptersInfo(infos, &len);
-  if (ret != NO_ERROR) {
-    LOG_ERR_EX(LS_ERROR, ret) << "GetAdaptersInfo failed";
-    return false;
-  }
-
-  int count = 0;
-  for (IP_ADAPTER_INFO *info = infos; info != NULL; info = info->Next) {
-    // Ignore the loopback device.
-    if (info->Type == MIB_IF_TYPE_LOOPBACK) {
-      continue;
-    }
-
-    // In non-debug builds, don't transmit the network name because of
-    // privacy concerns. Transmit a number instead.
-    std::string name;
-#ifdef _DEBUG
-    name = info->Description;
-#else  // !_DEBUG
-    std::ostringstream ost;
-    ost << count;
-    name = ost.str();
-    count++;
-#endif  // !_DEBUG
-    IPAddress ip;
-    if (IPFromString(info->IpAddressList.IpAddress.String, &ip)) {
-      scoped_ptr<Network> network(new Network(name, info->Description, ip));
-      network->set_ignored(IsIgnoredNetwork(*network));
-      if (include_ignored || !network->ignored()) {
-        networks->push_back(network.release());
-      }
-    }
-  }
-
-  return true;
-}
-#endif  // WIN32
-
-bool BasicNetworkManager::IsIgnoredNetwork(const Network& network) {
-#ifdef POSIX
-  // Ignore local networks (lo, lo0, etc)
-  // Also filter out VMware interfaces, typically named vmnet1 and vmnet8
-  if (strncmp(network.name().c_str(), "lo", 2) == 0 ||
-      strncmp(network.name().c_str(), "vmnet", 5) == 0) {
-    return true;
-  }
-#elif defined(WIN32)
-  // Ignore any HOST side vmware adapters with a description like:
-  // VMware Virtual Ethernet Adapter for VMnet1
-  // but don't ignore any GUEST side adapters with a description like:
-  // VMware Accelerated AMD PCNet Adapter #2
-  if (strstr(network.description().c_str(), "VMnet") != NULL) {
-    return true;
-  }
-#endif
-
-  // Ignore any networks with a 0.x.y.z IP
-  if (network.ip().family() == AF_INET) {
-    return (network.ip().v4AddressAsHostOrderInteger() < 0x01000000);
-  }
-  return false;
-}
-
-void BasicNetworkManager::StartUpdating() {
-  if (started_) {
-    sent_first_update_ = false;
-    return;
-  }
-
-  thread_ = Thread::Current();
-  started_ = true;
-  sent_first_update_ = false;
-  thread_->Post(this, kUpdateNetworksMessage);
-}
-
-void BasicNetworkManager::StopUpdating() {
-  ASSERT(Thread::Current() == thread_);
-  started_ = false;
-}
-
-void BasicNetworkManager::OnMessage(Message* msg) {
-  ASSERT(msg->message_id == kUpdateNetworksMessage);
-  DoUpdateNetworks();
-}
-
-void BasicNetworkManager::DoUpdateNetworks() {
-  if (!started_)
-    return;
-
-  ASSERT(Thread::Current() == thread_);
-
-  NetworkList list;
-  if (!CreateNetworks(false, &list)) {
-    SignalError();
-  } else {
-    MergeNetworkList(list, !sent_first_update_);
-    sent_first_update_ = true;
-  }
-
-  thread_->PostDelayed(kNetworksUpdateIntervalMs, this, kUpdateNetworksMessage);
-}
-
-void BasicNetworkManager::DumpNetworks(bool include_ignored) {
-  NetworkList list;
-  CreateNetworks(include_ignored, &list);
-  LOG(LS_INFO) << "NetworkManager detected " << list.size() << " networks:";
-  for (size_t i = 0; i < list.size(); ++i) {
-    const Network* network = list[i];
-    if (!network->ignored() || include_ignored) {
-      LOG(LS_INFO) << network->ToString() << ": " << network->description()
-                   << ((network->ignored()) ? ", Ignored" : "");
-    }
-  }
-}
-
-Network::Network(const std::string& name, const std::string& desc,
-                 const IPAddress& ip)
-    : name_(name), description_(desc), ip_(ip), ignored_(false),
-      uniform_numerator_(0), uniform_denominator_(0),
-      exponential_numerator_(0), exponential_denominator_(0) {
-}
-
-std::string Network::ToString() const {
-  std::stringstream ss;
-  // Print out the first space-terminated token of the network desc, plus
-  // the IP address.
-  ss << "Net[" << description_.substr(0, description_.find(' '))
-     << ":" << ip_ << "]";
-  return ss.str();
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/network.h b/third_party/libjingle/source/talk/base/network.h
deleted file mode 100644
index bb5f15d..0000000
--- a/third_party/libjingle/source/talk/base/network.h
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_NETWORK_H_
-#define TALK_BASE_NETWORK_H_
-
-#include <deque>
-#include <map>
-#include <string>
-#include <vector>
-
-#include "talk/base/basictypes.h"
-#include "talk/base/ipaddress.h"
-#include "talk/base/messagehandler.h"
-#include "talk/base/sigslot.h"
-
-namespace talk_base {
-
-class Network;
-class NetworkSession;
-class Thread;
-
-// Generic network manager interface. It provides list of local
-// networks.
-class NetworkManager {
- public:
-  typedef std::vector<Network*> NetworkList;
-
-  NetworkManager();
-  virtual ~NetworkManager();
-
-  // Called when network list is updated.
-  sigslot::signal0<> SignalNetworksChanged;
-
-  // Indicates a failure when getting list of network interfaces.
-  sigslot::signal0<> SignalError;
-
-  // Start/Stop monitoring of network interfaces
-  // list. SignalNetworksChanged or SignalError is emitted immidiately
-  // after StartUpdating() is called. After that SignalNetworksChanged
-  // is emitted wheneven list of networks changes.
-  virtual void StartUpdating() = 0;
-  virtual void StopUpdating() = 0;
-
-  // Returns the current list of networks available on this machine.
-  // UpdateNetworks() must be called before this method is called.
-  // It makes sure that repeated calls return the same object for a
-  // given network, so that quality is tracked appropriately. Does not
-  // include ignored networks.
-  virtual void GetNetworks(NetworkList* networks) const = 0;
-};
-
-// Base class for NetworkManager implementations.
-class NetworkManagerBase : public NetworkManager {
- public:
-  NetworkManagerBase();
-  virtual ~NetworkManagerBase();
-
-  virtual void GetNetworks(std::vector<Network*>* networks) const;
-
- protected:
-  // Updates |networks_| with the networks listed in |list|. If
-  // |network_map_| already has a Network object for a network listed
-  // in the |list| then it is reused. Accept ownership of the Network
-  // objects in the |list|. SignalNetworkListUpdated is emitted if
-  // there is a change in network configuration or
-  // |force_notification| is set to true.
-  void MergeNetworkList(const NetworkList& list, bool force_notification);
-
- private:
-  typedef std::map<std::string, Network*> NetworkMap;
-
-  void DoUpdateNetworks();
-
-  NetworkList networks_;
-  NetworkMap networks_map_;
-};
-
-// Basic implementation of the NetworkManager interface that gets list
-// of networks using OS APIs.
-class BasicNetworkManager : public NetworkManagerBase,
-                            public MessageHandler {
- public:
-  BasicNetworkManager();
-  virtual ~BasicNetworkManager();
-
-  virtual void StartUpdating();
-  virtual void StopUpdating();
-
-  // Logs the available networks.
-  static void DumpNetworks(bool include_ignored);
-
-  // MessageHandler interface.
-  virtual void OnMessage(Message* msg);
-
- protected:
-  // Creates a network object for each network available on the machine.
-  static bool CreateNetworks(bool include_ignored, NetworkList* networks);
-  // Determines if a network should be ignored.
-  static bool IsIgnoredNetwork(const Network& network);
-
- private:
-  friend class NetworkTest;
-
-  void DoUpdateNetworks();
-
-  Thread* thread_;
-  bool started_;
-  bool sent_first_update_;
-};
-
-// Represents a Unix-type network interface, with a name and single address.
-class Network {
- public:
-  Network() : ip_(INADDR_ANY) {}
-
-  Network(const std::string& name, const std::string& description,
-          const IPAddress& ip);
-
-  // Returns the index of this network.  This is considered the primary key
-  // that identifies each network.
-  const std::string& name() const { return name_; }
-
-  // Returns the OS-assigned name for this network. This is useful for
-  // debugging but should not be sent over the wire (for privacy reasons).
-  const std::string& description() const { return description_; }
-
-  // Identifies the current IP address used by this network.
-  const IPAddress& ip() const { return ip_; }
-  void set_ip(const IPAddress& ip) { ip_ = ip; }
-
-  // Indicates whether this network should be ignored, perhaps because
-  // the IP is 0, or the interface is one we know is invalid.
-  bool ignored() const { return ignored_; }
-  void set_ignored(bool ignored) { ignored_ = ignored; }
-
-  // Debugging description of this network
-  std::string ToString() const;
-
- private:
-  typedef std::vector<NetworkSession*> SessionList;
-
-  std::string name_;
-  std::string description_;
-  IPAddress ip_;
-  bool ignored_;
-  SessionList sessions_;
-  double uniform_numerator_;
-  double uniform_denominator_;
-  double exponential_numerator_;
-  double exponential_denominator_;
-
-  friend class NetworkManager;
-};
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_NETWORK_H_
diff --git a/third_party/libjingle/source/talk/base/network_unittest.cc b/third_party/libjingle/source/talk/base/network_unittest.cc
deleted file mode 100644
index d48abbb..0000000
--- a/third_party/libjingle/source/talk/base/network_unittest.cc
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <vector>
-#include "talk/base/gunit.h"
-#include "talk/base/network.h"
-
-namespace talk_base {
-
-// A network that should not be ignored.
-static const Network kNetwork1("test1", "Test Network Adapter 1",
-                               IPAddress(0x12345678));
-// A network that should be ignored (IP is 0.1.0.4).
-static const Network kNetwork2("test2", "Test Network Adapter 2",
-                               IPAddress(0x00010004));
-
-class NetworkTest : public testing::Test, public sigslot::has_slots<>  {
- public:
-  NetworkTest()
-      : callback_called_(false) {
-  }
-
-  void OnNetworksChanged() {
-    callback_called_ = true;
-  }
-
-  void MergeNetworkList(BasicNetworkManager& network_manager,
-                        const NetworkManager::NetworkList& list,
-                        bool force_notification) {
-    network_manager.MergeNetworkList(list, force_notification);
-  }
-
-  bool IsIgnoredNetwork(const Network& network) {
-    return BasicNetworkManager::IsIgnoredNetwork(network);
-  }
-
-  NetworkManager::NetworkList GetNetworks(
-      const BasicNetworkManager& network_manager, bool include_ignored) {
-    NetworkManager::NetworkList list;
-    network_manager.CreateNetworks(include_ignored, &list);
-    return list;
-  }
-
- protected:
-  bool callback_called_;
-};
-
-// Test that the Network ctor works properly.
-TEST_F(NetworkTest, TestNetworkConstruct) {
-  EXPECT_EQ("test1", kNetwork1.name());
-  EXPECT_EQ("Test Network Adapter 1", kNetwork1.description());
-  EXPECT_EQ(IPAddress(0x12345678U), kNetwork1.ip());
-  EXPECT_FALSE(kNetwork1.ignored());
-}
-
-// Tests that our ignore function works properly.
-TEST_F(NetworkTest, TestNetworkIgnore) {
-  EXPECT_FALSE(IsIgnoredNetwork(kNetwork1));
-  EXPECT_TRUE(IsIgnoredNetwork(kNetwork2));
-}
-
-TEST_F(NetworkTest, TestCreateNetworks) {
-  BasicNetworkManager manager;
-  NetworkManager::NetworkList result = GetNetworks(manager, true);
-  // We should be able to bind to any addresses we find.
-  // (Excluding IPv6 link-local for now, as we don't (yet) record scope ids.)
-  NetworkManager::NetworkList::iterator it;
-  for (it = result.begin();
-       it != result.end();
-       ++it) {
-    sockaddr_storage storage;
-    memset(&storage, 0, sizeof(storage));
-    IPAddress ip = (*it)->ip();
-    // This condition excludes FE80::/16, i.e. IPv6 link-local addresses. These
-    // require their scope id to be known. Remove when scope ids are supported.
-    if (!(ip.family() == AF_INET6 && IPIsPrivate(ip) && !IPIsLoopback(ip))) {
-      SocketAddress bindaddress(ip, 0);
-      // TODO: Make this use talk_base::AsyncSocket once it supports IPv6.
-      int fd = socket(ip.family(), SOCK_STREAM, IPPROTO_TCP);
-      if (fd > 0) {
-        size_t ipsize = bindaddress.ToSockAddrStorage(&storage);
-        EXPECT_GE(ipsize, 0U);
-        int success = ::bind(fd,
-                             reinterpret_cast<sockaddr*>(&storage),
-                             ipsize);
-        EXPECT_EQ(0, success);
-#ifdef WIN32
-        closesocket(fd);
-#else
-        close(fd);
-#endif
-      }
-    }
-  }
-}
-
-// Test that UpdateNetworks succeeds.
-TEST_F(NetworkTest, TestUpdateNetworks) {
-  BasicNetworkManager manager;
-  manager.SignalNetworksChanged.connect(
-      static_cast<NetworkTest*>(this), &NetworkTest::OnNetworksChanged);
-  manager.StartUpdating();
-  Thread::Current()->ProcessMessages(0);
-  EXPECT_TRUE(callback_called_);
-}
-
-// Verify that MergeNetworkList() merges network lists properly.
-TEST_F(NetworkTest, TestMergeNetworkList) {
-  BasicNetworkManager manager;
-  manager.SignalNetworksChanged.connect(
-      static_cast<NetworkTest*>(this), &NetworkTest::OnNetworksChanged);
-
-  // Add kNetwork1 to the list of networks.
-  NetworkManager::NetworkList list;
-  list.push_back(new Network(kNetwork1));
-  callback_called_ = false;
-  MergeNetworkList(manager, list, false);
-  EXPECT_TRUE(callback_called_);
-  list.clear();
-
-  manager.GetNetworks(&list);
-  EXPECT_EQ(1U, list.size());
-  EXPECT_EQ(kNetwork1.ToString(), list[0]->ToString());
-  Network* net1 = list[0];
-  list.clear();
-
-  // Replace kNetwork1 with kNetwork2.
-  list.push_back(new Network(kNetwork2));
-  callback_called_ = false;
-  MergeNetworkList(manager, list, false);
-  EXPECT_TRUE(callback_called_);
-  list.clear();
-
-  manager.GetNetworks(&list);
-  EXPECT_EQ(1U, list.size());
-  EXPECT_EQ(kNetwork2.ToString(), list[0]->ToString());
-  Network* net2 = list[0];
-  list.clear();
-
-  // Add Network2 back.
-  list.push_back(new Network(kNetwork1));
-  list.push_back(new Network(kNetwork2));
-  callback_called_ = false;
-  MergeNetworkList(manager, list, false);
-  EXPECT_TRUE(callback_called_);
-  list.clear();
-
-  // Verify that we get previous instances of Network objects.
-  manager.GetNetworks(&list);
-  EXPECT_EQ(2U, list.size());
-  EXPECT_TRUE((net1 == list[0] && net2 == list[1]) ||
-              (net1 == list[1] && net2 == list[0]));
-  list.clear();
-
-  // Call MergeNetworkList() again and verify that we don't get update
-  // notification.
-  list.push_back(new Network(kNetwork2));
-  list.push_back(new Network(kNetwork1));
-  callback_called_ = false;
-  MergeNetworkList(manager, list, false);
-  EXPECT_FALSE(callback_called_);
-  list.clear();
-
-  // Verify that we get previous instances of Network objects.
-  manager.GetNetworks(&list);
-  EXPECT_EQ(2U, list.size());
-  EXPECT_TRUE((net1 == list[0] && net2 == list[1]) ||
-              (net1 == list[1] && net2 == list[0]));
-  list.clear();
-}
-
-// Test that DumpNetworks works.
-TEST_F(NetworkTest, TestDumpNetworks) {
-  BasicNetworkManager::DumpNetworks(true);
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/openssladapter.cc b/third_party/libjingle/source/talk/base/openssladapter.cc
deleted file mode 100644
index ea40172..0000000
--- a/third_party/libjingle/source/talk/base/openssladapter.cc
+++ /dev/null
@@ -1,895 +0,0 @@
-/*
- * libjingle
- * Copyright 2008, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#if HAVE_CONFIG_H
-#include "config.h"
-#endif  // HAVE_CONFIG_H
-
-#if HAVE_OPENSSL_SSL_H
-
-#include <openssl/bio.h>
-#include <openssl/crypto.h>
-#include <openssl/err.h>
-#include <openssl/opensslv.h>
-#include <openssl/rand.h>
-#include <openssl/ssl.h>
-#include <openssl/x509v3.h>
-
-#include "talk/base/common.h"
-#include "talk/base/logging.h"
-#include "talk/base/openssladapter.h"
-#include "talk/base/sslroots.h"
-#include "talk/base/stringutils.h"
-
-// TODO: Use a nicer abstraction for mutex.
-
-#if defined(WIN32)
-  #define MUTEX_TYPE HANDLE
-  #define MUTEX_SETUP(x) (x) = CreateMutex(NULL, FALSE, NULL)
-  #define MUTEX_CLEANUP(x) CloseHandle(x)
-  #define MUTEX_LOCK(x) WaitForSingleObject((x), INFINITE)
-  #define MUTEX_UNLOCK(x) ReleaseMutex(x)
-  #define THREAD_ID GetCurrentThreadId()
-#elif defined(_POSIX_THREADS)
-  // _POSIX_THREADS is normally defined in unistd.h if pthreads are available
-  // on your platform.
-  #define MUTEX_TYPE pthread_mutex_t
-  #define MUTEX_SETUP(x) pthread_mutex_init(&(x), NULL)
-  #define MUTEX_CLEANUP(x) pthread_mutex_destroy(&(x))
-  #define MUTEX_LOCK(x) pthread_mutex_lock(&(x))
-  #define MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x))
-  #define THREAD_ID pthread_self()
-#else
-  #error You must define mutex operations appropriate for your platform!
-#endif
-
-struct CRYPTO_dynlock_value {
-  MUTEX_TYPE mutex;
-};
-
-//////////////////////////////////////////////////////////////////////
-// SocketBIO
-//////////////////////////////////////////////////////////////////////
-
-static int socket_write(BIO* h, const char* buf, int num);
-static int socket_read(BIO* h, char* buf, int size);
-static int socket_puts(BIO* h, const char* str);
-static long socket_ctrl(BIO* h, int cmd, long arg1, void* arg2);
-static int socket_new(BIO* h);
-static int socket_free(BIO* data);
-
-static BIO_METHOD methods_socket = {
-  BIO_TYPE_BIO,
-  "socket",
-  socket_write,
-  socket_read,
-  socket_puts,
-  0,
-  socket_ctrl,
-  socket_new,
-  socket_free,
-  NULL,
-};
-
-BIO_METHOD* BIO_s_socket2() { return(&methods_socket); }
-
-BIO* BIO_new_socket(talk_base::AsyncSocket* socket) {
-  BIO* ret = BIO_new(BIO_s_socket2());
-  if (ret == NULL) {
-          return NULL;
-  }
-  ret->ptr = socket;
-  return ret;
-}
-
-static int socket_new(BIO* b) {
-  b->shutdown = 0;
-  b->init = 1;
-  b->num = 0; // 1 means socket closed
-  b->ptr = 0;
-  return 1;
-}
-
-static int socket_free(BIO* b) {
-  if (b == NULL)
-    return 0;
-  return 1;
-}
-
-static int socket_read(BIO* b, char* out, int outl) {
-  if (!out)
-    return -1;
-  talk_base::AsyncSocket* socket = static_cast<talk_base::AsyncSocket*>(b->ptr);
-  BIO_clear_retry_flags(b);
-  int result = socket->Recv(out, outl);
-  if (result > 0) {
-    return result;
-  } else if (result == 0) {
-    b->num = 1;
-  } else if (socket->IsBlocking()) {
-    BIO_set_retry_read(b);
-  }
-  return -1;
-}
-
-static int socket_write(BIO* b, const char* in, int inl) {
-  if (!in)
-    return -1;
-  talk_base::AsyncSocket* socket = static_cast<talk_base::AsyncSocket*>(b->ptr);
-  BIO_clear_retry_flags(b);
-  int result = socket->Send(in, inl);
-  if (result > 0) {
-    return result;
-  } else if (socket->IsBlocking()) {
-    BIO_set_retry_write(b);
-  }
-  return -1;
-}
-
-static int socket_puts(BIO* b, const char* str) {
-  return socket_write(b, str, strlen(str));
-}
-
-static long socket_ctrl(BIO* b, int cmd, long num, void* ptr) {
-  UNUSED(num);
-  UNUSED(ptr);
-
-  switch (cmd) {
-  case BIO_CTRL_RESET:
-    return 0;
-  case BIO_CTRL_EOF:
-    return b->num;
-  case BIO_CTRL_WPENDING:
-  case BIO_CTRL_PENDING:
-    return 0;
-  case BIO_CTRL_FLUSH:
-    return 1;
-  default:
-    return 0;
-  }
-}
-
-/////////////////////////////////////////////////////////////////////////////
-// OpenSSLAdapter
-/////////////////////////////////////////////////////////////////////////////
-
-namespace talk_base {
-
-// This array will store all of the mutexes available to OpenSSL.
-static MUTEX_TYPE* mutex_buf = NULL;
-
-static void locking_function(int mode, int n, const char * file, int line) {
-  if (mode & CRYPTO_LOCK) {
-    MUTEX_LOCK(mutex_buf[n]);
-  } else {
-    MUTEX_UNLOCK(mutex_buf[n]);
-  }
-}
-
-static pthread_t id_function() {
-  return THREAD_ID;
-}
-
-static CRYPTO_dynlock_value* dyn_create_function(const char* file, int line) {
-  CRYPTO_dynlock_value* value = new CRYPTO_dynlock_value;
-  if (!value)
-    return NULL;
-  MUTEX_SETUP(value->mutex);
-  return value;
-}
-
-static void dyn_lock_function(int mode, CRYPTO_dynlock_value* l,
-                              const char* file, int line) {
-  if (mode & CRYPTO_LOCK) {
-    MUTEX_LOCK(l->mutex);
-  } else {
-    MUTEX_UNLOCK(l->mutex);
-  }
-}
-
-static void dyn_destroy_function(CRYPTO_dynlock_value* l,
-                                 const char* file, int line) {
-  MUTEX_CLEANUP(l->mutex);
-  delete l;
-}
-
-VerificationCallback OpenSSLAdapter::custom_verify_callback_ = NULL;
-
-bool OpenSSLAdapter::InitializeSSL(VerificationCallback callback) {
-  if (!InitializeSSLThread() || !SSL_library_init())
-      return false;
-  SSL_load_error_strings();
-  ERR_load_BIO_strings();
-  OpenSSL_add_all_algorithms();
-  RAND_poll();
-  custom_verify_callback_ = callback;
-  return true;
-}
-
-bool OpenSSLAdapter::InitializeSSLThread() {
-  mutex_buf = new MUTEX_TYPE[CRYPTO_num_locks()];
-  if (!mutex_buf)
-    return false;
-  for (int i = 0; i < CRYPTO_num_locks(); ++i)
-    MUTEX_SETUP(mutex_buf[i]);
-
-  // we need to cast our id_function to return an unsigned long -- pthread_t is a pointer
-  CRYPTO_set_id_callback((unsigned long (*)())id_function);
-  CRYPTO_set_locking_callback(locking_function);
-  CRYPTO_set_dynlock_create_callback(dyn_create_function);
-  CRYPTO_set_dynlock_lock_callback(dyn_lock_function);
-  CRYPTO_set_dynlock_destroy_callback(dyn_destroy_function);
-  return true;
-}
-
-bool OpenSSLAdapter::CleanupSSL() {
-  if (!mutex_buf)
-    return false;
-  CRYPTO_set_id_callback(NULL);
-  CRYPTO_set_locking_callback(NULL);
-  CRYPTO_set_dynlock_create_callback(NULL);
-  CRYPTO_set_dynlock_lock_callback(NULL);
-  CRYPTO_set_dynlock_destroy_callback(NULL);
-  for (int i = 0; i < CRYPTO_num_locks(); ++i)
-    MUTEX_CLEANUP(mutex_buf[i]);
-  delete [] mutex_buf;
-  mutex_buf = NULL;
-  return true;
-}
-
-OpenSSLAdapter::OpenSSLAdapter(AsyncSocket* socket)
-  : SSLAdapter(socket),
-    state_(SSL_NONE),
-    ssl_read_needs_write_(false),
-    ssl_write_needs_read_(false),
-    restartable_(false),
-    ssl_(NULL), ssl_ctx_(NULL),
-    custom_verification_succeeded_(false) {
-}
-
-OpenSSLAdapter::~OpenSSLAdapter() {
-  Cleanup();
-}
-
-int
-OpenSSLAdapter::StartSSL(const char* hostname, bool restartable) {
-  if (state_ != SSL_NONE)
-    return -1;
-
-  ssl_host_name_ = hostname;
-  restartable_ = restartable;
-
-  if (socket_->GetState() != Socket::CS_CONNECTED) {
-    state_ = SSL_WAIT;
-    return 0;
-  }
-
-  state_ = SSL_CONNECTING;
-  if (int err = BeginSSL()) {
-    Error("BeginSSL", err, false);
-    return err;
-  }
-
-  return 0;
-}
-
-int
-OpenSSLAdapter::BeginSSL() {
-  LOG(LS_INFO) << "BeginSSL: " << ssl_host_name_;
-  ASSERT(state_ == SSL_CONNECTING);
-
-  int err = 0;
-  BIO* bio = NULL;
-
-  // First set up the context
-  if (!ssl_ctx_)
-    ssl_ctx_ = SetupSSLContext();
-
-  if (!ssl_ctx_) {
-    err = -1;
-    goto ssl_error;
-  }
-
-  bio = BIO_new_socket(static_cast<AsyncSocketAdapter*>(socket_));
-  if (!bio) {
-    err = -1;
-    goto ssl_error;
-  }
-
-  ssl_ = SSL_new(ssl_ctx_);
-  if (!ssl_) {
-    err = -1;
-    goto ssl_error;
-  }
-
-  SSL_set_app_data(ssl_, this);
-
-  SSL_set_bio(ssl_, bio, bio);
-  SSL_set_mode(ssl_, SSL_MODE_ENABLE_PARTIAL_WRITE |
-                     SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
-
-  // the SSL object owns the bio now
-  bio = NULL;
-
-  // Do the connect
-  err = ContinueSSL();
-  if (err != 0)
-    goto ssl_error;
-
-  return err;
-
-ssl_error:
-  Cleanup();
-  if (bio)
-    BIO_free(bio);
-
-  return err;
-}
-
-int
-OpenSSLAdapter::ContinueSSL() {
-  LOG(LS_INFO) << "ContinueSSL";
-  ASSERT(state_ == SSL_CONNECTING);
-
-  int code = SSL_connect(ssl_);
-  switch (SSL_get_error(ssl_, code)) {
-  case SSL_ERROR_NONE:
-    LOG(LS_INFO) << " -- success";
-
-    if (!SSLPostConnectionCheck(ssl_, ssl_host_name_.c_str())) {
-      LOG(LS_ERROR) << "TLS post connection check failed";
-      // make sure we close the socket
-      Cleanup();
-      // The connect failed so return -1 to shut down the socket
-      return -1;
-    }
-
-    state_ = SSL_CONNECTED;
-    AsyncSocketAdapter::OnConnectEvent(this);
-#if 0  // TODO: worry about this
-    // Don't let ourselves go away during the callbacks
-    PRefPtr<OpenSSLAdapter> lock(this);
-    LOG(LS_INFO) << " -- onStreamReadable";
-    AsyncSocketAdapter::OnReadEvent(this);
-    LOG(LS_INFO) << " -- onStreamWriteable";
-    AsyncSocketAdapter::OnWriteEvent(this);
-#endif
-    break;
-
-  case SSL_ERROR_WANT_READ:
-    LOG(LS_INFO) << " -- error want read";
-    break;
-
-  case SSL_ERROR_WANT_WRITE:
-    LOG(LS_INFO) << " -- error want write";
-    break;
-
-  case SSL_ERROR_ZERO_RETURN:
-  default:
-    LOG(LS_INFO) << " -- error " << code;
-    return (code != 0) ? code : -1;
-  }
-
-  return 0;
-}
-
-void
-OpenSSLAdapter::Error(const char* context, int err, bool signal) {
-  LOG(LS_WARNING) << "OpenSSLAdapter::Error("
-                  << context << ", " << err << ")";
-  state_ = SSL_ERROR;
-  SetError(err);
-  if (signal)
-    AsyncSocketAdapter::OnCloseEvent(this, err);
-}
-
-void
-OpenSSLAdapter::Cleanup() {
-  LOG(LS_INFO) << "Cleanup";
-
-  state_ = SSL_NONE;
-  ssl_read_needs_write_ = false;
-  ssl_write_needs_read_ = false;
-  custom_verification_succeeded_ = false;
-
-  if (ssl_) {
-    SSL_free(ssl_);
-    ssl_ = NULL;
-  }
-
-  if (ssl_ctx_) {
-    SSL_CTX_free(ssl_ctx_);
-    ssl_ctx_ = NULL;
-  }
-}
-
-//
-// AsyncSocket Implementation
-//
-
-int
-OpenSSLAdapter::Send(const void* pv, size_t cb) {
-  //LOG(LS_INFO) << "OpenSSLAdapter::Send(" << cb << ")";
-
-  switch (state_) {
-  case SSL_NONE:
-    return AsyncSocketAdapter::Send(pv, cb);
-
-  case SSL_WAIT:
-  case SSL_CONNECTING:
-    SetError(EWOULDBLOCK);
-    return SOCKET_ERROR;
-
-  case SSL_CONNECTED:
-    break;
-
-  case SSL_ERROR:
-  default:
-    return SOCKET_ERROR;
-  }
-
-  // OpenSSL will return an error if we try to write zero bytes
-  if (cb == 0)
-    return 0;
-
-  ssl_write_needs_read_ = false;
-
-  int code = SSL_write(ssl_, pv, cb);
-  switch (SSL_get_error(ssl_, code)) {
-  case SSL_ERROR_NONE:
-    //LOG(LS_INFO) << " -- success";
-    return code;
-  case SSL_ERROR_WANT_READ:
-    //LOG(LS_INFO) << " -- error want read";
-    ssl_write_needs_read_ = true;
-    SetError(EWOULDBLOCK);
-    break;
-  case SSL_ERROR_WANT_WRITE:
-    //LOG(LS_INFO) << " -- error want write";
-    SetError(EWOULDBLOCK);
-    break;
-  case SSL_ERROR_ZERO_RETURN:
-    //LOG(LS_INFO) << " -- remote side closed";
-    SetError(EWOULDBLOCK);
-    // do we need to signal closure?
-    break;
-  default:
-    //LOG(LS_INFO) << " -- error " << code;
-    Error("SSL_write", (code ? code : -1), false);
-    break;
-  }
-
-  return SOCKET_ERROR;
-}
-
-int
-OpenSSLAdapter::Recv(void* pv, size_t cb) {
-  //LOG(LS_INFO) << "OpenSSLAdapter::Recv(" << cb << ")";
-  switch (state_) {
-
-  case SSL_NONE:
-    return AsyncSocketAdapter::Recv(pv, cb);
-
-  case SSL_WAIT:
-  case SSL_CONNECTING:
-    SetError(EWOULDBLOCK);
-    return SOCKET_ERROR;
-
-  case SSL_CONNECTED:
-    break;
-
-  case SSL_ERROR:
-  default:
-    return SOCKET_ERROR;
-  }
-
-  // Don't trust OpenSSL with zero byte reads
-  if (cb == 0)
-    return 0;
-
-  ssl_read_needs_write_ = false;
-
-  int code = SSL_read(ssl_, pv, cb);
-  switch (SSL_get_error(ssl_, code)) {
-  case SSL_ERROR_NONE:
-    //LOG(LS_INFO) << " -- success";
-    return code;
-  case SSL_ERROR_WANT_READ:
-    //LOG(LS_INFO) << " -- error want read";
-    SetError(EWOULDBLOCK);
-    break;
-  case SSL_ERROR_WANT_WRITE:
-    //LOG(LS_INFO) << " -- error want write";
-    ssl_read_needs_write_ = true;
-    SetError(EWOULDBLOCK);
-    break;
-  case SSL_ERROR_ZERO_RETURN:
-    //LOG(LS_INFO) << " -- remote side closed";
-    SetError(EWOULDBLOCK);
-    // do we need to signal closure?
-    break;
-  default:
-    //LOG(LS_INFO) << " -- error " << code;
-    Error("SSL_read", (code ? code : -1), false);
-    break;
-  }
-
-  return SOCKET_ERROR;
-}
-
-int
-OpenSSLAdapter::Close() {
-  Cleanup();
-  state_ = restartable_ ? SSL_WAIT : SSL_NONE;
-  return AsyncSocketAdapter::Close();
-}
-
-Socket::ConnState
-OpenSSLAdapter::GetState() const {
-  //if (signal_close_)
-  //  return CS_CONNECTED;
-  ConnState state = socket_->GetState();
-  if ((state == CS_CONNECTED)
-      && ((state_ == SSL_WAIT) || (state_ == SSL_CONNECTING)))
-    state = CS_CONNECTING;
-  return state;
-}
-
-void
-OpenSSLAdapter::OnConnectEvent(AsyncSocket* socket) {
-  LOG(LS_INFO) << "OpenSSLAdapter::OnConnectEvent";
-  if (state_ != SSL_WAIT) {
-    ASSERT(state_ == SSL_NONE);
-    AsyncSocketAdapter::OnConnectEvent(socket);
-    return;
-  }
-
-  state_ = SSL_CONNECTING;
-  if (int err = BeginSSL()) {
-    AsyncSocketAdapter::OnCloseEvent(socket, err);
-  }
-}
-
-void
-OpenSSLAdapter::OnReadEvent(AsyncSocket* socket) {
-  //LOG(LS_INFO) << "OpenSSLAdapter::OnReadEvent";
-
-  if (state_ == SSL_NONE) {
-    AsyncSocketAdapter::OnReadEvent(socket);
-    return;
-  }
-
-  if (state_ == SSL_CONNECTING) {
-    if (int err = ContinueSSL()) {
-      Error("ContinueSSL", err);
-    }
-    return;
-  }
-
-  if (state_ != SSL_CONNECTED)
-    return;
-
-  // Don't let ourselves go away during the callbacks
-  //PRefPtr<OpenSSLAdapter> lock(this); // TODO: fix this
-  if (ssl_write_needs_read_)  {
-    //LOG(LS_INFO) << " -- onStreamWriteable";
-    AsyncSocketAdapter::OnWriteEvent(socket);
-  }
-
-  //LOG(LS_INFO) << " -- onStreamReadable";
-  AsyncSocketAdapter::OnReadEvent(socket);
-}
-
-void
-OpenSSLAdapter::OnWriteEvent(AsyncSocket* socket) {
-  //LOG(LS_INFO) << "OpenSSLAdapter::OnWriteEvent";
-
-  if (state_ == SSL_NONE) {
-    AsyncSocketAdapter::OnWriteEvent(socket);
-    return;
-  }
-
-  if (state_ == SSL_CONNECTING) {
-    if (int err = ContinueSSL()) {
-      Error("ContinueSSL", err);
-    }
-    return;
-  }
-
-  if (state_ != SSL_CONNECTED)
-    return;
-
-  // Don't let ourselves go away during the callbacks
-  //PRefPtr<OpenSSLAdapter> lock(this); // TODO: fix this
-
-  if (ssl_read_needs_write_)  {
-    //LOG(LS_INFO) << " -- onStreamReadable";
-    AsyncSocketAdapter::OnReadEvent(socket);
-  }
-
-  //LOG(LS_INFO) << " -- onStreamWriteable";
-  AsyncSocketAdapter::OnWriteEvent(socket);
-}
-
-void
-OpenSSLAdapter::OnCloseEvent(AsyncSocket* socket, int err) {
-  LOG(LS_INFO) << "OpenSSLAdapter::OnCloseEvent(" << err << ")";
-  AsyncSocketAdapter::OnCloseEvent(socket, err);
-}
-
-// This code is taken from the "Network Security with OpenSSL"
-// sample in chapter 5
-
-bool OpenSSLAdapter::VerifyServerName(SSL* ssl, const char* host,
-                                      bool ignore_bad_cert) {
-  if (!host)
-    return false;
-
-  // Checking the return from SSL_get_peer_certificate here is not strictly
-  // necessary.  With our setup, it is not possible for it to return
-  // NULL.  However, it is good form to check the return.
-  X509* certificate = SSL_get_peer_certificate(ssl);
-  if (!certificate)
-    return false;
-
-#ifdef _DEBUG
-  {
-    LOG(LS_INFO) << "Certificate from server:";
-    BIO* mem = BIO_new(BIO_s_mem());
-    X509_print_ex(mem, certificate, XN_FLAG_SEP_CPLUS_SPC, X509_FLAG_NO_HEADER);
-    BIO_write(mem, "\0", 1);
-    char* buffer;
-    BIO_get_mem_data(mem, &buffer);
-    LOG(LS_INFO) << buffer;
-    BIO_free(mem);
-
-    char* cipher_description =
-      SSL_CIPHER_description(SSL_get_current_cipher(ssl), NULL, 128);
-    LOG(LS_INFO) << "Cipher: " << cipher_description;
-    OPENSSL_free(cipher_description);
-  }
-#endif
-
-  bool ok = false;
-  int extension_count = X509_get_ext_count(certificate);
-  for (int i = 0; i < extension_count; ++i) {
-    X509_EXTENSION* extension = X509_get_ext(certificate, i);
-    int extension_nid = OBJ_obj2nid(X509_EXTENSION_get_object(extension));
-
-    if (extension_nid == NID_subject_alt_name) {
-#if OPENSSL_VERSION_NUMBER >= 0x10000000L
-      const X509V3_EXT_METHOD* meth = X509V3_EXT_get(extension);
-#else
-      X509V3_EXT_METHOD* meth = X509V3_EXT_get(extension);
-#endif
-      if (!meth)
-        break;
-
-      void* ext_str = NULL;
-
-      // We assign this to a local variable, instead of passing the address
-      // directly to ASN1_item_d2i.
-      // See http://readlist.com/lists/openssl.org/openssl-users/0/4761.html.
-      unsigned char* ext_value_data = extension->value->data;
-
-#if OPENSSL_VERSION_NUMBER >= 0x0090800fL
-      const unsigned char **ext_value_data_ptr =
-          (const_cast<const unsigned char **>(&ext_value_data));
-#else
-      unsigned char **ext_value_data_ptr = &ext_value_data;
-#endif
-
-      if (meth->it) {
-        ext_str = ASN1_item_d2i(NULL, ext_value_data_ptr,
-                                extension->value->length,
-                                ASN1_ITEM_ptr(meth->it));
-      } else {
-        ext_str = meth->d2i(NULL, ext_value_data_ptr, extension->value->length);
-      }
-
-      STACK_OF(CONF_VALUE)* value = meth->i2v(meth, ext_str, NULL);
-      for (int j = 0; j < sk_CONF_VALUE_num(value); ++j) {
-        CONF_VALUE* nval = sk_CONF_VALUE_value(value, j);
-        // The value for nval can contain wildcards
-        if (!strcmp(nval->name, "DNS") && string_match(host, nval->value)) {
-          ok = true;
-          break;
-        }
-      }
-      sk_CONF_VALUE_pop_free(value, X509V3_conf_free);
-      value = NULL;
-
-      if (meth->it) {
-        ASN1_item_free(reinterpret_cast<ASN1_VALUE*>(ext_str), meth->it);
-      } else {
-        meth->ext_free(ext_str);
-      }
-      ext_str = NULL;
-    }
-    if (ok)
-      break;
-  }
-
-  char data[256];
-  X509_name_st* subject;
-  if (!ok
-      && (subject = X509_get_subject_name(certificate))
-      && (X509_NAME_get_text_by_NID(subject, NID_commonName,
-                                    data, sizeof(data)) > 0)) {
-    data[sizeof(data)-1] = 0;
-    if (_stricmp(data, host) == 0)
-      ok = true;
-  }
-
-  X509_free(certificate);
-
-  // This should only ever be turned on for debugging and development.
-  if (!ok && ignore_bad_cert) {
-    LOG(LS_WARNING) << "TLS certificate check FAILED.  "
-      << "Allowing connection anyway.";
-    ok = true;
-  }
-
-  return ok;
-}
-
-bool OpenSSLAdapter::SSLPostConnectionCheck(SSL* ssl, const char* host) {
-  bool ok = VerifyServerName(ssl, host, ignore_bad_cert());
-
-  if (ok) {
-    ok = (SSL_get_verify_result(ssl) == X509_V_OK ||
-          custom_verification_succeeded_);
-  }
-
-  if (!ok && ignore_bad_cert()) {
-    LOG(LS_INFO) << "Other TLS post connection checks failed.";
-    ok = true;
-  }
-
-  return ok;
-}
-
-#if _DEBUG
-
-// We only use this for tracing and so it is only needed in debug mode
-
-void
-OpenSSLAdapter::SSLInfoCallback(const SSL* s, int where, int ret) {
-  const char* str = "undefined";
-  int w = where & ~SSL_ST_MASK;
-  if (w & SSL_ST_CONNECT) {
-    str = "SSL_connect";
-  } else if (w & SSL_ST_ACCEPT) {
-    str = "SSL_accept";
-  }
-  if (where & SSL_CB_LOOP) {
-    LOG(LS_INFO) <<  str << ":" << SSL_state_string_long(s);
-  } else if (where & SSL_CB_ALERT) {
-    str = (where & SSL_CB_READ) ? "read" : "write";
-    LOG(LS_INFO) <<  "SSL3 alert " << str
-      << ":" << SSL_alert_type_string_long(ret)
-      << ":" << SSL_alert_desc_string_long(ret);
-  } else if (where & SSL_CB_EXIT) {
-    if (ret == 0) {
-      LOG(LS_INFO) << str << ":failed in " << SSL_state_string_long(s);
-    } else if (ret < 0) {
-      LOG(LS_INFO) << str << ":error in " << SSL_state_string_long(s);
-    }
-  }
-}
-
-#endif  // _DEBUG
-
-int
-OpenSSLAdapter::SSLVerifyCallback(int ok, X509_STORE_CTX* store) {
-#if _DEBUG
-  if (!ok) {
-    char data[256];
-    X509* cert = X509_STORE_CTX_get_current_cert(store);
-    int depth = X509_STORE_CTX_get_error_depth(store);
-    int err = X509_STORE_CTX_get_error(store);
-
-    LOG(LS_INFO) << "Error with certificate at depth: " << depth;
-    X509_NAME_oneline(X509_get_issuer_name(cert), data, sizeof(data));
-    LOG(LS_INFO) << "  issuer  = " << data;
-    X509_NAME_oneline(X509_get_subject_name(cert), data, sizeof(data));
-    LOG(LS_INFO) << "  subject = " << data;
-    LOG(LS_INFO) << "  err     = " << err
-      << ":" << X509_verify_cert_error_string(err);
-  }
-#endif
-
-  // Get our stream pointer from the store
-  SSL* ssl = reinterpret_cast<SSL*>(
-                X509_STORE_CTX_get_ex_data(store,
-                  SSL_get_ex_data_X509_STORE_CTX_idx()));
-
-  OpenSSLAdapter* stream =
-    reinterpret_cast<OpenSSLAdapter*>(SSL_get_app_data(ssl));
-
-  if (!ok && custom_verify_callback_) {
-    void* cert =
-        reinterpret_cast<void*>(X509_STORE_CTX_get_current_cert(store));
-    if (custom_verify_callback_(cert)) {
-      stream->custom_verification_succeeded_ = true;
-      LOG(LS_INFO) << "validated certificate using custom callback";
-      ok = true;
-    }
-  }
-
-  // Should only be used for debugging and development.
-  if (!ok && stream->ignore_bad_cert()) {
-    LOG(LS_WARNING) << "Ignoring cert error while verifying cert chain";
-    ok = 1;
-  }
-
-  return ok;
-}
-
-bool OpenSSLAdapter::ConfigureTrustedRootCertificates(SSL_CTX* ctx) {
-  // Add the root cert that we care about to the SSL context
-#if OPENSSL_VERSION_NUMBER >= 0x0090800fL
-   const unsigned char* cert_buffer
-#else
-   unsigned char* cert_buffer
-#endif
-    = Equifax_Secure_Certificate_Authority_certificate;
-  size_t cert_buffer_len =
-      sizeof(Equifax_Secure_Certificate_Authority_certificate);
-  X509* cert = d2i_X509(NULL, &cert_buffer, cert_buffer_len);
-  if (cert == NULL)
-    return false;
-  bool success = X509_STORE_add_cert(SSL_CTX_get_cert_store(ctx), cert);
-  X509_free(cert);
-  return success;
-}
-
-SSL_CTX*
-OpenSSLAdapter::SetupSSLContext() {
-  SSL_CTX* ctx = SSL_CTX_new(TLSv1_client_method());
-  if (ctx == NULL)
-    return NULL;
-
-  if (!ConfigureTrustedRootCertificates(ctx)) {
-    SSL_CTX_free(ctx);
-    return NULL;
-  }
-
-#ifdef _DEBUG
-  SSL_CTX_set_info_callback(ctx, SSLInfoCallback);
-#endif
-
-  SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, SSLVerifyCallback);
-  SSL_CTX_set_verify_depth(ctx, 4);
-  SSL_CTX_set_cipher_list(ctx, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
-
-  return ctx;
-}
-
-} // namespace talk_base
-
-#endif  // HAVE_OPENSSL_SSL_H
diff --git a/third_party/libjingle/source/talk/base/openssladapter.h b/third_party/libjingle/source/talk/base/openssladapter.h
deleted file mode 100644
index c89c292..0000000
--- a/third_party/libjingle/source/talk/base/openssladapter.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_OPENSSLADAPTER_H__
-#define TALK_BASE_OPENSSLADAPTER_H__
-
-#include <string>
-#include "talk/base/ssladapter.h"
-
-typedef struct ssl_st SSL;
-typedef struct ssl_ctx_st SSL_CTX;
-typedef struct x509_store_ctx_st X509_STORE_CTX;
-
-namespace talk_base {
-
-///////////////////////////////////////////////////////////////////////////////
-
-class OpenSSLAdapter : public SSLAdapter {
-public:
-  static bool InitializeSSL(VerificationCallback callback);
-  static bool InitializeSSLThread();
-  static bool CleanupSSL();
-
-  OpenSSLAdapter(AsyncSocket* socket);
-  virtual ~OpenSSLAdapter();
-
-  virtual int StartSSL(const char* hostname, bool restartable);
-  virtual int Send(const void* pv, size_t cb);
-  virtual int Recv(void* pv, size_t cb);
-  virtual int Close();
-
-  // Note that the socket returns ST_CONNECTING while SSL is being negotiated.
-  virtual ConnState GetState() const;
-
-protected:
-  virtual void OnConnectEvent(AsyncSocket* socket);
-  virtual void OnReadEvent(AsyncSocket* socket);
-  virtual void OnWriteEvent(AsyncSocket* socket);
-  virtual void OnCloseEvent(AsyncSocket* socket, int err);
-
-private:
-  enum SSLState {
-    SSL_NONE, SSL_WAIT, SSL_CONNECTING, SSL_CONNECTED, SSL_ERROR
-  };
-
-  int BeginSSL();
-  int ContinueSSL();
-  void Error(const char* context, int err, bool signal = true);
-  void Cleanup();
-
-  static bool VerifyServerName(SSL* ssl, const char* host,
-                               bool ignore_bad_cert);
-  bool SSLPostConnectionCheck(SSL* ssl, const char* host);
-#if _DEBUG
-  static void SSLInfoCallback(const SSL* s, int where, int ret);
-#endif  // !_DEBUG
-  static int SSLVerifyCallback(int ok, X509_STORE_CTX* store);
-  static VerificationCallback custom_verify_callback_;
-  friend class OpenSSLStreamAdapter;  // for custom_verify_callback_;
-
-  static bool ConfigureTrustedRootCertificates(SSL_CTX* ctx);
-  static SSL_CTX* SetupSSLContext();
-
-  SSLState state_;
-  bool ssl_read_needs_write_;
-  bool ssl_write_needs_read_;
-  // If true, socket will retain SSL configuration after Close.
-  bool restartable_;
-
-  SSL* ssl_;
-  SSL_CTX* ssl_ctx_;
-  std::string ssl_host_name_;
-
-  bool custom_verification_succeeded_;
-};
-
-/////////////////////////////////////////////////////////////////////////////
-
-} // namespace talk_base
-
-#endif // TALK_BASE_OPENSSLADAPTER_H__
diff --git a/third_party/libjingle/source/talk/base/opensslidentity.cc b/third_party/libjingle/source/talk/base/opensslidentity.cc
deleted file mode 100644
index f18b776..0000000
--- a/third_party/libjingle/source/talk/base/opensslidentity.cc
+++ /dev/null
@@ -1,343 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2008, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/opensslidentity.h"
-
-#include <openssl/ssl.h>
-#include <openssl/bio.h>
-#include <openssl/err.h>
-#include <openssl/pem.h>
-#include <openssl/bn.h>
-#include <openssl/rsa.h>
-#include <openssl/crypto.h>
-
-#include "talk/base/logging.h"
-#include "talk/base/helpers.h"
-
-namespace talk_base {
-
-// We could have exposed a myriad of parameters for the crypto stuff,
-// but keeping it simple seems best.
-
-// Strength of generated keys. Those are RSA.
-static const int KEY_LENGTH = 1024;
-
-// Random bits for certificate serial number
-static const int SERIAL_RAND_BITS = 64;
-
-// Certificate validity lifetime
-static const int CERTIFICATE_LIFETIME = 60*60*24*365;  // one year, arbitrarily
-
-// Generate a key pair. Caller is responsible for freeing the returned object.
-static EVP_PKEY* MakeKey() {
-  LOG(LS_INFO) << "Making key pair";
-  EVP_PKEY* pkey = EVP_PKEY_new();
-#if OPENSSL_VERSION_NUMBER < 0x00908000l
-  // Only RSA_generate_key is available. Use that.
-  RSA* rsa = RSA_generate_key(KEY_LENGTH, 0x10001, NULL, NULL);
-  if (!EVP_PKEY_assign_RSA(pkey, rsa)) {
-    EVP_PKEY_free(pkey);
-    RSA_free(rsa);
-    return NULL;
-  }
-#else
-  // RSA_generate_key is deprecated. Use _ex version.
-  BIGNUM* exponent = BN_new();
-  RSA* rsa = RSA_new();
-  if (!pkey || !exponent || !rsa ||
-      !BN_set_word(exponent, 0x10001) ||  // 65537 RSA exponent
-      !RSA_generate_key_ex(rsa, KEY_LENGTH, exponent, NULL) ||
-      !EVP_PKEY_assign_RSA(pkey, rsa)) {
-    EVP_PKEY_free(pkey);
-    BN_free(exponent);
-    RSA_free(rsa);
-    return NULL;
-  }
-  // ownership of rsa struct was assigned, don't free it.
-  BN_free(exponent);
-#endif
-  LOG(LS_INFO) << "Returning key pair";
-  return pkey;
-}
-
-// Generate a self-signed certificate, with the public key from the
-// given key pair. Caller is responsible for freeing the returned object.
-static X509* MakeCertificate(EVP_PKEY* pkey, const char* common_name) {
-  LOG(LS_INFO) << "Making certificate for " << common_name;
-  X509* x509 = NULL;
-  BIGNUM* serial_number = NULL;
-  X509_NAME* name = NULL;
-
-  if ((x509=X509_new()) == NULL)
-    goto error;
-
-  if (!X509_set_pubkey(x509, pkey))
-    goto error;
-
-  // serial number
-  // temporary reference to serial number inside x509 struct
-  ASN1_INTEGER* asn1_serial_number;
-  if (!(serial_number = BN_new()) ||
-      !BN_pseudo_rand(serial_number, SERIAL_RAND_BITS, 0, 0) ||
-      !(asn1_serial_number = X509_get_serialNumber(x509)) ||
-      !BN_to_ASN1_INTEGER(serial_number, asn1_serial_number))
-    goto error;
-
-  if (!X509_set_version(x509, 0L))  // version 1
-    goto error;
-
-  // There are a lot of possible components for the name entries. In
-  // our P2P SSL mode however, the certificates are pre-exchanged
-  // (through the secure XMPP channel), and so the certificate
-  // identification is arbitrary. It can't be empty, so we set some
-  // arbitrary common_name. Note that this certificate goes out in
-  // clear during SSL negotiation, so there may be a privacy issue in
-  // putting anything recognizable here.
-  if (!(name = X509_NAME_new()) ||
-      !X509_NAME_add_entry_by_NID(name, NID_commonName, MBSTRING_UTF8,
-                                     (unsigned char*)common_name, -1, -1, 0) ||
-      !X509_set_subject_name(x509, name) ||
-      !X509_set_issuer_name(x509, name))
-    goto error;
-
-  if (!X509_gmtime_adj(X509_get_notBefore(x509), 0) ||
-      !X509_gmtime_adj(X509_get_notAfter(x509), CERTIFICATE_LIFETIME))
-    goto error;
-
-  if (!X509_sign(x509, pkey, EVP_sha1()))
-    goto error;
-
-  BN_free(serial_number);
-  X509_NAME_free(name);
-  LOG(LS_INFO) << "Returning certificate";
-  return x509;
-
- error:
-  BN_free(serial_number);
-  X509_NAME_free(name);
-  X509_free(x509);
-  return NULL;
-}
-
-// This dumps the SSL error stack to the log.
-static void LogSSLErrors(const std::string& prefix) {
-  char error_buf[200];
-  unsigned long err;
-
-  while ((err = ERR_get_error())) {
-    ERR_error_string_n(err, error_buf, sizeof(error_buf));
-    LOG(LS_ERROR) << prefix << ": " << error_buf << "\n";
-  }
-}
-
-OpenSSLKeyPair* OpenSSLKeyPair::Generate() {
-  EVP_PKEY* pkey = MakeKey();
-  if (!pkey) {
-    LogSSLErrors("Generating key pair");
-    return NULL;
-  }
-  return new OpenSSLKeyPair(pkey);
-}
-
-OpenSSLKeyPair::~OpenSSLKeyPair() {
-  EVP_PKEY_free(pkey_);
-}
-
-void OpenSSLKeyPair::AddReference() {
-  CRYPTO_add(&pkey_->references, 1, CRYPTO_LOCK_EVP_PKEY);
-}
-
-#ifdef _DEBUG
-// Print a certificate to the log, for debugging.
-static void PrintCert(X509* x509) {
-  BIO* temp_memory_bio = BIO_new(BIO_s_mem());
-  if (!temp_memory_bio) {
-    LOG_F(LS_ERROR) << "Failed to allocate temporary memory bio";
-    return;
-  }
-  X509_print_ex(temp_memory_bio, x509, XN_FLAG_SEP_CPLUS_SPC, 0);
-  BIO_write(temp_memory_bio, "\0", 1);
-  char* buffer;
-  BIO_get_mem_data(temp_memory_bio, &buffer);
-  LOG(LS_VERBOSE) << buffer;
-  BIO_free(temp_memory_bio);
-}
-#endif
-
-OpenSSLCertificate* OpenSSLCertificate::Generate(
-    OpenSSLKeyPair* key_pair, const std::string& common_name) {
-  std::string actual_common_name = common_name;
-  if (actual_common_name.empty())
-    // Use a random string, arbitrarily 8chars long.
-    actual_common_name = CreateRandomString(8);
-  X509* x509 = MakeCertificate(key_pair->pkey(), actual_common_name.c_str());
-  if (!x509) {
-    LogSSLErrors("Generating certificate");
-    return NULL;
-  }
-#ifdef _DEBUG
-  PrintCert(x509);
-#endif
-  return new OpenSSLCertificate(x509);
-}
-
-OpenSSLCertificate* OpenSSLCertificate::FromPEMString(
-    const std::string& pem_string, int* pem_length) {
-  BIO* bio = BIO_new_mem_buf(const_cast<char*>(pem_string.c_str()), -1);
-  if (!bio)
-    return NULL;
-  (void)BIO_set_close(bio, BIO_NOCLOSE);
-  BIO_set_mem_eof_return(bio, 0);
-  X509 *x509 = PEM_read_bio_X509(bio, NULL, NULL,
-                                 const_cast<char*>("\0"));
-  char *ptr;
-  int remaining_length = BIO_get_mem_data(bio, &ptr);
-  BIO_free(bio);
-  if (pem_length)
-    *pem_length = pem_string.length() - remaining_length;
-  if (x509)
-    return new OpenSSLCertificate(x509);
-  else
-    return NULL;
-}
-
-bool OpenSSLCertificate::GetDigestLength(const std::string &algorithm,
-                                         std::size_t *length) {
-  const EVP_MD *md;
-
-  if (!GetDigestEVP(algorithm, &md))
-    return false;
-
-  *length = EVP_MD_size(md);
-
-  return true;
-}
-
-bool OpenSSLCertificate::ComputeDigest(const std::string &algorithm,
-                                       unsigned char *digest,
-                                       std::size_t size,
-                                       std::size_t *length) const {
-  return ComputeDigest(x509_, algorithm, digest, size, length);
-}
-
-bool OpenSSLCertificate::ComputeDigest(const X509 *x509,
-                                       const std::string &algorithm,
-                                       unsigned char *digest,
-                                       std::size_t size,
-                                       std::size_t *length) {
-  const EVP_MD *md;
-  unsigned int n;
-
-  if (!GetDigestEVP(algorithm, &md))
-    return false;
-
-  if (size < static_cast<size_t>(EVP_MD_size(md)))
-    return false;
-
-  X509_digest(x509, md, digest, &n);
-
-  *length = n;
-
-  return true;
-}
-
-
-bool OpenSSLCertificate::GetDigestEVP(const std::string &algorithm,
-                                      const EVP_MD **mdp) {
-#if defined(HAS_OPENSSL_1_0) && defined(LINUX)
-  const EVP_MD *md;
-  if (algorithm == DIGEST_SHA_1) {
-    md = EVP_sha1();
-  } else if (algorithm == DIGEST_SHA_224) {
-    md = EVP_sha224();
-  } else if (algorithm == DIGEST_SHA_256) {
-    md = EVP_sha256();
-  } else if (algorithm == DIGEST_SHA_384) {
-    md = EVP_sha384();
-  } else if (algorithm == DIGEST_SHA_512) {
-    md = EVP_sha512();
-  } else {
-    return false;
-  }
-
-  // Can't happen
-  ASSERT(EVP_MD_size(md) >= 20);
-  *mdp = md;
-  return true;
-#else
-  return false;
-#endif
-}
-
-OpenSSLCertificate::~OpenSSLCertificate() {
-  X509_free(x509_);
-}
-
-std::string OpenSSLCertificate::ToPEMString() const {
-  BIO* bio = BIO_new(BIO_s_mem());
-  if (!bio)
-    return NULL;
-  if (!PEM_write_bio_X509(bio, x509_)) {
-    BIO_free(bio);
-    return NULL;
-  }
-  BIO_write(bio, "\0", 1);
-  char* buffer;
-  BIO_get_mem_data(bio, &buffer);
-  std::string ret(buffer);
-  BIO_free(bio);
-  return ret;
-}
-
-void OpenSSLCertificate::AddReference() {
-  CRYPTO_add(&x509_->references, 1, CRYPTO_LOCK_X509);
-}
-
-OpenSSLIdentity* OpenSSLIdentity::Generate(const std::string& common_name) {
-  OpenSSLKeyPair *key_pair = OpenSSLKeyPair::Generate();
-  if (key_pair) {
-    OpenSSLCertificate *certificate =
-        OpenSSLCertificate::Generate(key_pair, common_name);
-    if (certificate)
-      return new OpenSSLIdentity(key_pair, certificate);
-    delete key_pair;
-  }
-  LOG(LS_INFO) << "Identity generation failed";
-  return NULL;
-}
-
-bool OpenSSLIdentity::ConfigureIdentity(SSL_CTX* ctx) {
-  // 1 is the documented success return code.
-  if (SSL_CTX_use_certificate(ctx, certificate_->x509()) != 1 ||
-     SSL_CTX_use_PrivateKey(ctx, key_pair_->pkey()) != 1) {
-    LogSSLErrors("Configuring key and certificate");
-    return false;
-  }
-  return true;
-}
-
-}  // talk_base namespace
diff --git a/third_party/libjingle/source/talk/base/opensslidentity.h b/third_party/libjingle/source/talk/base/opensslidentity.h
deleted file mode 100644
index f642736..0000000
--- a/third_party/libjingle/source/talk/base/opensslidentity.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2008, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_OPENSSLIDENTITY_H__
-#define TALK_BASE_OPENSSLIDENTITY_H__
-
-#include <openssl/evp.h>
-#include <openssl/x509.h>
-
-#include <string>
-
-#include "talk/base/common.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/base/sslidentity.h"
-
-typedef struct ssl_ctx_st SSL_CTX;
-
-namespace talk_base {
-
-// OpenSSLKeyPair encapsulates an OpenSSL EVP_PKEY* keypair object,
-// which is reference counted inside the OpenSSL library.
-class OpenSSLKeyPair {
- public:
-  static OpenSSLKeyPair* Generate();
-
-  virtual ~OpenSSLKeyPair();
-
-  virtual OpenSSLKeyPair* GetReference() {
-    AddReference();
-    return new OpenSSLKeyPair(pkey_);
-  }
-
-  EVP_PKEY* pkey() const { return pkey_; }
-
- private:
-  explicit OpenSSLKeyPair(EVP_PKEY* pkey) : pkey_(pkey) {
-    ASSERT(pkey_ != NULL);
-  }
-  void AddReference();
-
-  EVP_PKEY* pkey_;
-
-  DISALLOW_EVIL_CONSTRUCTORS(OpenSSLKeyPair);
-};
-
-// OpenSSLCertificate encapsulates an OpenSSL X509* certificate object,
-// which is also reference counted inside the OpenSSL library.
-class OpenSSLCertificate : public SSLCertificate {
- public:
-  static OpenSSLCertificate* Generate(OpenSSLKeyPair* key_pair,
-                                      const std::string& common_name);
-  static OpenSSLCertificate* FromPEMString(const std::string& pem_string,
-                                           int* pem_length);
-
-  virtual ~OpenSSLCertificate();
-
-  virtual OpenSSLCertificate* GetReference() {
-    AddReference();
-    return new OpenSSLCertificate(x509_);
-  }
-
-  X509* x509() const { return x509_; }
-
-  virtual std::string ToPEMString() const;
-
-  // Compute the digest of the certificate given algorithm
-  virtual bool ComputeDigest(const std::string &algorithm,
-                             unsigned char *digest, std::size_t size,
-                             std::size_t *length) const;
-
-  // Compute the digest of a certificate as an X509 *
-  static bool ComputeDigest(const X509 *x509,
-                             const std::string &algorithm,
-                             unsigned char *digest,
-                             std::size_t size,
-                             std::size_t *length);
-
-  // Helper function to get the length of a digest
-  static bool GetDigestLength(const std::string &algorithm,
-                              std::size_t *length);
-
- private:
-  explicit OpenSSLCertificate(X509* x509) : x509_(x509) {
-    ASSERT(x509_ != NULL);
-  }
-  void AddReference();
-
-  X509* x509_;
-
-  // Helper function to look up a digest
-  static bool GetDigestEVP(const std::string &algorithm,
-                           const EVP_MD **md);
-
-  DISALLOW_EVIL_CONSTRUCTORS(OpenSSLCertificate);
-};
-
-// Holds a keypair and certificate together, and a method to generate
-// them consistently.
-class OpenSSLIdentity : public SSLIdentity {
- public:
-  static OpenSSLIdentity* Generate(const std::string& common_name);
-
-  virtual ~OpenSSLIdentity() { }
-
-  virtual OpenSSLCertificate& certificate() const {
-    return *certificate_;
-  }
-
-  virtual OpenSSLIdentity* GetReference() {
-    return new OpenSSLIdentity(key_pair_->GetReference(),
-                               certificate_->GetReference());
-  }
-
-  // Configure an SSL context object to use our key and certificate.
-  bool ConfigureIdentity(SSL_CTX* ctx);
-
- private:
-  OpenSSLIdentity(OpenSSLKeyPair* key_pair,
-                  OpenSSLCertificate* certificate)
-      : key_pair_(key_pair), certificate_(certificate) {
-    ASSERT(key_pair != NULL);
-    ASSERT(certificate != NULL);
-  }
-
-  scoped_ptr<OpenSSLKeyPair> key_pair_;
-  scoped_ptr<OpenSSLCertificate> certificate_;
-
-  DISALLOW_EVIL_CONSTRUCTORS(OpenSSLIdentity);
-};
-
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_OPENSSLIDENTITY_H__
diff --git a/third_party/libjingle/source/talk/base/opensslstreamadapter.cc b/third_party/libjingle/source/talk/base/opensslstreamadapter.cc
deleted file mode 100644
index 18cef5c..0000000
--- a/third_party/libjingle/source/talk/base/opensslstreamadapter.cc
+++ /dev/null
@@ -1,789 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2008, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#if HAVE_CONFIG_H
-#include "config.h"
-#endif  // HAVE_CONFIG_H
-
-#if HAVE_OPENSSL_SSL_H
-
-#include "talk/base/opensslstreamadapter.h"
-
-#include <openssl/bio.h>
-#include <openssl/crypto.h>
-#include <openssl/err.h>
-#include <openssl/rand.h>
-#include <openssl/ssl.h>
-#include <openssl/x509v3.h>
-
-#include "talk/base/common.h"
-#include "talk/base/logging.h"
-#include "talk/base/stream.h"
-#include "talk/base/openssladapter.h"
-#include "talk/base/opensslidentity.h"
-#include "talk/base/stringutils.h"
-#include "talk/base/thread.h"
-
-namespace talk_base {
-
-
-//////////////////////////////////////////////////////////////////////
-// StreamBIO
-//////////////////////////////////////////////////////////////////////
-
-static int stream_write(BIO* h, const char* buf, int num);
-static int stream_read(BIO* h, char* buf, int size);
-static int stream_puts(BIO* h, const char* str);
-static long stream_ctrl(BIO* h, int cmd, long arg1, void* arg2);
-static int stream_new(BIO* h);
-static int stream_free(BIO* data);
-
-static BIO_METHOD methods_stream = {
-  BIO_TYPE_BIO,
-  "stream",
-  stream_write,
-  stream_read,
-  stream_puts,
-  0,
-  stream_ctrl,
-  stream_new,
-  stream_free,
-  NULL,
-};
-
-static BIO_METHOD* BIO_s_stream() { return(&methods_stream); }
-
-static BIO* BIO_new_stream(StreamInterface* stream) {
-  BIO* ret = BIO_new(BIO_s_stream());
-  if (ret == NULL)
-    return NULL;
-  ret->ptr = stream;
-  return ret;
-}
-
-// bio methods return 1 (or at least non-zero) on success and 0 on failure.
-
-static int stream_new(BIO* b) {
-  b->shutdown = 0;
-  b->init = 1;
-  b->num = 0;  // 1 means end-of-stream
-  b->ptr = 0;
-  return 1;
-}
-
-static int stream_free(BIO* b) {
-  if (b == NULL)
-    return 0;
-  return 1;
-}
-
-static int stream_read(BIO* b, char* out, int outl) {
-  if (!out)
-    return -1;
-  StreamInterface* stream = static_cast<StreamInterface*>(b->ptr);
-  BIO_clear_retry_flags(b);
-  size_t read;
-  int error;
-  StreamResult result = stream->Read(out, outl, &read, &error);
-  if (result == SR_SUCCESS) {
-    return read;
-  } else if (result == SR_EOS) {
-    b->num = 1;
-  } else if (result == SR_BLOCK) {
-    BIO_set_retry_read(b);
-  }
-  return -1;
-}
-
-static int stream_write(BIO* b, const char* in, int inl) {
-  if (!in)
-    return -1;
-  StreamInterface* stream = static_cast<StreamInterface*>(b->ptr);
-  BIO_clear_retry_flags(b);
-  size_t written;
-  int error;
-  StreamResult result = stream->Write(in, inl, &written, &error);
-  if (result == SR_SUCCESS) {
-    return written;
-  } else if (result == SR_BLOCK) {
-    BIO_set_retry_write(b);
-  }
-  return -1;
-}
-
-static int stream_puts(BIO* b, const char* str) {
-  return stream_write(b, str, strlen(str));
-}
-
-static long stream_ctrl(BIO* b, int cmd, long num, void* ptr) {
-  UNUSED(num);
-  UNUSED(ptr);
-
-  switch (cmd) {
-    case BIO_CTRL_RESET:
-      return 0;
-    case BIO_CTRL_EOF:
-      return b->num;
-    case BIO_CTRL_WPENDING:
-    case BIO_CTRL_PENDING:
-      return 0;
-    case BIO_CTRL_FLUSH:
-      return 1;
-    default:
-      return 0;
-  }
-}
-
-/////////////////////////////////////////////////////////////////////////////
-// OpenSSLStreamAdapter
-/////////////////////////////////////////////////////////////////////////////
-
-OpenSSLStreamAdapter::OpenSSLStreamAdapter(StreamInterface* stream)
-    : SSLStreamAdapter(stream),
-      state_(SSL_NONE),
-      role_(SSL_CLIENT),
-      ssl_read_needs_write_(false), ssl_write_needs_read_(false),
-      ssl_(NULL), ssl_ctx_(NULL),
-      custom_verification_succeeded_(false),
-      ssl_mode_(SSL_MODE_TLS) {
-}
-
-OpenSSLStreamAdapter::~OpenSSLStreamAdapter() {
-  Cleanup();
-}
-
-void OpenSSLStreamAdapter::SetIdentity(SSLIdentity* identity) {
-  ASSERT(identity_.get() == NULL);
-  identity_.reset(static_cast<OpenSSLIdentity*>(identity));
-}
-
-void OpenSSLStreamAdapter::SetServerRole(SSLRole role) {
-  role_ = role;
-}
-
-void OpenSSLStreamAdapter::SetPeerCertificate(SSLCertificate* cert) {
-  ASSERT(peer_certificate_.get() == NULL);
-  ASSERT(peer_certificate_digest_algorithm_.empty());
-  ASSERT(ssl_server_name_.empty());
-  peer_certificate_.reset(static_cast<OpenSSLCertificate*>(cert));
-}
-
-bool OpenSSLStreamAdapter::SetPeerCertificateDigest(const std::string
-                                                    &digest_alg,
-                                                    const unsigned char*
-                                                    digest_val,
-                                                    size_t digest_len) {
-  ASSERT(peer_certificate_.get() == NULL);
-  ASSERT(peer_certificate_digest_algorithm_.size() == 0);
-  ASSERT(ssl_server_name_.empty());
-  size_t expected_len;
-
-  if (!OpenSSLCertificate::GetDigestLength(digest_alg, &expected_len)) {
-    LOG(LS_WARNING) << "Unknown digest algorithm: " << digest_alg;
-    return false;
-  }
-  if (expected_len != digest_len)
-    return false;
-
-  peer_certificate_digest_value_.SetData(digest_val, digest_len);
-  peer_certificate_digest_algorithm_ = digest_alg;
-
-  return true;
-}
-
-
-int OpenSSLStreamAdapter::StartSSLWithServer(const char* server_name) {
-  ASSERT(server_name != NULL && server_name[0] != '\0');
-  ssl_server_name_ = server_name;
-  return StartSSL();
-}
-
-int OpenSSLStreamAdapter::StartSSLWithPeer() {
-  ASSERT(ssl_server_name_.empty());
-  // It is permitted to specify peer_certificate_ only later.
-  return StartSSL();
-}
-
-void OpenSSLStreamAdapter::SetMode(SSLMode mode) {
-  ASSERT(state_ == SSL_NONE);
-  ssl_mode_ = mode;
-}
-
-//
-// StreamInterface Implementation
-//
-
-StreamResult OpenSSLStreamAdapter::Write(const void* data, size_t data_len,
-                                         size_t* written, int* error) {
-  LOG(LS_INFO) << "OpenSSLStreamAdapter::Write(" << data_len << ")";
-
-  switch (state_) {
-  case SSL_NONE:
-    // pass-through in clear text
-    return StreamAdapterInterface::Write(data, data_len, written, error);
-
-  case SSL_WAIT:
-  case SSL_CONNECTING:
-    return SR_BLOCK;
-
-  case SSL_CONNECTED:
-    break;
-
-  case SSL_ERROR:
-  case SSL_CLOSED:
-  default:
-    if (error)
-      *error = ssl_error_code_;
-    return SR_ERROR;
-  }
-
-  // OpenSSL will return an error if we try to write zero bytes
-  if (data_len == 0) {
-    if (written)
-      *written = 0;
-    return SR_SUCCESS;
-  }
-
-  ssl_write_needs_read_ = false;
-
-  int code = SSL_write(ssl_, data, data_len);
-  int ssl_error = SSL_get_error(ssl_, code);
-  switch (ssl_error) {
-  case SSL_ERROR_NONE:
-    LOG(LS_INFO) << " -- success";
-    ASSERT(0 < code && static_cast<unsigned>(code) <= data_len);
-    if (written)
-      *written = code;
-    return SR_SUCCESS;
-  case SSL_ERROR_WANT_READ:
-    LOG(LS_INFO) << " -- error want read";
-    ssl_write_needs_read_ = true;
-    return SR_BLOCK;
-  case SSL_ERROR_WANT_WRITE:
-    LOG(LS_INFO) << " -- error want write";
-    return SR_BLOCK;
-
-  case SSL_ERROR_ZERO_RETURN:
-  default:
-    Error("SSL_write", (ssl_error ? ssl_error : -1), false);
-    if (error)
-      *error = ssl_error_code_;
-    return SR_ERROR;
-  }
-  // not reached
-}
-
-StreamResult OpenSSLStreamAdapter::Read(void* data, size_t data_len,
-                                        size_t* read, int* error) {
-  LOG(LS_INFO) << "OpenSSLStreamAdapter::Read(" << data_len << ")";
-  switch (state_) {
-    case SSL_NONE:
-      // pass-through in clear text
-      return StreamAdapterInterface::Read(data, data_len, read, error);
-
-    case SSL_WAIT:
-    case SSL_CONNECTING:
-      return SR_BLOCK;
-
-    case SSL_CONNECTED:
-      break;
-
-    case SSL_CLOSED:
-      return SR_EOS;
-
-    case SSL_ERROR:
-    default:
-      if (error)
-        *error = ssl_error_code_;
-      return SR_ERROR;
-  }
-
-  // Don't trust OpenSSL with zero byte reads
-  if (data_len == 0) {
-    if (read)
-      *read = 0;
-    return SR_SUCCESS;
-  }
-
-  ssl_read_needs_write_ = false;
-
-  int code = SSL_read(ssl_, data, data_len);
-  int ssl_error = SSL_get_error(ssl_, code);
-  switch (ssl_error) {
-    case SSL_ERROR_NONE:
-      LOG(LS_INFO) << " -- success";
-      ASSERT(0 < code && static_cast<unsigned>(code) <= data_len);
-      if (read)
-        *read = code;
-
-      if (ssl_mode_ == SSL_MODE_DTLS) {
-        // Enforce atomic reads -- this is a short read
-        unsigned int pending = SSL_pending(ssl_);
-
-        if (pending) {
-          LOG(LS_INFO) << " -- short DTLS read. flushing";
-          FlushInput(pending);
-          if (error)
-            *error = SSE_MSG_TRUNC;
-          return SR_ERROR;
-        }
-      }
-      return SR_SUCCESS;
-    case SSL_ERROR_WANT_READ:
-      LOG(LS_INFO) << " -- error want read";
-      return SR_BLOCK;
-    case SSL_ERROR_WANT_WRITE:
-      LOG(LS_INFO) << " -- error want write";
-      ssl_read_needs_write_ = true;
-      return SR_BLOCK;
-    case SSL_ERROR_ZERO_RETURN:
-      LOG(LS_INFO) << " -- remote side closed";
-      return SR_EOS;
-      break;
-    default:
-      LOG(LS_INFO) << " -- error " << code;
-      Error("SSL_read", (ssl_error ? ssl_error : -1), false);
-      if (error)
-        *error = ssl_error_code_;
-      return SR_ERROR;
-  }
-  // not reached
-}
-
-void OpenSSLStreamAdapter::FlushInput(unsigned int left) {
-  unsigned char buf[2048];
-
-  while (left) {
-    // This should always succeed
-    int toread = (sizeof(buf) < left) ? sizeof(buf) : left;
-    int code = SSL_read(ssl_, buf, toread);
-
-    int ssl_error = SSL_get_error(ssl_, code);
-    ASSERT(ssl_error == SSL_ERROR_NONE);
-
-    if (ssl_error != SSL_ERROR_NONE) {
-      LOG(LS_INFO) << " -- error " << code;
-      Error("SSL_read", (ssl_error ? ssl_error : -1), false);
-      return;
-    }
-    LOG(LS_INFO) << " -- flushed " << code << " bytes";
-    left -= code;
-  }
-}
-
-void OpenSSLStreamAdapter::Close() {
-  Cleanup();
-  ASSERT(state_ == SSL_CLOSED || state_ == SSL_ERROR);
-  StreamAdapterInterface::Close();
-}
-
-StreamState OpenSSLStreamAdapter::GetState() const {
-  switch (state_) {
-    case SSL_WAIT:
-    case SSL_CONNECTING:
-      return SS_OPENING;
-    case SSL_CONNECTED:
-      return SS_OPEN;
-    default:
-      return SS_CLOSED;
-  };
-  // not reached
-}
-
-void OpenSSLStreamAdapter::OnEvent(StreamInterface* stream, int events,
-                                   int err) {
-  int events_to_signal = 0;
-  int signal_error = 0;
-  ASSERT(stream == this->stream());
-  if ((events & SE_OPEN)) {
-    LOG(LS_INFO) << "OpenSSLStreamAdapter::OnEvent SE_OPEN";
-    if (state_ != SSL_WAIT) {
-      ASSERT(state_ == SSL_NONE);
-      events_to_signal |= SE_OPEN;
-    } else {
-      state_ = SSL_CONNECTING;
-      if (int err = BeginSSL()) {
-        Error("BeginSSL", err, true);
-        return;
-      }
-    }
-  }
-  if ((events & (SE_READ|SE_WRITE))) {
-    LOG(LS_INFO) << "OpenSSLStreamAdapter::OnEvent"
-                 << ((events & SE_READ) ? " SE_READ" : "")
-                 << ((events & SE_WRITE) ? " SE_WRITE" : "");
-    if (state_ == SSL_NONE) {
-      events_to_signal |= events & (SE_READ|SE_WRITE);
-    } else if (state_ == SSL_CONNECTING) {
-      if (int err = ContinueSSL()) {
-        Error("ContinueSSL", err, true);
-        return;
-      }
-    } else if (state_ == SSL_CONNECTED) {
-      if (((events & SE_READ) && ssl_write_needs_read_) ||
-          (events & SE_WRITE)) {
-        LOG(LS_INFO) << " -- onStreamWriteable";
-        events_to_signal |= SE_WRITE;
-      }
-      if (((events & SE_WRITE) && ssl_read_needs_write_) ||
-          (events & SE_READ)) {
-        LOG(LS_INFO) << " -- onStreamReadable";
-        events_to_signal |= SE_READ;
-      }
-    }
-  }
-  if ((events & SE_CLOSE)) {
-    LOG(LS_INFO) << "OpenSSLStreamAdapter::OnEvent(SE_CLOSE, " << err << ")";
-    Cleanup();
-    events_to_signal |= SE_CLOSE;
-    // SE_CLOSE is the only event that uses the final parameter to OnEvent().
-    ASSERT(signal_error == 0);
-    signal_error = err;
-  }
-  if (events_to_signal)
-    StreamAdapterInterface::OnEvent(stream, events_to_signal, signal_error);
-}
-
-int OpenSSLStreamAdapter::StartSSL() {
-  ASSERT(state_ == SSL_NONE);
-
-  if (StreamAdapterInterface::GetState() != SS_OPEN) {
-    state_ = SSL_WAIT;
-    return 0;
-  }
-
-  state_ = SSL_CONNECTING;
-  if (int err = BeginSSL()) {
-    Error("BeginSSL", err, false);
-    return err;
-  }
-
-  return 0;
-}
-
-int OpenSSLStreamAdapter::BeginSSL() {
-  ASSERT(state_ == SSL_CONNECTING);
-  // The underlying stream has open. If we are in peer-to-peer mode
-  // then a peer certificate must have been specified by now.
-  ASSERT(!ssl_server_name_.empty() ||
-         peer_certificate_.get() != NULL ||
-         !peer_certificate_digest_algorithm_.empty());
-  LOG(LS_INFO) << "BeginSSL: "
-               << (!ssl_server_name_.empty() ? ssl_server_name_ :
-                                               "with peer");
-
-  BIO* bio = NULL;
-
-  // First set up the context
-  ASSERT(ssl_ctx_ == NULL);
-  ssl_ctx_ = SetupSSLContext();
-  if (!ssl_ctx_)
-    return -1;
-
-  bio = BIO_new_stream(static_cast<StreamInterface*>(stream()));
-  if (!bio)
-    return -1;
-
-  ssl_ = SSL_new(ssl_ctx_);
-  if (!ssl_) {
-    BIO_free(bio);
-    return -1;
-  }
-
-  SSL_set_app_data(ssl_, this);
-
-  SSL_set_bio(ssl_, bio, bio);  // the SSL object owns the bio now.
-
-  SSL_set_mode(ssl_, SSL_MODE_ENABLE_PARTIAL_WRITE |
-               SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
-
-  // Do the connect
-  return ContinueSSL();
-}
-
-int OpenSSLStreamAdapter::ContinueSSL() {
-  LOG(LS_INFO) << "ContinueSSL";
-  ASSERT(state_ == SSL_CONNECTING);
-
-  // Clear the DTLS timer
-  Thread::Current()->Clear(this, MSG_TIMEOUT);
-
-  int code = (role_ == SSL_CLIENT) ? SSL_connect(ssl_) : SSL_accept(ssl_);
-  int ssl_error;
-  switch (ssl_error = SSL_get_error(ssl_, code)) {
-    case SSL_ERROR_NONE:
-      LOG(LS_INFO) << " -- success";
-
-      if (!SSLPostConnectionCheck(ssl_, ssl_server_name_.c_str(),
-                                  peer_certificate_.get() != NULL
-                                  ? peer_certificate_->x509() : NULL,
-                                  peer_certificate_digest_algorithm_)) {
-        LOG(LS_ERROR) << "TLS post connection check failed";
-        return -1;
-      }
-
-      state_ = SSL_CONNECTED;
-      StreamAdapterInterface::OnEvent(stream(), SE_OPEN|SE_READ|SE_WRITE, 0);
-      break;
-
-    case SSL_ERROR_WANT_READ:{
-        LOG(LS_INFO) << " -- error want read";
-#if defined(HAS_OPENSSL_1_0) && defined(LINUX)
-        struct timeval timeout;
-        if (DTLSv1_get_timeout(ssl_, &timeout)) {
-          int delay = timeout.tv_sec * 1000 + timeout.tv_usec/1000;
-
-          Thread::Current()->PostDelayed(delay, this, MSG_TIMEOUT, 0);
-        }
-#endif
-      }
-      break;
-
-    case SSL_ERROR_WANT_WRITE:
-      LOG(LS_INFO) << " -- error want write";
-      break;
-
-    case SSL_ERROR_ZERO_RETURN:
-    default:
-      LOG(LS_INFO) << " -- error " << code;
-      return (ssl_error != 0) ? ssl_error : -1;
-  }
-
-  return 0;
-}
-
-void OpenSSLStreamAdapter::Error(const char* context, int err, bool signal) {
-  LOG(LS_WARNING) << "OpenSSLStreamAdapter::Error("
-                  << context << ", " << err << ")";
-  state_ = SSL_ERROR;
-  ssl_error_code_ = err;
-  Cleanup();
-  if (signal)
-    StreamAdapterInterface::OnEvent(stream(), SE_CLOSE, err);
-}
-
-void OpenSSLStreamAdapter::Cleanup() {
-  LOG(LS_INFO) << "Cleanup";
-
-  if (state_ != SSL_ERROR) {
-    state_ = SSL_CLOSED;
-    ssl_error_code_ = 0;
-  }
-
-  if (ssl_) {
-    SSL_free(ssl_);
-    ssl_ = NULL;
-  }
-  if (ssl_ctx_) {
-    SSL_CTX_free(ssl_ctx_);
-    ssl_ctx_ = NULL;
-  }
-  identity_.reset();
-  peer_certificate_.reset();
-
-  // Clear the DTLS timer
-  Thread::Current()->Clear(this, MSG_TIMEOUT);
-}
-
-
-void OpenSSLStreamAdapter::OnMessage(Message* msg) {
-  // Process our own messages and then pass others to the superclass
-  if (MSG_TIMEOUT == msg->message_id) {
-    LOG(LS_INFO) << "DTLS timeout expired";
-#if defined(HAS_OPENSSL_1_0) && defined(LINUX)
-    DTLSv1_handle_timeout(ssl_);
-#endif
-    ContinueSSL();
-  } else {
-    StreamInterface::OnMessage(msg);
-  }
-}
-
-SSL_CTX* OpenSSLStreamAdapter::SetupSSLContext() {
-  SSL_CTX *ctx = NULL;
-
-#if defined(HAS_OPENSSL_1_0) && defined(LINUX)
-  if (role_ == SSL_CLIENT) {
-    ctx = SSL_CTX_new(ssl_mode_ == SSL_MODE_DTLS ?
-        DTLSv1_client_method() : TLSv1_client_method());
-  } else {
-    ctx = SSL_CTX_new(ssl_mode_ == SSL_MODE_DTLS ?
-        DTLSv1_server_method() : TLSv1_server_method());
-  }
-#endif
-  if (ctx == NULL)
-    return NULL;
-
-  if (identity_.get() && !identity_->ConfigureIdentity(ctx)) {
-    SSL_CTX_free(ctx);
-    return NULL;
-  }
-
-  if (peer_certificate_.get() == NULL) {  // traditional mode
-    // Add the root cert to the SSL context
-    if (!OpenSSLAdapter::ConfigureTrustedRootCertificates(ctx)) {
-      SSL_CTX_free(ctx);
-      return NULL;
-    }
-  }
-
-  if (peer_certificate_.get() != NULL && role_ == SSL_SERVER)
-    // we must specify which client cert to ask for
-    SSL_CTX_add_client_CA(ctx, peer_certificate_->x509());
-
-#ifdef _DEBUG
-  SSL_CTX_set_info_callback(ctx, OpenSSLAdapter::SSLInfoCallback);
-#endif
-
-  SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER |SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
-                     SSLVerifyCallback);
-  SSL_CTX_set_verify_depth(ctx, 4);
-  SSL_CTX_set_cipher_list(ctx, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
-
-  return ctx;
-}
-
-int OpenSSLStreamAdapter::SSLVerifyCallback(int ok, X509_STORE_CTX* store) {
-#if _DEBUG
-  if (!ok) {
-    char data[256];
-    X509* cert = X509_STORE_CTX_get_current_cert(store);
-    int depth = X509_STORE_CTX_get_error_depth(store);
-    int err = X509_STORE_CTX_get_error(store);
-
-    LOG(LS_INFO) << "Error with certificate at depth: " << depth;
-    X509_NAME_oneline(X509_get_issuer_name(cert), data, sizeof(data));
-    LOG(LS_INFO) << "  issuer  = " << data;
-    X509_NAME_oneline(X509_get_subject_name(cert), data, sizeof(data));
-    LOG(LS_INFO) << "  subject = " << data;
-    LOG(LS_INFO) << "  err     = " << err
-      << ":" << X509_verify_cert_error_string(err);
-  }
-#endif
-
-  // Get our SSL structure from the store
-  SSL* ssl = reinterpret_cast<SSL*>(X509_STORE_CTX_get_ex_data(
-                                        store,
-                                        SSL_get_ex_data_X509_STORE_CTX_idx()));
-
-  OpenSSLStreamAdapter* stream =
-    reinterpret_cast<OpenSSLStreamAdapter*>(SSL_get_app_data(ssl));
-
-  // In peer-to-peer mode, no root cert / certificate authority was
-  // specified, so the libraries knows of no certificate to accept,
-  // and therefore it will necessarily call here on the first cert it
-  // tries to verify.
-  if (!ok && stream->peer_certificate_.get() != NULL) {
-    X509* cert = X509_STORE_CTX_get_current_cert(store);
-    int err = X509_STORE_CTX_get_error(store);
-    // peer-to-peer mode: allow the certificate to be self-signed,
-    // assuming it matches the cert that was specified.
-    if (err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT &&
-        X509_cmp(cert, stream->peer_certificate_->x509()) == 0) {
-      LOG(LS_INFO) << "Accepted self-signed peer certificate authority";
-      ok = 1;
-    }
-  } else if (!ok && !stream->peer_certificate_digest_algorithm_.empty()) {
-    X509* cert = X509_STORE_CTX_get_current_cert(store);
-    int err = X509_STORE_CTX_get_error(store);
-
-    // peer-to-peer mode: allow the certificate to be self-signed,
-    // assuming it matches the digest that was specified.
-    if (err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) {
-      unsigned char digest[EVP_MAX_MD_SIZE];
-      std::size_t digest_length;
-
-      if (OpenSSLCertificate::
-         ComputeDigest(cert,
-                       stream->peer_certificate_digest_algorithm_,
-                       digest, sizeof(digest),
-                       &digest_length)) {
-        Buffer computed_digest(digest, digest_length);
-        if (computed_digest == stream->peer_certificate_digest_value_) {
-          LOG(LS_INFO) <<
-              "Accepted self-signed peer certificate authority";
-          ok = 1;
-        }
-      }
-    }
-  } else if (!ok && OpenSSLAdapter::custom_verify_callback_) {
-    // this applies only in traditional mode
-    void* cert =
-        reinterpret_cast<void*>(X509_STORE_CTX_get_current_cert(store));
-    if (OpenSSLAdapter::custom_verify_callback_(cert)) {
-      stream->custom_verification_succeeded_ = true;
-      LOG(LS_INFO) << "validated certificate using custom callback";
-      ok = 1;
-    }
-  }
-
-  if (!ok && stream->ignore_bad_cert()) {
-    LOG(LS_WARNING) << "Ignoring cert error while verifying cert chain";
-    ok = 1;
-  }
-
-  return ok;
-}
-
-// This code is taken from the "Network Security with OpenSSL"
-// sample in chapter 5
-bool OpenSSLStreamAdapter::SSLPostConnectionCheck(SSL* ssl,
-                                                  const char* server_name,
-                                                  const X509* peer_cert,
-                                                  const std::string
-                                                  &peer_digest) {
-  ASSERT(server_name != NULL);
-  bool ok;
-  if (server_name[0] != '\0') {  // traditional mode
-    ok = OpenSSLAdapter::VerifyServerName(ssl, server_name, ignore_bad_cert());
-
-    if (ok) {
-      ok = (SSL_get_verify_result(ssl) == X509_V_OK ||
-            custom_verification_succeeded_);
-    }
-  } else {  // peer-to-peer mode
-    ASSERT((peer_cert != NULL) || (!peer_digest.empty()));
-    // no server name validation
-    ok = true;
-  }
-
-  if (!ok && ignore_bad_cert()) {
-    LOG(LS_ERROR) << "SSL_get_verify_result(ssl) = "
-                  << SSL_get_verify_result(ssl);
-    LOG(LS_INFO) << "Other TLS post connection checks failed.";
-    ok = true;
-  }
-
-  return ok;
-}
-
-
-
-
-}  // namespace talk_base
-
-#endif  // HAVE_OPENSSL_SSL_H
diff --git a/third_party/libjingle/source/talk/base/opensslstreamadapter.h b/third_party/libjingle/source/talk/base/opensslstreamadapter.h
deleted file mode 100644
index 1f94e2b..0000000
--- a/third_party/libjingle/source/talk/base/opensslstreamadapter.h
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2008, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_OPENSSLSTREAMADAPTER_H__
-#define TALK_BASE_OPENSSLSTREAMADAPTER_H__
-
-#include <string>
-#include "talk/base/buffer.h"
-#include "talk/base/sslstreamadapter.h"
-#include "talk/base/opensslidentity.h"
-
-typedef struct ssl_st SSL;
-typedef struct ssl_ctx_st SSL_CTX;
-typedef struct x509_store_ctx_st X509_STORE_CTX;
-
-namespace talk_base {
-
-// This class was written with OpenSSLAdapter (a socket adapter) as a
-// starting point. It has similar structure and functionality, with
-// the peer-to-peer mode added.
-//
-// Static methods to initialize and deinit the SSL library are in
-// OpenSSLAdapter. This class also uses
-// OpenSSLAdapter::custom_verify_callback_ (a static field). These
-// should probably be moved out to a neutral class.
-//
-// In a few cases I have factored out some OpenSSLAdapter code into
-// static methods so it can be reused from this class. Eventually that
-// code should probably be moved to a common support
-// class. Unfortunately there remain a few duplicated sections of
-// code. I have not done more restructuring because I did not want to
-// affect existing code that uses OpenSSLAdapter.
-//
-// This class does not support the SSL connection restart feature
-// present in OpenSSLAdapter. I am not entirely sure how the feature
-// is useful and I am not convinced that it works properly.
-//
-// This implementation is careful to disallow data exchange after an
-// SSL error, and it has an explicit SSL_CLOSED state. It should not
-// be possible to send any data in clear after one of the StartSSL
-// methods has been called.
-
-// Look in sslstreamadapter.h for documentation of the methods.
-
-class OpenSSLIdentity;
-
-///////////////////////////////////////////////////////////////////////////////
-
-class OpenSSLStreamAdapter : public SSLStreamAdapter {
- public:
-  explicit OpenSSLStreamAdapter(StreamInterface* stream);
-  virtual ~OpenSSLStreamAdapter();
-
-  virtual void SetIdentity(SSLIdentity* identity);
-
-  // Default argument is for compatibility
-  virtual void SetServerRole(SSLRole role = SSL_SERVER);
-  virtual void SetPeerCertificate(SSLCertificate* cert);
-  virtual bool SetPeerCertificateDigest(const std::string& digest_alg,
-                                        const unsigned char* digest_val,
-                                        size_t digest_len);
-
-  virtual int StartSSLWithServer(const char* server_name);
-  virtual int StartSSLWithPeer();
-  virtual void SetMode(SSLMode mode);
-
-  virtual StreamResult Read(void* data, size_t data_len,
-                            size_t* read, int* error);
-  virtual StreamResult Write(const void* data, size_t data_len,
-                             size_t* written, int* error);
-  virtual void Close();
-  virtual StreamState GetState() const;
-
- protected:
-  virtual void OnEvent(StreamInterface* stream, int events, int err);
-
- private:
-  enum SSLState {
-    // Before calling one of the StartSSL methods, data flows
-    // in clear text.
-    SSL_NONE,
-    SSL_WAIT,  // waiting for the stream to open to start SSL negotiation
-    SSL_CONNECTING,  // SSL negotiation in progress
-    SSL_CONNECTED,  // SSL stream successfully established
-    SSL_ERROR,  // some SSL error occurred, stream is closed
-    SSL_CLOSED  // Clean close
-  };
-
-  enum { MSG_TIMEOUT = MSG_MAX+1};
-
-  // The following three methods return 0 on success and a negative
-  // error code on failure. The error code may be from OpenSSL or -1
-  // on some other error cases, so it can't really be interpreted
-  // unfortunately.
-
-  // Go from state SSL_NONE to either SSL_CONNECTING or SSL_WAIT,
-  // depending on whether the underlying stream is already open or
-  // not.
-  int StartSSL();
-  // Prepare SSL library, state is SSL_CONNECTING.
-  int BeginSSL();
-  // Perform SSL negotiation steps.
-  int ContinueSSL();
-
-  // Error handler helper. signal is given as true for errors in
-  // asynchronous contexts (when an error method was not returned
-  // through some other method), and in that case an SE_CLOSE event is
-  // raised on the stream with the specified error.
-  // A 0 error means a graceful close, otherwise there is not really enough
-  // context to interpret the error code.
-  void Error(const char* context, int err, bool signal);
-  void Cleanup();
-
-  // Override MessageHandler
-  virtual void OnMessage(Message* msg);
-
-  // Flush the input buffers by reading left bytes (for DTLS)
-  void FlushInput(unsigned int left);
-
-  // SSL library configuration
-  SSL_CTX* SetupSSLContext();
-  // SSL verification check
-  bool SSLPostConnectionCheck(SSL* ssl, const char* server_name,
-                              const X509* peer_cert,
-                              const std::string& peer_digest);
-  // SSL certification verification error handler, called back from
-  // the openssl library. Returns an int interpreted as a boolean in
-  // the C style: zero means verification failure, non-zero means
-  // passed.
-  static int SSLVerifyCallback(int ok, X509_STORE_CTX* store);
-
-
-  SSLState state_;
-  SSLRole role_;
-  int ssl_error_code_;  // valid when state_ == SSL_ERROR or SSL_CLOSED
-  // Whether the SSL negotiation is blocked on needing to read or
-  // write to the wrapped stream.
-  bool ssl_read_needs_write_;
-  bool ssl_write_needs_read_;
-
-  SSL* ssl_;
-  SSL_CTX* ssl_ctx_;
-
-  // Our key and certificate, mostly useful in peer-to-peer mode.
-  scoped_ptr<OpenSSLIdentity> identity_;
-  // in traditional mode, the server name that the server's certificate
-  // must specify. Empty in peer-to-peer mode.
-  std::string ssl_server_name_;
-  // In peer-to-peer mode, the certificate that the peer must
-  // present. Empty in traditional mode.
-  scoped_ptr<OpenSSLCertificate> peer_certificate_;
-  // In peer-to-peer mode, the digest of the certificate that
-  // the peer must present.
-  Buffer peer_certificate_digest_value_;
-  std::string peer_certificate_digest_algorithm_;
-
-  // OpenSSLAdapter::custom_verify_callback_ result
-  bool custom_verification_succeeded_;
-
-  // Do DTLS or not
-  SSLMode ssl_mode_;
-};
-
-/////////////////////////////////////////////////////////////////////////////
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_OPENSSLSTREAMADAPTER_H__
diff --git a/third_party/libjingle/source/talk/base/optionsfile.cc b/third_party/libjingle/source/talk/base/optionsfile.cc
deleted file mode 100644
index 82a5c86..0000000
--- a/third_party/libjingle/source/talk/base/optionsfile.cc
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * libjingle
- * Copyright 2008, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/optionsfile.h"
-
-#include <ctype.h>
-
-#include "talk/base/logging.h"
-#include "talk/base/stream.h"
-#include "talk/base/stringencode.h"
-
-namespace talk_base {
-
-OptionsFile::OptionsFile(const std::string &path) : path_(path) {
-}
-
-bool OptionsFile::Load() {
-  options_.clear();
-  // Open file.
-  FileStream stream;
-  int err;
-  if (!stream.Open(path_, "r", &err)) {
-    LOG_F(LS_WARNING) << "Could not open file, err=" << err;
-    // We do not consider this an error because we expect there to be no file
-    // until the user saves a setting.
-    return true;
-  }
-  // Read in all its data.
-  std::string line;
-  StreamResult res;
-  for (;;) {
-    res = stream.ReadLine(&line);
-    if (res != SR_SUCCESS) {
-      break;
-    }
-    size_t equals_pos = line.find('=');
-    if (equals_pos == std::string::npos) {
-      // We do not consider this an error. Instead we ignore the line and
-      // keep going.
-      LOG_F(LS_WARNING) << "Ignoring malformed line in " << path_;
-      continue;
-    }
-    std::string key(line, 0, equals_pos);
-    std::string value(line, equals_pos + 1, line.length() - (equals_pos + 1));
-    options_[key] = value;
-  }
-  if (res != SR_EOS) {
-    LOG_F(LS_ERROR) << "Error when reading from file";
-    return false;
-  } else {
-    return true;
-  }
-}
-
-bool OptionsFile::Save() {
-  // Open file.
-  FileStream stream;
-  int err;
-  if (!stream.Open(path_, "w", &err)) {
-    LOG_F(LS_ERROR) << "Could not open file, err=" << err;
-    return false;
-  }
-  // Write out all the data.
-  StreamResult res = SR_SUCCESS;
-  size_t written;
-  int error;
-  for (OptionsMap::const_iterator i = options_.begin(); i != options_.end();
-       ++i) {
-    res = stream.WriteAll(i->first.c_str(), i->first.length(), &written,
-        &error);
-    if (res != SR_SUCCESS) {
-      break;
-    }
-    res = stream.WriteAll("=", 1, &written, &error);
-    if (res != SR_SUCCESS) {
-      break;
-    }
-    res = stream.WriteAll(i->second.c_str(), i->second.length(), &written,
-        &error);
-    if (res != SR_SUCCESS) {
-      break;
-    }
-    res = stream.WriteAll("\n", 1, &written, &error);
-    if (res != SR_SUCCESS) {
-      break;
-    }
-  }
-  if (res != SR_SUCCESS) {
-    LOG_F(LS_ERROR) << "Unable to write to file";
-    return false;
-  } else {
-    return true;
-  }
-}
-
-bool OptionsFile::IsLegalName(const std::string &name) {
-  for (size_t pos = 0; pos < name.length(); ++pos) {
-    if (name[pos] == '\n' || name[pos] == '\\' || name[pos] == '=') {
-      // Illegal character.
-      LOG(LS_WARNING) << "Ignoring operation for illegal option " << name;
-      return false;
-    }
-  }
-  return true;
-}
-
-bool OptionsFile::IsLegalValue(const std::string &value) {
-  for (size_t pos = 0; pos < value.length(); ++pos) {
-    if (value[pos] == '\n' || value[pos] == '\\') {
-      // Illegal character.
-      LOG(LS_WARNING) << "Ignoring operation for illegal value " << value;
-      return false;
-    }
-  }
-  return true;
-}
-
-bool OptionsFile::GetStringValue(const std::string& option,
-                                 std::string *out_val) const {
-  LOG(LS_VERBOSE) << "OptionsFile::GetStringValue "
-                  << option;
-  if (!IsLegalName(option)) {
-    return false;
-  }
-  OptionsMap::const_iterator i = options_.find(option);
-  if (i == options_.end()) {
-    return false;
-  }
-  *out_val = i->second;
-  return true;
-}
-
-bool OptionsFile::GetIntValue(const std::string& option,
-                              int *out_val) const {
-  LOG(LS_VERBOSE) << "OptionsFile::GetIntValue "
-                  << option;
-  if (!IsLegalName(option)) {
-    return false;
-  }
-  OptionsMap::const_iterator i = options_.find(option);
-  if (i == options_.end()) {
-    return false;
-  }
-  return FromString(i->second, out_val);
-}
-
-bool OptionsFile::SetStringValue(const std::string& option,
-                                 const std::string& value) {
-  LOG(LS_VERBOSE) << "OptionsFile::SetStringValue "
-                  << option << ":" << value;
-  if (!IsLegalName(option) || !IsLegalValue(value)) {
-    return false;
-  }
-  options_[option] = value;
-  return true;
-}
-
-bool OptionsFile::SetIntValue(const std::string& option,
-                              int value) {
-  LOG(LS_VERBOSE) << "OptionsFile::SetIntValue "
-                  << option << ":" << value;
-  if (!IsLegalName(option)) {
-    return false;
-  }
-  return ToString(value, &options_[option]);
-}
-
-bool OptionsFile::RemoveValue(const std::string& option) {
-  LOG(LS_VERBOSE) << "OptionsFile::RemoveValue " << option;
-  if (!IsLegalName(option)) {
-    return false;
-  }
-  options_.erase(option);
-  return true;
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/optionsfile.h b/third_party/libjingle/source/talk/base/optionsfile.h
deleted file mode 100644
index 9e5f457..0000000
--- a/third_party/libjingle/source/talk/base/optionsfile.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * libjingle
- * Copyright 2008, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_OPTIONSFILE_H_
-#define TALK_BASE_OPTIONSFILE_H_
-
-#include <map>
-#include <string>
-
-namespace talk_base {
-
-// Implements storage of simple options in a text file on disk. This is
-// cross-platform, but it is intended mostly for Linux where there is no
-// first-class options storage system.
-class OptionsFile {
- public:
-  OptionsFile(const std::string &path);
-
-  // Loads the file from disk, overwriting the in-memory values.
-  bool Load();
-  // Saves the contents in memory, overwriting the on-disk values.
-  bool Save();
-
-  bool GetStringValue(const std::string& option, std::string* out_val) const;
-  bool GetIntValue(const std::string& option, int* out_val) const;
-  bool SetStringValue(const std::string& option, const std::string& val);
-  bool SetIntValue(const std::string& option, int val);
-  bool RemoveValue(const std::string& option);
-
- private:
-  typedef std::map<std::string, std::string> OptionsMap;
-
-  static bool IsLegalName(const std::string &name);
-  static bool IsLegalValue(const std::string &value);
-
-  std::string path_;
-  OptionsMap options_;
-};
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_OPTIONSFILE_H_
diff --git a/third_party/libjingle/source/talk/base/optionsfile_unittest.cc b/third_party/libjingle/source/talk/base/optionsfile_unittest.cc
deleted file mode 100644
index 65861ff..0000000
--- a/third_party/libjingle/source/talk/base/optionsfile_unittest.cc
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * libjingle
- * Copyright 2008, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/gunit.h"
-#include "talk/base/optionsfile.h"
-
-namespace talk_base {
-
-#ifdef ANDROID
-static const char *kTestFile = "/sdcard/.testfile";
-#elif CHROMEOS
-static const char *kTestFile = "/tmp/.testfile";
-#else
-static const char *kTestFile = ".testfile";
-#endif
-
-static const std::string kTestOptionA = "test-option-a";
-static const std::string kTestOptionB = "test-option-b";
-static const std::string kTestString1 = "a string";
-static const std::string kTestString2 = "different string";
-static const std::string kOptionWithEquals = "foo=bar";
-static const std::string kOptionWithNewline = "foo\nbar";
-static const std::string kValueWithEquals = "baz=quux";
-static const std::string kValueWithNewline = "baz\nquux";
-static const std::string kEmptyString = "";
-static const char kOptionWithUtf8[] = {'O', 'p', 't', '\302', '\256', 'i', 'o',
-    'n', '\342', '\204', '\242', '\0'};  // Opt(R)io(TM).
-static const char kValueWithUtf8[] = {'V', 'a', 'l', '\302', '\256', 'v', 'e',
-    '\342', '\204', '\242', '\0'};  // Val(R)ue(TM).
-static int kTestInt1 = 12345;
-static int kTestInt2 = 67890;
-static int kNegInt = -634;
-static int kZero = 0;
-
-TEST(OptionsFile, GetSetString) {
-  OptionsFile store(kTestFile);
-  // Clear contents of the file on disk.
-  EXPECT_TRUE(store.Save());
-  std::string out1, out2;
-  EXPECT_FALSE(store.GetStringValue(kTestOptionA, &out1));
-  EXPECT_FALSE(store.GetStringValue(kTestOptionB, &out2));
-  EXPECT_TRUE(store.SetStringValue(kTestOptionA, kTestString1));
-  EXPECT_TRUE(store.Save());
-  EXPECT_TRUE(store.Load());
-  EXPECT_TRUE(store.SetStringValue(kTestOptionB, kTestString2));
-  EXPECT_TRUE(store.Save());
-  EXPECT_TRUE(store.Load());
-  EXPECT_TRUE(store.GetStringValue(kTestOptionA, &out1));
-  EXPECT_TRUE(store.GetStringValue(kTestOptionB, &out2));
-  EXPECT_EQ(kTestString1, out1);
-  EXPECT_EQ(kTestString2, out2);
-  EXPECT_TRUE(store.RemoveValue(kTestOptionA));
-  EXPECT_TRUE(store.Save());
-  EXPECT_TRUE(store.Load());
-  EXPECT_TRUE(store.RemoveValue(kTestOptionB));
-  EXPECT_TRUE(store.Save());
-  EXPECT_TRUE(store.Load());
-  EXPECT_FALSE(store.GetStringValue(kTestOptionA, &out1));
-  EXPECT_FALSE(store.GetStringValue(kTestOptionB, &out2));
-}
-
-TEST(OptionsFile, GetSetInt) {
-  OptionsFile store(kTestFile);
-  // Clear contents of the file on disk.
-  EXPECT_TRUE(store.Save());
-  int out1, out2;
-  EXPECT_FALSE(store.GetIntValue(kTestOptionA, &out1));
-  EXPECT_FALSE(store.GetIntValue(kTestOptionB, &out2));
-  EXPECT_TRUE(store.SetIntValue(kTestOptionA, kTestInt1));
-  EXPECT_TRUE(store.Save());
-  EXPECT_TRUE(store.Load());
-  EXPECT_TRUE(store.SetIntValue(kTestOptionB, kTestInt2));
-  EXPECT_TRUE(store.Save());
-  EXPECT_TRUE(store.Load());
-  EXPECT_TRUE(store.GetIntValue(kTestOptionA, &out1));
-  EXPECT_TRUE(store.GetIntValue(kTestOptionB, &out2));
-  EXPECT_EQ(kTestInt1, out1);
-  EXPECT_EQ(kTestInt2, out2);
-  EXPECT_TRUE(store.RemoveValue(kTestOptionA));
-  EXPECT_TRUE(store.Save());
-  EXPECT_TRUE(store.Load());
-  EXPECT_TRUE(store.RemoveValue(kTestOptionB));
-  EXPECT_TRUE(store.Save());
-  EXPECT_TRUE(store.Load());
-  EXPECT_FALSE(store.GetIntValue(kTestOptionA, &out1));
-  EXPECT_FALSE(store.GetIntValue(kTestOptionB, &out2));
-  EXPECT_TRUE(store.SetIntValue(kTestOptionA, kNegInt));
-  EXPECT_TRUE(store.GetIntValue(kTestOptionA, &out1));
-  EXPECT_EQ(kNegInt, out1);
-  EXPECT_TRUE(store.SetIntValue(kTestOptionA, kZero));
-  EXPECT_TRUE(store.GetIntValue(kTestOptionA, &out1));
-  EXPECT_EQ(kZero, out1);
-}
-
-TEST(OptionsFile, Persist) {
-  {
-    OptionsFile store(kTestFile);
-    // Clear contents of the file on disk.
-    EXPECT_TRUE(store.Save());
-    EXPECT_TRUE(store.SetStringValue(kTestOptionA, kTestString1));
-    EXPECT_TRUE(store.SetIntValue(kTestOptionB, kNegInt));
-    EXPECT_TRUE(store.Save());
-  }
-  {
-    OptionsFile store(kTestFile);
-    // Load the saved contents from above.
-    EXPECT_TRUE(store.Load());
-    std::string out1;
-    int out2;
-    EXPECT_TRUE(store.GetStringValue(kTestOptionA, &out1));
-    EXPECT_TRUE(store.GetIntValue(kTestOptionB, &out2));
-    EXPECT_EQ(kTestString1, out1);
-    EXPECT_EQ(kNegInt, out2);
-  }
-}
-
-TEST(OptionsFile, SpecialCharacters) {
-  OptionsFile store(kTestFile);
-  // Clear contents of the file on disk.
-  EXPECT_TRUE(store.Save());
-  std::string out;
-  EXPECT_FALSE(store.SetStringValue(kOptionWithEquals, kTestString1));
-  EXPECT_FALSE(store.GetStringValue(kOptionWithEquals, &out));
-  EXPECT_FALSE(store.SetStringValue(kOptionWithNewline, kTestString1));
-  EXPECT_FALSE(store.GetStringValue(kOptionWithNewline, &out));
-  EXPECT_TRUE(store.SetStringValue(kOptionWithUtf8, kValueWithUtf8));
-  EXPECT_TRUE(store.SetStringValue(kTestOptionA, kTestString1));
-  EXPECT_TRUE(store.Save());
-  EXPECT_TRUE(store.Load());
-  EXPECT_TRUE(store.GetStringValue(kTestOptionA, &out));
-  EXPECT_EQ(kTestString1, out);
-  EXPECT_TRUE(store.GetStringValue(kOptionWithUtf8, &out));
-  EXPECT_EQ(kValueWithUtf8, out);
-  EXPECT_FALSE(store.SetStringValue(kTestOptionA, kValueWithNewline));
-  EXPECT_TRUE(store.GetStringValue(kTestOptionA, &out));
-  EXPECT_EQ(kTestString1, out);
-  EXPECT_TRUE(store.SetStringValue(kTestOptionA, kValueWithEquals));
-  EXPECT_TRUE(store.Save());
-  EXPECT_TRUE(store.Load());
-  EXPECT_TRUE(store.GetStringValue(kTestOptionA, &out));
-  EXPECT_EQ(kValueWithEquals, out);
-  EXPECT_TRUE(store.SetStringValue(kEmptyString, kTestString2));
-  EXPECT_TRUE(store.Save());
-  EXPECT_TRUE(store.Load());
-  EXPECT_TRUE(store.GetStringValue(kEmptyString, &out));
-  EXPECT_EQ(kTestString2, out);
-  EXPECT_TRUE(store.SetStringValue(kTestOptionB, kEmptyString));
-  EXPECT_TRUE(store.Save());
-  EXPECT_TRUE(store.Load());
-  EXPECT_TRUE(store.GetStringValue(kTestOptionB, &out));
-  EXPECT_EQ(kEmptyString, out);
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/packetsocketfactory.h b/third_party/libjingle/source/talk/base/packetsocketfactory.h
deleted file mode 100644
index 7c74e86..0000000
--- a/third_party/libjingle/source/talk/base/packetsocketfactory.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * libjingle
- * Copyright 2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_PACKETSOCKETFACTORY_H_
-#define TALK_BASE_PACKETSOCKETFACTORY_H_
-
-#include "talk/base/proxyinfo.h"
-
-namespace talk_base {
-
-class AsyncPacketSocket;
-
-class PacketSocketFactory {
- public:
-  PacketSocketFactory() { }
-  virtual ~PacketSocketFactory() { }
-
-  virtual AsyncPacketSocket* CreateUdpSocket(
-      const SocketAddress& address, int min_port, int max_port) = 0;
-  virtual AsyncPacketSocket* CreateServerTcpSocket(
-      const SocketAddress& local_address, int min_port, int max_port,
-      bool ssl) = 0;
-
-  // TODO: |proxy_info| and |user_agent| should be set
-  // per-factory and not when socket is created.
-  virtual AsyncPacketSocket* CreateClientTcpSocket(
-      const SocketAddress& local_address, const SocketAddress& remote_address,
-      const ProxyInfo& proxy_info, const std::string& user_agent, bool ssl) = 0;
-
- private:
-  DISALLOW_EVIL_CONSTRUCTORS(PacketSocketFactory);
-};
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_PACKETSOCKETFACTORY_H_
diff --git a/third_party/libjingle/source/talk/base/pathutils.cc b/third_party/libjingle/source/talk/base/pathutils.cc
deleted file mode 100644
index 02aba7f..0000000
--- a/third_party/libjingle/source/talk/base/pathutils.cc
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifdef WIN32
-#include "talk/base/win32.h"
-#include <shellapi.h>
-#include <shlobj.h>
-#include <tchar.h>
-#endif  // WIN32
-
-#include "talk/base/common.h"
-#include "talk/base/fileutils.h"
-#include "talk/base/logging.h"
-#include "talk/base/pathutils.h"
-#include "talk/base/stringutils.h"
-#include "talk/base/urlencode.h"
-
-namespace talk_base {
-
-static const char EMPTY_STR[] = "";
-
-// EXT_DELIM separates a file basename from extension
-const char EXT_DELIM = '.';
-
-// FOLDER_DELIMS separate folder segments and the filename
-const char* const FOLDER_DELIMS = "/\\";
-
-// DEFAULT_FOLDER_DELIM is the preferred delimiter for this platform
-#if WIN32
-const char DEFAULT_FOLDER_DELIM = '\\';
-#else  // !WIN32
-const char DEFAULT_FOLDER_DELIM = '/';
-#endif  // !WIN32
-
-///////////////////////////////////////////////////////////////////////////////
-// Pathname - parsing of pathnames into components, and vice versa
-///////////////////////////////////////////////////////////////////////////////
-
-bool Pathname::IsFolderDelimiter(char ch) {
-  return (NULL != ::strchr(FOLDER_DELIMS, ch));
-}
-
-char Pathname::DefaultFolderDelimiter() {
-  return DEFAULT_FOLDER_DELIM;
-}
-
-Pathname::Pathname()
-    : folder_delimiter_(DEFAULT_FOLDER_DELIM) {
-}
-
-Pathname::Pathname(const std::string& pathname)
-    : folder_delimiter_(DEFAULT_FOLDER_DELIM) {
-  SetPathname(pathname);
-}
-
-Pathname::Pathname(const std::string& folder, const std::string& filename)
-    : folder_delimiter_(DEFAULT_FOLDER_DELIM) {
-  SetPathname(folder, filename);
-}
-
-void Pathname::SetFolderDelimiter(char delimiter) {
-  ASSERT(IsFolderDelimiter(delimiter));
-  folder_delimiter_ = delimiter;
-}
-
-void Pathname::Normalize() {
-  for (size_t i=0; i<folder_.length(); ++i) {
-    if (IsFolderDelimiter(folder_[i])) {
-      folder_[i] = folder_delimiter_;
-    }
-  }
-}
-
-void Pathname::clear() {
-  folder_.clear();
-  basename_.clear();
-  extension_.clear();
-}
-
-bool Pathname::empty() const {
-  return folder_.empty() && basename_.empty() && extension_.empty();
-}
-
-std::string Pathname::pathname() const {
-  std::string pathname(folder_);
-  pathname.append(basename_);
-  pathname.append(extension_);
-  if (pathname.empty()) {
-    // Instead of the empty pathname, return the current working directory.
-    pathname.push_back('.');
-    pathname.push_back(folder_delimiter_);
-  }
-  return pathname;
-}
-
-std::string Pathname::url() const {
-  std::string s = "file:///";
-  for (size_t i=0; i<folder_.length(); ++i) {
-    if (IsFolderDelimiter(folder_[i]))
-      s += '/';
-    else
-      s += folder_[i];
-  }
-  s += basename_;
-  s += extension_;
-  return UrlEncodeStringForOnlyUnsafeChars(s);
-}
-
-void Pathname::SetPathname(const std::string& pathname) {
-  std::string::size_type pos = pathname.find_last_of(FOLDER_DELIMS);
-  if (pos != std::string::npos) {
-    SetFolder(pathname.substr(0, pos + 1));
-    SetFilename(pathname.substr(pos + 1));
-  } else {
-    SetFolder(EMPTY_STR);
-    SetFilename(pathname);
-  }
-}
-
-void Pathname::SetPathname(const std::string& folder,
-                           const std::string& filename) {
-  SetFolder(folder);
-  SetFilename(filename);
-}
-
-void Pathname::AppendPathname(const std::string& pathname) {
-  std::string full_pathname(folder_);
-  full_pathname.append(pathname);
-  SetPathname(full_pathname);
-}
-
-std::string Pathname::folder() const {
-  return folder_;
-}
-
-std::string Pathname::folder_name() const {
-  std::string::size_type pos = std::string::npos;
-  if (folder_.size() >= 2) {
-    pos = folder_.find_last_of(FOLDER_DELIMS, folder_.length() - 2);
-  }
-  if (pos != std::string::npos) {
-    return folder_.substr(pos + 1);
-  } else {
-    return folder_;
-  }
-}
-
-std::string Pathname::parent_folder() const {
-  std::string::size_type pos = std::string::npos;
-  if (folder_.size() >= 2) {
-    pos = folder_.find_last_of(FOLDER_DELIMS, folder_.length() - 2);
-  }
-  if (pos != std::string::npos) {
-    return folder_.substr(0, pos + 1);
-  } else {
-    return EMPTY_STR;
-  }
-}
-
-void Pathname::SetFolder(const std::string& folder) {
-  folder_.assign(folder);
-  // Ensure folder ends in a path delimiter
-  if (!folder_.empty() && !IsFolderDelimiter(folder_[folder_.length()-1])) {
-    folder_.push_back(folder_delimiter_);
-  }
-}
-
-void Pathname::AppendFolder(const std::string& folder) {
-  folder_.append(folder);
-  // Ensure folder ends in a path delimiter
-  if (!folder_.empty() && !IsFolderDelimiter(folder_[folder_.length()-1])) {
-    folder_.push_back(folder_delimiter_);
-  }
-}
-
-std::string Pathname::basename() const {
-  return basename_;
-}
-
-bool Pathname::SetBasename(const std::string& basename) {
-  if(basename.find_first_of(FOLDER_DELIMS) != std::string::npos) {
-    return false;
-  }
-  basename_.assign(basename);
-  return true;
-}
-
-std::string Pathname::extension() const {
-  return extension_;
-}
-
-bool Pathname::SetExtension(const std::string& extension) {
-  if (extension.find_first_of(FOLDER_DELIMS) != std::string::npos ||
-    extension.find_first_of(EXT_DELIM, 1) != std::string::npos) {
-      return false;
-  }
-  extension_.assign(extension);
-  // Ensure extension begins with the extension delimiter
-  if (!extension_.empty() && (extension_[0] != EXT_DELIM)) {
-    extension_.insert(extension_.begin(), EXT_DELIM);
-  }
-  return true;
-}
-
-std::string Pathname::filename() const {
-  std::string filename(basename_);
-  filename.append(extension_);
-  return filename;
-}
-
-bool Pathname::SetFilename(const std::string& filename) {
-  std::string::size_type pos = filename.rfind(EXT_DELIM);
-  if ((pos == std::string::npos) || (pos == 0)) {
-    return SetExtension(EMPTY_STR) && SetBasename(filename);
-  } else {
-    return SetExtension(filename.substr(pos)) && SetBasename(filename.substr(0, pos));
-  }
-}
-
-#ifdef WIN32
-bool Pathname::GetDrive(char *drive, uint32 bytes) const {
-  return GetDrive(drive, bytes, folder_);
-}
-
-// static
-bool Pathname::GetDrive(char *drive, uint32 bytes,
-                        const std::string& pathname) {
-  // need at lease 4 bytes to save c:
-  if (bytes < 4 || pathname.size() < 3) {
-    return false;
-  }
-
-  memcpy(drive, pathname.c_str(), 3);
-  drive[3] = 0;
-  // sanity checking
-  return (isalpha(drive[0]) &&
-          drive[1] == ':' &&
-          drive[2] == '\\');
-}
-#endif
-
-///////////////////////////////////////////////////////////////////////////////
-
-} // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/pathutils.h b/third_party/libjingle/source/talk/base/pathutils.h
deleted file mode 100644
index ab2aacd..0000000
--- a/third_party/libjingle/source/talk/base/pathutils.h
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_PATHUTILS_H__
-#define TALK_BASE_PATHUTILS_H__
-
-#include <string>
-// Temporary, until deprecated helpers are removed.
-#include "talk/base/fileutils.h"
-
-namespace talk_base {
-
-///////////////////////////////////////////////////////////////////////////////
-// Pathname - parsing of pathnames into components, and vice versa.
-//
-// To establish consistent terminology, a filename never contains a folder
-// component.  A folder never contains a filename.  A pathname may include
-// a folder and/or filename component.  Here are some examples:
-//
-//   pathname()      /home/john/example.txt
-//   folder()        /home/john/
-//   filename()                 example.txt
-//   parent_folder() /home/
-//   folder_name()         john/
-//   basename()                 example
-//   extension()                       .txt
-//
-// Basename may begin, end, and/or include periods, but no folder delimiters.
-// If extension exists, it consists of a period followed by zero or more
-// non-period/non-delimiter characters, and basename is non-empty.
-///////////////////////////////////////////////////////////////////////////////
-
-class Pathname {
-public:
-  // Folder delimiters are slash and backslash
-  static bool IsFolderDelimiter(char ch);
-  static char DefaultFolderDelimiter();
-
-  Pathname();
-  Pathname(const std::string& pathname);
-  Pathname(const std::string& folder, const std::string& filename);
-
-  // Set's the default folder delimiter for this Pathname
-  char folder_delimiter() const { return folder_delimiter_; }
-  void SetFolderDelimiter(char delimiter);
-
-  // Normalize changes all folder delimiters to folder_delimiter()
-  void Normalize();
-
-  // Reset to the empty pathname
-  void clear();
-
-  // Returns true if the pathname is empty.  Note: this->pathname().empty()
-  // is always false.
-  bool empty() const;
-
-  std::string url() const;
-
-  // Returns the folder and filename components.  If the pathname is empty,
-  // returns a string representing the current directory (as a relative path,
-  // i.e., ".").
-  std::string pathname() const;
-  void SetPathname(const std::string& pathname);
-  void SetPathname(const std::string& folder, const std::string& filename);
-
-  // Append pathname to the current folder (if any).  Any existing filename
-  // will be discarded.
-  void AppendPathname(const std::string& pathname);
-
-  std::string folder() const;
-  std::string folder_name() const;
-  std::string parent_folder() const;
-  // SetFolder and AppendFolder will append a folder delimiter, if needed.
-  void SetFolder(const std::string& folder);
-  void AppendFolder(const std::string& folder);
-
-  std::string basename() const;
-  bool SetBasename(const std::string& basename);
-
-  std::string extension() const;
-  // SetExtension will prefix a period, if needed.
-  bool SetExtension(const std::string& extension);
-
-  std::string filename() const;
-  bool SetFilename(const std::string& filename);
-
-#ifdef WIN32
-  bool GetDrive(char *drive, uint32 bytes) const;
-  static bool GetDrive(char *drive, uint32 bytes,const std::string& pathname);
-#endif
-
-private:
-  std::string folder_, basename_, extension_;
-  char folder_delimiter_;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// Global Helpers (deprecated)
-///////////////////////////////////////////////////////////////////////////////
-
-inline void SetOrganizationName(const std::string& organization) {
-  Filesystem::SetOrganizationName(organization);
-}
-inline void SetApplicationName(const std::string& application) {
-  Filesystem::SetApplicationName(application);
-}
-inline void GetOrganizationName(std::string* organization) {
-  Filesystem::GetOrganizationName(organization);
-}
-inline void GetApplicationName(std::string* application) {
-  Filesystem::GetApplicationName(application);
-}
-inline bool CreateFolder(const Pathname& path) {
-  return Filesystem::CreateFolder(path);
-}
-inline bool FinishPath(Pathname& path, bool create, const std::string& append) {
-  if (!append.empty())
-    path.AppendFolder(append);
-  return !create || CreateFolder(path);
-}
-// Note: this method uses the convention of <temp>/<appname> for the temporary
-// folder.  Filesystem uses <temp>/<exename>.  We will be migrating exclusively
-// to <temp>/<orgname>/<appname> eventually.  Since these are temp folders,
-// it's probably ok to orphan them during the transition.
-inline bool GetTemporaryFolder(Pathname& path, bool create,
-                               const std::string& append) {
-  std::string application_name;
-  Filesystem::GetApplicationName(&application_name);
-  ASSERT(!application_name.empty());
-  return Filesystem::GetTemporaryFolder(path, create, &application_name)
-         && FinishPath(path, create, append);
-}
-inline bool GetAppDataFolder(Pathname& path, bool create,
-                             const std::string& append) {
-  ASSERT(!create); // TODO: Support create flag on Filesystem::GetAppDataFolder.
-  return Filesystem::GetAppDataFolder(&path, true)
-         && FinishPath(path, create, append);
-}
-inline bool CleanupTemporaryFolder() {
-  Pathname path;
-  if (!GetTemporaryFolder(path, false, ""))
-    return false;
-  if (Filesystem::IsAbsent(path))
-    return true;
-  if (!Filesystem::IsTemporaryPath(path)) {
-    ASSERT(false);
-    return false;
-  }
-  return Filesystem::DeleteFolderContents(path);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-}  // namespace talk_base
-
-#endif // TALK_BASE_PATHUTILS_H__
diff --git a/third_party/libjingle/source/talk/base/pathutils_unittest.cc b/third_party/libjingle/source/talk/base/pathutils_unittest.cc
deleted file mode 100644
index 0a9739b..0000000
--- a/third_party/libjingle/source/talk/base/pathutils_unittest.cc
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * libjingle
- * Copyright 2007, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/pathutils.h"
-#include "talk/base/gunit.h"
-
-TEST(Pathname, ReturnsDotForEmptyPathname) {
-  const std::string kCWD =
-      std::string(".") + talk_base::Pathname::DefaultFolderDelimiter();
-
-  talk_base::Pathname path("/", "");
-  EXPECT_FALSE(path.empty());
-  EXPECT_FALSE(path.folder().empty());
-  EXPECT_TRUE (path.filename().empty());
-  EXPECT_FALSE(path.pathname().empty());
-  EXPECT_EQ(std::string("/"), path.pathname());
-
-  path.SetPathname("", "foo");
-  EXPECT_FALSE(path.empty());
-  EXPECT_TRUE (path.folder().empty());
-  EXPECT_FALSE(path.filename().empty());
-  EXPECT_FALSE(path.pathname().empty());
-  EXPECT_EQ(std::string("foo"), path.pathname());
-
-  path.SetPathname("", "");
-  EXPECT_TRUE (path.empty());
-  EXPECT_TRUE (path.folder().empty());
-  EXPECT_TRUE (path.filename().empty());
-  EXPECT_FALSE(path.pathname().empty());
-  EXPECT_EQ(kCWD, path.pathname());
-
-  path.SetPathname(kCWD, "");
-  EXPECT_FALSE(path.empty());
-  EXPECT_FALSE(path.folder().empty());
-  EXPECT_TRUE (path.filename().empty());
-  EXPECT_FALSE(path.pathname().empty());
-  EXPECT_EQ(kCWD, path.pathname());
-
-  talk_base::Pathname path2("c:/foo bar.txt");
-  EXPECT_EQ(path2.url(), std::string("file:///c:/foo%20bar.txt"));
-}
diff --git a/third_party/libjingle/source/talk/base/physicalsocketserver.cc b/third_party/libjingle/source/talk/base/physicalsocketserver.cc
deleted file mode 100644
index 10d534f..0000000
--- a/third_party/libjingle/source/talk/base/physicalsocketserver.cc
+++ /dev/null
@@ -1,1624 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#if defined(_MSC_VER) && _MSC_VER < 1300
-#pragma warning(disable:4786)
-#endif
-
-#include <cassert>
-
-#ifdef POSIX
-#include <string.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/time.h>
-#include <unistd.h>
-#include <signal.h>
-#endif
-
-#ifdef WIN32
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#undef SetPort
-#endif
-
-#include <algorithm>
-#include <map>
-
-#include "talk/base/basictypes.h"
-#include "talk/base/byteorder.h"
-#include "talk/base/common.h"
-#include "talk/base/logging.h"
-#include "talk/base/nethelpers.h"
-#include "talk/base/physicalsocketserver.h"
-#include "talk/base/timeutils.h"
-#include "talk/base/winping.h"
-#include "talk/base/win32socketinit.h"
-
-// stm: this will tell us if we are on OSX
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#ifdef POSIX
-#include <netinet/tcp.h>  // for TCP_NODELAY
-#define IP_MTU 14 // Until this is integrated from linux/in.h to netinet/in.h
-typedef void* SockOptArg;
-#endif  // POSIX
-
-#ifdef WIN32
-typedef char* SockOptArg;
-#endif
-
-namespace talk_base {
-
-// Standard MTUs, from RFC 1191
-const uint16 PACKET_MAXIMUMS[] = {
-  65535,    // Theoretical maximum, Hyperchannel
-  32000,    // Nothing
-  17914,    // 16Mb IBM Token Ring
-  8166,     // IEEE 802.4
-  //4464,   // IEEE 802.5 (4Mb max)
-  4352,     // FDDI
-  //2048,   // Wideband Network
-  2002,     // IEEE 802.5 (4Mb recommended)
-  //1536,   // Expermental Ethernet Networks
-  //1500,   // Ethernet, Point-to-Point (default)
-  1492,     // IEEE 802.3
-  1006,     // SLIP, ARPANET
-  //576,    // X.25 Networks
-  //544,    // DEC IP Portal
-  //512,    // NETBIOS
-  508,      // IEEE 802/Source-Rt Bridge, ARCNET
-  296,      // Point-to-Point (low delay)
-  68,       // Official minimum
-  0,        // End of list marker
-};
-
-const uint32 IP_HEADER_SIZE = 20;
-const uint32 ICMP_HEADER_SIZE = 8;
-
-class PhysicalSocket : public AsyncSocket, public sigslot::has_slots<> {
- public:
-  PhysicalSocket(PhysicalSocketServer* ss, SOCKET s = INVALID_SOCKET)
-    : ss_(ss), s_(s), enabled_events_(0), error_(0),
-      state_((s == INVALID_SOCKET) ? CS_CLOSED : CS_CONNECTED),
-      resolver_(NULL) {
-#ifdef WIN32
-    // EnsureWinsockInit() ensures that winsock is initialized. The default
-    // version of this function doesn't do anything because winsock is
-    // initialized by constructor of a static object. If neccessary libjingle
-    // users can link it with a different version of this function by replacing
-    // win32socketinit.cc. See win32socketinit.cc for more details.
-    EnsureWinsockInit();
-#endif
-    if (s_ != INVALID_SOCKET) {
-      enabled_events_ = DE_READ | DE_WRITE;
-
-      int type = SOCK_STREAM;
-      socklen_t len = sizeof(type);
-      VERIFY(0 == getsockopt(s_, SOL_SOCKET, SO_TYPE, (SockOptArg)&type, &len));
-      udp_ = (SOCK_DGRAM == type);
-    }
-  }
-
-  virtual ~PhysicalSocket() {
-    Close();
-  }
-
-  // Creates the underlying OS socket (same as the "socket" function).
-  virtual bool Create(int type) {
-    Close();
-    s_ = ::socket(AF_INET, type, 0);
-    udp_ = (SOCK_DGRAM == type);
-    UpdateLastError();
-    if (udp_)
-      enabled_events_ = DE_READ | DE_WRITE;
-    return s_ != INVALID_SOCKET;
-  }
-
-  SocketAddress GetLocalAddress() const {
-    sockaddr_in addr;
-    socklen_t addrlen = sizeof(addr);
-    int result = ::getsockname(s_, (sockaddr*)&addr, &addrlen);
-    SocketAddress address;
-    if (result >= 0) {
-      ASSERT(addrlen == sizeof(addr));
-      address.FromSockAddr(addr);
-    } else {
-      LOG(LS_WARNING) << "GetLocalAddress: unable to get local addr, socket="
-                      << s_;
-    }
-    return address;
-  }
-
-  SocketAddress GetRemoteAddress() const {
-    sockaddr_in addr;
-    socklen_t addrlen = sizeof(addr);
-    int result = ::getpeername(s_, (sockaddr*)&addr, &addrlen);
-    SocketAddress address;
-    if (result >= 0) {
-      ASSERT(addrlen == sizeof(addr));
-      address.FromSockAddr(addr);
-    } else {
-      LOG(LS_WARNING) << "GetRemoteAddress: unable to get remote addr, socket="
-                      << s_;
-    }
-    return address;
-  }
-
-  int Bind(const SocketAddress& addr) {
-    sockaddr_in saddr;
-    addr.ToSockAddr(&saddr);
-    int err = ::bind(s_, (sockaddr*)&saddr, sizeof(saddr));
-    UpdateLastError();
-#ifdef _DEBUG
-    if (0 == err) {
-      dbg_addr_ = "Bound @ ";
-      dbg_addr_.append(GetLocalAddress().ToString());
-    }
-#endif  // _DEBUG
-    return err;
-  }
-
-  int Connect(const SocketAddress& addr) {
-    // TODO: Implicit creation is required to reconnect...
-    // ...but should we make it more explicit?
-    if ((s_ == INVALID_SOCKET) && !Create(SOCK_STREAM))
-      return SOCKET_ERROR;
-    if (addr.IsUnresolved()) {
-      if (state_ != CS_CLOSED) {
-        SetError(EALREADY);
-        return SOCKET_ERROR;
-      }
-
-      LOG(LS_VERBOSE) << "Resolving addr in PhysicalSocket::Connect";
-      resolver_ = new AsyncResolver();
-      resolver_->set_address(addr);
-      resolver_->SignalWorkDone.connect(this, &PhysicalSocket::OnResolveResult);
-      resolver_->Start();
-      state_ = CS_CONNECTING;
-      return 0;
-    }
-
-    return DoConnect(addr);
-  }
-
-  int DoConnect(const SocketAddress& addr) {
-    sockaddr_in saddr;
-    addr.ToSockAddr(&saddr);
-    int err = ::connect(s_, (sockaddr*)&saddr, sizeof(saddr));
-    UpdateLastError();
-    if (err == 0) {
-      state_ = CS_CONNECTED;
-    } else if (IsBlockingError(error_)) {
-      state_ = CS_CONNECTING;
-      enabled_events_ |= DE_CONNECT;
-    } else {
-      return SOCKET_ERROR;
-    }
-
-    enabled_events_ |= DE_READ | DE_WRITE;
-    return 0;
-  }
-
-  int GetError() const {
-    return error_;
-  }
-
-  void SetError(int error) {
-    error_ = error;
-  }
-
-  ConnState GetState() const {
-    return state_;
-  }
-
-  int GetOption(Option opt, int* value) {
-    int slevel;
-    int sopt;
-    if (TranslateOption(opt, &slevel, &sopt) == -1)
-      return -1;
-    socklen_t optlen = sizeof(*value);
-    int ret = ::getsockopt(s_, slevel, sopt, (SockOptArg)value, &optlen);
-    if (ret != -1 && opt == OPT_DONTFRAGMENT) {
-#ifdef LINUX
-      *value = (*value != IP_PMTUDISC_DONT) ? 1 : 0;
-#endif
-    }
-    return ret;
-  }
-
-  int SetOption(Option opt, int value) {
-    int slevel;
-    int sopt;
-    if (TranslateOption(opt, &slevel, &sopt) == -1)
-      return -1;
-    if (opt == OPT_DONTFRAGMENT) {
-#ifdef LINUX
-      value = (value) ? IP_PMTUDISC_DO : IP_PMTUDISC_DONT;
-#endif
-    }
-    return ::setsockopt(s_, slevel, sopt, (SockOptArg)&value, sizeof(value));
-  }
-
-  int Send(const void *pv, size_t cb) {
-    int sent = ::send(s_, reinterpret_cast<const char *>(pv), (int)cb,
-#ifdef LINUX
-        // Suppress SIGPIPE. Without this, attempting to send on a socket whose
-        // other end is closed will result in a SIGPIPE signal being raised to
-        // our process, which by default will terminate the process, which we
-        // don't want. By specifying this flag, we'll just get the error EPIPE
-        // instead and can handle the error gracefully.
-        MSG_NOSIGNAL
-#else
-        0
-#endif
-        );
-    UpdateLastError();
-    // We have seen minidumps where this may be false.
-    ASSERT(sent <= static_cast<int>(cb));
-    if ((sent < 0) && IsBlockingError(error_)) {
-      enabled_events_ |= DE_WRITE;
-    }
-    return sent;
-  }
-
-  int SendTo(const void *pv, size_t cb, const SocketAddress& addr) {
-    sockaddr_in saddr;
-    addr.ToSockAddr(&saddr);
-    int sent = ::sendto(
-        s_, (const char *)pv, (int)cb,
-#ifdef LINUX
-        // Suppress SIGPIPE. See above for explanation.
-        MSG_NOSIGNAL,
-#else
-        0,
-#endif
-        (sockaddr*)&saddr, sizeof(saddr));
-    UpdateLastError();
-    // We have seen minidumps where this may be false.
-    ASSERT(sent <= static_cast<int>(cb));
-    if ((sent < 0) && IsBlockingError(error_)) {
-      enabled_events_ |= DE_WRITE;
-    }
-    return sent;
-  }
-
-  int Recv(void *pv, size_t cb) {
-    int received = ::recv(s_, (char *)pv, (int)cb, 0);
-    if ((received == 0) && (cb != 0)) {
-      // Note: on graceful shutdown, recv can return 0.  In this case, we
-      // pretend it is blocking, and then signal close, so that simplifying
-      // assumptions can be made about Recv.
-      LOG(LS_WARNING) << "EOF from socket; deferring close event";
-      // Must turn this back on so that the select() loop will notice the close
-      // event.
-      enabled_events_ |= DE_READ;
-      error_ = EWOULDBLOCK;
-      return SOCKET_ERROR;
-    }
-    UpdateLastError();
-    bool success = (received >= 0) || IsBlockingError(error_);
-    if (udp_ || success) {
-      enabled_events_ |= DE_READ;
-    }
-    if (!success) {
-      LOG_F(LS_VERBOSE) << "Error = " << error_;
-    }
-    return received;
-  }
-
-  int RecvFrom(void *pv, size_t cb, SocketAddress *paddr) {
-    sockaddr_in saddr;
-    socklen_t cbAddr = sizeof(saddr);
-    int received = ::recvfrom(s_, (char *)pv, (int)cb, 0, (sockaddr*)&saddr,
-                              &cbAddr);
-    UpdateLastError();
-    if ((received >= 0) && (paddr != NULL))
-      paddr->FromSockAddr(saddr);
-    bool success = (received >= 0) || IsBlockingError(error_);
-    if (udp_ || success) {
-      enabled_events_ |= DE_READ;
-    }
-    if (!success) {
-      LOG_F(LS_VERBOSE) << "Error = " << error_;
-    }
-    return received;
-  }
-
-  int Listen(int backlog) {
-    int err = ::listen(s_, backlog);
-    UpdateLastError();
-    if (err == 0) {
-      state_ = CS_CONNECTING;
-      enabled_events_ |= DE_ACCEPT;
-#ifdef _DEBUG
-      dbg_addr_ = "Listening @ ";
-      dbg_addr_.append(GetLocalAddress().ToString());
-#endif  // _DEBUG
-    }
-    return err;
-  }
-
-  AsyncSocket* Accept(SocketAddress *paddr) {
-    sockaddr_in saddr;
-    socklen_t cbAddr = sizeof(saddr);
-    SOCKET s = ::accept(s_, (sockaddr*)&saddr, &cbAddr);
-    UpdateLastError();
-    if (s == INVALID_SOCKET)
-      return NULL;
-    enabled_events_ |= DE_ACCEPT;
-    if (paddr != NULL)
-      paddr->FromSockAddr(saddr);
-    return ss_->WrapSocket(s);
-  }
-
-  int Close() {
-    if (s_ == INVALID_SOCKET)
-      return 0;
-    int err = ::closesocket(s_);
-    UpdateLastError();
-    s_ = INVALID_SOCKET;
-    state_ = CS_CLOSED;
-    enabled_events_ = 0;
-    if (resolver_) {
-      resolver_->Destroy(false);
-      resolver_ = NULL;
-    }
-    return err;
-  }
-
-  int EstimateMTU(uint16* mtu) {
-    SocketAddress addr = GetRemoteAddress();
-    if (addr.IsAny()) {
-      error_ = ENOTCONN;
-      return -1;
-    }
-
-#if defined(WIN32)
-    // Gets the interface MTU (TTL=1) for the interface used to reach |addr|.
-    WinPing ping;
-    if (!ping.IsValid()) {
-      error_ = EINVAL; // can't think of a better error ID
-      return -1;
-    }
-
-    for (int level = 0; PACKET_MAXIMUMS[level + 1] > 0; ++level) {
-      int32 size = PACKET_MAXIMUMS[level] - IP_HEADER_SIZE - ICMP_HEADER_SIZE;
-      WinPing::PingResult result = ping.Ping(addr.ip(), size, 0, 1, false);
-      if (result == WinPing::PING_FAIL) {
-        error_ = EINVAL; // can't think of a better error ID
-        return -1;
-      } else if (result != WinPing::PING_TOO_LARGE) {
-        *mtu = PACKET_MAXIMUMS[level];
-        return 0;
-      }
-    }
-
-    ASSERT(false);
-    return -1;
-#elif defined(IOS) || defined(OSX)
-    // No simple way to do this on Mac OS X.
-    // SIOCGIFMTU would work if we knew which interface would be used, but
-    // figuring that out is pretty complicated. For now we'll return an error
-    // and let the caller pick a default MTU.
-    error_ = EINVAL;
-    return -1;
-#elif defined(LINUX) || defined(ANDROID)
-    // Gets the path MTU.
-    int value;
-    socklen_t vlen = sizeof(value);
-    int err = getsockopt(s_, IPPROTO_IP, IP_MTU, &value, &vlen);
-    if (err < 0) {
-      UpdateLastError();
-      return err;
-    }
-
-    ASSERT((0 <= value) && (value <= 65536));
-    *mtu = value;
-    return 0;
-#endif
-  }
-
-  SocketServer* socketserver() { return ss_; }
-
- protected:
-  void OnResolveResult(SignalThread* thread) {
-    if (thread != resolver_) {
-      return;
-    }
-
-    int error = resolver_->error();
-    if (error == 0) {
-      error = DoConnect(resolver_->address());
-    } else {
-      Close();
-    }
-
-    if (error) {
-      error_ = error;
-      SignalCloseEvent(this, error_);
-    }
-  }
-
-  void UpdateLastError() {
-    error_ = LAST_SYSTEM_ERROR;
-  }
-
-  static int TranslateOption(Option opt, int* slevel, int* sopt) {
-    switch (opt) {
-      case OPT_DONTFRAGMENT:
-#ifdef WIN32
-        *slevel = IPPROTO_IP;
-        *sopt = IP_DONTFRAGMENT;
-        break;
-#elif defined(IOS) || defined(OSX) || defined(BSD)
-        LOG(LS_WARNING) << "Socket::OPT_DONTFRAGMENT not supported.";
-        return -1;
-#elif defined(POSIX)
-        *slevel = IPPROTO_IP;
-        *sopt = IP_MTU_DISCOVER;
-        break;
-#endif
-      case OPT_RCVBUF:
-        *slevel = SOL_SOCKET;
-        *sopt = SO_RCVBUF;
-        break;
-      case OPT_SNDBUF:
-        *slevel = SOL_SOCKET;
-        *sopt = SO_SNDBUF;
-        break;
-      case OPT_NODELAY:
-        *slevel = IPPROTO_TCP;
-        *sopt = TCP_NODELAY;
-        break;
-      default:
-        ASSERT(false);
-        return -1;
-    }
-    return 0;
-  }
-
-  PhysicalSocketServer* ss_;
-  SOCKET s_;
-  uint8 enabled_events_;
-  bool udp_;
-  int error_;
-  ConnState state_;
-  AsyncResolver* resolver_;
-
-#ifdef _DEBUG
-  std::string dbg_addr_;
-#endif  // _DEBUG;
-};
-
-#ifdef POSIX
-class EventDispatcher : public Dispatcher {
- public:
-  EventDispatcher(PhysicalSocketServer* ss) : ss_(ss), fSignaled_(false) {
-    if (pipe(afd_) < 0)
-      LOG(LERROR) << "pipe failed";
-    ss_->Add(this);
-  }
-
-  virtual ~EventDispatcher() {
-    ss_->Remove(this);
-    close(afd_[0]);
-    close(afd_[1]);
-  }
-
-  virtual void Signal() {
-    CritScope cs(&crit_);
-    if (!fSignaled_) {
-      const uint8 b[1] = { 0 };
-      if (VERIFY(1 == write(afd_[1], b, sizeof(b)))) {
-        fSignaled_ = true;
-      }
-    }
-  }
-
-  virtual uint32 GetRequestedEvents() {
-    return DE_READ;
-  }
-
-  virtual void OnPreEvent(uint32 ff) {
-    // It is not possible to perfectly emulate an auto-resetting event with
-    // pipes.  This simulates it by resetting before the event is handled.
-
-    CritScope cs(&crit_);
-    if (fSignaled_) {
-      uint8 b[4];  // Allow for reading more than 1 byte, but expect 1.
-      VERIFY(1 == read(afd_[0], b, sizeof(b)));
-      fSignaled_ = false;
-    }
-  }
-
-  virtual void OnEvent(uint32 ff, int err) {
-    ASSERT(false);
-  }
-
-  virtual int GetDescriptor() {
-    return afd_[0];
-  }
-
-  virtual bool IsDescriptorClosed() {
-    return false;
-  }
-
- private:
-  PhysicalSocketServer *ss_;
-  int afd_[2];
-  bool fSignaled_;
-  CriticalSection crit_;
-};
-
-// These two classes use the self-pipe trick to deliver POSIX signals to our
-// select loop. This is the only safe, reliable, cross-platform way to do
-// non-trivial things with a POSIX signal in an event-driven program (until
-// proper pselect() implementations become ubiquitous).
-
-class PosixSignalHandler {
- public:
-  // POSIX only specifies 32 signals, but in principle the system might have
-  // more and the programmer might choose to use them, so we size our array
-  // for 128.
-  static const int kNumPosixSignals = 128;
-
-  static PosixSignalHandler *Instance() { return &instance_; }
-
-  // Returns true if the given signal number is set.
-  bool IsSignalSet(int signum) const {
-    ASSERT(signum < ARRAY_SIZE(received_signal_));
-    if (signum < ARRAY_SIZE(received_signal_)) {
-      return received_signal_[signum];
-    } else {
-      return false;
-    }
-  }
-
-  // Clears the given signal number.
-  void ClearSignal(int signum) {
-    ASSERT(signum < ARRAY_SIZE(received_signal_));
-    if (signum < ARRAY_SIZE(received_signal_)) {
-      received_signal_[signum] = false;
-    }
-  }
-
-  // Returns the file descriptor to monitor for signal events.
-  int GetDescriptor() const {
-    return afd_[0];
-  }
-
-  // This is called directly from our real signal handler, so it must be
-  // signal-handler-safe. That means it cannot assume anything about the
-  // user-level state of the process, since the handler could be executed at any
-  // time on any thread.
-  void OnPosixSignalReceived(int signum) {
-    if (signum >= ARRAY_SIZE(received_signal_)) {
-      // We don't have space in our array for this.
-      return;
-    }
-    // Set a flag saying we've seen this signal.
-    received_signal_[signum] = true;
-    // Notify application code that we got a signal.
-    const uint8 b[1] = { 0 };
-    if (-1 == write(afd_[1], b, sizeof(b))) {
-      // Nothing we can do here. If there's an error somehow then there's
-      // nothing we can safely do from a signal handler.
-      // No, we can't even safely log it.
-      // But, we still have to check the return value here. Otherwise,
-      // GCC 4.4.1 complains ignoring return value. Even (void) doesn't help.
-      return;
-    }
-  }
-
- private:
-  PosixSignalHandler() {
-    if (pipe(afd_) < 0) {
-      LOG_ERR(LS_ERROR) << "pipe failed";
-      return;
-    }
-    if (fcntl(afd_[0], F_SETFL, O_NONBLOCK) < 0) {
-      LOG_ERR(LS_WARNING) << "fcntl #1 failed";
-    }
-    if (fcntl(afd_[1], F_SETFL, O_NONBLOCK) < 0) {
-      LOG_ERR(LS_WARNING) << "fcntl #2 failed";
-    }
-    memset(const_cast<void *>(static_cast<volatile void *>(received_signal_)),
-           0,
-           sizeof(received_signal_));
-  }
-
-  ~PosixSignalHandler() {
-    int fd1 = afd_[0];
-    int fd2 = afd_[1];
-    // We clobber the stored file descriptor numbers here or else in principle
-    // a signal that happens to be delivered during application termination
-    // could erroneously write a zero byte to an unrelated file handle in
-    // OnPosixSignalReceived() if some other file happens to be opened later
-    // during shutdown and happens to be given the same file descriptor number
-    // as our pipe had. Unfortunately even with this precaution there is still a
-    // race where that could occur if said signal happens to be handled
-    // concurrently with this code and happens to have already read the value of
-    // afd_[1] from memory before we clobber it, but that's unlikely.
-    afd_[0] = -1;
-    afd_[1] = -1;
-    close(fd1);
-    close(fd2);
-  }
-
-  // There is just a single global instance. (Signal handlers do not get any
-  // sort of user-defined void * parameter, so they can't access anything that
-  // isn't global.)
-  static PosixSignalHandler instance_;
-
-  int afd_[2];
-  // These are boolean flags that will be set in our signal handler and read
-  // and cleared from Wait(). There is a race involved in this, but it is
-  // benign. The signal handler sets the flag before signaling the pipe, so
-  // we'll never end up blocking in select() while a flag is still true.
-  // However, if two of the same signal arrive close to each other then it's
-  // possible that the second time the handler may set the flag while it's still
-  // true, meaning that signal will be missed. But the first occurrence of it
-  // will still be handled, so this isn't a problem.
-  // Volatile is not necessary here for correctness, but this data _is_ volatile
-  // so I've marked it as such.
-  volatile uint8 received_signal_[kNumPosixSignals];
-};
-
-PosixSignalHandler PosixSignalHandler::instance_;
-
-class PosixSignalDispatcher : public Dispatcher {
- public:
-  PosixSignalDispatcher(PhysicalSocketServer *owner) : owner_(owner) {
-    owner_->Add(this);
-  }
-
-  virtual ~PosixSignalDispatcher() {
-    owner_->Remove(this);
-  }
-
-  virtual uint32 GetRequestedEvents() {
-    return DE_READ;
-  }
-
-  virtual void OnPreEvent(uint32 ff) {
-    // Events might get grouped if signals come very fast, so we read out up to
-    // 16 bytes to make sure we keep the pipe empty.
-    uint8 b[16];
-    ssize_t ret = read(GetDescriptor(), b, sizeof(b));
-    if (ret < 0) {
-      LOG_ERR(LS_WARNING) << "Error in read()";
-    } else if (ret == 0) {
-      LOG(LS_WARNING) << "Should have read at least one byte";
-    }
-  }
-
-  virtual void OnEvent(uint32 ff, int err) {
-    for (int signum = 0; signum < PosixSignalHandler::kNumPosixSignals;
-         ++signum) {
-      if (PosixSignalHandler::Instance()->IsSignalSet(signum)) {
-        PosixSignalHandler::Instance()->ClearSignal(signum);
-        HandlerMap::iterator i = handlers_.find(signum);
-        if (i == handlers_.end()) {
-          // This can happen if a signal is delivered to our process at around
-          // the same time as we unset our handler for it. It is not an error
-          // condition, but it's unusual enough to be worth logging.
-          LOG(LS_INFO) << "Received signal with no handler: " << signum;
-        } else {
-          // Otherwise, execute our handler.
-          (*i->second)(signum);
-        }
-      }
-    }
-  }
-
-  virtual int GetDescriptor() {
-    return PosixSignalHandler::Instance()->GetDescriptor();
-  }
-
-  virtual bool IsDescriptorClosed() {
-    return false;
-  }
-
-  void SetHandler(int signum, void (*handler)(int)) {
-    handlers_[signum] = handler;
-  }
-
-  void ClearHandler(int signum) {
-    handlers_.erase(signum);
-  }
-
-  bool HasHandlers() {
-    return !handlers_.empty();
-  }
-
- private:
-  typedef std::map<int, void (*)(int)> HandlerMap;
-
-  HandlerMap handlers_;
-  // Our owner.
-  PhysicalSocketServer *owner_;
-};
-
-class SocketDispatcher : public Dispatcher, public PhysicalSocket {
- public:
-  explicit SocketDispatcher(PhysicalSocketServer *ss) : PhysicalSocket(ss) {
-  }
-  SocketDispatcher(SOCKET s, PhysicalSocketServer *ss) : PhysicalSocket(ss, s) {
-  }
-
-  virtual ~SocketDispatcher() {
-    Close();
-  }
-
-  bool Initialize() {
-    ss_->Add(this);
-    fcntl(s_, F_SETFL, fcntl(s_, F_GETFL, 0) | O_NONBLOCK);
-    return true;
-  }
-
-  virtual bool Create(int type) {
-    // Change the socket to be non-blocking.
-    if (!PhysicalSocket::Create(type))
-      return false;
-
-    return Initialize();
-  }
-
-  virtual int GetDescriptor() {
-    return s_;
-  }
-
-  virtual bool IsDescriptorClosed() {
-    // We don't have a reliable way of distinguishing end-of-stream
-    // from readability.  So test on each readable call.  Is this
-    // inefficient?  Probably.
-    char ch;
-    ssize_t res = ::recv(s_, &ch, 1, MSG_PEEK);
-    if (res > 0) {
-      // Data available, so not closed.
-      return false;
-    } else if (res == 0) {
-      // EOF, so closed.
-      return true;
-    } else {  // error
-      switch (errno) {
-        // Returned if we've already closed s_.
-        case EBADF:
-        // Returned during ungraceful peer shutdown.
-        case ECONNRESET:
-          return true;
-        default:
-          // Assume that all other errors are just blocking errors, meaning the
-          // connection is still good but we just can't read from it right now.
-          // This should only happen when connecting (and at most once), because
-          // in all other cases this function is only called if the file
-          // descriptor is already known to be in the readable state. However,
-          // it's not necessary a problem if we spuriously interpret a
-          // "connection lost"-type error as a blocking error, because typically
-          // the next recv() will get EOF, so we'll still eventually notice that
-          // the socket is closed.
-          LOG_ERR(LS_WARNING) << "Assuming benign blocking error";
-          return false;
-      }
-    }
-  }
-
-  virtual uint32 GetRequestedEvents() {
-    return enabled_events_;
-  }
-
-  virtual void OnPreEvent(uint32 ff) {
-    if ((ff & DE_CONNECT) != 0)
-      state_ = CS_CONNECTED;
-    if ((ff & DE_CLOSE) != 0)
-      state_ = CS_CLOSED;
-  }
-
-  virtual void OnEvent(uint32 ff, int err) {
-    if ((ff & DE_READ) != 0) {
-      enabled_events_ &= ~DE_READ;
-      SignalReadEvent(this);
-    }
-    if ((ff & DE_WRITE) != 0) {
-      enabled_events_ &= ~DE_WRITE;
-      SignalWriteEvent(this);
-    }
-    if ((ff & DE_CONNECT) != 0) {
-      enabled_events_ &= ~DE_CONNECT;
-      SignalConnectEvent(this);
-    }
-    if ((ff & DE_ACCEPT) != 0) {
-      enabled_events_ &= ~DE_ACCEPT;
-      SignalReadEvent(this);
-    }
-    if ((ff & DE_CLOSE) != 0) {
-      // The socket is now dead to us, so stop checking it.
-      enabled_events_ = 0;
-      SignalCloseEvent(this, err);
-    }
-  }
-
-  virtual int Close() {
-    if (s_ == INVALID_SOCKET)
-      return 0;
-
-    ss_->Remove(this);
-    return PhysicalSocket::Close();
-  }
-};
-
-class FileDispatcher: public Dispatcher, public AsyncFile {
- public:
-  FileDispatcher(int fd, PhysicalSocketServer *ss) : ss_(ss), fd_(fd) {
-    set_readable(true);
-
-    ss_->Add(this);
-
-    fcntl(fd_, F_SETFL, fcntl(fd_, F_GETFL, 0) | O_NONBLOCK);
-  }
-
-  virtual ~FileDispatcher() {
-    ss_->Remove(this);
-  }
-
-  SocketServer* socketserver() { return ss_; }
-
-  virtual int GetDescriptor() {
-    return fd_;
-  }
-
-  virtual bool IsDescriptorClosed() {
-    return false;
-  }
-
-  virtual uint32 GetRequestedEvents() {
-    return flags_;
-  }
-
-  virtual void OnPreEvent(uint32 ff) {
-  }
-
-  virtual void OnEvent(uint32 ff, int err) {
-    if ((ff & DE_READ) != 0)
-      SignalReadEvent(this);
-    if ((ff & DE_WRITE) != 0)
-      SignalWriteEvent(this);
-    if ((ff & DE_CLOSE) != 0)
-      SignalCloseEvent(this, err);
-  }
-
-  virtual bool readable() {
-    return (flags_ & DE_READ) != 0;
-  }
-
-  virtual void set_readable(bool value) {
-    flags_ = value ? (flags_ | DE_READ) : (flags_ & ~DE_READ);
-  }
-
-  virtual bool writable() {
-    return (flags_ & DE_WRITE) != 0;
-  }
-
-  virtual void set_writable(bool value) {
-    flags_ = value ? (flags_ | DE_WRITE) : (flags_ & ~DE_WRITE);
-  }
-
- private:
-  PhysicalSocketServer* ss_;
-  int fd_;
-  int flags_;
-};
-
-AsyncFile* PhysicalSocketServer::CreateFile(int fd) {
-  return new FileDispatcher(fd, this);
-}
-
-#endif // POSIX
-
-#ifdef WIN32
-static uint32 FlagsToEvents(uint32 events) {
-  uint32 ffFD = FD_CLOSE;
-  if (events & DE_READ)
-    ffFD |= FD_READ;
-  if (events & DE_WRITE)
-    ffFD |= FD_WRITE;
-  if (events & DE_CONNECT)
-    ffFD |= FD_CONNECT;
-  if (events & DE_ACCEPT)
-    ffFD |= FD_ACCEPT;
-  return ffFD;
-}
-
-class EventDispatcher : public Dispatcher {
- public:
-  EventDispatcher(PhysicalSocketServer *ss) : ss_(ss) {
-    hev_ = WSACreateEvent();
-    if (hev_) {
-      ss_->Add(this);
-    }
-  }
-
-  ~EventDispatcher() {
-    if (hev_ != NULL) {
-      ss_->Remove(this);
-      WSACloseEvent(hev_);
-      hev_ = NULL;
-    }
-  }
-
-  virtual void Signal() {
-    if (hev_ != NULL)
-      WSASetEvent(hev_);
-  }
-
-  virtual uint32 GetRequestedEvents() {
-    return 0;
-  }
-
-  virtual void OnPreEvent(uint32 ff) {
-    WSAResetEvent(hev_);
-  }
-
-  virtual void OnEvent(uint32 ff, int err) {
-  }
-
-  virtual WSAEVENT GetWSAEvent() {
-    return hev_;
-  }
-
-  virtual SOCKET GetSocket() {
-    return INVALID_SOCKET;
-  }
-
-  virtual bool CheckSignalClose() { return false; }
-
-private:
-  PhysicalSocketServer* ss_;
-  WSAEVENT hev_;
-};
-
-class SocketDispatcher : public Dispatcher, public PhysicalSocket {
- public:
-  static int next_id_;
-  int id_;
-  bool signal_close_;
-  int signal_err_;
-
-  SocketDispatcher(PhysicalSocketServer* ss)
-      : PhysicalSocket(ss),
-        id_(0),
-        signal_close_(false) {
-  }
-
-  SocketDispatcher(SOCKET s, PhysicalSocketServer* ss)
-      : PhysicalSocket(ss, s),
-        id_(0),
-        signal_close_(false) {
-  }
-
-  virtual ~SocketDispatcher() {
-    Close();
-  }
-
-  bool Initialize() {
-    ASSERT(s_ != INVALID_SOCKET);
-    // Must be a non-blocking
-    u_long argp = 1;
-    ioctlsocket(s_, FIONBIO, &argp);
-    ss_->Add(this);
-    return true;
-  }
-
-  virtual bool Create(int type) {
-    // Create socket
-    if (!PhysicalSocket::Create(type))
-      return false;
-
-    if (!Initialize())
-      return false;
-
-    do { id_ = ++next_id_; } while (id_ == 0);
-    return true;
-  }
-
-  virtual int Close() {
-    if (s_ == INVALID_SOCKET)
-      return 0;
-
-    id_ = 0;
-    signal_close_ = false;
-    ss_->Remove(this);
-    return PhysicalSocket::Close();
-  }
-
-  virtual uint32 GetRequestedEvents() {
-    return enabled_events_;
-  }
-
-  virtual void OnPreEvent(uint32 ff) {
-    if ((ff & DE_CONNECT) != 0)
-      state_ = CS_CONNECTED;
-    // We set CS_CLOSED from CheckSignalClose.
-  }
-
-  virtual void OnEvent(uint32 ff, int err) {
-    int cache_id = id_;
-    if ((ff & DE_READ) != 0) {
-      enabled_events_ &= ~DE_READ;
-      SignalReadEvent(this);
-    }
-    if (((ff & DE_WRITE) != 0) && (id_ == cache_id)) {
-      enabled_events_ &= ~DE_WRITE;
-      SignalWriteEvent(this);
-    }
-    if (((ff & DE_CONNECT) != 0) && (id_ == cache_id)) {
-      if (ff != DE_CONNECT)
-        LOG(LS_VERBOSE) << "Signalled with DE_CONNECT: " << ff;
-      enabled_events_ &= ~DE_CONNECT;
-#ifdef _DEBUG
-      dbg_addr_ = "Connected @ ";
-      dbg_addr_.append(GetRemoteAddress().ToString());
-#endif  // _DEBUG
-      SignalConnectEvent(this);
-    }
-    if (((ff & DE_ACCEPT) != 0) && (id_ == cache_id)) {
-      enabled_events_ &= ~DE_ACCEPT;
-      SignalReadEvent(this);
-    }
-    if (((ff & DE_CLOSE) != 0) && (id_ == cache_id)) {
-      signal_close_ = true;
-      signal_err_ = err;
-    }
-  }
-
-  virtual WSAEVENT GetWSAEvent() {
-    return WSA_INVALID_EVENT;
-  }
-
-  virtual SOCKET GetSocket() {
-    return s_;
-  }
-
-  virtual bool CheckSignalClose() {
-    if (!signal_close_)
-      return false;
-
-    char ch;
-    if (recv(s_, &ch, 1, MSG_PEEK) > 0)
-      return false;
-
-    state_ = CS_CLOSED;
-    signal_close_ = false;
-    SignalCloseEvent(this, signal_err_);
-    return true;
-  }
-};
-
-int SocketDispatcher::next_id_ = 0;
-
-#endif  // WIN32
-
-// Sets the value of a boolean value to false when signaled.
-class Signaler : public EventDispatcher {
- public:
-  Signaler(PhysicalSocketServer* ss, bool* pf)
-      : EventDispatcher(ss), pf_(pf) {
-  }
-  virtual ~Signaler() { }
-
-  void OnEvent(uint32 ff, int err) {
-    if (pf_)
-      *pf_ = false;
-  }
-
- private:
-  bool *pf_;
-};
-
-PhysicalSocketServer::PhysicalSocketServer()
-    : fWait_(false),
-      last_tick_tracked_(0),
-      last_tick_dispatch_count_(0) {
-  signal_wakeup_ = new Signaler(this, &fWait_);
-#ifdef WIN32
-  socket_ev_ = WSACreateEvent();
-#endif
-}
-
-PhysicalSocketServer::~PhysicalSocketServer() {
-#ifdef WIN32
-  WSACloseEvent(socket_ev_);
-#endif
-#ifdef POSIX
-  signal_dispatcher_.reset();
-#endif
-  delete signal_wakeup_;
-  ASSERT(dispatchers_.empty());
-}
-
-void PhysicalSocketServer::WakeUp() {
-  signal_wakeup_->Signal();
-}
-
-Socket* PhysicalSocketServer::CreateSocket(int type) {
-  PhysicalSocket* socket = new PhysicalSocket(this);
-  if (socket->Create(type)) {
-    return socket;
-  } else {
-    delete socket;
-    return 0;
-  }
-}
-
-AsyncSocket* PhysicalSocketServer::CreateAsyncSocket(int type) {
-  SocketDispatcher* dispatcher = new SocketDispatcher(this);
-  if (dispatcher->Create(type)) {
-    return dispatcher;
-  } else {
-    delete dispatcher;
-    return 0;
-  }
-}
-
-AsyncSocket* PhysicalSocketServer::WrapSocket(SOCKET s) {
-  SocketDispatcher* dispatcher = new SocketDispatcher(s, this);
-  if (dispatcher->Initialize()) {
-    return dispatcher;
-  } else {
-    delete dispatcher;
-    return 0;
-  }
-}
-
-void PhysicalSocketServer::Add(Dispatcher *pdispatcher) {
-  CritScope cs(&crit_);
-  // Prevent duplicates. This can cause dead dispatchers to stick around.
-  DispatcherList::iterator pos = std::find(dispatchers_.begin(),
-                                           dispatchers_.end(),
-                                           pdispatcher);
-  if (pos != dispatchers_.end())
-    return;
-  dispatchers_.push_back(pdispatcher);
-}
-
-void PhysicalSocketServer::Remove(Dispatcher *pdispatcher) {
-  CritScope cs(&crit_);
-  DispatcherList::iterator pos = std::find(dispatchers_.begin(),
-                                           dispatchers_.end(),
-                                           pdispatcher);
-  ASSERT(pos != dispatchers_.end());
-  size_t index = pos - dispatchers_.begin();
-  dispatchers_.erase(pos);
-  for (IteratorList::iterator it = iterators_.begin(); it != iterators_.end();
-       ++it) {
-    if (index < **it) {
-      --**it;
-    }
-  }
-}
-
-#ifdef POSIX
-bool PhysicalSocketServer::Wait(int cmsWait, bool process_io) {
-  // Calculate timing information
-
-  struct timeval *ptvWait = NULL;
-  struct timeval tvWait;
-  struct timeval tvStop;
-  if (cmsWait != kForever) {
-    // Calculate wait timeval
-    tvWait.tv_sec = cmsWait / 1000;
-    tvWait.tv_usec = (cmsWait % 1000) * 1000;
-    ptvWait = &tvWait;
-
-    // Calculate when to return in a timeval
-    gettimeofday(&tvStop, NULL);
-    tvStop.tv_sec += tvWait.tv_sec;
-    tvStop.tv_usec += tvWait.tv_usec;
-    if (tvStop.tv_usec >= 1000000) {
-      tvStop.tv_usec -= 1000000;
-      tvStop.tv_sec += 1;
-    }
-  }
-
-  // Zero all fd_sets. Don't need to do this inside the loop since
-  // select() zeros the descriptors not signaled
-
-  fd_set fdsRead;
-  FD_ZERO(&fdsRead);
-  fd_set fdsWrite;
-  FD_ZERO(&fdsWrite);
-
-  fWait_ = true;
-
-  while (fWait_) {
-    int fdmax = -1;
-    {
-      CritScope cr(&crit_);
-      for (size_t i = 0; i < dispatchers_.size(); ++i) {
-        // Query dispatchers for read and write wait state
-        Dispatcher *pdispatcher = dispatchers_[i];
-        ASSERT(pdispatcher);
-        if (!process_io && (pdispatcher != signal_wakeup_))
-          continue;
-        int fd = pdispatcher->GetDescriptor();
-        if (fd > fdmax)
-          fdmax = fd;
-
-        uint32 ff = pdispatcher->GetRequestedEvents();
-        if (ff & (DE_READ | DE_ACCEPT))
-          FD_SET(fd, &fdsRead);
-        if (ff & (DE_WRITE | DE_CONNECT))
-          FD_SET(fd, &fdsWrite);
-      }
-    }
-
-    // Wait then call handlers as appropriate
-    // < 0 means error
-    // 0 means timeout
-    // > 0 means count of descriptors ready
-    int n = select(fdmax + 1, &fdsRead, &fdsWrite, NULL, ptvWait);
-
-    // If error, return error.
-    if (n < 0) {
-      if (errno != EINTR) {
-        LOG_E(LS_ERROR, EN, errno) << "select";
-        return false;
-      }
-      // Else ignore the error and keep going. If this EINTR was for one of the
-      // signals managed by this PhysicalSocketServer, the
-      // PosixSignalDeliveryDispatcher will be in the signaled state in the next
-      // iteration.
-    } else if (n == 0) {
-      // If timeout, return success
-      return true;
-    } else {
-      // We have signaled descriptors
-      CritScope cr(&crit_);
-      for (size_t i = 0; i < dispatchers_.size(); ++i) {
-        Dispatcher *pdispatcher = dispatchers_[i];
-        int fd = pdispatcher->GetDescriptor();
-        uint32 ff = 0;
-        int errcode = 0;
-
-        // Reap any error code, which can be signaled through reads or writes.
-        // TODO: Should we set errcode if getsockopt fails?
-        if (FD_ISSET(fd, &fdsRead) || FD_ISSET(fd, &fdsWrite)) {
-          socklen_t len = sizeof(errcode);
-          ::getsockopt(fd, SOL_SOCKET, SO_ERROR, &errcode, &len);
-        }
-
-        // Check readable descriptors. If we're waiting on an accept, signal
-        // that. Otherwise we're waiting for data, check to see if we're
-        // readable or really closed.
-        // TODO: Only peek at TCP descriptors.
-        if (FD_ISSET(fd, &fdsRead)) {
-          FD_CLR(fd, &fdsRead);
-          if (pdispatcher->GetRequestedEvents() & DE_ACCEPT) {
-            ff |= DE_ACCEPT;
-          } else if (errcode || pdispatcher->IsDescriptorClosed()) {
-            ff |= DE_CLOSE;
-          } else {
-            ff |= DE_READ;
-          }
-        }
-
-        // Check writable descriptors. If we're waiting on a connect, detect
-        // success versus failure by the reaped error code.
-        if (FD_ISSET(fd, &fdsWrite)) {
-          FD_CLR(fd, &fdsWrite);
-          if (pdispatcher->GetRequestedEvents() & DE_CONNECT) {
-            if (!errcode) {
-              ff |= DE_CONNECT;
-            } else {
-              ff |= DE_CLOSE;
-            }
-          } else {
-            ff |= DE_WRITE;
-          }
-        }
-
-        // Tell the descriptor about the event.
-        if (ff != 0) {
-          pdispatcher->OnPreEvent(ff);
-          pdispatcher->OnEvent(ff, errcode);
-        }
-      }
-    }
-
-    // Recalc the time remaining to wait. Doing it here means it doesn't get
-    // calced twice the first time through the loop
-
-    if (cmsWait != kForever) {
-      ptvWait->tv_sec = 0;
-      ptvWait->tv_usec = 0;
-      struct timeval tvT;
-      gettimeofday(&tvT, NULL);
-      if ((tvStop.tv_sec > tvT.tv_sec)
-          || ((tvStop.tv_sec == tvT.tv_sec)
-              && (tvStop.tv_usec > tvT.tv_usec))) {
-        ptvWait->tv_sec = tvStop.tv_sec - tvT.tv_sec;
-        ptvWait->tv_usec = tvStop.tv_usec - tvT.tv_usec;
-        if (ptvWait->tv_usec < 0) {
-          ASSERT(ptvWait->tv_sec > 0);
-          ptvWait->tv_usec += 1000000;
-          ptvWait->tv_sec -= 1;
-        }
-      }
-    }
-  }
-
-  return true;
-}
-
-static void GlobalSignalHandler(int signum) {
-  PosixSignalHandler::Instance()->OnPosixSignalReceived(signum);
-}
-
-bool PhysicalSocketServer::SetPosixSignalHandler(int signum,
-                                                 void (*handler)(int)) {
-  // If handler is SIG_IGN or SIG_DFL then clear our user-level handler,
-  // otherwise set one.
-  if (handler == SIG_IGN || handler == SIG_DFL) {
-    if (!InstallSignal(signum, handler)) {
-      return false;
-    }
-    if (signal_dispatcher_.get()) {
-      signal_dispatcher_->ClearHandler(signum);
-      if (!signal_dispatcher_->HasHandlers()) {
-        signal_dispatcher_.reset();
-      }
-    }
-  } else {
-    if (!signal_dispatcher_.get()) {
-      signal_dispatcher_.reset(new PosixSignalDispatcher(this));
-    }
-    signal_dispatcher_->SetHandler(signum, handler);
-    if (!InstallSignal(signum, &GlobalSignalHandler)) {
-      return false;
-    }
-  }
-  return true;
-}
-
-Dispatcher* PhysicalSocketServer::signal_dispatcher() {
-  return signal_dispatcher_.get();
-}
-
-bool PhysicalSocketServer::InstallSignal(int signum, void (*handler)(int)) {
-  struct sigaction act;
-  // It doesn't really matter what we set this mask to.
-  if (sigemptyset(&act.sa_mask) != 0) {
-    LOG_ERR(LS_ERROR) << "Couldn't set mask";
-    return false;
-  }
-  act.sa_handler = handler;
-  // Use SA_RESTART so that our syscalls don't get EINTR, since we don't need it
-  // and it's a nuisance. Though some syscalls still return EINTR and there's no
-  // real standard for which ones. :(
-  act.sa_flags = SA_RESTART;
-  if (sigaction(signum, &act, NULL) != 0) {
-    LOG_ERR(LS_ERROR) << "Couldn't set sigaction";
-    return false;
-  }
-  return true;
-}
-#endif  // POSIX
-
-#ifdef WIN32
-bool PhysicalSocketServer::Wait(int cmsWait, bool process_io) {
-  int cmsTotal = cmsWait;
-  int cmsElapsed = 0;
-  uint32 msStart = Time();
-
-#if LOGGING
-  if (last_tick_dispatch_count_ == 0) {
-    last_tick_tracked_ = msStart;
-  }
-#endif
-
-  fWait_ = true;
-  while (fWait_) {
-    std::vector<WSAEVENT> events;
-    std::vector<Dispatcher *> event_owners;
-
-    events.push_back(socket_ev_);
-
-    {
-      CritScope cr(&crit_);
-      size_t i = 0;
-      iterators_.push_back(&i);
-      // Don't track dispatchers_.size(), because we want to pick up any new
-      // dispatchers that were added while processing the loop.
-      while (i < dispatchers_.size()) {
-        Dispatcher* disp = dispatchers_[i++];
-        if (!process_io && (disp != signal_wakeup_))
-          continue;
-        SOCKET s = disp->GetSocket();
-        if (disp->CheckSignalClose()) {
-          // We just signalled close, don't poll this socket
-        } else if (s != INVALID_SOCKET) {
-          WSAEventSelect(s,
-                         events[0],
-                         FlagsToEvents(disp->GetRequestedEvents()));
-        } else {
-          events.push_back(disp->GetWSAEvent());
-          event_owners.push_back(disp);
-        }
-      }
-      ASSERT(iterators_.back() == &i);
-      iterators_.pop_back();
-    }
-
-    // Which is shorter, the delay wait or the asked wait?
-
-    int cmsNext;
-    if (cmsWait == kForever) {
-      cmsNext = cmsWait;
-    } else {
-      cmsNext = _max(0, cmsTotal - cmsElapsed);
-    }
-
-    // Wait for one of the events to signal
-    DWORD dw = WSAWaitForMultipleEvents(static_cast<DWORD>(events.size()),
-                                        &events[0],
-                                        false,
-                                        cmsNext,
-                                        false);
-
-#if 0  // LOGGING
-    // we track this information purely for logging purposes.
-    last_tick_dispatch_count_++;
-    if (last_tick_dispatch_count_ >= 1000) {
-      int32 elapsed = TimeSince(last_tick_tracked_);
-      LOG(INFO) << "PhysicalSocketServer took " << elapsed
-                << "ms for 1000 events";
-
-      // If we get more than 1000 events in a second, we are spinning badly
-      // (normally it should take about 8-20 seconds).
-      ASSERT(elapsed > 1000);
-
-      last_tick_tracked_ = Time();
-      last_tick_dispatch_count_ = 0;
-    }
-#endif
-
-    if (dw == WSA_WAIT_FAILED) {
-      // Failed?
-      // TODO: need a better strategy than this!
-      int error = WSAGetLastError();
-      ASSERT(false);
-      return false;
-    } else if (dw == WSA_WAIT_TIMEOUT) {
-      // Timeout?
-      return true;
-    } else {
-      // Figure out which one it is and call it
-      CritScope cr(&crit_);
-      int index = dw - WSA_WAIT_EVENT_0;
-      if (index > 0) {
-        --index; // The first event is the socket event
-        event_owners[index]->OnPreEvent(0);
-        event_owners[index]->OnEvent(0, 0);
-      } else if (process_io) {
-        size_t i = 0, end = dispatchers_.size();
-        iterators_.push_back(&i);
-        iterators_.push_back(&end);  // Don't iterate over new dispatchers.
-        while (i < end) {
-          Dispatcher* disp = dispatchers_[i++];
-          SOCKET s = disp->GetSocket();
-          if (s == INVALID_SOCKET)
-            continue;
-
-          WSANETWORKEVENTS wsaEvents;
-          int err = WSAEnumNetworkEvents(s, events[0], &wsaEvents);
-          if (err == 0) {
-
-#if LOGGING
-            {
-              if ((wsaEvents.lNetworkEvents & FD_READ) &&
-                  wsaEvents.iErrorCode[FD_READ_BIT] != 0) {
-                LOG(WARNING) << "PhysicalSocketServer got FD_READ_BIT error "
-                             << wsaEvents.iErrorCode[FD_READ_BIT];
-              }
-              if ((wsaEvents.lNetworkEvents & FD_WRITE) &&
-                  wsaEvents.iErrorCode[FD_WRITE_BIT] != 0) {
-                LOG(WARNING) << "PhysicalSocketServer got FD_WRITE_BIT error "
-                             << wsaEvents.iErrorCode[FD_WRITE_BIT];
-              }
-              if ((wsaEvents.lNetworkEvents & FD_CONNECT) &&
-                  wsaEvents.iErrorCode[FD_CONNECT_BIT] != 0) {
-                LOG(WARNING) << "PhysicalSocketServer got FD_CONNECT_BIT error "
-                             << wsaEvents.iErrorCode[FD_CONNECT_BIT];
-              }
-              if ((wsaEvents.lNetworkEvents & FD_ACCEPT) &&
-                  wsaEvents.iErrorCode[FD_ACCEPT_BIT] != 0) {
-                LOG(WARNING) << "PhysicalSocketServer got FD_ACCEPT_BIT error "
-                             << wsaEvents.iErrorCode[FD_ACCEPT_BIT];
-              }
-              if ((wsaEvents.lNetworkEvents & FD_CLOSE) &&
-                  wsaEvents.iErrorCode[FD_CLOSE_BIT] != 0) {
-                LOG(WARNING) << "PhysicalSocketServer got FD_CLOSE_BIT error "
-                             << wsaEvents.iErrorCode[FD_CLOSE_BIT];
-              }
-            }
-#endif
-            uint32 ff = 0;
-            int errcode = 0;
-            if (wsaEvents.lNetworkEvents & FD_READ)
-              ff |= DE_READ;
-            if (wsaEvents.lNetworkEvents & FD_WRITE)
-              ff |= DE_WRITE;
-            if (wsaEvents.lNetworkEvents & FD_CONNECT) {
-              if (wsaEvents.iErrorCode[FD_CONNECT_BIT] == 0) {
-                ff |= DE_CONNECT;
-              } else {
-                ff |= DE_CLOSE;
-                errcode = wsaEvents.iErrorCode[FD_CONNECT_BIT];
-              }
-            }
-            if (wsaEvents.lNetworkEvents & FD_ACCEPT)
-              ff |= DE_ACCEPT;
-            if (wsaEvents.lNetworkEvents & FD_CLOSE) {
-              ff |= DE_CLOSE;
-              errcode = wsaEvents.iErrorCode[FD_CLOSE_BIT];
-            }
-            if (ff != 0) {
-              disp->OnPreEvent(ff);
-              disp->OnEvent(ff, errcode);
-            }
-          }
-        }
-        ASSERT(iterators_.back() == &end);
-        iterators_.pop_back();
-        ASSERT(iterators_.back() == &i);
-        iterators_.pop_back();
-      }
-
-      // Reset the network event until new activity occurs
-      WSAResetEvent(socket_ev_);
-    }
-
-    // Break?
-    if (!fWait_)
-      break;
-    cmsElapsed = TimeSince(msStart);
-    if ((cmsWait != kForever) && (cmsElapsed >= cmsWait)) {
-       break;
-    }
-  }
-
-  // Done
-  return true;
-}
-#endif  // WIN32
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/physicalsocketserver.h b/third_party/libjingle/source/talk/base/physicalsocketserver.h
deleted file mode 100644
index 1b7a298..0000000
--- a/third_party/libjingle/source/talk/base/physicalsocketserver.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_PHYSICALSOCKETSERVER_H__
-#define TALK_BASE_PHYSICALSOCKETSERVER_H__
-
-#include <vector>
-
-#include "talk/base/asyncfile.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/base/socketserver.h"
-#include "talk/base/criticalsection.h"
-
-#ifdef POSIX
-typedef int SOCKET;
-#endif // POSIX
-
-namespace talk_base {
-
-// Event constants for the Dispatcher class.
-enum DispatcherEvent {
-  DE_READ    = 0x0001,
-  DE_WRITE   = 0x0002,
-  DE_CONNECT = 0x0004,
-  DE_CLOSE   = 0x0008,
-  DE_ACCEPT  = 0x0010,
-};
-
-class Signaler;
-#ifdef POSIX
-class PosixSignalDispatcher;
-#endif
-
-class Dispatcher {
- public:
-  virtual ~Dispatcher() {}
-  virtual uint32 GetRequestedEvents() = 0;
-  virtual void OnPreEvent(uint32 ff) = 0;
-  virtual void OnEvent(uint32 ff, int err) = 0;
-#ifdef WIN32
-  virtual WSAEVENT GetWSAEvent() = 0;
-  virtual SOCKET GetSocket() = 0;
-  virtual bool CheckSignalClose() = 0;
-#elif POSIX
-  virtual int GetDescriptor() = 0;
-  virtual bool IsDescriptorClosed() = 0;
-#endif
-};
-
-// A socket server that provides the real sockets of the underlying OS.
-class PhysicalSocketServer : public SocketServer {
- public:
-  PhysicalSocketServer();
-  virtual ~PhysicalSocketServer();
-
-  // SocketFactory:
-  virtual Socket* CreateSocket(int type);
-  virtual AsyncSocket* CreateAsyncSocket(int type);
-
-  // Internal Factory for Accept
-  AsyncSocket* WrapSocket(SOCKET s);
-
-  // SocketServer:
-  virtual bool Wait(int cms, bool process_io);
-  virtual void WakeUp();
-
-  void Add(Dispatcher* dispatcher);
-  void Remove(Dispatcher* dispatcher);
-
-#ifdef POSIX
-  AsyncFile* CreateFile(int fd);
-
-  // Sets the function to be executed in response to the specified POSIX signal.
-  // The function is executed from inside Wait() using the "self-pipe trick"--
-  // regardless of which thread receives the signal--and hence can safely
-  // manipulate user-level data structures.
-  // "handler" may be SIG_IGN, SIG_DFL, or a user-specified function, just like
-  // with signal(2).
-  // Only one PhysicalSocketServer should have user-level signal handlers.
-  // Dispatching signals on multiple PhysicalSocketServers is not reliable.
-  // The signal mask is not modified. It is the caller's responsibily to
-  // maintain it as desired.
-  virtual bool SetPosixSignalHandler(int signum, void (*handler)(int));
-
- protected:
-  Dispatcher* signal_dispatcher();
-#endif
-
- private:
-  typedef std::vector<Dispatcher*> DispatcherList;
-  typedef std::vector<size_t*> IteratorList;
-
-#ifdef POSIX
-  static bool InstallSignal(int signum, void (*handler)(int));
-
-  scoped_ptr<PosixSignalDispatcher> signal_dispatcher_;
-#endif
-  DispatcherList dispatchers_;
-  IteratorList iterators_;
-  Signaler* signal_wakeup_;
-  CriticalSection crit_;
-  bool fWait_;
-  uint32 last_tick_tracked_;
-  int last_tick_dispatch_count_;
-#ifdef WIN32
-  WSAEVENT socket_ev_;
-#endif
-};
-
-} // namespace talk_base
-
-#endif // TALK_BASE_PHYSICALSOCKETSERVER_H__
diff --git a/third_party/libjingle/source/talk/base/proxy_unittest.cc b/third_party/libjingle/source/talk/base/proxy_unittest.cc
deleted file mode 100644
index e1a51f3..0000000
--- a/third_party/libjingle/source/talk/base/proxy_unittest.cc
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * libjingle
- * Copyright 2009, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string>
-#include "talk/base/autodetectproxy.h"
-#include "talk/base/gunit.h"
-#include "talk/base/httpserver.h"
-#include "talk/base/proxyserver.h"
-#include "talk/base/socketadapters.h"
-#include "talk/base/testclient.h"
-#include "talk/base/testechoserver.h"
-#include "talk/base/virtualsocketserver.h"
-
-using talk_base::Socket;
-using talk_base::Thread;
-using talk_base::SocketAddress;
-
-static const SocketAddress kSocksProxyIntAddr("1.2.3.4", 1080);
-static const SocketAddress kSocksProxyExtAddr("1.2.3.5", 0);
-static const SocketAddress kHttpsProxyIntAddr("1.2.3.4", 443);
-static const SocketAddress kHttpsProxyExtAddr("1.2.3.5", 0);
-static const SocketAddress kBogusProxyIntAddr("1.2.3.4", 999);
-
-// Used to run a proxy detect on the current thread. Otherwise we would need
-// to make both threads share the same VirtualSocketServer.
-class AutoDetectProxyRunner : public talk_base::AutoDetectProxy {
- public:
-  explicit AutoDetectProxyRunner(const std::string& agent)
-      : AutoDetectProxy(agent) {}
-  void Run() {
-    DoWork();
-    Thread::Current()->Restart();  // needed to reset the messagequeue
-  }
-};
-
-// Sets up a virtual socket server and HTTPS/SOCKS5 proxy servers.
-class ProxyTest : public testing::Test {
- public:
-  ProxyTest() : ss_(new talk_base::VirtualSocketServer(NULL)) {
-    Thread::Current()->set_socketserver(ss_.get());
-    socks_.reset(new talk_base::SocksProxyServer(
-        ss_.get(), kSocksProxyIntAddr, ss_.get(), kSocksProxyExtAddr));
-    https_.reset(new talk_base::HttpListenServer());
-    https_->Listen(kHttpsProxyIntAddr);
-  }
-  ~ProxyTest() {
-    Thread::Current()->set_socketserver(NULL);
-  }
-
-  talk_base::SocketServer* ss() { return ss_.get(); }
-
-  talk_base::ProxyType DetectProxyType(const SocketAddress& address) {
-    talk_base::ProxyType type;
-    AutoDetectProxyRunner* detect = new AutoDetectProxyRunner("unittest/1.0");
-    detect->set_proxy(address);
-    detect->Run();  // blocks until done
-    type = detect->proxy().type;
-    detect->Destroy(false);
-    return type;
-  }
-
- private:
-  talk_base::scoped_ptr<talk_base::SocketServer> ss_;
-  talk_base::scoped_ptr<talk_base::SocksProxyServer> socks_;
-  // TODO: Make this a real HTTPS proxy server.
-  talk_base::scoped_ptr<talk_base::HttpListenServer> https_;
-};
-
-// Tests whether we can use a SOCKS5 proxy to connect to a server.
-TEST_F(ProxyTest, TestSocks5Connect) {
-  talk_base::AsyncSocket* socket = ss()->CreateAsyncSocket(SOCK_STREAM);
-  talk_base::AsyncSocksProxySocket* proxy_socket =
-      new talk_base::AsyncSocksProxySocket(socket, kSocksProxyIntAddr,
-                                           "", talk_base::CryptString());
-
-  talk_base::TestEchoServer server(Thread::Current(), SocketAddress());
-
-  talk_base::AsyncTCPSocket* packet_socket = talk_base::AsyncTCPSocket::Create(
-      proxy_socket, SocketAddress(), server.address());
-  EXPECT_TRUE(packet_socket != NULL);
-  talk_base::TestClient client(packet_socket);
-
-  EXPECT_EQ(Socket::CS_CONNECTING, proxy_socket->GetState());
-  EXPECT_TRUE(client.CheckConnected());
-  EXPECT_EQ(Socket::CS_CONNECTED, proxy_socket->GetState());
-  EXPECT_EQ(server.address(), client.remote_address());
-  client.Send("foo", 3);
-  EXPECT_TRUE(client.CheckNextPacket("foo", 3, NULL));
-  EXPECT_TRUE(client.CheckNoPacket());
-}
-
-/*
-// Tests whether we can use a HTTPS proxy to connect to a server.
-TEST_F(ProxyTest, TestHttpsConnect) {
-  AsyncSocket* socket = ss()->CreateAsyncSocket(SOCK_STREAM);
-  AsyncHttpsProxySocket* proxy_socket = new AsyncHttpsProxySocket(
-      socket, "unittest/1.0", kHttpsProxyIntAddress, "", CryptString());
-  TestClient client(new AsyncTCPSocket(proxy_socket));
-  TestEchoServer server(Thread::Current(), SocketAddress());
-
-  EXPECT_TRUE(client.Connect(server.address()));
-  EXPECT_TRUE(client.CheckConnected());
-  EXPECT_EQ(server.address(), client.remote_address());
-  client.Send("foo", 3);
-  EXPECT_TRUE(client.CheckNextPacket("foo", 3, NULL));
-  EXPECT_TRUE(client.CheckNoPacket());
-}
-*/
-
-// Tests whether we can autodetect a SOCKS5 proxy.
-TEST_F(ProxyTest, TestAutoDetectSocks5) {
-  EXPECT_EQ(talk_base::PROXY_SOCKS5, DetectProxyType(kSocksProxyIntAddr));
-}
-
-/*
-// Tests whether we can autodetect a HTTPS proxy.
-TEST_F(ProxyTest, TestAutoDetectHttps) {
-  EXPECT_EQ(talk_base::PROXY_HTTPS, DetectProxyType(kHttpsProxyIntAddr));
-}
-*/
-
-// Tests whether we fail properly for no proxy.
-TEST_F(ProxyTest, TestAutoDetectBogus) {
-  EXPECT_EQ(talk_base::PROXY_UNKNOWN, DetectProxyType(kBogusProxyIntAddr));
-}
diff --git a/third_party/libjingle/source/talk/base/proxydetect.cc b/third_party/libjingle/source/talk/base/proxydetect.cc
deleted file mode 100644
index 4bfae29..0000000
--- a/third_party/libjingle/source/talk/base/proxydetect.cc
+++ /dev/null
@@ -1,1261 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/proxydetect.h"
-
-#ifdef WIN32
-#include "talk/base/win32.h"
-#include <shlobj.h>
-#endif  // WIN32
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#ifdef OSX
-#include <SystemConfiguration/SystemConfiguration.h>
-#include <CoreFoundation/CoreFoundation.h>
-#include <CoreServices/CoreServices.h>
-#include <Security/Security.h>
-#include "macconversion.h"
-#endif
-
-#include <map>
-
-#include "talk/base/fileutils.h"
-#include "talk/base/httpcommon.h"
-#include "talk/base/httpcommon-inl.h"
-#include "talk/base/pathutils.h"
-#include "talk/base/stringutils.h"
-
-#ifdef WIN32
-#define _TRY_WINHTTP 1
-#define _TRY_JSPROXY 0
-#define _TRY_WM_FINDPROXY 0
-#define _TRY_IE_LAN_SETTINGS 1
-#endif  // WIN32
-
-// For all platforms try Firefox.
-#define _TRY_FIREFOX 1
-
-// Use profiles.ini to find the correct profile for this user.
-// If not set, we'll just look for the default one.
-#define USE_FIREFOX_PROFILES_INI 1
-
-static const size_t kMaxLineLength = 1024;
-static const char kFirefoxPattern[] = "Firefox";
-static const char kInternetExplorerPattern[] = "MSIE";
-
-struct StringMap {
- public:
-  void Add(const char * name, const char * value) { map_[name] = value; }
-  const std::string& Get(const char * name, const char * def = "") const {
-    std::map<std::string, std::string>::const_iterator it =
-        map_.find(name);
-    if (it != map_.end())
-      return it->second;
-    def_ = def;
-    return def_;
-  }
-  bool IsSet(const char * name) const {
-    return (map_.find(name) != map_.end());
-  }
- private:
-  std::map<std::string, std::string> map_;
-  mutable std::string def_;
-};
-
-enum UserAgent {
-  UA_FIREFOX,
-  UA_INTERNETEXPLORER,
-  UA_OTHER,
-  UA_UNKNOWN
-};
-
-#if _TRY_WINHTTP
-//#include <winhttp.h>
-// Note: From winhttp.h
-
-const char WINHTTP[] = "winhttp";
-
-typedef LPVOID HINTERNET;
-
-typedef struct {
-  DWORD  dwAccessType;      // see WINHTTP_ACCESS_* types below
-  LPWSTR lpszProxy;         // proxy server list
-  LPWSTR lpszProxyBypass;   // proxy bypass list
-} WINHTTP_PROXY_INFO, * LPWINHTTP_PROXY_INFO;
-
-typedef struct {
-  DWORD   dwFlags;
-  DWORD   dwAutoDetectFlags;
-  LPCWSTR lpszAutoConfigUrl;
-  LPVOID  lpvReserved;
-  DWORD   dwReserved;
-  BOOL    fAutoLogonIfChallenged;
-} WINHTTP_AUTOPROXY_OPTIONS;
-
-typedef struct {
-  BOOL    fAutoDetect;
-  LPWSTR  lpszAutoConfigUrl;
-  LPWSTR  lpszProxy;
-  LPWSTR  lpszProxyBypass;
-} WINHTTP_CURRENT_USER_IE_PROXY_CONFIG;
-
-extern "C" {
-  typedef HINTERNET (WINAPI * pfnWinHttpOpen)
-      (
-          IN LPCWSTR pwszUserAgent,
-          IN DWORD   dwAccessType,
-          IN LPCWSTR pwszProxyName   OPTIONAL,
-          IN LPCWSTR pwszProxyBypass OPTIONAL,
-          IN DWORD   dwFlags
-          );
-  typedef BOOL (STDAPICALLTYPE * pfnWinHttpCloseHandle)
-      (
-          IN HINTERNET hInternet
-          );
-  typedef BOOL (STDAPICALLTYPE * pfnWinHttpGetProxyForUrl)
-      (
-          IN  HINTERNET                   hSession,
-          IN  LPCWSTR                     lpcwszUrl,
-          IN  WINHTTP_AUTOPROXY_OPTIONS * pAutoProxyOptions,
-          OUT WINHTTP_PROXY_INFO *        pProxyInfo
-          );
-  typedef BOOL (STDAPICALLTYPE * pfnWinHttpGetIEProxyConfig)
-      (
-          IN OUT WINHTTP_CURRENT_USER_IE_PROXY_CONFIG * pProxyConfig
-          );
-
-} // extern "C"
-
-#define WINHTTP_AUTOPROXY_AUTO_DETECT           0x00000001
-#define WINHTTP_AUTOPROXY_CONFIG_URL            0x00000002
-#define WINHTTP_AUTOPROXY_RUN_INPROCESS         0x00010000
-#define WINHTTP_AUTOPROXY_RUN_OUTPROCESS_ONLY   0x00020000
-#define WINHTTP_AUTO_DETECT_TYPE_DHCP           0x00000001
-#define WINHTTP_AUTO_DETECT_TYPE_DNS_A          0x00000002
-#define WINHTTP_ACCESS_TYPE_DEFAULT_PROXY               0
-#define WINHTTP_ACCESS_TYPE_NO_PROXY                    1
-#define WINHTTP_ACCESS_TYPE_NAMED_PROXY                 3
-#define WINHTTP_NO_PROXY_NAME     NULL
-#define WINHTTP_NO_PROXY_BYPASS   NULL
-
-#endif // _TRY_WINHTTP
-
-#if _TRY_JSPROXY
-extern "C" {
-  typedef BOOL (STDAPICALLTYPE * pfnInternetGetProxyInfo)
-      (
-          LPCSTR lpszUrl,
-          DWORD dwUrlLength,
-          LPSTR lpszUrlHostName,
-          DWORD dwUrlHostNameLength,
-          LPSTR * lplpszProxyHostName,
-          LPDWORD lpdwProxyHostNameLength
-          );
-} // extern "C"
-#endif // _TRY_JSPROXY
-
-#if _TRY_WM_FINDPROXY
-#include <comutil.h>
-#include <wmnetsourcecreator.h>
-#include <wmsinternaladminnetsource.h>
-#endif // _TRY_WM_FINDPROXY
-
-#if _TRY_IE_LAN_SETTINGS
-#include <wininet.h>
-#include <string>
-#endif // _TRY_IE_LAN_SETTINGS
-
-namespace talk_base {
-
-//////////////////////////////////////////////////////////////////////
-// Utility Functions
-//////////////////////////////////////////////////////////////////////
-
-#ifdef WIN32
-#ifdef _UNICODE
-
-typedef std::wstring tstring;
-std::string Utf8String(const tstring& str) { return ToUtf8(str); }
-
-#else  // !_UNICODE
-
-typedef std::string tstring;
-std::string Utf8String(const tstring& str) { return str; }
-
-#endif  // !_UNICODE
-#endif  // WIN32
-
-bool ProxyItemMatch(const Url<char>& url, char * item, size_t len) {
-  // hostname:443
-  if (char * port = ::strchr(item, ':')) {
-    *port++ = '\0';
-    if (url.port() != atol(port)) {
-      return false;
-    }
-  }
-
-  // A.B.C.D or A.B.C.D/24
-  int a, b, c, d, m;
-  int match = sscanf(item, "%d.%d.%d.%d/%d", &a, &b, &c, &d, &m);
-  if (match >= 4) {
-    uint32 ip = ((a & 0xFF) << 24) | ((b & 0xFF) << 16) | ((c & 0xFF) << 8) |
-        (d & 0xFF);
-    if ((match < 5) || (m > 32))
-      m = 32;
-    else if (m < 0)
-      m = 0;
-    uint32 mask = (m == 0) ? 0 : (~0UL) << (32 - m);
-    SocketAddress addr(url.host(), 0);
-    // TODO: Support IPv6 proxyitems. This code block is IPv4 only anyway.
-    return !addr.IsUnresolved() &&
-        ((addr.ipaddr().v4AddressAsHostOrderInteger() & mask) == (ip & mask));
-  }
-
-  // .foo.com
-  if (*item == '.') {
-    size_t hostlen = url.host().length();
-    return (hostlen > len)
-        && (stricmp(url.host().c_str() + (hostlen - len), item) == 0);
-  }
-
-  // localhost or www.*.com
-  if (!string_match(url.host().c_str(), item))
-    return false;
-
-  return true;
-}
-
-bool ProxyListMatch(const Url<char>& url, const std::string& proxy_list,
-                    char sep) {
-  const size_t BUFSIZE = 256;
-  char buffer[BUFSIZE];
-  const char* list = proxy_list.c_str();
-  while (*list) {
-    // Remove leading space
-    if (isspace(*list)) {
-      ++list;
-      continue;
-    }
-    // Break on separator
-    size_t len;
-    const char * start = list;
-    if (const char * end = ::strchr(list, sep)) {
-      len = (end - list);
-      list += len + 1;
-    } else {
-      len = strlen(list);
-      list += len;
-    }
-    // Remove trailing space
-    while ((len > 0) && isspace(start[len-1]))
-      --len;
-    // Check for oversized entry
-    if (len >= BUFSIZE)
-      continue;
-    memcpy(buffer, start, len);
-    buffer[len] = 0;
-    if (!ProxyItemMatch(url, buffer, len))
-      continue;
-    return true;
-  }
-  return false;
-}
-
-bool Better(ProxyType lhs, const ProxyType rhs) {
-  // PROXY_NONE, PROXY_HTTPS, PROXY_SOCKS5, PROXY_UNKNOWN
-  const int PROXY_VALUE[5] = { 0, 2, 3, 1 };
-  return (PROXY_VALUE[lhs] > PROXY_VALUE[rhs]);
-}
-
-bool ParseProxy(const std::string& saddress, ProxyInfo* proxy) {
-  const size_t kMaxAddressLength = 1024;
-  // Allow semicolon, space, or tab as an address separator
-  const char* const kAddressSeparator = " ;\t";
-
-  ProxyType ptype;
-  std::string host;
-  uint16 port;
-
-  const char* address = saddress.c_str();
-  while (*address) {
-    size_t len;
-    const char * start = address;
-    if (const char * sep = strchr(address, kAddressSeparator)) {
-      len = (sep - address);
-      address += len + 1;
-      while (*address != '\0' && ::strchr(kAddressSeparator, *address)) {
-        address += 1;
-      }
-    } else {
-      len = strlen(address);
-      address += len;
-    }
-
-    if (len > kMaxAddressLength - 1) {
-      LOG(LS_WARNING) << "Proxy address too long [" << start << "]";
-      continue;
-    }
-
-    char buffer[kMaxAddressLength];
-    memcpy(buffer, start, len);
-    buffer[len] = 0;
-
-    char * colon = ::strchr(buffer, ':');
-    if (!colon) {
-      LOG(LS_WARNING) << "Proxy address without port [" << buffer << "]";
-      continue;
-    }
-
-    *colon = 0;
-    char * endptr;
-    port = static_cast<uint16>(strtol(colon + 1, &endptr, 0));
-    if (*endptr != 0) {
-      LOG(LS_WARNING) << "Proxy address with invalid port [" << buffer << "]";
-      continue;
-    }
-
-    if (char * equals = ::strchr(buffer, '=')) {
-      *equals = 0;
-      host = equals + 1;
-      if (_stricmp(buffer, "socks") == 0) {
-        ptype = PROXY_SOCKS5;
-      } else if (_stricmp(buffer, "https") == 0) {
-        ptype = PROXY_HTTPS;
-      } else {
-        LOG(LS_WARNING) << "Proxy address with unknown protocol ["
-                        << buffer << "]";
-        ptype = PROXY_UNKNOWN;
-      }
-    } else {
-      host = buffer;
-      ptype = PROXY_UNKNOWN;
-    }
-
-    if (Better(ptype, proxy->type)) {
-      proxy->type = ptype;
-      proxy->address.SetIP(host);
-      proxy->address.SetPort(port);
-    }
-  }
-
-  return proxy->type != PROXY_NONE;
-}
-
-UserAgent GetAgent(const char* agent) {
-  if (agent) {
-    std::string agent_str(agent);
-    if (agent_str.find(kFirefoxPattern) != std::string::npos) {
-      return UA_FIREFOX;
-    } else if (agent_str.find(kInternetExplorerPattern) != std::string::npos) {
-      return UA_INTERNETEXPLORER;
-    } else if (agent_str.empty()) {
-      return UA_UNKNOWN;
-    }
-  }
-  return UA_OTHER;
-}
-
-bool EndsWith(const std::string& a, const std::string& b) {
-  if (b.size() > a.size()) {
-    return false;
-  }
-  int result = a.compare(a.size() - b.size(), b.size(), b);
-  return result == 0;
-}
-
-bool GetFirefoxProfilePath(Pathname* path) {
-#ifdef WIN32
-  wchar_t w_path[MAX_PATH];
-  if (SHGetFolderPath(0, CSIDL_APPDATA, 0, SHGFP_TYPE_CURRENT, w_path) !=
-      S_OK) {
-    LOG(LS_ERROR) << "SHGetFolderPath failed";
-    return false;
-  }
-  path->SetFolder(ToUtf8(w_path, wcslen(w_path)));
-  path->AppendFolder("Mozilla");
-  path->AppendFolder("Firefox");
-#elif OSX
-  FSRef fr;
-  if (0 != FSFindFolder(kUserDomain, kApplicationSupportFolderType,
-                        kCreateFolder, &fr)) {
-    LOG(LS_ERROR) << "FSFindFolder failed";
-    return false;
-  }
-  char buffer[NAME_MAX + 1];
-  if (0 != FSRefMakePath(&fr, reinterpret_cast<uint8*>(buffer),
-                         ARRAY_SIZE(buffer))) {
-    LOG(LS_ERROR) << "FSRefMakePath failed";
-    return false;
-  }
-  path->SetFolder(std::string(buffer));
-  path->AppendFolder("Firefox");
-#else
-  char* user_home = getenv("HOME");
-  if (user_home == NULL) {
-    return false;
-  }
-  path->SetFolder(std::string(user_home));
-  path->AppendFolder(".mozilla");
-  path->AppendFolder("firefox");
-#endif  // WIN32
-  return true;
-}
-
-bool GetDefaultFirefoxProfile(Pathname* profile_path) {
-  ASSERT(NULL != profile_path);
-  Pathname path;
-  if (!GetFirefoxProfilePath(&path)) {
-    return false;
-  }
-
-#if USE_FIREFOX_PROFILES_INI
-  // [Profile0]
-  // Name=default
-  // IsRelative=1
-  // Path=Profiles/2de53ejb.default
-  // Default=1
-
-  // Note: we are looking for the first entry with "Default=1", or the last
-  // entry in the file
-  path.SetFilename("profiles.ini");
-  FileStream* fs = Filesystem::OpenFile(path, "r");
-  if (!fs) {
-    return false;
-  }
-  Pathname candidate;
-  bool relative = true;
-  std::string line;
-  while (fs->ReadLine(&line) == SR_SUCCESS) {
-    if (line.length() == 0) {
-      continue;
-    }
-    if (line.at(0) == '[') {
-      relative = true;
-      candidate.clear();
-    } else if (line.find("IsRelative=") == 0 &&
-               line.length() >= 12) {
-      // TODO: The initial Linux public launch revealed a fairly
-      // high number of machines where IsRelative= did not have anything after
-      // it. Perhaps that is legal profiles.ini syntax?
-      relative = (line.at(11) != '0');
-    } else if (line.find("Path=") == 0 &&
-               line.length() >= 6) {
-      if (relative) {
-        candidate = path;
-      } else {
-        candidate.clear();
-      }
-      candidate.AppendFolder(line.substr(5));
-    } else if (line.find("Default=") == 0 &&
-               line.length() >= 9) {
-      if ((line.at(8) != '0') && !candidate.empty()) {
-        break;
-      }
-    }
-  }
-  fs->Close();
-  if (candidate.empty()) {
-    return false;
-  }
-  profile_path->SetPathname(candidate.pathname());
-
-#else // !USE_FIREFOX_PROFILES_INI
-  path.AppendFolder("Profiles");
-  DirectoryIterator* it = Filesystem::IterateDirectory();
-  it->Iterate(path);
-  std::string extension(".default");
-  while (!EndsWith(it->Name(), extension)) {
-    if (!it->Next()) {
-      return false;
-    }
-  }
-
-  profile_path->SetPathname(path);
-  profile->AppendFolder("Profiles");
-  profile->AppendFolder(it->Name());
-  delete it;
-
-#endif // !USE_FIREFOX_PROFILES_INI
-
-  return true;
-}
-
-bool ReadFirefoxPrefs(const Pathname& filename,
-                      const char * prefix,
-                      StringMap* settings) {
-  FileStream* fs = Filesystem::OpenFile(filename, "r");
-  if (!fs) {
-    LOG(LS_ERROR) << "Failed to open file: " << filename.pathname();
-    return false;
-  }
-
-  std::string line;
-  while (fs->ReadLine(&line) == SR_SUCCESS) {
-    size_t prefix_len = strlen(prefix);
-
-    // Skip blank lines and too long lines.
-    if ((line.length() == 0) || (line.length() > kMaxLineLength)
-        || (line.at(0) == '#') || line.compare(0, 2, "/*") == 0
-        || line.compare(0, 2, " *") == 0) {
-      continue;
-    }
-
-    char buffer[kMaxLineLength];
-    strcpyn(buffer, sizeof(buffer), line.c_str());
-    int nstart = 0, nend = 0, vstart = 0, vend = 0;
-    sscanf(buffer, "user_pref(\"%n%*[^\"]%n\", %n%*[^)]%n);",
-           &nstart, &nend, &vstart, &vend);
-    if (vend > 0) {
-      char* name = buffer + nstart;
-      name[nend - nstart] = 0;
-      if ((vend - vstart >= 2) && (buffer[vstart] == '"')) {
-        vstart += 1;
-        vend -= 1;
-      }
-      char* value = buffer + vstart;
-      value[vend - vstart] = 0;
-      if ((strncmp(name, prefix, prefix_len) == 0) && *value) {
-        settings->Add(name + prefix_len, value);
-      }
-    } else {
-      LOG_F(LS_WARNING) << "Unparsed pref [" << buffer << "]";
-    }
-  }
-  fs->Close();
-  return true;
-}
-
-bool GetFirefoxProxySettings(const char* url, ProxyInfo* proxy) {
-  Url<char> purl(url);
-  Pathname path;
-  bool success = false;
-  if (GetDefaultFirefoxProfile(&path)) {
-    StringMap settings;
-    path.SetFilename("prefs.js");
-    if (ReadFirefoxPrefs(path, "network.proxy.", &settings)) {
-      success = true;
-      proxy->bypass_list =
-          settings.Get("no_proxies_on", "localhost, 127.0.0.1");
-      if (settings.Get("type") == "1") {
-        // User has manually specified a proxy, try to figure out what
-        // type it is.
-        if (ProxyListMatch(purl, proxy->bypass_list.c_str(), ',')) {
-          // Our url is in the list of url's to bypass proxy.
-        } else if (settings.Get("share_proxy_settings") == "true") {
-          proxy->type = PROXY_UNKNOWN;
-          proxy->address.SetIP(settings.Get("http"));
-          proxy->address.SetPort(atoi(settings.Get("http_port").c_str()));
-        } else if (settings.IsSet("socks")) {
-          proxy->type = PROXY_SOCKS5;
-          proxy->address.SetIP(settings.Get("socks"));
-          proxy->address.SetPort(atoi(settings.Get("socks_port").c_str()));
-        } else if (settings.IsSet("ssl")) {
-          proxy->type = PROXY_HTTPS;
-          proxy->address.SetIP(settings.Get("ssl"));
-          proxy->address.SetPort(atoi(settings.Get("ssl_port").c_str()));
-        } else if (settings.IsSet("http")) {
-          proxy->type = PROXY_HTTPS;
-          proxy->address.SetIP(settings.Get("http"));
-          proxy->address.SetPort(atoi(settings.Get("http_port").c_str()));
-        }
-      } else if (settings.Get("type") == "2") {
-        // Browser is configured to get proxy settings from a given url.
-        proxy->autoconfig_url = settings.Get("autoconfig_url").c_str();
-      } else if (settings.Get("type") == "4") {
-        // Browser is configured to auto detect proxy config.
-        proxy->autodetect = true;
-      } else {
-        // No proxy set.
-      }
-    }
-  }
-  return success;
-}
-
-#ifdef WIN32  // Windows specific implementation for reading Internet
-              // Explorer proxy settings.
-
-void LogGetProxyFault() {
-  LOG_GLEM(LERROR, WINHTTP) << "WinHttpGetProxyForUrl faulted!!";
-}
-
-BOOL MyWinHttpGetProxyForUrl(pfnWinHttpGetProxyForUrl pWHGPFU,
-                             HINTERNET hWinHttp, LPCWSTR url,
-                             WINHTTP_AUTOPROXY_OPTIONS *options,
-                             WINHTTP_PROXY_INFO *info) {
-  // WinHttpGetProxyForUrl() can call plugins which can crash.
-  // In the case of McAfee scriptproxy.dll, it does crash in
-  // older versions. Try to catch crashes here and treat as an
-  // error.
-  BOOL success = FALSE;
-
-#if (_HAS_EXCEPTIONS == 0)
-  __try {
-    success = pWHGPFU(hWinHttp, url, options, info);
-  } __except(EXCEPTION_EXECUTE_HANDLER) {
-    // This is a separate function to avoid
-    // Visual C++ error 2712 when compiling with C++ EH
-    LogGetProxyFault();
-  }
-#else
-  success = pWHGPFU(hWinHttp, url, options, info);
-#endif  // (_HAS_EXCEPTIONS == 0)
-
-  return success;
-}
-
-bool IsDefaultBrowserFirefox() {
-  HKEY key;
-  LONG result = RegOpenKeyEx(HKEY_CLASSES_ROOT, L"http\\shell\\open\\command",
-                             0, KEY_READ, &key);
-  if (ERROR_SUCCESS != result)
-    return false;
-
-  wchar_t* value = NULL;
-  DWORD size, type;
-  result = RegQueryValueEx(key, L"", 0, &type, NULL, &size);
-  if (REG_SZ != type) {
-    result = ERROR_ACCESS_DENIED;  // Any error is fine
-  } else if (ERROR_SUCCESS == result) {
-    value = new wchar_t[size+1];
-    BYTE* buffer = reinterpret_cast<BYTE*>(value);
-    result = RegQueryValueEx(key, L"", 0, &type, buffer, &size);
-  }
-  RegCloseKey(key);
-
-  bool success = false;
-  if (ERROR_SUCCESS == result) {
-    value[size] = L'\0';
-    for (size_t i = 0; i < size; ++i) {
-      value[i] = tolowercase(value[i]);
-    }
-    success = (NULL != strstr(value, L"firefox.exe"));
-  }
-  delete [] value;
-  return success;
-}
-
-bool GetWinHttpProxySettings(const char* url, ProxyInfo* proxy) {
-  HMODULE winhttp_handle = LoadLibrary(L"winhttp.dll");
-  if (winhttp_handle == NULL) {
-    LOG(LS_ERROR) << "Failed to load winhttp.dll.";
-    return false;
-  }
-  WINHTTP_CURRENT_USER_IE_PROXY_CONFIG iecfg;
-  memset(&iecfg, 0, sizeof(iecfg));
-  Url<char> purl(url);
-  pfnWinHttpGetIEProxyConfig pWHGIEPC =
-      reinterpret_cast<pfnWinHttpGetIEProxyConfig>(
-          GetProcAddress(winhttp_handle,
-                         "WinHttpGetIEProxyConfigForCurrentUser"));
-  bool success = false;
-  if (pWHGIEPC && pWHGIEPC(&iecfg)) {
-    // We were read proxy config successfully.
-    success = true;
-    if (iecfg.fAutoDetect) {
-      proxy->autodetect = true;
-    }
-    if (iecfg.lpszAutoConfigUrl) {
-      proxy->autoconfig_url = ToUtf8(iecfg.lpszAutoConfigUrl);
-      GlobalFree(iecfg.lpszAutoConfigUrl);
-    }
-    if (iecfg.lpszProxyBypass) {
-      proxy->bypass_list = ToUtf8(iecfg.lpszProxyBypass);
-      GlobalFree(iecfg.lpszProxyBypass);
-    }
-    if (iecfg.lpszProxy) {
-      if (!ProxyListMatch(purl, proxy->bypass_list, ';')) {
-        ParseProxy(ToUtf8(iecfg.lpszProxy), proxy);
-      }
-      GlobalFree(iecfg.lpszProxy);
-    }
-  }
-  FreeLibrary(winhttp_handle);
-  return success;
-}
-
-// Uses the WinHTTP API to auto detect proxy for the given url. Firefox and IE
-// have slightly different option dialogs for proxy settings. In Firefox,
-// either a location of a proxy configuration file can be specified or auto
-// detection can be selected. In IE theese two options can be independently
-// selected. For the case where both options are selected (only IE) we try to
-// fetch the config file first, and if that fails we'll perform an auto
-// detection.
-//
-// Returns true if we successfully performed an auto detection not depending on
-// whether we found a proxy or not. Returns false on error.
-bool WinHttpAutoDetectProxyForUrl(const char* agent, const char* url,
-                                  ProxyInfo* proxy) {
-  Url<char> purl(url);
-  bool success = true;
-  HMODULE winhttp_handle = LoadLibrary(L"winhttp.dll");
-  if (winhttp_handle == NULL) {
-    LOG(LS_ERROR) << "Failed to load winhttp.dll.";
-    return false;
-  }
-  pfnWinHttpOpen pWHO =
-      reinterpret_cast<pfnWinHttpOpen>(GetProcAddress(winhttp_handle,
-                                                      "WinHttpOpen"));
-  pfnWinHttpCloseHandle pWHCH =
-      reinterpret_cast<pfnWinHttpCloseHandle>(
-          GetProcAddress(winhttp_handle, "WinHttpCloseHandle"));
-  pfnWinHttpGetProxyForUrl pWHGPFU =
-      reinterpret_cast<pfnWinHttpGetProxyForUrl>(
-          GetProcAddress(winhttp_handle, "WinHttpGetProxyForUrl"));
-  if (pWHO && pWHCH && pWHGPFU) {
-    if (HINTERNET hWinHttp = pWHO(ToUtf16(agent).c_str(),
-                                  WINHTTP_ACCESS_TYPE_NO_PROXY,
-                                  WINHTTP_NO_PROXY_NAME,
-                                  WINHTTP_NO_PROXY_BYPASS,
-                                  0)) {
-      BOOL result = FALSE;
-      WINHTTP_PROXY_INFO info;
-      memset(&info, 0, sizeof(info));
-      if (proxy->autodetect) {
-        // Use DHCP and DNS to try to find any proxy to use.
-        WINHTTP_AUTOPROXY_OPTIONS options;
-        memset(&options, 0, sizeof(options));
-        options.fAutoLogonIfChallenged = TRUE;
-
-        options.dwFlags |= WINHTTP_AUTOPROXY_AUTO_DETECT;
-        options.dwAutoDetectFlags |= WINHTTP_AUTO_DETECT_TYPE_DHCP
-            | WINHTTP_AUTO_DETECT_TYPE_DNS_A;
-        result = MyWinHttpGetProxyForUrl(
-            pWHGPFU, hWinHttp, ToUtf16(url).c_str(), &options, &info);
-      }
-      if (!result && !proxy->autoconfig_url.empty()) {
-        // We have the location of a proxy config file. Download it and
-        // execute it to find proxy settings for our url.
-        WINHTTP_AUTOPROXY_OPTIONS options;
-        memset(&options, 0, sizeof(options));
-        memset(&info, 0, sizeof(info));
-        options.fAutoLogonIfChallenged = TRUE;
-
-        std::wstring autoconfig_url16((ToUtf16)(proxy->autoconfig_url));
-        options.dwFlags |= WINHTTP_AUTOPROXY_CONFIG_URL;
-        options.lpszAutoConfigUrl = autoconfig_url16.c_str();
-
-        result = MyWinHttpGetProxyForUrl(
-            pWHGPFU, hWinHttp, ToUtf16(url).c_str(), &options, &info);
-      }
-      if (result) {
-        // Either the given auto config url was valid or auto
-        // detection found a proxy on this network.
-        if (info.lpszProxy) {
-          // TODO: Does this bypass list differ from the list
-          // retreived from GetWinHttpProxySettings earlier?
-          if (info.lpszProxyBypass) {
-            proxy->bypass_list = ToUtf8(info.lpszProxyBypass);
-            GlobalFree(info.lpszProxyBypass);
-          } else {
-            proxy->bypass_list.clear();
-          }
-          if (!ProxyListMatch(purl, proxy->bypass_list, ';')) {
-            // Found proxy for this URL. If parsing the address turns
-            // out ok then we are successful.
-            success = ParseProxy(ToUtf8(info.lpszProxy), proxy);
-          }
-          GlobalFree(info.lpszProxy);
-        }
-      } else {
-        // We could not find any proxy for this url.
-        LOG(LS_INFO) << "No proxy detected for " << url;
-      }
-      pWHCH(hWinHttp);
-    }
-  } else {
-    LOG(LS_ERROR) << "Failed loading WinHTTP functions.";
-    success = false;
-  }
-  FreeLibrary(winhttp_handle);
-  return success;
-}
-
-#if 0  // Below functions currently not used.
-
-bool GetJsProxySettings(const char* url, ProxyInfo* proxy) {
-  Url<char> purl(url);
-  bool success = false;
-
-  if (HMODULE hModJS = LoadLibrary(_T("jsproxy.dll"))) {
-    pfnInternetGetProxyInfo pIGPI =
-        reinterpret_cast<pfnInternetGetProxyInfo>(
-            GetProcAddress(hModJS, "InternetGetProxyInfo"));
-    if (pIGPI) {
-      char proxy[256], host[256];
-      memset(proxy, 0, sizeof(proxy));
-      char * ptr = proxy;
-      DWORD proxylen = sizeof(proxy);
-      std::string surl = Utf8String(url);
-      DWORD hostlen = _snprintf(host, sizeof(host), "http%s://%S",
-                                purl.secure() ? "s" : "", purl.server());
-      if (pIGPI(surl.data(), surl.size(), host, hostlen, &ptr, &proxylen)) {
-        LOG(INFO) << "Proxy: " << proxy;
-      } else {
-        LOG_GLE(INFO) << "InternetGetProxyInfo";
-      }
-    }
-    FreeLibrary(hModJS);
-  }
-  return success;
-}
-
-bool GetWmProxySettings(const char* url, ProxyInfo* proxy) {
-  Url<char> purl(url);
-  bool success = false;
-
-  INSNetSourceCreator * nsc = 0;
-  HRESULT hr = CoCreateInstance(CLSID_ClientNetManager, 0, CLSCTX_ALL,
-                                IID_INSNetSourceCreator, (LPVOID *) &nsc);
-  if (SUCCEEDED(hr)) {
-    if (SUCCEEDED(hr = nsc->Initialize())) {
-      VARIANT dispatch;
-      VariantInit(&dispatch);
-      if (SUCCEEDED(hr = nsc->GetNetSourceAdminInterface(L"http", &dispatch))) {
-        IWMSInternalAdminNetSource * ians = 0;
-        if (SUCCEEDED(hr = dispatch.pdispVal->QueryInterface(
-                IID_IWMSInternalAdminNetSource, (LPVOID *) &ians))) {
-          _bstr_t host(purl.server());
-          BSTR proxy = 0;
-          BOOL bProxyEnabled = FALSE;
-          DWORD port, context = 0;
-          if (SUCCEEDED(hr = ians->FindProxyForURL(
-                  L"http", host, &bProxyEnabled, &proxy, &port, &context))) {
-            success = true;
-            if (bProxyEnabled) {
-              _bstr_t sproxy = proxy;
-              proxy->ptype = PT_HTTPS;
-              proxy->host = sproxy;
-              proxy->port = port;
-            }
-          }
-          SysFreeString(proxy);
-          if (FAILED(hr = ians->ShutdownProxyContext(context))) {
-            LOG(LS_INFO) << "IWMSInternalAdminNetSource::ShutdownProxyContext"
-                         << "failed: " << hr;
-          }
-          ians->Release();
-        }
-      }
-      VariantClear(&dispatch);
-      if (FAILED(hr = nsc->Shutdown())) {
-        LOG(LS_INFO) << "INSNetSourceCreator::Shutdown failed: " << hr;
-      }
-    }
-    nsc->Release();
-  }
-  return success;
-}
-
-bool GetIePerConnectionProxySettings(const char* url, ProxyInfo* proxy) {
-  Url<char> purl(url);
-  bool success = false;
-
-  INTERNET_PER_CONN_OPTION_LIST list;
-  INTERNET_PER_CONN_OPTION options[3];
-  memset(&list, 0, sizeof(list));
-  memset(&options, 0, sizeof(options));
-
-  list.dwSize = sizeof(list);
-  list.dwOptionCount = 3;
-  list.pOptions = options;
-  options[0].dwOption = INTERNET_PER_CONN_FLAGS;
-  options[1].dwOption = INTERNET_PER_CONN_PROXY_SERVER;
-  options[2].dwOption = INTERNET_PER_CONN_PROXY_BYPASS;
-  DWORD dwSize = sizeof(list);
-
-  if (!InternetQueryOption(0, INTERNET_OPTION_PER_CONNECTION_OPTION, &list,
-                           &dwSize)) {
-    LOG(LS_INFO) << "InternetQueryOption failed: " << GetLastError();
-  } else if ((options[0].Value.dwValue & PROXY_TYPE_PROXY) != 0) {
-    success = true;
-    if (!ProxyListMatch(purl, nonnull(options[2].Value.pszValue), _T(';'))) {
-      ParseProxy(nonnull(options[1].Value.pszValue), proxy);
-    }
-  } else if ((options[0].Value.dwValue & PROXY_TYPE_DIRECT) != 0) {
-    success = true;
-  } else {
-    LOG(LS_INFO) << "unknown internet access type: "
-                 << options[0].Value.dwValue;
-  }
-  if (options[1].Value.pszValue) {
-    GlobalFree(options[1].Value.pszValue);
-  }
-  if (options[2].Value.pszValue) {
-    GlobalFree(options[2].Value.pszValue);
-  }
-  return success;
-}
-
-#endif  // 0
-
-// Uses the InternetQueryOption function to retrieve proxy settings
-// from the registry. This will only give us the 'static' settings,
-// ie, not any information about auto config etc.
-bool GetIeLanProxySettings(const char* url, ProxyInfo* proxy) {
-  Url<char> purl(url);
-  bool success = false;
-
-  wchar_t buffer[1024];
-  memset(buffer, 0, sizeof(buffer));
-  INTERNET_PROXY_INFO * info = reinterpret_cast<INTERNET_PROXY_INFO *>(buffer);
-  DWORD dwSize = sizeof(buffer);
-
-  if (!InternetQueryOption(0, INTERNET_OPTION_PROXY, info, &dwSize)) {
-    LOG(LS_INFO) << "InternetQueryOption failed: " << GetLastError();
-  } else if (info->dwAccessType == INTERNET_OPEN_TYPE_DIRECT) {
-    success = true;
-  } else if (info->dwAccessType == INTERNET_OPEN_TYPE_PROXY) {
-    success = true;
-    if (!ProxyListMatch(purl, nonnull(reinterpret_cast<const char*>(
-            info->lpszProxyBypass)), ' ')) {
-      ParseProxy(nonnull(reinterpret_cast<const char*>(info->lpszProxy)),
-                 proxy);
-    }
-  } else {
-    LOG(LS_INFO) << "unknown internet access type: " << info->dwAccessType;
-  }
-  return success;
-}
-
-bool GetIeProxySettings(const char* agent, const char* url, ProxyInfo* proxy) {
-  bool success = GetWinHttpProxySettings(url, proxy);
-  if (!success) {
-    // TODO: Should always call this if no proxy were detected by
-    // GetWinHttpProxySettings?
-    // WinHttp failed. Try using the InternetOptionQuery method instead.
-    return GetIeLanProxySettings(url, proxy);
-  }
-  return true;
-}
-
-#endif  // WIN32
-
-#ifdef OSX  // OSX specific implementation for reading system wide
-            // proxy settings.
-
-bool p_getProxyInfoForTypeFromDictWithKeys(ProxyInfo* proxy,
-                                           ProxyType type,
-                                           const CFDictionaryRef proxyDict,
-                                           const CFStringRef enabledKey,
-                                           const CFStringRef hostKey,
-                                           const CFStringRef portKey) {
-  // whether or not we set up the proxy info.
-  bool result = false;
-
-  // we use this as a scratch variable for determining if operations
-  // succeeded.
-  bool converted = false;
-
-  // the data we need to construct the SocketAddress for the proxy.
-  std::string hostname;
-  int port;
-
-  if ((proxyDict != NULL) &&
-      (CFGetTypeID(proxyDict) == CFDictionaryGetTypeID())) {
-    // CoreFoundation stuff that we'll have to get from
-    // the dictionaries and interpret or convert into more usable formats.
-    CFNumberRef enabledCFNum;
-    CFNumberRef portCFNum;
-    CFStringRef hostCFStr;
-
-    enabledCFNum = (CFNumberRef)CFDictionaryGetValue(proxyDict, enabledKey);
-
-    if (p_isCFNumberTrue(enabledCFNum)) {
-      // let's see if we can get the address and port.
-      hostCFStr = (CFStringRef)CFDictionaryGetValue(proxyDict, hostKey);
-      converted = p_convertHostCFStringRefToCPPString(hostCFStr, hostname);
-      if (converted) {
-        portCFNum = (CFNumberRef)CFDictionaryGetValue(proxyDict, portKey);
-        converted = p_convertCFNumberToInt(portCFNum, &port);
-        if (converted) {
-          // we have something enabled, with a hostname and a port.
-          // That's sufficient to set up the proxy info.
-          proxy->type = type;
-          proxy->address.SetIP(hostname);
-          proxy->address.SetPort(port);
-          result = true;
-        }
-      }
-    }
-  }
-
-  return result;
-}
-
-// Looks for proxy information in the given dictionary,
-// return true if it found sufficient information to define one,
-// false otherwise.  This is guaranteed to not change the values in proxy
-// unless a full-fledged proxy description was discovered in the dictionary.
-// However, at the present time this does not support username or password.
-// Checks first for a SOCKS proxy, then for HTTPS, then HTTP.
-bool GetMacProxySettingsFromDictionary(ProxyInfo* proxy,
-                                       const CFDictionaryRef proxyDict) {
-  // the function result.
-  bool gotProxy = false;
-
-
-  // first we see if there's a SOCKS proxy in place.
-  gotProxy = p_getProxyInfoForTypeFromDictWithKeys(proxy,
-                                                   PROXY_SOCKS5,
-                                                   proxyDict,
-                                                   kSCPropNetProxiesSOCKSEnable,
-                                                   kSCPropNetProxiesSOCKSProxy,
-                                                   kSCPropNetProxiesSOCKSPort);
-
-  if (!gotProxy) {
-    // okay, no SOCKS proxy, let's look for https.
-    gotProxy = p_getProxyInfoForTypeFromDictWithKeys(proxy,
-                                               PROXY_HTTPS,
-                                               proxyDict,
-                                               kSCPropNetProxiesHTTPSEnable,
-                                               kSCPropNetProxiesHTTPSProxy,
-                                               kSCPropNetProxiesHTTPSPort);
-    if (!gotProxy) {
-      // Finally, try HTTP proxy. Note that flute doesn't
-      // differentiate between HTTPS and HTTP, hence we are using the
-      // same flute type here, ie. PROXY_HTTPS.
-      gotProxy = p_getProxyInfoForTypeFromDictWithKeys(
-          proxy, PROXY_HTTPS, proxyDict, kSCPropNetProxiesHTTPEnable,
-          kSCPropNetProxiesHTTPProxy, kSCPropNetProxiesHTTPPort);
-    }
-  }
-  return gotProxy;
-}
-
-bool p_putPasswordInProxyInfo(ProxyInfo* proxy) {
-  bool result = true;  // by default we assume we're good.
-  // for all we know there isn't any password.  We'll set to false
-  // if we find a problem.
-
-  // Ask the keychain for an internet password search for the given protocol.
-  OSStatus oss = 0;
-  SecKeychainAttributeList attrList;
-  attrList.count = 3;
-  SecKeychainAttribute attributes[3];
-  attrList.attr = attributes;
-
-  attributes[0].tag = kSecProtocolItemAttr;
-  attributes[0].length = sizeof(SecProtocolType);
-  SecProtocolType protocol;
-  switch (proxy->type) {
-    case PROXY_HTTPS :
-      protocol = kSecProtocolTypeHTTPS;
-      break;
-    case PROXY_SOCKS5 :
-      protocol = kSecProtocolTypeSOCKS;
-      break;
-    default :
-      LOG(LS_ERROR) << "asked for proxy password for unknown proxy type.";
-      result = false;
-      break;
-  }
-  attributes[0].data = &protocol;
-
-  UInt32 port = proxy->address.port();
-  attributes[1].tag = kSecPortItemAttr;
-  attributes[1].length = sizeof(UInt32);
-  attributes[1].data = &port;
-
-  std::string ip = proxy->address.IPAsString();
-  attributes[2].tag = kSecServerItemAttr;
-  attributes[2].length = ip.length();
-  attributes[2].data = const_cast<char*>(ip.c_str());
-
-  if (result) {
-    LOG(LS_INFO) << "trying to get proxy username/password";
-    SecKeychainSearchRef sref;
-    oss = SecKeychainSearchCreateFromAttributes(NULL,
-                                                kSecInternetPasswordItemClass,
-                                                &attrList, &sref);
-    if (0 == oss) {
-      LOG(LS_INFO) << "SecKeychainSearchCreateFromAttributes was good";
-      // Get the first item, if there is one.
-      SecKeychainItemRef iref;
-      oss = SecKeychainSearchCopyNext(sref, &iref);
-      if (0 == oss) {
-        LOG(LS_INFO) << "...looks like we have the username/password data";
-        // If there is, get the username and the password.
-
-        SecKeychainAttributeInfo attribsToGet;
-        attribsToGet.count = 1;
-        UInt32 tag = kSecAccountItemAttr;
-        UInt32 format = CSSM_DB_ATTRIBUTE_FORMAT_STRING;
-        void *data;
-        UInt32 length;
-        SecKeychainAttributeList *localList;
-
-        attribsToGet.tag = &tag;
-        attribsToGet.format = &format;
-        OSStatus copyres = SecKeychainItemCopyAttributesAndData(iref,
-                                                                &attribsToGet,
-                                                                NULL,
-                                                                &localList,
-                                                                &length,
-                                                                &data);
-        if (0 == copyres) {
-          LOG(LS_INFO) << "...and we can pull it out.";
-          // now, we know from experimentation (sadly not from docs)
-          // that the username is in the local attribute list,
-          // and the password in the data,
-          // both without null termination but with info on their length.
-          // grab the password from the data.
-          std::string password;
-          password.append(static_cast<const char*>(data), length);
-
-          // make the password into a CryptString
-          // huh, at the time of writing, you can't.
-          // so we'll skip that for now and come back to it later.
-
-          // now put the username in the proxy.
-          if (1 <= localList->attr->length) {
-            proxy->username.append(
-                static_cast<const char*>(localList->attr->data),
-                localList->attr->length);
-            LOG(LS_INFO) << "username is " << proxy->username;
-          } else {
-            LOG(LS_ERROR) << "got keychain entry with no username";
-            result = false;
-          }
-        } else {
-          LOG(LS_ERROR) << "couldn't copy info from keychain.";
-          result = false;
-        }
-        SecKeychainItemFreeAttributesAndData(localList, data);
-      } else if (errSecItemNotFound == oss) {
-        LOG(LS_INFO) << "...username/password info not found";
-      } else {
-        // oooh, neither 0 nor itemNotFound.
-        LOG(LS_ERROR) << "Couldn't get keychain information, error code" << oss;
-        result = false;
-      }
-    } else if (errSecItemNotFound == oss) {  // noop
-    } else {
-      // oooh, neither 0 nor itemNotFound.
-      LOG(LS_ERROR) << "Couldn't get keychain information, error code" << oss;
-      result = false;
-    }
-  }
-
-  return result;
-}
-
-bool GetMacProxySettings(ProxyInfo* proxy) {
-  // based on the Apple Technical Q&A QA1234
-  // http://developer.apple.com/qa/qa2001/qa1234.html
-  CFDictionaryRef proxyDict = SCDynamicStoreCopyProxies(NULL);
-  bool result = false;
-
-  if (proxyDict != NULL) {
-    // sending it off to another function makes it easier to unit test
-    // since we can make our own dictionary to hand to that function.
-    result = GetMacProxySettingsFromDictionary(proxy, proxyDict);
-
-    if (result) {
-      result = p_putPasswordInProxyInfo(proxy);
-    }
-
-    // We created the dictionary with something that had the
-    // word 'copy' in it, so we have to release it, according
-    // to the Carbon memory management standards.
-    CFRelease(proxyDict);
-  } else {
-    LOG(LS_ERROR) << "SCDynamicStoreCopyProxies failed";
-  }
-
-  return result;
-}
-#endif  // OSX
-
-bool AutoDetectProxySettings(const char* agent, const char* url,
-                             ProxyInfo* proxy) {
-#ifdef WIN32
-  return WinHttpAutoDetectProxyForUrl(agent, url, proxy);
-#else
-  LOG(LS_WARNING) << "Proxy auto-detection not implemented for this platform";
-  return false;
-#endif
-}
-
-bool GetSystemDefaultProxySettings(const char* agent, const char* url,
-                                   ProxyInfo* proxy) {
-#ifdef WIN32
-  return GetIeProxySettings(agent, url, proxy);
-#elif OSX
-  return GetMacProxySettings(proxy);
-#else
-  // TODO: Get System settings if browser is not firefox.
-  return GetFirefoxProxySettings(url, proxy);
-#endif
-}
-
-bool GetProxySettingsForUrl(const char* agent, const char* url,
-                            ProxyInfo& proxy, bool long_operation) {
-  UserAgent a = GetAgent(agent);
-  bool result;
-  switch (a) {
-    case UA_FIREFOX: {
-      result = GetFirefoxProxySettings(url, &proxy);
-      break;
-    }
-#ifdef WIN32
-    case UA_INTERNETEXPLORER:
-      result = GetIeProxySettings(agent, url, &proxy);
-      break;
-    case UA_UNKNOWN:
-      // Agent not defined, check default browser.
-      if (IsDefaultBrowserFirefox()) {
-        result = GetFirefoxProxySettings(url, &proxy);
-      } else {
-        result = GetIeProxySettings(agent, url, &proxy);
-      }
-      break;
-#endif  // WIN32
-    default:
-      result = GetSystemDefaultProxySettings(agent, url, &proxy);
-      break;
-  }
-
-  // TODO: Consider using the 'long_operation' parameter to
-  // decide whether to do the auto detection.
-  if (result && (proxy.autodetect ||
-                 !proxy.autoconfig_url.empty())) {
-    // Use WinHTTP to auto detect proxy for us.
-    result = AutoDetectProxySettings(agent, url, &proxy);
-    if (!result) {
-      // Either auto detection is not supported or we simply didn't
-      // find any proxy, reset type.
-      proxy.type = talk_base::PROXY_NONE;
-    }
-  }
-  return result;
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/proxydetect.h b/third_party/libjingle/source/talk/base/proxydetect.h
deleted file mode 100644
index 36ee672..0000000
--- a/third_party/libjingle/source/talk/base/proxydetect.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * libjingle
- * Copyright 2007, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _PROXYDETECT_H_
-#define _PROXYDETECT_H_
-
-#include "talk/base/proxyinfo.h"
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-namespace talk_base {
-// Auto-detect the proxy server.  Returns true if a proxy is configured,
-// although hostname may be empty if the proxy is not required for
-// the given URL.
-
-bool GetProxySettingsForUrl(const char* agent, const char* url,
-                            talk_base::ProxyInfo& proxy,
-                            bool long_operation = false);
-
-}  // namespace talk_base
-
-#endif  // _PROXYDETECT_H_
diff --git a/third_party/libjingle/source/talk/base/proxydetect_unittest.cc b/third_party/libjingle/source/talk/base/proxydetect_unittest.cc
deleted file mode 100644
index 4855650..0000000
--- a/third_party/libjingle/source/talk/base/proxydetect_unittest.cc
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * libjingle
- * Copyright 2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string>
-
-#include "talk/base/fileutils_mock.h"
-#include "talk/base/proxydetect.h"
-
-namespace talk_base {
-
-static const std::string kFirefoxProfilesIni =
-  "[Profile0]\n"
-  "Name=default\n"
-  "IsRelative=1\n"
-  "Path=Profiles/2de53ejb.default\n"
-  "Default=1\n";
-
-static const std::string kFirefoxHeader =
-  "# Mozilla User Preferences\n"
-  "\n"
-  "/* Some Comments\n"
-  "*\n"
-  "*/\n"
-  "\n";
-
-static const std::string kFirefoxCorruptHeader =
-  "iuahueqe32164";
-
-static const std::string kProxyAddress = "proxy.net.com";
-static const int kProxyPort = 9999;
-
-// Mocking out platform specific path to firefox prefs file.
-class FirefoxPrefsFileSystem : public FakeFileSystem {
- public:
-  explicit FirefoxPrefsFileSystem(const std::vector<File>& all_files) :
-      FakeFileSystem(all_files) {
-  }
-  virtual FileStream* OpenFile(const Pathname& filename,
-                               const std::string& mode) {
-    // TODO: We could have a platform dependent check of paths here.
-    std::string name = filename.basename();
-    name.append(filename.extension());
-    EXPECT_TRUE(name.compare("prefs.js") == 0 ||
-                name.compare("profiles.ini") == 0);
-    FileStream* stream = FakeFileSystem::OpenFile(name, mode);
-    return stream;
-  }
-};
-
-class ProxyDetectTest : public testing::Test {
-};
-
-bool GetProxyInfo(const std::string prefs, ProxyInfo* info) {
-  std::vector<talk_base::FakeFileSystem::File> files;
-  files.push_back(talk_base::FakeFileSystem::File("profiles.ini",
-                                                  kFirefoxProfilesIni));
-  files.push_back(talk_base::FakeFileSystem::File("prefs.js", prefs));
-  talk_base::FilesystemScope fs(new talk_base::FirefoxPrefsFileSystem(files));
-  return GetProxySettingsForUrl("Firefox", "www.google.com", *info, false);
-}
-
-// Verifies that an empty Firefox prefs file results in no proxy detected.
-TEST_F(ProxyDetectTest, DISABLED_TestFirefoxEmptyPrefs) {
-  ProxyInfo proxy_info;
-  EXPECT_TRUE(GetProxyInfo(kFirefoxHeader, &proxy_info));
-  EXPECT_EQ(PROXY_NONE, proxy_info.type);
-}
-
-// Verifies that corrupted prefs file results in no proxy detected.
-TEST_F(ProxyDetectTest, DISABLED_TestFirefoxCorruptedPrefs) {
-  ProxyInfo proxy_info;
-  EXPECT_TRUE(GetProxyInfo(kFirefoxCorruptHeader, &proxy_info));
-  EXPECT_EQ(PROXY_NONE, proxy_info.type);
-}
-
-// Verifies that SOCKS5 proxy is detected if configured. SOCKS uses a
-// handshake protocol to inform the proxy software about the
-// connection that the client is trying to make and may be used for
-// any form of TCP or UDP socket connection.
-TEST_F(ProxyDetectTest, DISABLED_TestFirefoxProxySocks) {
-  ProxyInfo proxy_info;
-  SocketAddress proxy_address("proxy.socks.com", 6666);
-  std::string prefs(kFirefoxHeader);
-  prefs.append("user_pref(\"network.proxy.socks\", \"proxy.socks.com\");\n");
-  prefs.append("user_pref(\"network.proxy.socks_port\", 6666);\n");
-  prefs.append("user_pref(\"network.proxy.type\", 1);\n");
-
-  EXPECT_TRUE(GetProxyInfo(prefs, &proxy_info));
-
-  EXPECT_EQ(PROXY_SOCKS5, proxy_info.type);
-  EXPECT_EQ(proxy_address, proxy_info.address);
-}
-
-// Verified that SSL proxy is detected if configured. SSL proxy is an
-// extention of a HTTP proxy to support secure connections.
-TEST_F(ProxyDetectTest, DISABLED_TestFirefoxProxySsl) {
-  ProxyInfo proxy_info;
-  SocketAddress proxy_address("proxy.ssl.com", 7777);
-  std::string prefs(kFirefoxHeader);
-
-  prefs.append("user_pref(\"network.proxy.ssl\", \"proxy.ssl.com\");\n");
-  prefs.append("user_pref(\"network.proxy.ssl_port\", 7777);\n");
-  prefs.append("user_pref(\"network.proxy.type\", 1);\n");
-
-  EXPECT_TRUE(GetProxyInfo(prefs, &proxy_info));
-
-  EXPECT_EQ(PROXY_HTTPS, proxy_info.type);
-  EXPECT_EQ(proxy_address, proxy_info.address);
-}
-
-// Verifies that a HTTP proxy is detected if configured.
-TEST_F(ProxyDetectTest, DISABLED_TestFirefoxProxyHttp) {
-  ProxyInfo proxy_info;
-  SocketAddress proxy_address("proxy.http.com", 8888);
-  std::string prefs(kFirefoxHeader);
-
-  prefs.append("user_pref(\"network.proxy.http\", \"proxy.http.com\");\n");
-  prefs.append("user_pref(\"network.proxy.http_port\", 8888);\n");
-  prefs.append("user_pref(\"network.proxy.type\", 1);\n");
-
-  EXPECT_TRUE(GetProxyInfo(prefs, &proxy_info));
-
-  EXPECT_EQ(PROXY_HTTPS, proxy_info.type);
-  EXPECT_EQ(proxy_address, proxy_info.address);
-}
-
-// Verifies detection of automatic proxy detection.
-TEST_F(ProxyDetectTest, DISABLED_TestFirefoxProxyAuto) {
-  ProxyInfo proxy_info;
-  std::string prefs(kFirefoxHeader);
-
-  prefs.append("user_pref(\"network.proxy.type\", 4);\n");
-
-  EXPECT_TRUE(GetProxyInfo(prefs, &proxy_info));
-
-  EXPECT_EQ(PROXY_NONE, proxy_info.type);
-  EXPECT_TRUE(proxy_info.autodetect);
-  EXPECT_TRUE(proxy_info.autoconfig_url.empty());
-}
-
-// Verifies detection of automatic proxy detection using a static url
-// to config file.
-TEST_F(ProxyDetectTest, DISABLED_TestFirefoxProxyAutoUrl) {
-  ProxyInfo proxy_info;
-  std::string prefs(kFirefoxHeader);
-
-  prefs.append(
-      "user_pref(\"network.proxy.autoconfig_url\", \"http://a/b.pac\");\n");
-  prefs.append("user_pref(\"network.proxy.type\", 2);\n");
-
-  EXPECT_TRUE(GetProxyInfo(prefs, &proxy_info));
-
-  EXPECT_FALSE(proxy_info.autodetect);
-  EXPECT_EQ(PROXY_NONE, proxy_info.type);
-  EXPECT_EQ(0, proxy_info.autoconfig_url.compare("http://a/b.pac"));
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/proxyinfo.cc b/third_party/libjingle/source/talk/base/proxyinfo.cc
deleted file mode 100644
index 1d9c588..0000000
--- a/third_party/libjingle/source/talk/base/proxyinfo.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/proxyinfo.h"
-
-namespace talk_base {
-
-const char * ProxyToString(ProxyType proxy) {
-  const char * const PROXY_NAMES[] = { "none", "https", "socks5", "unknown" };
-  return PROXY_NAMES[proxy];
-}
-
-} // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/proxyinfo.h b/third_party/libjingle/source/talk/base/proxyinfo.h
deleted file mode 100644
index 9e28f1a..0000000
--- a/third_party/libjingle/source/talk/base/proxyinfo.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_PROXYINFO_H__
-#define TALK_BASE_PROXYINFO_H__
-
-#include <string>
-#include "talk/base/socketaddress.h"
-#include "talk/base/cryptstring.h"
-
-namespace talk_base {
-
-enum ProxyType {
-  PROXY_NONE,
-  PROXY_HTTPS,
-  PROXY_SOCKS5,
-  PROXY_UNKNOWN
-};
-const char * ProxyToString(ProxyType proxy);
-
-struct ProxyInfo {
-  ProxyType type;
-  SocketAddress address;
-  std::string autoconfig_url;
-  bool autodetect;
-  std::string bypass_list;
-  std::string username;
-  CryptString password;
-
-  ProxyInfo() : type(PROXY_NONE), autodetect(false) { }
-};
-
-} // namespace talk_base
-
-#endif // TALK_BASE_PROXYINFO_H__
diff --git a/third_party/libjingle/source/talk/base/proxyserver.cc b/third_party/libjingle/source/talk/base/proxyserver.cc
deleted file mode 100644
index d764fd7..0000000
--- a/third_party/libjingle/source/talk/base/proxyserver.cc
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/proxyserver.h"
-
-#include <algorithm>
-#include "talk/base/socketfactory.h"
-
-namespace talk_base {
-
-// ProxyServer
-ProxyServer::ProxyServer(
-    SocketFactory* int_factory, const SocketAddress& int_addr,
-    SocketFactory* ext_factory, const SocketAddress& ext_ip)
-    : ext_factory_(ext_factory), ext_ip_(ext_ip.ipaddr(), 0),  // strip off port
-      server_socket_(int_factory->CreateAsyncSocket(SOCK_STREAM)) {
-  server_socket_->Bind(int_addr);
-  server_socket_->Listen(5);
-  server_socket_->SignalReadEvent.connect(this, &ProxyServer::OnAcceptEvent);
-}
-
-ProxyServer::~ProxyServer() {
-  for (BindingList::iterator it = bindings_.begin();
-       it != bindings_.end(); ++it) {
-    delete (*it);
-  }
-}
-
-void ProxyServer::OnAcceptEvent(AsyncSocket* socket) {
-  ASSERT(socket == server_socket_.get());
-  AsyncSocket* int_socket = socket->Accept(NULL);
-  AsyncProxyServerSocket* wrapped_socket = WrapSocket(int_socket);
-  AsyncSocket* ext_socket = ext_factory_->CreateAsyncSocket(SOCK_STREAM);
-  ext_socket->Bind(ext_ip_);
-  bindings_.push_back(new ProxyBinding(wrapped_socket, ext_socket));
-}
-
-void ProxyServer::OnBindingDestroyed(ProxyBinding* binding) {
-  BindingList::iterator it =
-      std::find(bindings_.begin(), bindings_.end(), binding);
-  delete (*it);
-  bindings_.erase(it);
-}
-
-// ProxyBinding
-ProxyBinding::ProxyBinding(AsyncProxyServerSocket* int_socket,
-                           AsyncSocket* ext_socket)
-    : int_socket_(int_socket), ext_socket_(ext_socket), connected_(false),
-      out_buffer_(kBufferSize), in_buffer_(kBufferSize) {
-  int_socket_->SignalConnectRequest.connect(this,
-                                            &ProxyBinding::OnConnectRequest);
-  int_socket_->SignalReadEvent.connect(this, &ProxyBinding::OnInternalRead);
-  int_socket_->SignalWriteEvent.connect(this, &ProxyBinding::OnInternalWrite);
-  int_socket_->SignalCloseEvent.connect(this, &ProxyBinding::OnInternalClose);
-  ext_socket_->SignalConnectEvent.connect(this,
-                                          &ProxyBinding::OnExternalConnect);
-  ext_socket_->SignalReadEvent.connect(this, &ProxyBinding::OnExternalRead);
-  ext_socket_->SignalWriteEvent.connect(this, &ProxyBinding::OnExternalWrite);
-  ext_socket_->SignalCloseEvent.connect(this, &ProxyBinding::OnExternalClose);
-}
-
-void ProxyBinding::OnConnectRequest(AsyncProxyServerSocket* socket,
-                                   const SocketAddress& addr) {
-  ASSERT(!connected_);
-  ext_socket_->Connect(addr);
-  // TODO: handle errors here
-}
-
-void ProxyBinding::OnInternalRead(AsyncSocket* socket) {
-  Read(int_socket_.get(), &out_buffer_);
-  Write(ext_socket_.get(), &out_buffer_);
-}
-
-void ProxyBinding::OnInternalWrite(AsyncSocket* socket) {
-  Write(int_socket_.get(), &in_buffer_);
-}
-
-void ProxyBinding::OnInternalClose(AsyncSocket* socket, int err) {
-  Destroy();
-}
-
-void ProxyBinding::OnExternalConnect(AsyncSocket* socket) {
-  connected_ = true;
-  int_socket_->SendConnectResult(0, socket->GetRemoteAddress());
-}
-
-void ProxyBinding::OnExternalRead(AsyncSocket* socket) {
-  Read(ext_socket_.get(), &in_buffer_);
-  Write(int_socket_.get(), &in_buffer_);
-}
-
-void ProxyBinding::OnExternalWrite(AsyncSocket* socket) {
-  Write(ext_socket_.get(), &out_buffer_);
-}
-
-void ProxyBinding::OnExternalClose(AsyncSocket* socket, int err) {
-  if (!connected_) {
-    int_socket_->SendConnectResult(err, SocketAddress());
-  }
-  Destroy();
-}
-
-void ProxyBinding::Read(AsyncSocket* socket, FifoBuffer* buffer) {
-  // Only read if the buffer is empty.
-  size_t size;
-  int read;
-  if (buffer->GetBuffered(&size) && size == 0) {
-    void* p = buffer->GetWriteBuffer(&size);
-    read = socket->Recv(p, size);
-    buffer->ConsumeWriteBuffer(_max(read, 0));
-  }
-}
-
-void ProxyBinding::Write(AsyncSocket* socket, FifoBuffer* buffer) {
-  size_t size;
-  int written;
-  const void* p = buffer->GetReadData(&size);
-  written = socket->Send(p, size);
-  buffer->ConsumeReadData(_max(written, 0));
-}
-
-void ProxyBinding::Destroy() {
-  SignalDestroyed(this);
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/proxyserver.h b/third_party/libjingle/source/talk/base/proxyserver.h
deleted file mode 100644
index 8e1ab6b..0000000
--- a/third_party/libjingle/source/talk/base/proxyserver.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_PROXYSERVER_H_
-#define TALK_BASE_PROXYSERVER_H_
-
-#include <list>
-#include "talk/base/asyncsocket.h"
-#include "talk/base/socketadapters.h"
-#include "talk/base/socketaddress.h"
-#include "talk/base/stream.h"
-
-namespace talk_base {
-
-class SocketFactory;
-
-// ProxyServer is a base class that allows for easy construction of proxy
-// servers. With its helper class ProxyBinding, it contains all the necessary
-// logic for receiving and bridging connections. The specific client-server
-// proxy protocol is implemented by an instance of the AsyncProxyServerSocket
-// class; children of ProxyServer implement WrapSocket appropriately to return
-// the correct protocol handler.
-
-class ProxyBinding : public sigslot::has_slots<> {
- public:
-  ProxyBinding(AsyncProxyServerSocket* in_socket, AsyncSocket* out_socket);
-  sigslot::signal1<ProxyBinding*> SignalDestroyed;
-
- private:
-  void OnConnectRequest(AsyncProxyServerSocket* socket,
-                        const SocketAddress& addr);
-  void OnInternalRead(AsyncSocket* socket);
-  void OnInternalWrite(AsyncSocket* socket);
-  void OnInternalClose(AsyncSocket* socket, int err);
-  void OnExternalConnect(AsyncSocket* socket);
-  void OnExternalRead(AsyncSocket* socket);
-  void OnExternalWrite(AsyncSocket* socket);
-  void OnExternalClose(AsyncSocket* socket, int err);
-
-  static void Read(AsyncSocket* socket, FifoBuffer* buffer);
-  static void Write(AsyncSocket* socket, FifoBuffer* buffer);
-  void Destroy();
-
-  static const int kBufferSize = 4096;
-  scoped_ptr<AsyncProxyServerSocket> int_socket_;
-  scoped_ptr<AsyncSocket> ext_socket_;
-  bool connected_;
-  FifoBuffer out_buffer_;
-  FifoBuffer in_buffer_;
-  DISALLOW_EVIL_CONSTRUCTORS(ProxyBinding);
-};
-
-class ProxyServer : public sigslot::has_slots<> {
- public:
-  ProxyServer(SocketFactory* int_factory, const SocketAddress& int_addr,
-              SocketFactory* ext_factory, const SocketAddress& ext_ip);
-  virtual ~ProxyServer();
-
- protected:
-  void OnAcceptEvent(AsyncSocket* socket);
-  virtual AsyncProxyServerSocket* WrapSocket(AsyncSocket* socket) = 0;
-  void OnBindingDestroyed(ProxyBinding* binding);
-
- private:
-  typedef std::list<ProxyBinding*> BindingList;
-  SocketFactory* ext_factory_;
-  SocketAddress ext_ip_;
-  scoped_ptr<AsyncSocket> server_socket_;
-  BindingList bindings_;
-  DISALLOW_EVIL_CONSTRUCTORS(ProxyServer);
-};
-
-// SocksProxyServer is a simple extension of ProxyServer to implement SOCKS.
-class SocksProxyServer : public ProxyServer {
- public:
-  SocksProxyServer(SocketFactory* int_factory, const SocketAddress& int_addr,
-                   SocketFactory* ext_factory, const SocketAddress& ext_ip)
-      : ProxyServer(int_factory, int_addr, ext_factory, ext_ip) {
-  }
- protected:
-  AsyncProxyServerSocket* WrapSocket(AsyncSocket* socket) {
-    return new AsyncSocksProxyServerSocket(socket);
-  }
-  DISALLOW_EVIL_CONSTRUCTORS(SocksProxyServer);
-};
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_PROXYSERVER_H_
diff --git a/third_party/libjingle/source/talk/base/ratetracker.cc b/third_party/libjingle/source/talk/base/ratetracker.cc
deleted file mode 100644
index 383df93..0000000
--- a/third_party/libjingle/source/talk/base/ratetracker.cc
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/ratetracker.h"
-#include "talk/base/timeutils.h"
-
-namespace talk_base {
-
-RateTracker::RateTracker()
-    : total_units_(0), units_second_(0),
-      last_units_second_time_(static_cast<uint32>(-1)),
-      last_units_second_calc_(0) {
-}
-
-size_t RateTracker::total_units() const {
-  return total_units_;
-}
-
-size_t RateTracker::units_second() {
-  // Snapshot units / second calculator. Determine how many seconds have
-  // elapsed since our last reference point. If over 1 second, establish
-  // a new reference point that is an integer number of seconds since the
-  // last one, and compute the units over that interval.
-  uint32 current_time = Time();
-  if (last_units_second_time_ != static_cast<uint32>(-1)) {
-    int delta = talk_base::TimeDiff(current_time, last_units_second_time_);
-    if (delta >= 1000) {
-      int fraction_time = delta % 1000;
-      int seconds = delta / 1000;
-      int fraction_units =
-          static_cast<int>(total_units_ - last_units_second_calc_) *
-              fraction_time / delta;
-      // Compute "units received during the interval" / "seconds in interval"
-      units_second_ =
-          (total_units_ - last_units_second_calc_ - fraction_units) / seconds;
-      last_units_second_time_ = current_time - fraction_time;
-      last_units_second_calc_ = total_units_ - fraction_units;
-    }
-  }
-  if (last_units_second_time_ == static_cast<uint32>(-1)) {
-    last_units_second_time_ = current_time;
-    last_units_second_calc_ = total_units_;
-  }
-
-  return units_second_;
-}
-
-void RateTracker::Update(size_t units) {
-  total_units_ += units;
-}
-
-uint32 RateTracker::Time() const {
-  return talk_base::Time();
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/ratetracker.h b/third_party/libjingle/source/talk/base/ratetracker.h
deleted file mode 100644
index 28c7bb3..0000000
--- a/third_party/libjingle/source/talk/base/ratetracker.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_RATETRACKER_H_
-#define TALK_BASE_RATETRACKER_H_
-
-#include <stdlib.h>
-#include "talk/base/basictypes.h"
-
-namespace talk_base {
-
-// Computes instantaneous units per second.
-class RateTracker {
- public:
-  RateTracker();
-  virtual ~RateTracker() {}
-
-  size_t total_units() const;
-  size_t units_second();
-  void Update(size_t units);
-
- protected:
-  // overrideable for tests
-  virtual uint32 Time() const;
-
- private:
-  size_t total_units_;
-  size_t units_second_;
-  uint32 last_units_second_time_;
-  size_t last_units_second_calc_;
-};
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_RATETRACKER_H_
diff --git a/third_party/libjingle/source/talk/base/ratetracker_unittest.cc b/third_party/libjingle/source/talk/base/ratetracker_unittest.cc
deleted file mode 100644
index 979d907..0000000
--- a/third_party/libjingle/source/talk/base/ratetracker_unittest.cc
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * libjingle
- * Copyright 2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/gunit.h"
-#include "talk/base/ratetracker.h"
-
-namespace talk_base {
-
-class RateTrackerForTest : public RateTracker {
- public:
-  RateTrackerForTest() : time_(0) {}
-  virtual uint32 Time() const { return time_; }
-  void AdvanceTime(uint32 delta) { time_ += delta; }
-
- private:
-  uint32 time_;
-};
-
-TEST(RateTrackerTest, TestBasics) {
-  RateTrackerForTest tracker;
-  EXPECT_EQ(0U, tracker.total_units());
-  EXPECT_EQ(0U, tracker.units_second());
-
-  // Add a sample.
-  tracker.Update(1234);
-  // Advance the clock by 100 ms.
-  tracker.AdvanceTime(100);
-  // total_units should advance, but units_second should stay 0.
-  EXPECT_EQ(1234U, tracker.total_units());
-  EXPECT_EQ(0U, tracker.units_second());
-
-  // Repeat.
-  tracker.Update(1234);
-  tracker.AdvanceTime(100);
-  EXPECT_EQ(1234U * 2, tracker.total_units());
-  EXPECT_EQ(0U, tracker.units_second());
-
-  // Advance the clock by 800 ms, so we've elapsed a full second.
-  // units_second should now be filled in properly.
-  tracker.AdvanceTime(800);
-  EXPECT_EQ(1234U * 2, tracker.total_units());
-  EXPECT_EQ(1234U * 2, tracker.units_second());
-
-  // Poll the tracker again immediately. The reported rate should stay the same.
-  EXPECT_EQ(1234U * 2, tracker.total_units());
-  EXPECT_EQ(1234U * 2, tracker.units_second());
-
-  // Do nothing and advance by a second. We should drop down to zero.
-  tracker.AdvanceTime(1000);
-  EXPECT_EQ(1234U * 2, tracker.total_units());
-  EXPECT_EQ(0U, tracker.units_second());
-
-  // Send a bunch of data at a constant rate for 5.5 "seconds".
-  // We should report the rate properly.
-  for (int i = 0; i < 5500; i += 100) {
-    tracker.Update(9876U);
-    tracker.AdvanceTime(100);
-  }
-  EXPECT_EQ(9876U * 10, tracker.units_second());
-
-  // Advance the clock by 500 ms. Since we sent nothing over this half-second,
-  // the reported rate should be reduced by half.
-  tracker.AdvanceTime(500);
-  EXPECT_EQ(9876U * 5, tracker.units_second());
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/referencecountedsingletonfactory.h b/third_party/libjingle/source/talk/base/referencecountedsingletonfactory.h
deleted file mode 100644
index 7f90b04..0000000
--- a/third_party/libjingle/source/talk/base/referencecountedsingletonfactory.h
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_REFERENCECOUNTEDSINGLETONFACTORY_H_
-#define TALK_BASE_REFERENCECOUNTEDSINGLETONFACTORY_H_
-
-#include "talk/base/common.h"
-#include "talk/base/criticalsection.h"
-#include "talk/base/logging.h"
-#include "talk/base/scoped_ptr.h"
-
-namespace talk_base {
-
-template <typename Interface> class rcsf_ptr;
-
-// A ReferenceCountedSingletonFactory is an object which owns another object,
-// and doles out the owned object to consumers in a reference-counted manner.
-// Thus, the factory owns at most one object of the desired kind, and
-// hands consumers a special pointer to it, through which they can access it.
-// When the consumers delete the pointer, the reference count goes down,
-// and if the reference count hits zero, the factory can throw the object
-// away.  If a consumer requests the pointer and the factory has none,
-// it can create one on the fly and pass it back.
-template <typename Interface>
-class ReferenceCountedSingletonFactory {
-  friend class rcsf_ptr<Interface>;
- public:
-  ReferenceCountedSingletonFactory() : ref_count_(0) {}
-
-  virtual ~ReferenceCountedSingletonFactory() {
-    ASSERT(ref_count_ == 0);
-  }
-
- protected:
-  // Must be implemented in a sub-class. The sub-class may choose whether or not
-  // to cache the instance across lifetimes by either reset()'ing or not
-  // reset()'ing the scoped_ptr in CleanupInstance().
-  virtual bool SetupInstance() = 0;
-  virtual void CleanupInstance() = 0;
-
-  scoped_ptr<Interface> instance_;
-
- private:
-  Interface* GetInstance() {
-    talk_base::CritScope cs(&crit_);
-    if (ref_count_ == 0) {
-      if (!SetupInstance()) {
-        LOG(LS_VERBOSE) << "Failed to setup instance";
-        return NULL;
-      }
-      ASSERT(instance_.get() != NULL);
-    }
-    ++ref_count_;
-
-    LOG(LS_VERBOSE) << "Number of references: " << ref_count_;
-    return instance_.get();
-  }
-
-  void ReleaseInstance() {
-    talk_base::CritScope cs(&crit_);
-    ASSERT(ref_count_ > 0);
-    ASSERT(instance_.get() != NULL);
-    --ref_count_;
-    LOG(LS_VERBOSE) << "Number of references: " << ref_count_;
-    if (ref_count_ == 0) {
-      CleanupInstance();
-    }
-  }
-
-  CriticalSection crit_;
-  int ref_count_;
-
-  DISALLOW_COPY_AND_ASSIGN(ReferenceCountedSingletonFactory);
-};
-
-template <typename Interface>
-class rcsf_ptr {
- public:
-  // Create a pointer that uses the factory to get the instance.
-  // This is lazy - it won't generate the instance until it is requested.
-  explicit rcsf_ptr(ReferenceCountedSingletonFactory<Interface>* factory)
-      : instance_(NULL),
-        factory_(factory) {
-  }
-
-  ~rcsf_ptr() {
-    release();
-  }
-
-  Interface& operator*() {
-    EnsureAcquired();
-    return *instance_;
-  }
-
-  Interface* operator->() {
-    EnsureAcquired();
-    return instance_;
-  }
-
-  // Gets the pointer, creating the singleton if necessary. May return NULL if
-  // creation failed.
-  Interface* get() {
-    Acquire();
-    return instance_;
-  }
-
-  // Set instance to NULL and tell the factory we aren't using the instance
-  // anymore.
-  void release() {
-    if (instance_) {
-      instance_ = NULL;
-      factory_->ReleaseInstance();
-    }
-  }
-
-  // Lets us know whether instance is valid or not right now.
-  // Even though attempts to use the instance will automatically create it, it
-  // is advisable to check this because creation can fail.
-  bool valid() const {
-    return instance_ != NULL;
-  }
-
-  // Returns the factory that this pointer is using.
-  ReferenceCountedSingletonFactory<Interface>* factory() const {
-    return factory_;
-  }
-
- private:
-  void EnsureAcquired() {
-    Acquire();
-    ASSERT(instance_ != NULL);
-  }
-
-  void Acquire() {
-    // Since we're getting a singleton back, acquire is a noop if instance is
-    // already populated.
-    if (!instance_) {
-      instance_ = factory_->GetInstance();
-    }
-  }
-
-  Interface* instance_;
-  ReferenceCountedSingletonFactory<Interface>* factory_;
-
-  DISALLOW_IMPLICIT_CONSTRUCTORS(rcsf_ptr);
-};
-
-};  // namespace talk_base
-
-#endif  // TALK_BASE_REFERENCECOUNTEDSINGLETONFACTORY_H_
diff --git a/third_party/libjingle/source/talk/base/referencecountedsingletonfactory_unittest.cc b/third_party/libjingle/source/talk/base/referencecountedsingletonfactory_unittest.cc
deleted file mode 100644
index 3fc7fd2..0000000
--- a/third_party/libjingle/source/talk/base/referencecountedsingletonfactory_unittest.cc
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/gunit.h"
-#include "talk/base/referencecountedsingletonfactory.h"
-
-namespace talk_base {
-
-class MyExistenceWatcher {
- public:
-  MyExistenceWatcher() { create_called_ = true; }
-  ~MyExistenceWatcher() { delete_called_ = true; }
-
-  static bool create_called_;
-  static bool delete_called_;
-};
-
-bool MyExistenceWatcher::create_called_ = false;
-bool MyExistenceWatcher::delete_called_ = false;
-
-class TestReferenceCountedSingletonFactory :
-    public ReferenceCountedSingletonFactory<MyExistenceWatcher> {
- protected:
-  virtual bool SetupInstance() {
-    instance_.reset(new MyExistenceWatcher());
-    return true;
-  }
-
-  virtual void CleanupInstance() {
-    instance_.reset();
-  }
-};
-
-static void DoCreateAndGoOutOfScope(
-    ReferenceCountedSingletonFactory<MyExistenceWatcher> *factory) {
-  rcsf_ptr<MyExistenceWatcher> ptr(factory);
-  ptr.get();
-  // and now ptr should go out of scope.
-}
-
-TEST(ReferenceCountedSingletonFactory, ZeroReferenceCountCausesDeletion) {
-  TestReferenceCountedSingletonFactory factory;
-  MyExistenceWatcher::delete_called_ = false;
-  DoCreateAndGoOutOfScope(&factory);
-  EXPECT_TRUE(MyExistenceWatcher::delete_called_);
-}
-
-TEST(ReferenceCountedSingletonFactory, NonZeroReferenceCountDoesNotDelete) {
-  TestReferenceCountedSingletonFactory factory;
-  rcsf_ptr<MyExistenceWatcher> ptr(&factory);
-  ptr.get();
-  MyExistenceWatcher::delete_called_ = false;
-  DoCreateAndGoOutOfScope(&factory);
-  EXPECT_FALSE(MyExistenceWatcher::delete_called_);
-}
-
-TEST(ReferenceCountedSingletonFactory, ReturnedPointersReferToSameThing) {
-  TestReferenceCountedSingletonFactory factory;
-  rcsf_ptr<MyExistenceWatcher> one(&factory), two(&factory);
-
-  EXPECT_EQ(one.get(), two.get());
-}
-
-TEST(ReferenceCountedSingletonFactory, Release) {
-  TestReferenceCountedSingletonFactory factory;
-
-  rcsf_ptr<MyExistenceWatcher> one(&factory);
-  one.get();
-
-  MyExistenceWatcher::delete_called_ = false;
-  one.release();
-  EXPECT_TRUE(MyExistenceWatcher::delete_called_);
-}
-
-TEST(ReferenceCountedSingletonFactory, GetWithoutRelease) {
-  TestReferenceCountedSingletonFactory factory;
-  rcsf_ptr<MyExistenceWatcher> one(&factory);
-  one.get();
-
-  MyExistenceWatcher::create_called_ = false;
-  one.get();
-  EXPECT_FALSE(MyExistenceWatcher::create_called_);
-}
-
-TEST(ReferenceCountedSingletonFactory, GetAfterRelease) {
-  TestReferenceCountedSingletonFactory factory;
-  rcsf_ptr<MyExistenceWatcher> one(&factory);
-
-  MyExistenceWatcher::create_called_ = false;
-  one.release();
-  one.get();
-  EXPECT_TRUE(MyExistenceWatcher::create_called_);
-}
-
-TEST(ReferenceCountedSingletonFactory, MultipleReleases) {
-  TestReferenceCountedSingletonFactory factory;
-  rcsf_ptr<MyExistenceWatcher> one(&factory), two(&factory);
-
-  MyExistenceWatcher::create_called_ = false;
-  MyExistenceWatcher::delete_called_ = false;
-  one.release();
-  EXPECT_FALSE(MyExistenceWatcher::delete_called_);
-  one.release();
-  EXPECT_FALSE(MyExistenceWatcher::delete_called_);
-  one.release();
-  EXPECT_FALSE(MyExistenceWatcher::delete_called_);
-  one.get();
-  EXPECT_TRUE(MyExistenceWatcher::create_called_);
-}
-
-TEST(ReferenceCountedSingletonFactory, Existentialism) {
-  TestReferenceCountedSingletonFactory factory;
-
-  rcsf_ptr<MyExistenceWatcher> one(&factory);
-
-  MyExistenceWatcher::create_called_ = false;
-  MyExistenceWatcher::delete_called_ = false;
-
-  one.get();
-  EXPECT_TRUE(MyExistenceWatcher::create_called_);
-  one.release();
-  EXPECT_TRUE(MyExistenceWatcher::delete_called_);
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/rollingaccumulator.h b/third_party/libjingle/source/talk/base/rollingaccumulator.h
deleted file mode 100644
index 3868031..0000000
--- a/third_party/libjingle/source/talk/base/rollingaccumulator.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * libjingle
- * Copyright 2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_ROLLINGACCUMULATOR_H_
-#define TALK_BASE_ROLLINGACCUMULATOR_H_
-
-#include <vector>
-
-#include "talk/base/common.h"
-
-namespace talk_base {
-
-// RollingAccumulator stores and reports statistics
-// over N most recent samples.
-//
-// T is assumed to be an int, long, double or float.
-template<typename T>
-class RollingAccumulator {
- public:
-  explicit RollingAccumulator(size_t max_count)
-    : count_(0),
-      next_index_(0),
-      sum_(0.0),
-      sum_2_(0.0),
-      samples_(max_count) {
-  }
-  ~RollingAccumulator() {
-  }
-
-  int max_count() const {
-    return samples_.size();
-  }
-
-  int count() const {
-    return count_;
-  }
-
-  void AddSample(T sample) {
-    if (count_ == max_count()) {
-      // Remove oldest sample.
-      T sample_to_remove = samples_[next_index_];
-      sum_ -= sample_to_remove;
-      sum_2_ -= sample_to_remove * sample_to_remove;
-    } else {
-      // Increase count of samples.
-      ++count_;
-    }
-    // Add new sample.
-    samples_[next_index_] = sample;
-    sum_ += sample;
-    sum_2_ += sample * sample;
-    // Update next_index_.
-    next_index_ = (next_index_ + 1) % max_count();
-  }
-
-  T ComputeSum() const {
-    return static_cast<T>(sum_);
-  }
-
-  T ComputeMean() const {
-    if (count_ == 0) {
-      return static_cast<T>(0);
-    }
-    return static_cast<T>(sum_ / count_);
-  }
-
-  // Compute estimated variance.  Estimation is more accurate
-  // as the number of samples grows.
-  T ComputeVariance() const {
-    if (count_ == 0) {
-      return static_cast<T>(0);
-    }
-    // Var = E[x^2] - (E[x])^2
-    double count_inv = 1.0 / count_;
-    double mean_2 = sum_2_ * count_inv;
-    double mean = sum_ * count_inv;
-    return static_cast<T>(mean_2 - (mean * mean));
-  }
-
- private:
-  int count_;
-  int next_index_;
-  double sum_;    // Sum(x)
-  double sum_2_;  // Sum(x*x)
-  std::vector<T> samples_;
-
-  DISALLOW_COPY_AND_ASSIGN(RollingAccumulator);
-};
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_ROLLINGACCUMULATOR_H_
diff --git a/third_party/libjingle/source/talk/base/rollingaccumulator_unittest.cc b/third_party/libjingle/source/talk/base/rollingaccumulator_unittest.cc
deleted file mode 100644
index 3630e5b..0000000
--- a/third_party/libjingle/source/talk/base/rollingaccumulator_unittest.cc
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * libjingle
- * Copyright 2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/gunit.h"
-#include "talk/base/rollingaccumulator.h"
-
-namespace talk_base {
-
-static bool IsApproximate(double expected, double value, double eps) {
-  return expected - eps <= value && value <= expected + eps;
-}
-
-TEST(RollingAccumulatorTest, TestZeroSamples) {
-  RollingAccumulator<int> accum(10);
-
-  EXPECT_EQ(0, accum.count());
-  EXPECT_EQ(0, accum.ComputeMean());
-  EXPECT_EQ(0, accum.ComputeVariance());
-}
-
-TEST(RollingAccumulatorTest, TestSomeSamples) {
-  RollingAccumulator<int> accum(10);
-  for (int i = 0; i < 4; ++i) {
-    accum.AddSample(i);
-  }
-
-  EXPECT_EQ(4, accum.count());
-  EXPECT_EQ(6, accum.ComputeSum());
-  EXPECT_EQ(1, accum.ComputeMean());
-  EXPECT_EQ(1, accum.ComputeVariance());
-}
-
-TEST(RollingAccumulatorTest, TestRollingSamples) {
-  RollingAccumulator<int> accum(10);
-  for (int i = 0; i < 12; ++i) {
-    accum.AddSample(i);
-  }
-
-  EXPECT_EQ(10, accum.count());
-  EXPECT_EQ(65, accum.ComputeSum());
-  EXPECT_EQ(6, accum.ComputeMean());
-  EXPECT_TRUE(IsApproximate(9, accum.ComputeVariance(), 1));
-}
-
-TEST(RollingAccumulatorTest, TestRollingSamplesDouble) {
-  RollingAccumulator<double> accum(10);
-  for (int i = 0; i < 23; ++i) {
-    accum.AddSample(5 * i);
-  }
-
-  EXPECT_EQ(10, accum.count());
-  EXPECT_TRUE(IsApproximate(875.0, accum.ComputeSum(), 1E-6));
-  EXPECT_TRUE(IsApproximate(87.5, accum.ComputeMean(), 1E-6));
-  EXPECT_TRUE(IsApproximate(229.166667, accum.ComputeVariance(), 25));
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/schanneladapter.cc b/third_party/libjingle/source/talk/base/schanneladapter.cc
deleted file mode 100644
index 01aa9ce..0000000
--- a/third_party/libjingle/source/talk/base/schanneladapter.cc
+++ /dev/null
@@ -1,722 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/win32.h"
-#define SECURITY_WIN32
-#include <security.h>
-#include <schannel.h>
-
-#include <iomanip>
-#include <vector>
-
-#include "talk/base/common.h"
-#include "talk/base/logging.h"
-#include "talk/base/schanneladapter.h"
-#include "talk/base/sec_buffer.h"
-#include "talk/base/thread.h"
-
-namespace talk_base {
-
-/////////////////////////////////////////////////////////////////////////////
-// SChannelAdapter
-/////////////////////////////////////////////////////////////////////////////
-
-extern const ConstantLabel SECURITY_ERRORS[];
-
-const ConstantLabel SCHANNEL_BUFFER_TYPES[] = {
-  KLABEL(SECBUFFER_EMPTY),              //  0
-  KLABEL(SECBUFFER_DATA),               //  1
-  KLABEL(SECBUFFER_TOKEN),              //  2
-  KLABEL(SECBUFFER_PKG_PARAMS),         //  3
-  KLABEL(SECBUFFER_MISSING),            //  4
-  KLABEL(SECBUFFER_EXTRA),              //  5
-  KLABEL(SECBUFFER_STREAM_TRAILER),     //  6
-  KLABEL(SECBUFFER_STREAM_HEADER),      //  7
-  KLABEL(SECBUFFER_MECHLIST),           // 11
-  KLABEL(SECBUFFER_MECHLIST_SIGNATURE), // 12
-  KLABEL(SECBUFFER_TARGET),             // 13
-  KLABEL(SECBUFFER_CHANNEL_BINDINGS),   // 14
-  LASTLABEL
-};
-
-void DescribeBuffer(LoggingSeverity severity, const char* prefix,
-                    const SecBuffer& sb) {
-  LOG_V(severity)
-    << prefix
-    << "(" << sb.cbBuffer
-    << ", " << FindLabel(sb.BufferType & ~SECBUFFER_ATTRMASK,
-                          SCHANNEL_BUFFER_TYPES)
-    << ", " << sb.pvBuffer << ")";
-}
-
-void DescribeBuffers(LoggingSeverity severity, const char* prefix,
-                     const SecBufferDesc* sbd) {
-  if (!LOG_CHECK_LEVEL_V(severity))
-    return;
-  LOG_V(severity) << prefix << "(";
-  for (size_t i=0; i<sbd->cBuffers; ++i) {
-    DescribeBuffer(severity, "  ", sbd->pBuffers[i]);
-  }
-  LOG_V(severity) << ")";
-}
-
-const ULONG SSL_FLAGS_DEFAULT = ISC_REQ_ALLOCATE_MEMORY
-                              | ISC_REQ_CONFIDENTIALITY
-                              | ISC_REQ_EXTENDED_ERROR
-                              | ISC_REQ_INTEGRITY
-                              | ISC_REQ_REPLAY_DETECT
-                              | ISC_REQ_SEQUENCE_DETECT
-                              | ISC_REQ_STREAM;
-                              //| ISC_REQ_USE_SUPPLIED_CREDS;
-
-typedef std::vector<char> SChannelBuffer;
-
-struct SChannelAdapter::SSLImpl {
-  CredHandle cred;
-  CtxtHandle ctx;
-  bool cred_init, ctx_init;
-  SChannelBuffer inbuf, outbuf, readable;
-  SecPkgContext_StreamSizes sizes;
-
-  SSLImpl() : cred_init(false), ctx_init(false) { }
-};
-
-SChannelAdapter::SChannelAdapter(AsyncSocket* socket)
-  : SSLAdapter(socket), state_(SSL_NONE),
-    restartable_(false), signal_close_(false), message_pending_(false),
-    impl_(new SSLImpl) {
-}
-
-SChannelAdapter::~SChannelAdapter() {
-  Cleanup();
-}
-
-int
-SChannelAdapter::StartSSL(const char* hostname, bool restartable) {
-  if (state_ != SSL_NONE)
-    return ERROR_ALREADY_INITIALIZED;
-
-  ssl_host_name_ = hostname;
-  restartable_ = restartable;
-
-  if (socket_->GetState() != Socket::CS_CONNECTED) {
-    state_ = SSL_WAIT;
-    return 0;
-  }
-
-  state_ = SSL_CONNECTING;
-  if (int err = BeginSSL()) {
-    Error("BeginSSL", err, false);
-    return err;
-  }
-
-  return 0;
-}
-
-int
-SChannelAdapter::BeginSSL() {
-  LOG(LS_VERBOSE) << "BeginSSL: " << ssl_host_name_;
-  ASSERT(state_ == SSL_CONNECTING);
-
-  SECURITY_STATUS ret;
-
-  SCHANNEL_CRED sc_cred = { 0 };
-  sc_cred.dwVersion = SCHANNEL_CRED_VERSION;
-  //sc_cred.dwMinimumCipherStrength = 128; // Note: use system default
-  sc_cred.dwFlags = SCH_CRED_NO_DEFAULT_CREDS | SCH_CRED_AUTO_CRED_VALIDATION;
-
-  ret = AcquireCredentialsHandle(NULL, UNISP_NAME, SECPKG_CRED_OUTBOUND, NULL,
-                                 &sc_cred, NULL, NULL, &impl_->cred, NULL);
-  if (ret != SEC_E_OK) {
-    LOG(LS_ERROR) << "AcquireCredentialsHandle error: "
-                  << ErrorName(ret, SECURITY_ERRORS);
-    return ret;
-  }
-  impl_->cred_init = true;
-
-  if (LOG_CHECK_LEVEL(LS_VERBOSE)) {
-    SecPkgCred_CipherStrengths cipher_strengths = { 0 };
-    ret = QueryCredentialsAttributes(&impl_->cred,
-                                     SECPKG_ATTR_CIPHER_STRENGTHS,
-                                     &cipher_strengths);
-    if (SUCCEEDED(ret)) {
-      LOG(LS_VERBOSE) << "SChannel cipher strength: "
-                  << cipher_strengths.dwMinimumCipherStrength << " - "
-                  << cipher_strengths.dwMaximumCipherStrength;
-    }
-
-    SecPkgCred_SupportedAlgs supported_algs = { 0 };
-    ret = QueryCredentialsAttributes(&impl_->cred,
-                                     SECPKG_ATTR_SUPPORTED_ALGS,
-                                     &supported_algs);
-    if (SUCCEEDED(ret)) {
-      LOG(LS_VERBOSE) << "SChannel supported algorithms:";
-      for (DWORD i=0; i<supported_algs.cSupportedAlgs; ++i) {
-        ALG_ID alg_id = supported_algs.palgSupportedAlgs[i];
-        PCCRYPT_OID_INFO oinfo = CryptFindOIDInfo(CRYPT_OID_INFO_ALGID_KEY,
-                                                  &alg_id, 0);
-        LPCWSTR alg_name = (NULL != oinfo) ? oinfo->pwszName : L"Unknown";
-        LOG(LS_VERBOSE) << "  " << ToUtf8(alg_name) << " (" << alg_id << ")";
-      }
-      CSecBufferBase::FreeSSPI(supported_algs.palgSupportedAlgs);
-    }
-  }
-
-  ULONG flags = SSL_FLAGS_DEFAULT, ret_flags = 0;
-  if (ignore_bad_cert())
-    flags |= ISC_REQ_MANUAL_CRED_VALIDATION;
-
-  CSecBufferBundle<2, CSecBufferBase::FreeSSPI> sb_out;
-  ret = InitializeSecurityContextA(&impl_->cred, NULL,
-                                   const_cast<char*>(ssl_host_name_.c_str()),
-                                   flags, 0, 0, NULL, 0,
-                                   &impl_->ctx, sb_out.desc(),
-                                   &ret_flags, NULL);
-  if (SUCCEEDED(ret))
-    impl_->ctx_init = true;
-  return ProcessContext(ret, NULL, sb_out.desc());
-}
-
-int
-SChannelAdapter::ContinueSSL() {
-  LOG(LS_VERBOSE) << "ContinueSSL";
-  ASSERT(state_ == SSL_CONNECTING);
-
-  SECURITY_STATUS ret;
-
-  CSecBufferBundle<2> sb_in;
-  sb_in[0].BufferType = SECBUFFER_TOKEN;
-  sb_in[0].cbBuffer = static_cast<unsigned long>(impl_->inbuf.size());
-  sb_in[0].pvBuffer = &impl_->inbuf[0];
-  //DescribeBuffers(LS_VERBOSE, "Input Buffer ", sb_in.desc());
-
-  ULONG flags = SSL_FLAGS_DEFAULT, ret_flags = 0;
-  if (ignore_bad_cert())
-    flags |= ISC_REQ_MANUAL_CRED_VALIDATION;
-
-  CSecBufferBundle<2, CSecBufferBase::FreeSSPI> sb_out;
-  ret = InitializeSecurityContextA(&impl_->cred, &impl_->ctx,
-                                   const_cast<char*>(ssl_host_name_.c_str()),
-                                   flags, 0, 0, sb_in.desc(), 0,
-                                   NULL, sb_out.desc(),
-                                   &ret_flags, NULL);
-  return ProcessContext(ret, sb_in.desc(), sb_out.desc());
-}
-
-int
-SChannelAdapter::ProcessContext(long int status, _SecBufferDesc* sbd_in,
-                                _SecBufferDesc* sbd_out) {
-  LoggingSeverity level = LS_ERROR;
-  if ((status == SEC_E_OK)
-      || (status != SEC_I_CONTINUE_NEEDED)
-      || (status != SEC_E_INCOMPLETE_MESSAGE)) {
-    level = LS_VERBOSE;  // Expected messages
-  }
-  LOG_V(level)
-    << "InitializeSecurityContext error: "
-    << ErrorName(status, SECURITY_ERRORS);
-  //if (sbd_in)
-  //  DescribeBuffers(LS_VERBOSE, "Input Buffer ", sbd_in);
-  //if (sbd_out)
-  //  DescribeBuffers(LS_VERBOSE, "Output Buffer ", sbd_out);
-
-  if (status == SEC_E_INCOMPLETE_MESSAGE) {
-    // Wait for more input from server.
-    return Flush();
-  }
-
-  if (FAILED(status)) {
-    // We can't continue.  Common errors:
-    // SEC_E_CERT_EXPIRED - Typically, this means the computer clock is wrong.
-    return status;
-  }
-
-  // Note: we check both input and output buffers for SECBUFFER_EXTRA.
-  // Experience shows it appearing in the input, but the documentation claims
-  // it should appear in the output.
-  size_t extra = 0;
-  if (sbd_in) {
-    for (size_t i=0; i<sbd_in->cBuffers; ++i) {
-      SecBuffer& buffer = sbd_in->pBuffers[i];
-      if (buffer.BufferType == SECBUFFER_EXTRA) {
-        extra += buffer.cbBuffer;
-      }
-    }
-  }
-  if (sbd_out) {
-    for (size_t i=0; i<sbd_out->cBuffers; ++i) {
-      SecBuffer& buffer = sbd_out->pBuffers[i];
-      if (buffer.BufferType == SECBUFFER_EXTRA) {
-        extra += buffer.cbBuffer;
-      } else if (buffer.BufferType == SECBUFFER_TOKEN) {
-        impl_->outbuf.insert(impl_->outbuf.end(),
-          reinterpret_cast<char*>(buffer.pvBuffer),
-          reinterpret_cast<char*>(buffer.pvBuffer) + buffer.cbBuffer);
-      }
-    }
-  }
-
-  if (extra) {
-    ASSERT(extra <= impl_->inbuf.size());
-    size_t consumed = impl_->inbuf.size() - extra;
-    memmove(&impl_->inbuf[0], &impl_->inbuf[consumed], extra);
-    impl_->inbuf.resize(extra);
-  } else {
-    impl_->inbuf.clear();
-  }
-
-  if (SEC_I_CONTINUE_NEEDED == status) {
-    // Send data to server and wait for response.
-    // Note: ContinueSSL will result in a Flush, anyway.
-    return impl_->inbuf.empty() ? Flush() : ContinueSSL();
-  }
-
-  if (SEC_E_OK == status) {
-    LOG(LS_VERBOSE) << "QueryContextAttributes";
-    status = QueryContextAttributes(&impl_->ctx, SECPKG_ATTR_STREAM_SIZES,
-                                    &impl_->sizes);
-    if (FAILED(status)) {
-      LOG(LS_ERROR) << "QueryContextAttributes error: "
-                    << ErrorName(status, SECURITY_ERRORS);
-      return status;
-    }
-
-    state_ = SSL_CONNECTED;
-
-    if (int err = DecryptData()) {
-      return err;
-    } else if (int err = Flush()) {
-      return err;
-    } else {
-      // If we decrypted any data, queue up a notification here
-      PostEvent();
-      // Signal our connectedness
-      AsyncSocketAdapter::OnConnectEvent(this);
-    }
-    return 0;
-  }
-
-  if (SEC_I_INCOMPLETE_CREDENTIALS == status) {
-    // We don't support client authentication in schannel.
-    return status;
-  }
-
-  // We don't expect any other codes
-  ASSERT(false);
-  return status;
-}
-
-int
-SChannelAdapter::DecryptData() {
-  SChannelBuffer& inbuf = impl_->inbuf;
-  SChannelBuffer& readable = impl_->readable;
-
-  while (!inbuf.empty()) {
-    CSecBufferBundle<4> in_buf;
-    in_buf[0].BufferType = SECBUFFER_DATA;
-    in_buf[0].cbBuffer = static_cast<unsigned long>(inbuf.size());
-    in_buf[0].pvBuffer = &inbuf[0];
-
-    //DescribeBuffers(LS_VERBOSE, "Decrypt In ", in_buf.desc());
-    SECURITY_STATUS status = DecryptMessage(&impl_->ctx, in_buf.desc(), 0, 0);
-    //DescribeBuffers(LS_VERBOSE, "Decrypt Out ", in_buf.desc());
-
-    // Note: We are explicitly treating SEC_E_OK, SEC_I_CONTEXT_EXPIRED, and
-    // any other successful results as continue.
-    if (SUCCEEDED(status)) {
-      size_t data_len = 0, extra_len = 0;
-      for (size_t i=0; i<in_buf.desc()->cBuffers; ++i) {
-        if (in_buf[i].BufferType == SECBUFFER_DATA) {
-          data_len += in_buf[i].cbBuffer;
-          readable.insert(readable.end(),
-            reinterpret_cast<char*>(in_buf[i].pvBuffer),
-            reinterpret_cast<char*>(in_buf[i].pvBuffer) + in_buf[i].cbBuffer);
-        } else if (in_buf[i].BufferType == SECBUFFER_EXTRA) {
-          extra_len += in_buf[i].cbBuffer;
-        }
-      }
-      // There is a bug on Win2K where SEC_I_CONTEXT_EXPIRED is misclassified.
-      if ((data_len == 0) && (inbuf[0] == 0x15)) {
-        status = SEC_I_CONTEXT_EXPIRED;
-      }
-      if (extra_len) {
-        size_t consumed = inbuf.size() - extra_len;
-        memmove(&inbuf[0], &inbuf[consumed], extra_len);
-        inbuf.resize(extra_len);
-      } else {
-        inbuf.clear();
-      }
-      // TODO: Handle SEC_I_CONTEXT_EXPIRED to do clean shutdown
-      if (status != SEC_E_OK) {
-        LOG(LS_INFO) << "DecryptMessage returned continuation code: "
-                      << ErrorName(status, SECURITY_ERRORS);
-      }
-      continue;
-    }
-
-    if (status == SEC_E_INCOMPLETE_MESSAGE) {
-      break;
-    } else {
-      return status;
-    }
-  }
-
-  return 0;
-}
-
-void
-SChannelAdapter::Cleanup() {
-  if (impl_->ctx_init)
-    DeleteSecurityContext(&impl_->ctx);
-  if (impl_->cred_init)
-    FreeCredentialsHandle(&impl_->cred);
-  delete impl_;
-}
-
-void
-SChannelAdapter::PostEvent() {
-  // Check if there's anything notable to signal
-  if (impl_->readable.empty() && !signal_close_)
-    return;
-
-  // Only one post in the queue at a time
-  if (message_pending_)
-    return;
-
-  if (Thread* thread = Thread::Current()) {
-    message_pending_ = true;
-    thread->Post(this);
-  } else {
-    LOG(LS_ERROR) << "No thread context available for SChannelAdapter";
-    ASSERT(false);
-  }
-}
-
-void
-SChannelAdapter::Error(const char* context, int err, bool signal) {
-  LOG(LS_WARNING) << "SChannelAdapter::Error("
-                  << context << ", "
-                  << ErrorName(err, SECURITY_ERRORS) << ")";
-  state_ = SSL_ERROR;
-  SetError(err);
-  if (signal)
-    AsyncSocketAdapter::OnCloseEvent(this, err);
-}
-
-int
-SChannelAdapter::Read() {
-  char buffer[4096];
-  SChannelBuffer& inbuf = impl_->inbuf;
-  while (true) {
-    int ret = AsyncSocketAdapter::Recv(buffer, sizeof(buffer));
-    if (ret > 0) {
-      inbuf.insert(inbuf.end(), buffer, buffer + ret);
-    } else if (GetError() == EWOULDBLOCK) {
-      return 0;  // Blocking
-    } else {
-      return GetError();
-    }
-  }
-}
-
-int
-SChannelAdapter::Flush() {
-  int result = 0;
-  size_t pos = 0;
-  SChannelBuffer& outbuf = impl_->outbuf;
-  while (pos < outbuf.size()) {
-    int sent = AsyncSocketAdapter::Send(&outbuf[pos], outbuf.size() - pos);
-    if (sent > 0) {
-      pos += sent;
-    } else if (GetError() == EWOULDBLOCK) {
-      break;  // Blocking
-    } else {
-      result = GetError();
-      break;
-    }
-  }
-  if (int remainder = outbuf.size() - pos) {
-    memmove(&outbuf[0], &outbuf[pos], remainder);
-    outbuf.resize(remainder);
-  } else {
-    outbuf.clear();
-  }
-  return result;
-}
-
-//
-// AsyncSocket Implementation
-//
-
-int
-SChannelAdapter::Send(const void* pv, size_t cb) {
-  switch (state_) {
-  case SSL_NONE:
-    return AsyncSocketAdapter::Send(pv, cb);
-
-  case SSL_WAIT:
-  case SSL_CONNECTING:
-    SetError(EWOULDBLOCK);
-    return SOCKET_ERROR;
-
-  case SSL_CONNECTED:
-    break;
-
-  case SSL_ERROR:
-  default:
-    return SOCKET_ERROR;
-  }
-
-  size_t written = 0;
-  SChannelBuffer& outbuf = impl_->outbuf;
-  while (written < cb) {
-    const size_t encrypt_len = std::min<size_t>(cb - written,
-                                                impl_->sizes.cbMaximumMessage);
-
-    CSecBufferBundle<4> out_buf;
-    out_buf[0].BufferType = SECBUFFER_STREAM_HEADER;
-    out_buf[0].cbBuffer = impl_->sizes.cbHeader;
-    out_buf[1].BufferType = SECBUFFER_DATA;
-    out_buf[1].cbBuffer = static_cast<unsigned long>(encrypt_len);
-    out_buf[2].BufferType = SECBUFFER_STREAM_TRAILER;
-    out_buf[2].cbBuffer = impl_->sizes.cbTrailer;
-
-    size_t packet_len = out_buf[0].cbBuffer
-                      + out_buf[1].cbBuffer
-                      + out_buf[2].cbBuffer;
-
-    SChannelBuffer message;
-    message.resize(packet_len);
-    out_buf[0].pvBuffer = &message[0];
-    out_buf[1].pvBuffer = &message[out_buf[0].cbBuffer];
-    out_buf[2].pvBuffer = &message[out_buf[0].cbBuffer + out_buf[1].cbBuffer];
-
-    memcpy(out_buf[1].pvBuffer,
-           static_cast<const char*>(pv) + written,
-           encrypt_len);
-
-    //DescribeBuffers(LS_VERBOSE, "Encrypt In ", out_buf.desc());
-    SECURITY_STATUS res = EncryptMessage(&impl_->ctx, 0, out_buf.desc(), 0);
-    //DescribeBuffers(LS_VERBOSE, "Encrypt Out ", out_buf.desc());
-
-    if (FAILED(res)) {
-      Error("EncryptMessage", res, false);
-      return SOCKET_ERROR;
-    }
-
-    // We assume that the header and data segments do not change length,
-    // or else encrypting the concatenated packet in-place is wrong.
-    ASSERT(out_buf[0].cbBuffer == impl_->sizes.cbHeader);
-    ASSERT(out_buf[1].cbBuffer == static_cast<unsigned long>(encrypt_len));
-
-    // However, the length of the trailer may change due to padding.
-    ASSERT(out_buf[2].cbBuffer <= impl_->sizes.cbTrailer);
-
-    packet_len = out_buf[0].cbBuffer
-               + out_buf[1].cbBuffer
-               + out_buf[2].cbBuffer;
-
-    written += encrypt_len;
-    outbuf.insert(outbuf.end(), &message[0], &message[packet_len-1]+1);
-  }
-
-  if (int err = Flush()) {
-    state_ = SSL_ERROR;
-    SetError(err);
-    return SOCKET_ERROR;
-  }
-
-  return static_cast<int>(written);
-}
-
-int
-SChannelAdapter::Recv(void* pv, size_t cb) {
-  switch (state_) {
-  case SSL_NONE:
-    return AsyncSocketAdapter::Recv(pv, cb);
-
-  case SSL_WAIT:
-  case SSL_CONNECTING:
-    SetError(EWOULDBLOCK);
-    return SOCKET_ERROR;
-
-  case SSL_CONNECTED:
-    break;
-
-  case SSL_ERROR:
-  default:
-    return SOCKET_ERROR;
-  }
-
-  SChannelBuffer& readable = impl_->readable;
-  if (readable.empty()) {
-    SetError(EWOULDBLOCK);
-    return SOCKET_ERROR;
-  }
-  size_t read = _min(cb, readable.size());
-  memcpy(pv, &readable[0], read);
-  if (size_t remaining = readable.size() - read) {
-    memmove(&readable[0], &readable[read], remaining);
-    readable.resize(remaining);
-  } else {
-    readable.clear();
-  }
-
-  PostEvent();
-  return static_cast<int>(read);
-}
-
-int
-SChannelAdapter::Close() {
-  if (!impl_->readable.empty()) {
-    LOG(WARNING) << "SChannelAdapter::Close with readable data";
-    // Note: this isn't strictly an error, but we're using it temporarily to
-    // track bugs.
-    //ASSERT(false);
-  }
-  if (state_ == SSL_CONNECTED) {
-    DWORD token = SCHANNEL_SHUTDOWN;
-    CSecBufferBundle<1> sb_in;
-    sb_in[0].BufferType = SECBUFFER_TOKEN;
-    sb_in[0].cbBuffer = sizeof(token);
-    sb_in[0].pvBuffer = &token;
-    ApplyControlToken(&impl_->ctx, sb_in.desc());
-    // TODO: In theory, to do a nice shutdown, we need to begin shutdown
-    // negotiation with more calls to InitializeSecurityContext.  Since the
-    // socket api doesn't support nice shutdown at this point, we don't bother.
-  }
-  Cleanup();
-  impl_ = new SSLImpl;
-  state_ = restartable_ ? SSL_WAIT : SSL_NONE;
-  signal_close_ = false;
-  message_pending_ = false;
-  return AsyncSocketAdapter::Close();
-}
-
-Socket::ConnState
-SChannelAdapter::GetState() const {
-  if (signal_close_)
-    return CS_CONNECTED;
-  ConnState state = socket_->GetState();
-  if ((state == CS_CONNECTED)
-      && ((state_ == SSL_WAIT) || (state_ == SSL_CONNECTING)))
-    state = CS_CONNECTING;
-  return state;
-}
-
-void
-SChannelAdapter::OnConnectEvent(AsyncSocket* socket) {
-  LOG(LS_VERBOSE) << "SChannelAdapter::OnConnectEvent";
-  if (state_ != SSL_WAIT) {
-    ASSERT(state_ == SSL_NONE);
-    AsyncSocketAdapter::OnConnectEvent(socket);
-    return;
-  }
-
-  state_ = SSL_CONNECTING;
-  if (int err = BeginSSL()) {
-    Error("BeginSSL", err);
-  }
-}
-
-void
-SChannelAdapter::OnReadEvent(AsyncSocket* socket) {
-  if (state_ == SSL_NONE) {
-    AsyncSocketAdapter::OnReadEvent(socket);
-    return;
-  }
-
-  if (int err = Read()) {
-    Error("Read", err);
-    return;
-  }
-
-  if (impl_->inbuf.empty())
-    return;
-
-  if (state_ == SSL_CONNECTED) {
-    if (int err = DecryptData()) {
-      Error("DecryptData", err);
-    } else if (!impl_->readable.empty()) {
-      AsyncSocketAdapter::OnReadEvent(this);
-    }
-  } else if (state_ == SSL_CONNECTING) {
-    if (int err = ContinueSSL()) {
-      Error("ContinueSSL", err);
-    }
-  }
-}
-
-void
-SChannelAdapter::OnWriteEvent(AsyncSocket* socket) {
-  if (state_ == SSL_NONE) {
-    AsyncSocketAdapter::OnWriteEvent(socket);
-    return;
-  }
-
-  if (int err = Flush()) {
-    Error("Flush", err);
-    return;
-  }
-
-  // See if we have more data to write
-  if (!impl_->outbuf.empty())
-    return;
-
-  // Buffer is empty, submit notification
-  if (state_ == SSL_CONNECTED) {
-    AsyncSocketAdapter::OnWriteEvent(socket);
-  }
-}
-
-void
-SChannelAdapter::OnCloseEvent(AsyncSocket* socket, int err) {
-  if ((state_ == SSL_NONE) || impl_->readable.empty()) {
-    AsyncSocketAdapter::OnCloseEvent(socket, err);
-    return;
-  }
-
-  // If readable is non-empty, then we have a pending Message
-  // that will allow us to signal close (eventually).
-  signal_close_ = true;
-}
-
-void
-SChannelAdapter::OnMessage(Message* pmsg) {
-  if (!message_pending_)
-    return;  // This occurs when socket is closed
-
-  message_pending_ = false;
-  if (!impl_->readable.empty()) {
-    AsyncSocketAdapter::OnReadEvent(this);
-  } else if (signal_close_) {
-    signal_close_ = false;
-    AsyncSocketAdapter::OnCloseEvent(this, 0); // TODO: cache this error?
-  }
-}
-
-} // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/schanneladapter.h b/third_party/libjingle/source/talk/base/schanneladapter.h
deleted file mode 100644
index a5ab7b3..0000000
--- a/third_party/libjingle/source/talk/base/schanneladapter.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_SCHANNELADAPTER_H__
-#define TALK_BASE_SCHANNELADAPTER_H__
-
-#include <string>
-#include "talk/base/ssladapter.h"
-#include "talk/base/messagequeue.h"
-struct _SecBufferDesc;
-
-namespace talk_base {
-
-///////////////////////////////////////////////////////////////////////////////
-
-class SChannelAdapter : public SSLAdapter, public MessageHandler {
-public:
-  SChannelAdapter(AsyncSocket* socket);
-  virtual ~SChannelAdapter();
-
-  virtual int StartSSL(const char* hostname, bool restartable);
-  virtual int Send(const void* pv, size_t cb);
-  virtual int Recv(void* pv, size_t cb);
-  virtual int Close();
-
-  // Note that the socket returns ST_CONNECTING while SSL is being negotiated.
-  virtual ConnState GetState() const;
-
-protected:
-  enum SSLState {
-    SSL_NONE, SSL_WAIT, SSL_CONNECTING, SSL_CONNECTED, SSL_ERROR
-  };
-  struct SSLImpl;
-
-  virtual void OnConnectEvent(AsyncSocket* socket);
-  virtual void OnReadEvent(AsyncSocket* socket);
-  virtual void OnWriteEvent(AsyncSocket* socket);
-  virtual void OnCloseEvent(AsyncSocket* socket, int err);
-  virtual void OnMessage(Message* pmsg);
-
-  int BeginSSL();
-  int ContinueSSL();
-  int ProcessContext(long int status, _SecBufferDesc* sbd_in,
-                     _SecBufferDesc* sbd_out);
-  int DecryptData();
-
-  int Read();
-  int Flush();
-  void Error(const char* context, int err, bool signal = true);
-  void Cleanup();
-
-  void PostEvent();
-
-private:
-  SSLState state_;
-  std::string ssl_host_name_;
-  // If true, socket will retain SSL configuration after Close.
-  bool restartable_; 
-  // If true, we are delaying signalling close until all data is read.
-  bool signal_close_;
-  // If true, we are waiting to be woken up to signal readability or closure.
-  bool message_pending_;
-  SSLImpl* impl_;
-};
-
-/////////////////////////////////////////////////////////////////////////////
-
-} // namespace talk_base
-
-#endif // TALK_BASE_SCHANNELADAPTER_H__
diff --git a/third_party/libjingle/source/talk/base/scoped_autorelease_pool.h b/third_party/libjingle/source/talk/base/scoped_autorelease_pool.h
deleted file mode 100644
index 611f811..0000000
--- a/third_party/libjingle/source/talk/base/scoped_autorelease_pool.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * libjingle
- * Copyright 2008 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// Automatically initialize and and free an autoreleasepool. Never allocate
-// an instance of this class using "new" - that will result in a compile-time
-// error. Only use it as a stack object.
-//
-// Note: NSAutoreleasePool docs say that you should not normally need to
-// declare an NSAutoreleasePool as a member of an object - but there's nothing
-// that indicates it will be a problem, as long as the stack lifetime of the
-// pool exactly matches the stack lifetime of the object.
-
-#ifndef TALK_BASE_SCOPED_AUTORELEASE_POOL_H__
-#define TALK_BASE_SCOPED_AUTORELEASE_POOL_H__
-
-#if defined(IOS) || defined(OSX)
-
-#include "talk/base/common.h"
-
-// This header may be included from Obj-C files or C++ files.
-#ifdef __OBJC__
-@class NSAutoreleasePool;
-#else
-class NSAutoreleasePool;
-#endif
-
-namespace talk_base {
-
-class ScopedAutoreleasePool {
- public:
-  ScopedAutoreleasePool();
-  ~ScopedAutoreleasePool();
-
- private:
-  // Declaring private overrides of new and delete here enforces the "only use
-  // as a stack object" discipline.
-  //
-  // Note: new is declared as "throw()" to get around a gcc warning about new
-  // returning NULL, but this method will never get called and therefore will
-  // never actually throw any exception.
-  void* operator new(size_t size) throw() { return NULL; }
-  void operator delete (void* ptr) {}
-
-  NSAutoreleasePool* pool_;
-
-  DISALLOW_EVIL_CONSTRUCTORS(ScopedAutoreleasePool);
-};
-
-}  // namespace talk_base
-
-#endif  // IOS || OSX
-#endif  // TALK_BASE_SCOPED_AUTORELEASE_POOL_H__
diff --git a/third_party/libjingle/source/talk/base/scoped_ptr.h b/third_party/libjingle/source/talk/base/scoped_ptr.h
deleted file mode 100644
index fd753ec..0000000
--- a/third_party/libjingle/source/talk/base/scoped_ptr.h
+++ /dev/null
@@ -1,258 +0,0 @@
-//  (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
-//  Copyright (c) 2001, 2002 Peter Dimov
-//
-//  Permission to copy, use, modify, sell and distribute this software
-//  is granted provided this copyright notice appears in all copies.
-//  This software is provided "as is" without express or implied
-//  warranty, and with no claim as to its suitability for any purpose.
-//
-//  See http://www.boost.org/libs/smart_ptr/scoped_ptr.htm for documentation.
-//
-
-//  scoped_ptr mimics a built-in pointer except that it guarantees deletion
-//  of the object pointed to, either on destruction of the scoped_ptr or via
-//  an explicit reset(). scoped_ptr is a simple solution for simple needs;
-//  use shared_ptr or std::auto_ptr if your needs are more complex.
-
-//  scoped_ptr_malloc added in by Google.  When one of
-//  these goes out of scope, instead of doing a delete or delete[], it
-//  calls free().  scoped_ptr_malloc<char> is likely to see much more
-//  use than any other specializations.
-
-//  release() added in by Google. Use this to conditionally
-//  transfer ownership of a heap-allocated object to the caller, usually on
-//  method success.
-#ifndef TALK_BASE_SCOPED_PTR_H__
-#define TALK_BASE_SCOPED_PTR_H__
-
-#include <cstddef>             // for std::ptrdiff_t
-#include <stdlib.h>            // for free() decl
-
-#include "talk/base/common.h"  // for ASSERT
-
-#ifdef _WIN32
-namespace std { using ::ptrdiff_t; };
-#endif // _WIN32
-
-namespace talk_base {
-
-template <typename T>
-class scoped_ptr {
- private:
-
-  T* ptr;
-
-  scoped_ptr(scoped_ptr const &);
-  scoped_ptr & operator=(scoped_ptr const &);
-
- public:
-
-  typedef T element_type;
-
-  explicit scoped_ptr(T* p = NULL): ptr(p) {}
-
-  ~scoped_ptr() {
-    typedef char type_must_be_complete[sizeof(T)];
-    delete ptr;
-  }
-
-  void reset(T* p = NULL) {
-    typedef char type_must_be_complete[sizeof(T)];
-
-    if (ptr != p) {
-      T* obj = ptr;
-      ptr = p;
-      // Delete last, in case obj destructor indirectly results in ~scoped_ptr
-      delete obj;
-    }
-  }
-
-  T& operator*() const {
-    ASSERT(ptr != NULL);
-    return *ptr;
-  }
-
-  T* operator->() const  {
-    ASSERT(ptr != NULL);
-    return ptr;
-  }
-
-  T* get() const  {
-    return ptr;
-  }
-
-  void swap(scoped_ptr & b) {
-    T* tmp = b.ptr;
-    b.ptr = ptr;
-    ptr = tmp;
-  }
-
-  T* release() {
-    T* tmp = ptr;
-    ptr = NULL;
-    return tmp;
-  }
-
-  T** accept() {
-    if (ptr) {
-      delete ptr;
-      ptr = NULL;
-    }
-    return &ptr;
-  }
-
-  T** use() {
-    return &ptr;
-  }
-};
-
-template<typename T> inline
-void swap(scoped_ptr<T>& a, scoped_ptr<T>& b) {
-  a.swap(b);
-}
-
-
-
-
-//  scoped_array extends scoped_ptr to arrays. Deletion of the array pointed to
-//  is guaranteed, either on destruction of the scoped_array or via an explicit
-//  reset(). Use shared_array or std::vector if your needs are more complex.
-
-template<typename T>
-class scoped_array {
- private:
-
-  T* ptr;
-
-  scoped_array(scoped_array const &);
-  scoped_array & operator=(scoped_array const &);
-
- public:
-
-  typedef T element_type;
-
-  explicit scoped_array(T* p = NULL) : ptr(p) {}
-
-  ~scoped_array() {
-    typedef char type_must_be_complete[sizeof(T)];
-    delete[] ptr;
-  }
-
-  void reset(T* p = NULL) {
-    typedef char type_must_be_complete[sizeof(T)];
-
-    if (ptr != p) {
-      T* arr = ptr;
-      ptr = p;
-      // Delete last, in case arr destructor indirectly results in ~scoped_array
-      delete [] arr;
-    }
-  }
-
-  T& operator[](std::ptrdiff_t i) const {
-    ASSERT(ptr != NULL);
-    ASSERT(i >= 0);
-    return ptr[i];
-  }
-
-  T* get() const {
-    return ptr;
-  }
-
-  void swap(scoped_array & b) {
-    T* tmp = b.ptr;
-    b.ptr = ptr;
-    ptr = tmp;
-  }
-
-  T* release() {
-    T* tmp = ptr;
-    ptr = NULL;
-    return tmp;
-  }
-
-  T** accept() {
-    if (ptr) {
-      delete [] ptr;
-      ptr = NULL;
-    }
-    return &ptr;
-  }
-};
-
-template<class T> inline
-void swap(scoped_array<T>& a, scoped_array<T>& b) {
-  a.swap(b);
-}
-
-// scoped_ptr_malloc<> is similar to scoped_ptr<>, but it accepts a
-// second template argument, the function used to free the object.
-
-template<typename T, void (*FF)(void*) = free> class scoped_ptr_malloc {
- private:
-
-  T* ptr;
-
-  scoped_ptr_malloc(scoped_ptr_malloc const &);
-  scoped_ptr_malloc & operator=(scoped_ptr_malloc const &);
-
- public:
-
-  typedef T element_type;
-
-  explicit scoped_ptr_malloc(T* p = 0): ptr(p) {}
-
-  ~scoped_ptr_malloc() {
-    FF(static_cast<void*>(ptr));
-  }
-
-  void reset(T* p = 0) {
-    if (ptr != p) {
-      FF(static_cast<void*>(ptr));
-      ptr = p;
-    }
-  }
-
-  T& operator*() const {
-    ASSERT(ptr != 0);
-    return *ptr;
-  }
-
-  T* operator->() const {
-    ASSERT(ptr != 0);
-    return ptr;
-  }
-
-  T* get() const {
-    return ptr;
-  }
-
-  void swap(scoped_ptr_malloc & b) {
-    T* tmp = b.ptr;
-    b.ptr = ptr;
-    ptr = tmp;
-  }
-
-  T* release() {
-    T* tmp = ptr;
-    ptr = 0;
-    return tmp;
-  }
-
-  T** accept() {
-    if (ptr) {
-      FF(static_cast<void*>(ptr));
-      ptr = 0;
-    }
-    return &ptr;
-  }
-};
-
-template<typename T, void (*FF)(void*)> inline
-void swap(scoped_ptr_malloc<T,FF>& a, scoped_ptr_malloc<T,FF>& b) {
-  a.swap(b);
-}
-
-} // namespace talk_base
-
-#endif  // #ifndef TALK_BASE_SCOPED_PTR_H__
diff --git a/third_party/libjingle/source/talk/base/scoped_ref_ptr.h b/third_party/libjingle/source/talk/base/scoped_ref_ptr.h
deleted file mode 100644
index 3ce72cb..0000000
--- a/third_party/libjingle/source/talk/base/scoped_ref_ptr.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * libjingle
- * Copyright 2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// Originally these classes are from Chromium.
-// http://src.chromium.org/viewvc/chrome/trunk/src/base/memory/ref_counted.h?view=markup
-
-//
-// A smart pointer class for reference counted objects.  Use this class instead
-// of calling AddRef and Release manually on a reference counted object to
-// avoid common memory leaks caused by forgetting to Release an object
-// reference.  Sample usage:
-//
-//   class MyFoo : public RefCounted<MyFoo> {
-//    ...
-//   };
-//
-//   void some_function() {
-//     scoped_refptr<MyFoo> foo = new MyFoo();
-//     foo->Method(param);
-//     // |foo| is released when this function returns
-//   }
-//
-//   void some_other_function() {
-//     scoped_refptr<MyFoo> foo = new MyFoo();
-//     ...
-//     foo = NULL;  // explicitly releases |foo|
-//     ...
-//     if (foo)
-//       foo->Method(param);
-//   }
-//
-// The above examples show how scoped_refptr<T> acts like a pointer to T.
-// Given two scoped_refptr<T> classes, it is also possible to exchange
-// references between the two objects, like so:
-//
-//   {
-//     scoped_refptr<MyFoo> a = new MyFoo();
-//     scoped_refptr<MyFoo> b;
-//
-//     b.swap(a);
-//     // now, |b| references the MyFoo object, and |a| references NULL.
-//   }
-//
-// To make both |a| and |b| in the above example reference the same MyFoo
-// object, simply use the assignment operator:
-//
-//   {
-//     scoped_refptr<MyFoo> a = new MyFoo();
-//     scoped_refptr<MyFoo> b;
-//
-//     b = a;
-//     // now, |a| and |b| each own a reference to the same MyFoo object.
-//   }
-//
-
-#ifndef TALK_BASE_SCOPED_REF_PTR_H_
-#define TALK_BASE_SCOPED_REF_PTR_H_
-
-namespace talk_base {
-
-template <class T>
-class scoped_refptr {
- public:
-  scoped_refptr() : ptr_(NULL) {
-  }
-
-  scoped_refptr(T* p) : ptr_(p) {
-    if (ptr_)
-      ptr_->AddRef();
-  }
-
-  scoped_refptr(const scoped_refptr<T>& r) : ptr_(r.ptr_) {
-    if (ptr_)
-      ptr_->AddRef();
-  }
-
-  template <typename U>
-  scoped_refptr(const scoped_refptr<U>& r) : ptr_(r.get()) {
-    if (ptr_)
-      ptr_->AddRef();
-  }
-
-  ~scoped_refptr() {
-    if (ptr_)
-      ptr_->Release();
-  }
-
-  T* get() const { return ptr_; }
-  operator T*() const { return ptr_; }
-  T* operator->() const { return ptr_; }
-
-  // Release a pointer.
-  // The return value is the current pointer held by this object.
-  // If this object holds a NULL pointer, the return value is NULL.
-  // After this operation, this object will hold a NULL pointer,
-  // and will not own the object any more.
-  T* release() {
-    T* retVal = ptr_;
-    ptr_ = NULL;
-    return retVal;
-  }
-
-  scoped_refptr<T>& operator=(T* p) {
-    // AddRef first so that self assignment should work
-    if (p)
-      p->AddRef();
-    if (ptr_ )
-      ptr_ ->Release();
-    ptr_ = p;
-    return *this;
-  }
-
-  scoped_refptr<T>& operator=(const scoped_refptr<T>& r) {
-    return *this = r.ptr_;
-  }
-
-  template <typename U>
-  scoped_refptr<T>& operator=(const scoped_refptr<U>& r) {
-    return *this = r.get();
-  }
-
-  void swap(T** pp) {
-    T* p = ptr_;
-    ptr_ = *pp;
-    *pp = p;
-  }
-
-  void swap(scoped_refptr<T>& r) {
-    swap(&r.ptr_);
-  }
-
- protected:
-  T* ptr_;
-};
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_SCOPED_REF_PTR_H_
diff --git a/third_party/libjingle/source/talk/base/sec_buffer.h b/third_party/libjingle/source/talk/base/sec_buffer.h
deleted file mode 100644
index 585e27f..0000000
--- a/third_party/libjingle/source/talk/base/sec_buffer.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// @file Contains utility classes that make it easier to use SecBuffers
-
-#ifndef TALK_BASE_SEC_BUFFER_H__
-#define TALK_BASE_SEC_BUFFER_H__
-
-namespace talk_base {
-
-// A base class for CSecBuffer<T>. Contains
-// all implementation that does not require
-// template arguments.
-class CSecBufferBase : public SecBuffer {
- public:
-  CSecBufferBase() {
-    Clear();
-  }
-
-  // Uses the SSPI to free a pointer, must be
-  // used for buffers returned from SSPI APIs.
-  static void FreeSSPI(void *ptr) {
-    if ( ptr ) {
-      SECURITY_STATUS status;
-      status = ::FreeContextBuffer(ptr);
-      ASSERT(SEC_E_OK == status); // "Freeing context buffer"
-    }
-  }
-
-  // Deletes a buffer with operator delete
-  static void FreeDelete(void *ptr) {
-    delete [] reinterpret_cast<char*>(ptr);
-  }
-
-  // A noop delete, for buffers over other
-  // people's memory
-  static void FreeNone(void *ptr) {
-  }
-
- protected:
-  // Clears the buffer to EMPTY & NULL
-  void Clear() {
-    this->BufferType = SECBUFFER_EMPTY;
-    this->cbBuffer = 0;
-    this->pvBuffer = NULL;
-  }
-};
-
-// Wrapper class for SecBuffer to take care
-// of initialization and destruction.
-template <void (*pfnFreeBuffer)(void *ptr)>
-class CSecBuffer: public CSecBufferBase {
- public:
-  // Initializes buffer to empty & NULL
-  CSecBuffer() {
-  }
-
-  // Frees any allocated memory
-  ~CSecBuffer() {
-    Release();
-  }
-
-  // Frees the buffer appropriately, and re-nulls
-  void Release() {
-    pfnFreeBuffer(this->pvBuffer);
-    Clear();
-  }
-
- private:
-  // A placeholder function for compile-time asserts on the class
-  void CompileAsserts() {
-    // never invoked...
-    assert(false); // _T("Notreached")
-
-    // This class must not extend the size of SecBuffer, since
-    // we use arrays of CSecBuffer in CSecBufferBundle below
-    cassert(sizeof(CSecBuffer<SSPIFree> == sizeof(SecBuffer)));
-  }
-};
-
-// Contains all generic implementation for the
-// SecBufferBundle class
-class SecBufferBundleBase {
- public:
-};
-
-// A template class that bundles a SecBufferDesc with
-// one or more SecBuffers for convenience. Can take
-// care of deallocating buffers appropriately, as indicated
-// by pfnFreeBuffer function.
-// By default does no deallocation.
-template <int num_buffers,
-          void (*pfnFreeBuffer)(void *ptr) = CSecBufferBase::FreeNone>
-class CSecBufferBundle : public SecBufferBundleBase {
- public:
-  // Constructs a security buffer bundle with num_buffers
-  // buffers, all of which are empty and nulled.
-  CSecBufferBundle() {
-    desc_.ulVersion = SECBUFFER_VERSION;
-    desc_.cBuffers = num_buffers;
-    desc_.pBuffers = buffers_;
-  }
-
-  // Frees all currently used buffers.
-  ~CSecBufferBundle() {
-    Release();
-  }
-
-  // Accessor for the descriptor
-  PSecBufferDesc desc() {
-    return &desc_;
-  }
-
-  // Accessor for the descriptor
-  const PSecBufferDesc desc() const {
-    return &desc_;
-  }
-
-  // returns the i-th security buffer
-  SecBuffer &operator[] (size_t num) {
-    ASSERT(num < num_buffers); // "Buffer index out of bounds"
-    return buffers_[num];
-  }
-
-  // returns the i-th security buffer
-  const SecBuffer &operator[] (size_t num) const {
-    ASSERT(num < num_buffers); // "Buffer index out of bounds"
-    return buffers_[num];
-  }
-
-  // Frees all non-NULL security buffers,
-  // using the deallocation function
-  void Release() {
-    for ( size_t i = 0; i < num_buffers; ++i ) {
-      buffers_[i].Release();
-    }
-  }
-
- private:
-  // Our descriptor
-  SecBufferDesc               desc_;
-  // Our bundled buffers, each takes care of its own
-  // initialization and destruction
-  CSecBuffer<pfnFreeBuffer>   buffers_[num_buffers];
-};
-
-} // namespace talk_base
-
-#endif  // TALK_BASE_SEC_BUFFER_H__
diff --git a/third_party/libjingle/source/talk/base/sharedexclusivelock.cc b/third_party/libjingle/source/talk/base/sharedexclusivelock.cc
deleted file mode 100644
index 0b0439a..0000000
--- a/third_party/libjingle/source/talk/base/sharedexclusivelock.cc
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * libjingle
- * Copyright 2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/sharedexclusivelock.h"
-
-namespace talk_base {
-
-SharedExclusiveLock::SharedExclusiveLock()
-    : shared_count_is_zero_(true, true),
-      shared_count_(0) {
-}
-
-void SharedExclusiveLock::LockExclusive() {
-  cs_exclusive_.Enter();
-  shared_count_is_zero_.Wait(talk_base::kForever);
-}
-
-void SharedExclusiveLock::UnlockExclusive() {
-  cs_exclusive_.Leave();
-}
-
-void SharedExclusiveLock::LockShared() {
-  CritScope exclusive_scope(&cs_exclusive_);
-  CritScope shared_scope(&cs_shared_);
-  if (++shared_count_ == 1) {
-    shared_count_is_zero_.Reset();
-  }
-}
-
-void SharedExclusiveLock::UnlockShared() {
-  CritScope shared_scope(&cs_shared_);
-  if (--shared_count_ == 0) {
-    shared_count_is_zero_.Set();
-  }
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/sharedexclusivelock.h b/third_party/libjingle/source/talk/base/sharedexclusivelock.h
deleted file mode 100644
index 2bdd854..0000000
--- a/third_party/libjingle/source/talk/base/sharedexclusivelock.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * libjingle
- * Copyright 2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_SHAREDEXCLUSIVELOCK_H_
-#define TALK_BASE_SHAREDEXCLUSIVELOCK_H_
-
-#include "talk/base/constructormagic.h"
-#include "talk/base/criticalsection.h"
-#include "talk/base/event.h"
-
-namespace talk_base {
-
-// This class provides shared-exclusive lock. It can be used in cases like
-// multiple-readers/single-writer model.
-class SharedExclusiveLock {
- public:
-  SharedExclusiveLock();
-
-  // Locking/unlocking methods. It is encouraged to use SharedScope or
-  // ExclusiveScope for protection.
-  void LockExclusive();
-  void UnlockExclusive();
-  void LockShared();
-  void UnlockShared();
-
- private:
-  talk_base::CriticalSection cs_exclusive_;
-  talk_base::CriticalSection cs_shared_;
-  talk_base::Event shared_count_is_zero_;
-  int shared_count_;
-
-  DISALLOW_COPY_AND_ASSIGN(SharedExclusiveLock);
-};
-
-class SharedScope {
- public:
-  explicit SharedScope(SharedExclusiveLock* lock) : lock_(lock) {
-    lock_->LockShared();
-  }
-
-  ~SharedScope() {
-    lock_->UnlockShared();
-  }
-
- private:
-  SharedExclusiveLock* lock_;
-
-  DISALLOW_COPY_AND_ASSIGN(SharedScope);
-};
-
-class ExclusiveScope {
- public:
-  explicit ExclusiveScope(SharedExclusiveLock* lock) : lock_(lock) {
-    lock_->LockExclusive();
-  }
-
-  ~ExclusiveScope() {
-    lock_->UnlockExclusive();
-  }
-
- private:
-  SharedExclusiveLock* lock_;
-
-  DISALLOW_COPY_AND_ASSIGN(ExclusiveScope);
-};
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_SHAREDEXCLUSIVELOCK_H_
diff --git a/third_party/libjingle/source/talk/base/sharedexclusivelock_unittest.cc b/third_party/libjingle/source/talk/base/sharedexclusivelock_unittest.cc
deleted file mode 100644
index 46b7fdf..0000000
--- a/third_party/libjingle/source/talk/base/sharedexclusivelock_unittest.cc
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * libjingle
- * Copyright 2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/common.h"
-#include "talk/base/gunit.h"
-#include "talk/base/messagehandler.h"
-#include "talk/base/messagequeue.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/base/sharedexclusivelock.h"
-#include "talk/base/thread.h"
-#include "talk/base/timeutils.h"
-
-namespace talk_base {
-
-static const uint32 kMsgRead = 0;
-static const uint32 kMsgWrite = 0;
-static const int kNoWaitThresholdInMs = 10;
-static const int kWaitThresholdInMs = 80;
-static const int kProcessTimeInMs = 100;
-static const int kProcessTimeoutInMs = 5000;
-
-class SharedExclusiveTask : public MessageHandler {
- public:
-  SharedExclusiveTask(SharedExclusiveLock* shared_exclusive_lock,
-                      int* value,
-                      bool* done)
-      : shared_exclusive_lock_(shared_exclusive_lock),
-        waiting_time_in_ms_(0),
-        value_(value),
-        done_(done) {
-    worker_thread_.reset(new Thread());
-    worker_thread_->Start();
-  }
-
-  int waiting_time_in_ms() const { return waiting_time_in_ms_; }
-
- protected:
-  scoped_ptr<Thread> worker_thread_;
-  SharedExclusiveLock* shared_exclusive_lock_;
-  int waiting_time_in_ms_;
-  int* value_;
-  bool* done_;
-};
-
-class ReadTask : public SharedExclusiveTask {
- public:
-  ReadTask(SharedExclusiveLock* shared_exclusive_lock, int* value, bool* done)
-      : SharedExclusiveTask(shared_exclusive_lock, value, done) {
-  }
-
-  void PostRead(int* value) {
-    worker_thread_->Post(this, kMsgRead, new TypedMessageData<int*>(value));
-  }
-
- private:
-  virtual void OnMessage(Message* message) {
-    ASSERT(talk_base::Thread::Current() == worker_thread_.get());
-    ASSERT(message != NULL);
-    ASSERT(message->message_id == kMsgRead);
-
-    TypedMessageData<int*>* message_data =
-        static_cast<TypedMessageData<int*>*>(message->pdata);
-
-    uint32 start_time = Time();
-    {
-      SharedScope ss(shared_exclusive_lock_);
-      waiting_time_in_ms_ = TimeDiff(Time(), start_time);
-
-      Thread::SleepMs(kProcessTimeInMs);
-      *message_data->data() = *value_;
-      *done_ = true;
-    }
-    delete message->pdata;
-    message->pdata = NULL;
-  }
-};
-
-class WriteTask : public SharedExclusiveTask {
- public:
-  WriteTask(SharedExclusiveLock* shared_exclusive_lock, int* value, bool* done)
-      : SharedExclusiveTask(shared_exclusive_lock, value, done) {
-  }
-
-  void PostWrite(int value) {
-    worker_thread_->Post(this, kMsgWrite, new TypedMessageData<int>(value));
-  }
-
- private:
-  virtual void OnMessage(Message* message) {
-    ASSERT(talk_base::Thread::Current() == worker_thread_.get());
-    ASSERT(message != NULL);
-    ASSERT(message->message_id == kMsgWrite);
-
-    TypedMessageData<int>* message_data =
-        static_cast<TypedMessageData<int>*>(message->pdata);
-
-    uint32 start_time = Time();
-    {
-      ExclusiveScope es(shared_exclusive_lock_);
-      waiting_time_in_ms_ = TimeDiff(Time(), start_time);
-
-      Thread::SleepMs(kProcessTimeInMs);
-      *value_ = message_data->data();
-      *done_ = true;
-    }
-    delete message->pdata;
-    message->pdata = NULL;
-  }
-};
-
-// Unit test for SharedExclusiveLock.
-class SharedExclusiveLockTest
-    : public testing::Test {
- public:
-  SharedExclusiveLockTest() : value_(0) {
-  }
-
-  virtual void SetUp() {
-    shared_exclusive_lock_.reset(new SharedExclusiveLock());
-  }
-
- protected:
-  scoped_ptr<SharedExclusiveLock> shared_exclusive_lock_;
-  int value_;
-};
-
-TEST_F(SharedExclusiveLockTest, TestSharedShared) {
-  int value0, value1;
-  bool done0, done1;
-  ReadTask reader0(shared_exclusive_lock_.get(), &value_, &done0);
-  ReadTask reader1(shared_exclusive_lock_.get(), &value_, &done1);
-
-  // Test shared locks can be shared without waiting.
-  {
-    SharedScope ss(shared_exclusive_lock_.get());
-    value_ = 1;
-    done0 = false;
-    done1 = false;
-    reader0.PostRead(&value0);
-    reader1.PostRead(&value1);
-    Thread::SleepMs(kProcessTimeInMs);
-  }
-
-  EXPECT_TRUE_WAIT(done0, kProcessTimeoutInMs);
-  EXPECT_EQ(1, value0);
-  EXPECT_LE(reader0.waiting_time_in_ms(), kNoWaitThresholdInMs);
-  EXPECT_TRUE_WAIT(done1, kProcessTimeoutInMs);
-  EXPECT_EQ(1, value1);
-  EXPECT_LE(reader1.waiting_time_in_ms(), kNoWaitThresholdInMs);
-}
-
-TEST_F(SharedExclusiveLockTest, TestSharedExclusive) {
-  bool done;
-  WriteTask writer(shared_exclusive_lock_.get(), &value_, &done);
-
-  // Test exclusive lock needs to wait for shared lock.
-  {
-    SharedScope ss(shared_exclusive_lock_.get());
-    value_ = 1;
-    done = false;
-    writer.PostWrite(2);
-    Thread::SleepMs(kProcessTimeInMs);
-    EXPECT_EQ(1, value_);
-  }
-
-  EXPECT_TRUE_WAIT(done, kProcessTimeoutInMs);
-  EXPECT_EQ(2, value_);
-  EXPECT_GE(writer.waiting_time_in_ms(), kWaitThresholdInMs);
-}
-
-TEST_F(SharedExclusiveLockTest, TestExclusiveShared) {
-  int value;
-  bool done;
-  ReadTask reader(shared_exclusive_lock_.get(), &value_, &done);
-
-  // Test shared lock needs to wait for exclusive lock.
-  {
-    ExclusiveScope es(shared_exclusive_lock_.get());
-    value_ = 1;
-    done = false;
-    reader.PostRead(&value);
-    Thread::SleepMs(kProcessTimeInMs);
-    value_ = 2;
-  }
-
-  EXPECT_TRUE_WAIT(done, kProcessTimeoutInMs);
-  EXPECT_EQ(2, value);
-  EXPECT_GE(reader.waiting_time_in_ms(), kWaitThresholdInMs);
-}
-
-TEST_F(SharedExclusiveLockTest, TestExclusiveExclusive) {
-  bool done;
-  WriteTask writer(shared_exclusive_lock_.get(), &value_, &done);
-
-  // Test exclusive lock needs to wait for exclusive lock.
-  {
-    ExclusiveScope es(shared_exclusive_lock_.get());
-    value_ = 1;
-    done = false;
-    writer.PostWrite(2);
-    Thread::SleepMs(kProcessTimeInMs);
-    EXPECT_EQ(1, value_);
-  }
-
-  EXPECT_TRUE_WAIT(done, kProcessTimeoutInMs);
-  EXPECT_EQ(2, value_);
-  EXPECT_GE(writer.waiting_time_in_ms(), kWaitThresholdInMs);
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/signalthread.cc b/third_party/libjingle/source/talk/base/signalthread.cc
deleted file mode 100644
index 88f3ff7..0000000
--- a/third_party/libjingle/source/talk/base/signalthread.cc
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2009, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/signalthread.h"
-
-#include "talk/base/common.h"
-
-namespace talk_base {
-
-///////////////////////////////////////////////////////////////////////////////
-// SignalThread
-///////////////////////////////////////////////////////////////////////////////
-
-SignalThread::SignalThread()
-    : main_(Thread::Current()),
-      worker_(this),
-      state_(kInit),
-      refcount_(1) {
-  main_->SignalQueueDestroyed.connect(this,
-                                      &SignalThread::OnMainThreadDestroyed);
-  worker_.SetName("SignalThread", this);
-}
-
-SignalThread::~SignalThread() {
-  ASSERT(refcount_ == 0);
-}
-
-bool SignalThread::SetName(const std::string& name, const void* obj) {
-  EnterExit ee(this);
-  ASSERT(main_->IsCurrent());
-  ASSERT(kInit == state_);
-  return worker_.SetName(name, obj);
-}
-
-bool SignalThread::SetPriority(ThreadPriority priority) {
-  EnterExit ee(this);
-  ASSERT(main_->IsCurrent());
-  ASSERT(kInit == state_);
-  return worker_.SetPriority(priority);
-}
-
-void SignalThread::Start() {
-  EnterExit ee(this);
-  ASSERT(main_->IsCurrent());
-  if (kInit == state_ || kComplete == state_) {
-    state_ = kRunning;
-    OnWorkStart();
-    worker_.Start();
-  } else {
-    ASSERT(false);
-  }
-}
-
-void SignalThread::Destroy(bool wait) {
-  EnterExit ee(this);
-  ASSERT(main_->IsCurrent());
-  if ((kInit == state_) || (kComplete == state_)) {
-    refcount_--;
-  } else if (kRunning == state_ || kReleasing == state_) {
-    state_ = kStopping;
-    // OnWorkStop() must follow Quit(), so that when the thread wakes up due to
-    // OWS(), ContinueWork() will return false.
-    worker_.Quit();
-    OnWorkStop();
-    if (wait) {
-      // Release the thread's lock so that it can return from ::Run.
-      cs_.Leave();
-      worker_.Stop();
-      cs_.Enter();
-      refcount_--;
-    }
-  } else {
-    ASSERT(false);
-  }
-}
-
-void SignalThread::Release() {
-  EnterExit ee(this);
-  ASSERT(main_->IsCurrent());
-  if (kComplete == state_) {
-    refcount_--;
-  } else if (kRunning == state_) {
-    state_ = kReleasing;
-  } else {
-    // if (kInit == state_) use Destroy()
-    ASSERT(false);
-  }
-}
-
-bool SignalThread::ContinueWork() {
-  EnterExit ee(this);
-  ASSERT(worker_.IsCurrent());
-  return worker_.ProcessMessages(0);
-}
-
-void SignalThread::OnMessage(Message *msg) {
-  EnterExit ee(this);
-  if (ST_MSG_WORKER_DONE == msg->message_id) {
-    ASSERT(main_->IsCurrent());
-    OnWorkDone();
-    bool do_delete = false;
-    if (kRunning == state_) {
-      state_ = kComplete;
-    } else {
-      do_delete = true;
-    }
-    if (kStopping != state_) {
-      // Before signaling that the work is done, make sure that the worker
-      // thread actually is done. We got here because DoWork() finished and
-      // Run() posted the ST_MSG_WORKER_DONE message. This means the worker
-      // thread is about to go away anyway, but sometimes it doesn't actually
-      // finish before SignalWorkDone is processed, and for a reusable
-      // SignalThread this makes an assert in thread.cc fire.
-      //
-      // Calling Stop() on the worker ensures that the OS thread that underlies
-      // the worker will finish, and will be set to NULL, enabling us to call
-      // Start() again.
-      worker_.Stop();
-      SignalWorkDone(this);
-    }
-    if (do_delete) {
-      refcount_--;
-    }
-  }
-}
-
-void SignalThread::Run() {
-  DoWork();
-  {
-    EnterExit ee(this);
-    if (main_) {
-      main_->Post(this, ST_MSG_WORKER_DONE);
-    }
-  }
-}
-
-void SignalThread::OnMainThreadDestroyed() {
-  EnterExit ee(this);
-  main_ = NULL;
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/signalthread.h b/third_party/libjingle/source/talk/base/signalthread.h
deleted file mode 100644
index e7f2994..0000000
--- a/third_party/libjingle/source/talk/base/signalthread.h
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2009, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_SIGNALTHREAD_H_
-#define TALK_BASE_SIGNALTHREAD_H_
-
-#include <string>
-
-#include "talk/base/constructormagic.h"
-#include "talk/base/thread.h"
-#include "talk/base/sigslot.h"
-
-namespace talk_base {
-
-///////////////////////////////////////////////////////////////////////////////
-// SignalThread - Base class for worker threads.  The main thread should call
-//  Start() to begin work, and then follow one of these models:
-//   Normal: Wait for SignalWorkDone, and then call Release to destroy.
-//   Cancellation: Call Release(true), to abort the worker thread.
-//   Fire-and-forget: Call Release(false), which allows the thread to run to
-//    completion, and then self-destruct without further notification.
-//   Periodic tasks: Wait for SignalWorkDone, then eventually call Start()
-//    again to repeat the task. When the instance isn't needed anymore,
-//    call Release. DoWork, OnWorkStart and OnWorkStop are called again,
-//    on a new thread.
-//  The subclass should override DoWork() to perform the background task.  By
-//   periodically calling ContinueWork(), it can check for cancellation.
-//   OnWorkStart and OnWorkDone can be overridden to do pre- or post-work
-//   tasks in the context of the main thread.
-///////////////////////////////////////////////////////////////////////////////
-
-class SignalThread : public sigslot::has_slots<>, protected MessageHandler {
- public:
-  SignalThread();
-
-  // Context: Main Thread.  Call before Start to change the worker's name.
-  bool SetName(const std::string& name, const void* obj);
-
-  // Context: Main Thread.  Call before Start to change the worker's priority.
-  bool SetPriority(ThreadPriority priority);
-
-  // Context: Main Thread.  Call to begin the worker thread.
-  void Start();
-
-  // Context: Main Thread.  If the worker thread is not running, deletes the
-  // object immediately.  Otherwise, asks the worker thread to abort processing,
-  // and schedules the object to be deleted once the worker exits.
-  // SignalWorkDone will not be signalled.  If wait is true, does not return
-  // until the thread is deleted.
-  void Destroy(bool wait);
-
-  // Context: Main Thread.  If the worker thread is complete, deletes the
-  // object immediately.  Otherwise, schedules the object to be deleted once
-  // the worker thread completes.  SignalWorkDone will be signalled.
-  void Release();
-
-  // Context: Main Thread.  Signalled when work is complete.
-  sigslot::signal1<SignalThread *> SignalWorkDone;
-
-  enum { ST_MSG_WORKER_DONE, ST_MSG_FIRST_AVAILABLE };
-
- protected:
-  virtual ~SignalThread();
-
-  Thread* worker() { return &worker_; }
-
-  // Context: Main Thread.  Subclass should override to do pre-work setup.
-  virtual void OnWorkStart() { }
-
-  // Context: Worker Thread.  Subclass should override to do work.
-  virtual void DoWork() = 0;
-
-  // Context: Worker Thread.  Subclass should call periodically to
-  // dispatch messages and determine if the thread should terminate.
-  bool ContinueWork();
-
-  // Context: Worker Thread.  Subclass should override when extra work is
-  // needed to abort the worker thread.
-  virtual void OnWorkStop() { }
-
-  // Context: Main Thread.  Subclass should override to do post-work cleanup.
-  virtual void OnWorkDone() { }
-
-  // Context: Any Thread.  If subclass overrides, be sure to call the base
-  // implementation.  Do not use (message_id < ST_MSG_FIRST_AVAILABLE)
-  virtual void OnMessage(Message *msg);
-
- private:
-  enum State {
-    kInit,            // Initialized, but not started
-    kRunning,         // Started and doing work
-    kReleasing,       // Same as running, but to be deleted when work is done
-    kComplete,        // Work is done
-    kStopping,        // Work is being interrupted
-  };
-
-  class Worker : public Thread {
-   public:
-    explicit Worker(SignalThread* parent) : parent_(parent) {}
-    virtual void Run() { parent_->Run(); }
-
-   private:
-    SignalThread* parent_;
-
-    DISALLOW_IMPLICIT_CONSTRUCTORS(Worker);
-  };
-
-  class EnterExit {
-   public:
-    explicit EnterExit(SignalThread* t) : t_(t) {
-      t_->cs_.Enter();
-      // If refcount_ is zero then the object has already been deleted and we
-      // will be double-deleting it in ~EnterExit()! (shouldn't happen)
-      ASSERT(t_->refcount_ != 0);
-      ++t_->refcount_;
-    }
-    ~EnterExit() {
-      bool d = (0 == --t_->refcount_);
-      t_->cs_.Leave();
-      if (d)
-        delete t_;
-    }
-
-   private:
-    SignalThread* t_;
-
-    DISALLOW_IMPLICIT_CONSTRUCTORS(EnterExit);
-  };
-
-  void Run();
-  void OnMainThreadDestroyed();
-
-  Thread* main_;
-  Worker worker_;
-  CriticalSection cs_;
-  State state_;
-  int refcount_;
-
-  DISALLOW_COPY_AND_ASSIGN(SignalThread);
-};
-
-///////////////////////////////////////////////////////////////////////////////
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_SIGNALTHREAD_H_
diff --git a/third_party/libjingle/source/talk/base/signalthread_unittest.cc b/third_party/libjingle/source/talk/base/signalthread_unittest.cc
deleted file mode 100644
index 91665aa..0000000
--- a/third_party/libjingle/source/talk/base/signalthread_unittest.cc
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/gunit.h"
-#include "talk/base/signalthread.h"
-#include "talk/base/thread.h"
-
-using namespace talk_base;
-
-class SignalThreadTest : public testing::Test, public sigslot::has_slots<> {
- public:
-  class SlowSignalThread : public SignalThread {
-   public:
-    SlowSignalThread(SignalThreadTest* harness) : harness_(harness) {
-    }
-
-    virtual ~SlowSignalThread() {
-      EXPECT_EQ(harness_->main_thread_, Thread::Current());
-      ++harness_->thread_deleted_;
-    }
-
-    const SignalThreadTest* harness() { return harness_; }
-
-   protected:
-    virtual void OnWorkStart() {
-      ASSERT_TRUE(harness_ != NULL);
-      ++harness_->thread_started_;
-      EXPECT_EQ(harness_->main_thread_, Thread::Current());
-      EXPECT_FALSE(worker()->started());  // not started yet
-    }
-
-    virtual void OnWorkStop() {
-      ++harness_->thread_stopped_;
-      EXPECT_EQ(harness_->main_thread_, Thread::Current());
-      EXPECT_TRUE(worker()->started());  // not stopped yet
-    }
-
-    virtual void OnWorkDone() {
-      ++harness_->thread_done_;
-      EXPECT_EQ(harness_->main_thread_, Thread::Current());
-      EXPECT_TRUE(worker()->started());  // not stopped yet
-    }
-
-    virtual void DoWork() {
-      EXPECT_NE(harness_->main_thread_, Thread::Current());
-      EXPECT_EQ(worker(), Thread::Current());
-      Thread::Current()->socketserver()->Wait(250, false);
-    }
-
-   private:
-    SignalThreadTest* harness_;
-    DISALLOW_EVIL_CONSTRUCTORS(SlowSignalThread);
-  };
-
-  void OnWorkComplete(talk_base::SignalThread* thread) {
-    SlowSignalThread* t = static_cast<SlowSignalThread*>(thread);
-    EXPECT_EQ(t->harness(), this);
-    EXPECT_EQ(main_thread_, Thread::Current());
-
-    ++thread_completed_;
-    if (!called_release_) {
-      thread->Release();
-    }
-  }
-
-  virtual void SetUp() {
-    main_thread_ = Thread::Current();
-    thread_ = new SlowSignalThread(this);
-    thread_->SignalWorkDone.connect(this, &SignalThreadTest::OnWorkComplete);
-    called_release_ = false;
-    thread_started_ = 0;
-    thread_done_ = 0;
-    thread_completed_ = 0;
-    thread_stopped_ = 0;
-    thread_deleted_ = 0;
-  }
-
-  virtual void TearDown() {
-  }
-
-  Thread* main_thread_;
-  SlowSignalThread* thread_;
-  bool called_release_;
-
-  int thread_started_;
-  int thread_done_;
-  int thread_completed_;
-  int thread_stopped_;
-  int thread_deleted_;
-};
-
-class OwnerThread : public Thread, public sigslot::has_slots<> {
- public:
-  OwnerThread(SignalThreadTest* harness) : harness_(harness) {
-  }
-
-  virtual void Run() {
-    SignalThreadTest::SlowSignalThread* signal_thread =
-        new SignalThreadTest::SlowSignalThread(harness_);
-    signal_thread->SignalWorkDone.connect(this, &OwnerThread::OnWorkDone);
-    signal_thread->Start();
-    Thread::Current()->socketserver()->Wait(100, false);
-    signal_thread->Release();
-  }
-
-  void OnWorkDone(SignalThread* signal_thread) {
-    FAIL() << " This shouldn't get called.";
-  }
-
- private:
-  SignalThreadTest* harness_;
-  DISALLOW_EVIL_CONSTRUCTORS(OwnerThread);
-};
-
-// Test for when the main thread goes away while the
-// signal thread is still working.  This may happen
-// when shutting down the process.
-TEST_F(SignalThreadTest, OwnerThreadGoesAway) {
-  {
-    scoped_ptr<OwnerThread> owner(new OwnerThread(this));
-    main_thread_ = owner.get();
-    owner->Start();
-    Thread::Current()->socketserver()->Wait(200, false);
-  }
-  // At this point the main thread has gone away.
-  // Give the SignalThread a little time to do its callback,
-  // which will crash if the signal thread doesn't handle
-  // this situation well.
-  Thread::Current()->socketserver()->Wait(500, false);
-}
-
-#define EXPECT_STATE(started, done, completed, stopped, deleted) \
-  EXPECT_EQ(started, thread_started_); \
-  EXPECT_EQ(done, thread_done_); \
-  EXPECT_EQ(completed, thread_completed_); \
-  EXPECT_EQ(stopped, thread_stopped_); \
-  EXPECT_EQ(deleted, thread_deleted_);
-
-TEST_F(SignalThreadTest, ThreadFinishes) {
-  thread_->Start();
-  EXPECT_STATE(1, 0, 0, 0, 0);
-  Thread::SleepMs(500);
-  EXPECT_STATE(1, 0, 0, 0, 0);
-  Thread::Current()->ProcessMessages(0);
-  EXPECT_STATE(1, 1, 1, 0, 1);
-}
-
-TEST_F(SignalThreadTest, ReleasedThreadFinishes) {
-  thread_->Start();
-  EXPECT_STATE(1, 0, 0, 0, 0);
-  thread_->Release();
-  called_release_ = true;
-  EXPECT_STATE(1, 0, 0, 0, 0);
-  Thread::SleepMs(500);
-  EXPECT_STATE(1, 0, 0, 0, 0);
-  Thread::Current()->ProcessMessages(0);
-  EXPECT_STATE(1, 1, 1, 0, 1);
-}
-
-TEST_F(SignalThreadTest, DestroyedThreadCleansUp) {
-  thread_->Start();
-  EXPECT_STATE(1, 0, 0, 0, 0);
-  thread_->Destroy(true);
-  EXPECT_STATE(1, 0, 0, 1, 1);
-  Thread::Current()->ProcessMessages(0);
-  EXPECT_STATE(1, 0, 0, 1, 1);
-}
-
-TEST_F(SignalThreadTest, DeferredDestroyedThreadCleansUp) {
-  thread_->Start();
-  EXPECT_STATE(1, 0, 0, 0, 0);
-  thread_->Destroy(false);
-  EXPECT_STATE(1, 0, 0, 1, 0);
-  Thread::SleepMs(500);
-  EXPECT_STATE(1, 0, 0, 1, 0);
-  Thread::Current()->ProcessMessages(0);
-  EXPECT_STATE(1, 1, 0, 1, 1);
-}
diff --git a/third_party/libjingle/source/talk/base/sigslot.h b/third_party/libjingle/source/talk/base/sigslot.h
deleted file mode 100644
index e4af30e..0000000
--- a/third_party/libjingle/source/talk/base/sigslot.h
+++ /dev/null
@@ -1,2817 +0,0 @@
-// sigslot.h: Signal/Slot classes
-// 
-// Written by Sarah Thompson (sarah@telergy.com) 2002.
-//
-// License: Public domain. You are free to use this code however you like, with the proviso that
-//          the author takes on no responsibility or liability for any use.
-//
-// QUICK DOCUMENTATION 
-//		
-//				(see also the full documentation at http://sigslot.sourceforge.net/)
-//
-//		#define switches
-//			SIGSLOT_PURE_ISO			- Define this to force ISO C++ compliance. This also disables
-//										  all of the thread safety support on platforms where it is 
-//										  available.
-//
-//			SIGSLOT_USE_POSIX_THREADS	- Force use of Posix threads when using a C++ compiler other than
-//										  gcc on a platform that supports Posix threads. (When using gcc,
-//										  this is the default - use SIGSLOT_PURE_ISO to disable this if 
-//										  necessary)
-//
-//			SIGSLOT_DEFAULT_MT_POLICY	- Where thread support is enabled, this defaults to multi_threaded_global.
-//										  Otherwise, the default is single_threaded. #define this yourself to
-//										  override the default. In pure ISO mode, anything other than
-//										  single_threaded will cause a compiler error.
-//
-//		PLATFORM NOTES
-//
-//			Win32						- On Win32, the WIN32 symbol must be #defined. Most mainstream
-//										  compilers do this by default, but you may need to define it
-//										  yourself if your build environment is less standard. This causes
-//										  the Win32 thread support to be compiled in and used automatically.
-//
-//			Unix/Linux/BSD, etc.		- If you're using gcc, it is assumed that you have Posix threads
-//										  available, so they are used automatically. You can override this
-//										  (as under Windows) with the SIGSLOT_PURE_ISO switch. If you're using
-//										  something other than gcc but still want to use Posix threads, you
-//										  need to #define SIGSLOT_USE_POSIX_THREADS.
-//
-//			ISO C++						- If none of the supported platforms are detected, or if
-//										  SIGSLOT_PURE_ISO is defined, all multithreading support is turned off,
-//										  along with any code that might cause a pure ISO C++ environment to
-//										  complain. Before you ask, gcc -ansi -pedantic won't compile this 
-//										  library, but gcc -ansi is fine. Pedantic mode seems to throw a lot of
-//										  errors that aren't really there. If you feel like investigating this,
-//										  please contact the author.
-//
-//		
-//		THREADING MODES
-//
-//			single_threaded				- Your program is assumed to be single threaded from the point of view
-//										  of signal/slot usage (i.e. all objects using signals and slots are
-//										  created and destroyed from a single thread). Behaviour if objects are
-//										  destroyed concurrently is undefined (i.e. you'll get the occasional
-//										  segmentation fault/memory exception).
-//
-//			multi_threaded_global		- Your program is assumed to be multi threaded. Objects using signals and
-//										  slots can be safely created and destroyed from any thread, even when
-//										  connections exist. In multi_threaded_global mode, this is achieved by a
-//										  single global mutex (actually a critical section on Windows because they
-//										  are faster). This option uses less OS resources, but results in more
-//										  opportunities for contention, possibly resulting in more context switches
-//										  than are strictly necessary.
-//
-//			multi_threaded_local		- Behaviour in this mode is essentially the same as multi_threaded_global,
-//										  except that each signal, and each object that inherits has_slots, all 
-//										  have their own mutex/critical section. In practice, this means that
-//										  mutex collisions (and hence context switches) only happen if they are
-//										  absolutely essential. However, on some platforms, creating a lot of 
-//										  mutexes can slow down the whole OS, so use this option with care.
-//
-//		USING THE LIBRARY
-//
-//			See the full documentation at http://sigslot.sourceforge.net/
-//
-//
-
-#ifndef TALK_BASE_SIGSLOT_H__
-#define TALK_BASE_SIGSLOT_H__
-
-#include <list>
-#include <set>
-#include <stdlib.h>
-
-// On our copy of sigslot.h, we force single threading
-#define SIGSLOT_PURE_ISO
-
-#if defined(SIGSLOT_PURE_ISO) || (!defined(WIN32) && !defined(__GNUG__) && !defined(SIGSLOT_USE_POSIX_THREADS))
-#	define _SIGSLOT_SINGLE_THREADED
-#elif defined(WIN32)
-#	define _SIGSLOT_HAS_WIN32_THREADS
-#	include <windows.h>
-#elif defined(__GNUG__) || defined(SIGSLOT_USE_POSIX_THREADS)
-#	define _SIGSLOT_HAS_POSIX_THREADS
-#	include <pthread.h>
-#else
-#	define _SIGSLOT_SINGLE_THREADED
-#endif
-
-#ifndef SIGSLOT_DEFAULT_MT_POLICY
-#	ifdef _SIGSLOT_SINGLE_THREADED
-#		define SIGSLOT_DEFAULT_MT_POLICY single_threaded
-#	else
-#		define SIGSLOT_DEFAULT_MT_POLICY multi_threaded_local
-#	endif
-#endif
-
-// TODO: change this namespace to talk_base?
-namespace sigslot {
-
-	class single_threaded
-	{
-	public:
-		single_threaded()
-		{
-			;
-		}
-
-		virtual ~single_threaded()
-		{
-			;
-		}
-
-		virtual void lock()
-		{
-			;
-		}
-
-		virtual void unlock()
-		{
-			;
-		}
-	};
-
-#ifdef _SIGSLOT_HAS_WIN32_THREADS
-	// The multi threading policies only get compiled in if they are enabled.
-	class multi_threaded_global
-	{
-	public:
-		multi_threaded_global()
-		{
-			static bool isinitialised = false;
-
-			if(!isinitialised)
-			{
-				InitializeCriticalSection(get_critsec());
-				isinitialised = true;
-			}
-		}
-
-		multi_threaded_global(const multi_threaded_global&)
-		{
-			;
-		}
-
-		virtual ~multi_threaded_global()
-		{
-			;
-		}
-
-		virtual void lock()
-		{
-			EnterCriticalSection(get_critsec());
-		}
-
-		virtual void unlock()
-		{
-			LeaveCriticalSection(get_critsec());
-		}
-
-	private:
-		CRITICAL_SECTION* get_critsec()
-		{
-			static CRITICAL_SECTION g_critsec;
-			return &g_critsec;
-		}
-	};
-
-	class multi_threaded_local
-	{
-	public:
-		multi_threaded_local()
-		{
-			InitializeCriticalSection(&m_critsec);
-		}
-
-		multi_threaded_local(const multi_threaded_local&)
-		{
-			InitializeCriticalSection(&m_critsec);
-		}
-
-		virtual ~multi_threaded_local()
-		{
-			DeleteCriticalSection(&m_critsec);
-		}
-
-		virtual void lock()
-		{
-			EnterCriticalSection(&m_critsec);
-		}
-
-		virtual void unlock()
-		{
-			LeaveCriticalSection(&m_critsec);
-		}
-
-	private:
-		CRITICAL_SECTION m_critsec;
-	};
-#endif // _SIGSLOT_HAS_WIN32_THREADS
-
-#ifdef _SIGSLOT_HAS_POSIX_THREADS
-	// The multi threading policies only get compiled in if they are enabled.
-	class multi_threaded_global
-	{
-	public:
-		multi_threaded_global()
-		{
-			pthread_mutex_init(get_mutex(), NULL);
-		}
-
-		multi_threaded_global(const multi_threaded_global&)
-		{
-			;
-		}
-
-		virtual ~multi_threaded_global()
-		{
-			;
-		}
-
-		virtual void lock()
-		{
-			pthread_mutex_lock(get_mutex());
-		}
-
-		virtual void unlock()
-		{
-			pthread_mutex_unlock(get_mutex());
-		}
-
-	private:
-		pthread_mutex_t* get_mutex()
-		{
-			static pthread_mutex_t g_mutex;
-			return &g_mutex;
-		}
-	};
-
-	class multi_threaded_local
-	{
-	public:
-		multi_threaded_local()
-		{
-			pthread_mutex_init(&m_mutex, NULL);
-		}
-
-		multi_threaded_local(const multi_threaded_local&)
-		{
-			pthread_mutex_init(&m_mutex, NULL);
-		}
-
-		virtual ~multi_threaded_local()
-		{
-			pthread_mutex_destroy(&m_mutex);
-		}
-
-		virtual void lock()
-		{
-			pthread_mutex_lock(&m_mutex);
-		}
-
-		virtual void unlock()
-		{
-			pthread_mutex_unlock(&m_mutex);
-		}
-
-	private:
-		pthread_mutex_t m_mutex;
-	};
-#endif // _SIGSLOT_HAS_POSIX_THREADS
-
-	template<class mt_policy>
-	class lock_block
-	{
-	public:
-		mt_policy *m_mutex;
-
-		lock_block(mt_policy *mtx)
-			: m_mutex(mtx)
-		{
-			m_mutex->lock();
-		}
-
-		~lock_block()
-		{
-			m_mutex->unlock();
-		}
-	};
-
-	template<class mt_policy>
-	class has_slots;
-
-	template<class mt_policy>
-	class _connection_base0
-	{
-	public:
-		virtual ~_connection_base0() {}
-		virtual has_slots<mt_policy>* getdest() const = 0;
-		virtual void emit() = 0;
-		virtual _connection_base0* clone() = 0;
-		virtual _connection_base0* duplicate(has_slots<mt_policy>* pnewdest) = 0;
-	};
-
-	template<class arg1_type, class mt_policy>
-	class _connection_base1
-	{
-	public:
-		virtual ~_connection_base1() {}
-		virtual has_slots<mt_policy>* getdest() const = 0;
-		virtual void emit(arg1_type) = 0;
-		virtual _connection_base1<arg1_type, mt_policy>* clone() = 0;
-		virtual _connection_base1<arg1_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0;
-	};
-
-	template<class arg1_type, class arg2_type, class mt_policy>
-	class _connection_base2
-	{
-	public:
-		virtual ~_connection_base2() {}
-		virtual has_slots<mt_policy>* getdest() const = 0;
-		virtual void emit(arg1_type, arg2_type) = 0;
-		virtual _connection_base2<arg1_type, arg2_type, mt_policy>* clone() = 0;
-		virtual _connection_base2<arg1_type, arg2_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0;
-	};
-
-	template<class arg1_type, class arg2_type, class arg3_type, class mt_policy>
-	class _connection_base3
-	{
-	public:
-		virtual ~_connection_base3() {}
-		virtual has_slots<mt_policy>* getdest() const = 0;
-		virtual void emit(arg1_type, arg2_type, arg3_type) = 0;
-		virtual _connection_base3<arg1_type, arg2_type, arg3_type, mt_policy>* clone() = 0;
-		virtual _connection_base3<arg1_type, arg2_type, arg3_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0;
-	};
-
-	template<class arg1_type, class arg2_type, class arg3_type, class arg4_type, class mt_policy>
-	class _connection_base4
-	{
-	public:
-		virtual ~_connection_base4() {}
-		virtual has_slots<mt_policy>* getdest() const = 0;
-		virtual void emit(arg1_type, arg2_type, arg3_type, arg4_type) = 0;
-		virtual _connection_base4<arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>* clone() = 0;
-		virtual _connection_base4<arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0;
-	};
-
-	template<class arg1_type, class arg2_type, class arg3_type, class arg4_type,
-	class arg5_type, class mt_policy>
-	class _connection_base5
-	{
-	public:
-		virtual ~_connection_base5() {}
-		virtual has_slots<mt_policy>* getdest() const = 0;
-		virtual void emit(arg1_type, arg2_type, arg3_type, arg4_type, 
-			arg5_type) = 0;
-		virtual _connection_base5<arg1_type, arg2_type, arg3_type, arg4_type,
-			arg5_type, mt_policy>* clone() = 0;
-		virtual _connection_base5<arg1_type, arg2_type, arg3_type, arg4_type,
-			arg5_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0;
-	};
-
-	template<class arg1_type, class arg2_type, class arg3_type, class arg4_type,
-	class arg5_type, class arg6_type, class mt_policy>
-	class _connection_base6
-	{
-	public:
-		virtual ~_connection_base6() {}
-		virtual has_slots<mt_policy>* getdest() const = 0;
-		virtual void emit(arg1_type, arg2_type, arg3_type, arg4_type, arg5_type,
-			arg6_type) = 0;
-		virtual _connection_base6<arg1_type, arg2_type, arg3_type, arg4_type,
-			arg5_type, arg6_type, mt_policy>* clone() = 0;
-		virtual _connection_base6<arg1_type, arg2_type, arg3_type, arg4_type,
-			arg5_type, arg6_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0;
-	};
-
-	template<class arg1_type, class arg2_type, class arg3_type, class arg4_type,
-	class arg5_type, class arg6_type, class arg7_type, class mt_policy>
-	class _connection_base7
-	{
-	public:
-		virtual ~_connection_base7() {}
-		virtual has_slots<mt_policy>* getdest() const = 0;
-		virtual void emit(arg1_type, arg2_type, arg3_type, arg4_type, arg5_type,
-			arg6_type, arg7_type) = 0;
-		virtual _connection_base7<arg1_type, arg2_type, arg3_type, arg4_type,
-			arg5_type, arg6_type, arg7_type, mt_policy>* clone() = 0;
-		virtual _connection_base7<arg1_type, arg2_type, arg3_type, arg4_type,
-			arg5_type, arg6_type, arg7_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0;
-	};
-
-	template<class arg1_type, class arg2_type, class arg3_type, class arg4_type,
-	class arg5_type, class arg6_type, class arg7_type, class arg8_type, class mt_policy>
-	class _connection_base8
-	{
-	public:
-		virtual ~_connection_base8() {}
-		virtual has_slots<mt_policy>* getdest() const = 0;
-		virtual void emit(arg1_type, arg2_type, arg3_type, arg4_type, arg5_type,
-			arg6_type, arg7_type, arg8_type) = 0;
-		virtual _connection_base8<arg1_type, arg2_type, arg3_type, arg4_type,
-			arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>* clone() = 0;
-		virtual _connection_base8<arg1_type, arg2_type, arg3_type, arg4_type,
-			arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0;
-	};
-
-	template<class mt_policy>
-	class _signal_base : public mt_policy
-	{
-	public:
-		virtual void slot_disconnect(has_slots<mt_policy>* pslot) = 0;
-		virtual void slot_duplicate(const has_slots<mt_policy>* poldslot, has_slots<mt_policy>* pnewslot) = 0;
-	};
-
-	template<class mt_policy = SIGSLOT_DEFAULT_MT_POLICY>
-	class has_slots : public mt_policy 
-	{
-	private:
-		typedef typename std::set<_signal_base<mt_policy> *> sender_set;
-		typedef typename sender_set::const_iterator const_iterator;
-
-	public:
-		has_slots()
-		{
-			;
-		}
-
-		has_slots(const has_slots& hs)
-			: mt_policy(hs)
-		{
-			lock_block<mt_policy> lock(this);
-			const_iterator it = hs.m_senders.begin();
-			const_iterator itEnd = hs.m_senders.end();
-
-			while(it != itEnd)
-			{
-				(*it)->slot_duplicate(&hs, this);
-				m_senders.insert(*it);
-				++it;
-			}
-		} 
-
-		void signal_connect(_signal_base<mt_policy>* sender)
-		{
-			lock_block<mt_policy> lock(this);
-			m_senders.insert(sender);
-		}
-
-		void signal_disconnect(_signal_base<mt_policy>* sender)
-		{
-			lock_block<mt_policy> lock(this);
-			m_senders.erase(sender);
-		}
-
-		virtual ~has_slots()
-		{
-			disconnect_all();
-		}
-
-		void disconnect_all()
-		{
-			lock_block<mt_policy> lock(this);
-			const_iterator it = m_senders.begin();
-			const_iterator itEnd = m_senders.end();
-
-			while(it != itEnd)
-			{
-				(*it)->slot_disconnect(this);
-				++it;
-			}
-
-			m_senders.erase(m_senders.begin(), m_senders.end());
-		}
-
-	private:
-		sender_set m_senders;
-	};
-
-	template<class mt_policy>
-	class _signal_base0 : public _signal_base<mt_policy>
-	{
-	public:
-		typedef std::list<_connection_base0<mt_policy> *>  connections_list;
-
-		_signal_base0()
-		{
-			;
-		}
-
-		_signal_base0(const _signal_base0& s)
-			: _signal_base<mt_policy>(s)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator it = s.m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = s.m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				(*it)->getdest()->signal_connect(this);
-				m_connected_slots.push_back((*it)->clone());
-
-				++it;
-			}
-		}
-
-		~_signal_base0()
-		{
-			disconnect_all();
-		}
-
-		bool is_empty()
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator it = m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = m_connected_slots.end();
-			return it == itEnd;
-		}
-
-		void disconnect_all()
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator it = m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				(*it)->getdest()->signal_disconnect(this);
-				delete *it;
-
-				++it;
-			}
-
-			m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());
-		}
-
-#ifdef _DEBUG
-			bool connected(has_slots<mt_policy>* pclass)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator itNext, it = m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = m_connected_slots.end();
-			while(it != itEnd)
-			{
-				itNext = it;
-				++itNext;
-				if ((*it)->getdest() == pclass)
-					return true;
-				it = itNext;
-			}
-			return false;
-		}
-#endif
-
-		void disconnect(has_slots<mt_policy>* pclass)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::iterator it = m_connected_slots.begin();
-			typename connections_list::iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				if((*it)->getdest() == pclass)
-				{
-					delete *it;
-					m_connected_slots.erase(it);
-					pclass->signal_disconnect(this);
-					return;
-				}
-
-				++it;
-			}
-		}
-
-		void slot_disconnect(has_slots<mt_policy>* pslot)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::iterator it = m_connected_slots.begin();
-			typename connections_list::iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				typename connections_list::iterator itNext = it;
-				++itNext;
-
-				if((*it)->getdest() == pslot)
-				{
-					delete *it;
-					m_connected_slots.erase(it);
-				}
-
-				it = itNext;
-			}
-		}
-
-		void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::iterator it = m_connected_slots.begin();
-			typename connections_list::iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				if((*it)->getdest() == oldtarget)
-				{
-					m_connected_slots.push_back((*it)->duplicate(newtarget));
-				}
-
-				++it;
-			}
-		}
-
-	protected:
-		connections_list m_connected_slots;   
-	};
-
-	template<class arg1_type, class mt_policy>
-	class _signal_base1 : public _signal_base<mt_policy>
-	{
-	public:
-		typedef std::list<_connection_base1<arg1_type, mt_policy> *>  connections_list;
-
-		_signal_base1()
-		{
-			;
-		}
-
-		_signal_base1(const _signal_base1<arg1_type, mt_policy>& s)
-			: _signal_base<mt_policy>(s)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator it = s.m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = s.m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				(*it)->getdest()->signal_connect(this);
-				m_connected_slots.push_back((*it)->clone());
-
-				++it;
-			}
-		}
-
-		void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::iterator it = m_connected_slots.begin();
-			typename connections_list::iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				if((*it)->getdest() == oldtarget)
-				{
-					m_connected_slots.push_back((*it)->duplicate(newtarget));
-				}
-
-				++it;
-			}
-		}
-
-		~_signal_base1()
-		{
-			disconnect_all();
-		}
-
-		bool is_empty()
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator it = m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = m_connected_slots.end();
-			return it == itEnd;
-		}
-
-		void disconnect_all()
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator it = m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				(*it)->getdest()->signal_disconnect(this);
-				delete *it;
-
-				++it;
-			}
-
-			m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());
-		}
-
-#ifdef _DEBUG
-			bool connected(has_slots<mt_policy>* pclass)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator itNext, it = m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = m_connected_slots.end();
-			while(it != itEnd)
-			{
-				itNext = it;
-				++itNext;
-				if ((*it)->getdest() == pclass)
-					return true;
-				it = itNext;
-			}
-			return false;
-		}
-#endif
-
-		void disconnect(has_slots<mt_policy>* pclass)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::iterator it = m_connected_slots.begin();
-			typename connections_list::iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				if((*it)->getdest() == pclass)
-				{
-					delete *it;
-					m_connected_slots.erase(it);
-					pclass->signal_disconnect(this);
-					return;
-				}
-
-				++it;
-			}
-		}
-
-		void slot_disconnect(has_slots<mt_policy>* pslot)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::iterator it = m_connected_slots.begin();
-			typename connections_list::iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				typename connections_list::iterator itNext = it;
-				++itNext;
-
-				if((*it)->getdest() == pslot)
-				{
-					delete *it;
-					m_connected_slots.erase(it);
-				}
-
-				it = itNext;
-			}
-		}
-
-
-	protected:
-		connections_list m_connected_slots;   
-	};
-
-	template<class arg1_type, class arg2_type, class mt_policy>
-	class _signal_base2 : public _signal_base<mt_policy>
-	{
-	public:
-		typedef std::list<_connection_base2<arg1_type, arg2_type, mt_policy> *>
-			connections_list;
-
-		_signal_base2()
-		{
-			;
-		}
-
-		_signal_base2(const _signal_base2<arg1_type, arg2_type, mt_policy>& s)
-			: _signal_base<mt_policy>(s)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator it = s.m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = s.m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				(*it)->getdest()->signal_connect(this);
-				m_connected_slots.push_back((*it)->clone());
-
-				++it;
-			}
-		}
-
-		void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::iterator it = m_connected_slots.begin();
-			typename connections_list::iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				if((*it)->getdest() == oldtarget)
-				{
-					m_connected_slots.push_back((*it)->duplicate(newtarget));
-				}
-
-				++it;
-			}
-		}
-
-		~_signal_base2()
-		{
-			disconnect_all();
-		}
-
-		bool is_empty()
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator it = m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = m_connected_slots.end();
-			return it == itEnd;
-		}
-
-		void disconnect_all()
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator it = m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				(*it)->getdest()->signal_disconnect(this);
-				delete *it;
-
-				++it;
-			}
-
-			m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());
-		}
-
-#ifdef _DEBUG
-			bool connected(has_slots<mt_policy>* pclass)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator itNext, it = m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = m_connected_slots.end();
-			while(it != itEnd)
-			{
-				itNext = it;
-				++itNext;
-				if ((*it)->getdest() == pclass)
-					return true;
-				it = itNext;
-			}
-			return false;
-		}
-#endif
-
-		void disconnect(has_slots<mt_policy>* pclass)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::iterator it = m_connected_slots.begin();
-			typename connections_list::iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				if((*it)->getdest() == pclass)
-				{
-					delete *it;
-					m_connected_slots.erase(it);
-					pclass->signal_disconnect(this);
-					return;
-				}
-
-				++it;
-			}
-		}
-
-		void slot_disconnect(has_slots<mt_policy>* pslot)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::iterator it = m_connected_slots.begin();
-			typename connections_list::iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				typename connections_list::iterator itNext = it;
-				++itNext;
-
-				if((*it)->getdest() == pslot)
-				{
-					delete *it;
-					m_connected_slots.erase(it);
-				}
-
-				it = itNext;
-			}
-		}
-
-	protected:
-		connections_list m_connected_slots;   
-	};
-
-	template<class arg1_type, class arg2_type, class arg3_type, class mt_policy>
-	class _signal_base3 : public _signal_base<mt_policy>
-	{
-	public:
-		typedef std::list<_connection_base3<arg1_type, arg2_type, arg3_type, mt_policy> *>
-			connections_list;
-
-		_signal_base3()
-		{
-			;
-		}
-
-		_signal_base3(const _signal_base3<arg1_type, arg2_type, arg3_type, mt_policy>& s)
-			: _signal_base<mt_policy>(s)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator it = s.m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = s.m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				(*it)->getdest()->signal_connect(this);
-				m_connected_slots.push_back((*it)->clone());
-
-				++it;
-			}
-		}
-
-		void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::iterator it = m_connected_slots.begin();
-			typename connections_list::iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				if((*it)->getdest() == oldtarget)
-				{
-					m_connected_slots.push_back((*it)->duplicate(newtarget));
-				}
-
-				++it;
-			}
-		}
-
-		~_signal_base3()
-		{
-			disconnect_all();
-		}
-
-		bool is_empty()
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator it = m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = m_connected_slots.end();
-			return it == itEnd;
-		}
-
-		void disconnect_all()
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator it = m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				(*it)->getdest()->signal_disconnect(this);
-				delete *it;
-
-				++it;
-			}
-
-			m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());
-		}
-
-#ifdef _DEBUG
-			bool connected(has_slots<mt_policy>* pclass)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator itNext, it = m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = m_connected_slots.end();
-			while(it != itEnd)
-			{
-				itNext = it;
-				++itNext;
-				if ((*it)->getdest() == pclass)
-					return true;
-				it = itNext;
-			}
-			return false;
-		}
-#endif
-
-		void disconnect(has_slots<mt_policy>* pclass)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::iterator it = m_connected_slots.begin();
-			typename connections_list::iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				if((*it)->getdest() == pclass)
-				{
-					delete *it;
-					m_connected_slots.erase(it);
-					pclass->signal_disconnect(this);
-					return;
-				}
-
-				++it;
-			}
-		}
-
-		void slot_disconnect(has_slots<mt_policy>* pslot)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::iterator it = m_connected_slots.begin();
-			typename connections_list::iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				typename connections_list::iterator itNext = it;
-				++itNext;
-
-				if((*it)->getdest() == pslot)
-				{
-					delete *it;
-					m_connected_slots.erase(it);
-				}
-
-				it = itNext;
-			}
-		}
-
-	protected:
-		connections_list m_connected_slots;   
-	};
-
-	template<class arg1_type, class arg2_type, class arg3_type, class arg4_type, class mt_policy>
-	class _signal_base4 : public _signal_base<mt_policy>
-	{
-	public:
-		typedef std::list<_connection_base4<arg1_type, arg2_type, arg3_type,
-			arg4_type, mt_policy> *>  connections_list;
-
-		_signal_base4()
-		{
-			;
-		}
-
-		_signal_base4(const _signal_base4<arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>& s)
-			: _signal_base<mt_policy>(s)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator it = s.m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = s.m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				(*it)->getdest()->signal_connect(this);
-				m_connected_slots.push_back((*it)->clone());
-
-				++it;
-			}
-		}
-
-		void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::iterator it = m_connected_slots.begin();
-			typename connections_list::iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				if((*it)->getdest() == oldtarget)
-				{
-					m_connected_slots.push_back((*it)->duplicate(newtarget));
-				}
-
-				++it;
-			}
-		}
-
-		~_signal_base4()
-		{
-			disconnect_all();
-		}
-
-		bool is_empty()
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator it = m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = m_connected_slots.end();
-			return it == itEnd;
-		}
-
-		void disconnect_all()
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator it = m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				(*it)->getdest()->signal_disconnect(this);
-				delete *it;
-
-				++it;
-			}
-
-			m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());
-		}
-
-#ifdef _DEBUG
-			bool connected(has_slots<mt_policy>* pclass)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator itNext, it = m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = m_connected_slots.end();
-			while(it != itEnd)
-			{
-				itNext = it;
-				++itNext;
-				if ((*it)->getdest() == pclass)
-					return true;
-				it = itNext;
-			}
-			return false;
-		}
-#endif
-
-		void disconnect(has_slots<mt_policy>* pclass)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::iterator it = m_connected_slots.begin();
-			typename connections_list::iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				if((*it)->getdest() == pclass)
-				{
-					delete *it;
-					m_connected_slots.erase(it);
-					pclass->signal_disconnect(this);
-					return;
-				}
-
-				++it;
-			}
-		}
-
-		void slot_disconnect(has_slots<mt_policy>* pslot)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::iterator it = m_connected_slots.begin();
-			typename connections_list::iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				typename connections_list::iterator itNext = it;
-				++itNext;
-
-				if((*it)->getdest() == pslot)
-				{
-					delete *it;
-					m_connected_slots.erase(it);
-				}
-
-				it = itNext;
-			}
-		}
-
-	protected:
-		connections_list m_connected_slots;   
-	};
-
-	template<class arg1_type, class arg2_type, class arg3_type, class arg4_type,
-	class arg5_type, class mt_policy>
-	class _signal_base5 : public _signal_base<mt_policy>
-	{
-	public:
-		typedef std::list<_connection_base5<arg1_type, arg2_type, arg3_type,
-			arg4_type, arg5_type, mt_policy> *>  connections_list;
-
-		_signal_base5()
-		{
-			;
-		}
-
-		_signal_base5(const _signal_base5<arg1_type, arg2_type, arg3_type, arg4_type,
-			arg5_type, mt_policy>& s)
-			: _signal_base<mt_policy>(s)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator it = s.m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = s.m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				(*it)->getdest()->signal_connect(this);
-				m_connected_slots.push_back((*it)->clone());
-
-				++it;
-			}
-		}
-
-		void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::iterator it = m_connected_slots.begin();
-			typename connections_list::iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				if((*it)->getdest() == oldtarget)
-				{
-					m_connected_slots.push_back((*it)->duplicate(newtarget));
-				}
-
-				++it;
-			}
-		}
-
-		~_signal_base5()
-		{
-			disconnect_all();
-		}
-
-		bool is_empty()
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator it = m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = m_connected_slots.end();
-			return it == itEnd;
-		}
-
-		void disconnect_all()
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator it = m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				(*it)->getdest()->signal_disconnect(this);
-				delete *it;
-
-				++it;
-			}
-
-			m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());
-		}
-
-#ifdef _DEBUG
-			bool connected(has_slots<mt_policy>* pclass)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator itNext, it = m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = m_connected_slots.end();
-			while(it != itEnd)
-			{
-				itNext = it;
-				++itNext;
-				if ((*it)->getdest() == pclass)
-					return true;
-				it = itNext;
-			}
-			return false;
-		}
-#endif
-
-		void disconnect(has_slots<mt_policy>* pclass)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::iterator it = m_connected_slots.begin();
-			typename connections_list::iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				if((*it)->getdest() == pclass)
-				{
-					delete *it;
-					m_connected_slots.erase(it);
-					pclass->signal_disconnect(this);
-					return;
-				}
-
-				++it;
-			}
-		}
-
-		void slot_disconnect(has_slots<mt_policy>* pslot)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::iterator it = m_connected_slots.begin();
-			typename connections_list::iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				typename connections_list::iterator itNext = it;
-				++itNext;
-
-				if((*it)->getdest() == pslot)
-				{
-					delete *it;
-					m_connected_slots.erase(it);
-				}
-
-				it = itNext;
-			}
-		}
-
-	protected:
-		connections_list m_connected_slots;   
-	};
-
-	template<class arg1_type, class arg2_type, class arg3_type, class arg4_type,
-	class arg5_type, class arg6_type, class mt_policy>
-	class _signal_base6 : public _signal_base<mt_policy>
-	{
-	public:
-		typedef std::list<_connection_base6<arg1_type, arg2_type, arg3_type, 
-			arg4_type, arg5_type, arg6_type, mt_policy> *>  connections_list;
-
-		_signal_base6()
-		{
-			;
-		}
-
-		_signal_base6(const _signal_base6<arg1_type, arg2_type, arg3_type, arg4_type,
-			arg5_type, arg6_type, mt_policy>& s)
-			: _signal_base<mt_policy>(s)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator it = s.m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = s.m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				(*it)->getdest()->signal_connect(this);
-				m_connected_slots.push_back((*it)->clone());
-
-				++it;
-			}
-		}
-
-		void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::iterator it = m_connected_slots.begin();
-			typename connections_list::iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				if((*it)->getdest() == oldtarget)
-				{
-					m_connected_slots.push_back((*it)->duplicate(newtarget));
-				}
-
-				++it;
-			}
-		}
-
-		~_signal_base6()
-		{
-			disconnect_all();
-		}
-
-		bool is_empty()
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator it = m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = m_connected_slots.end();
-			return it == itEnd;
-		}
-
-		void disconnect_all()
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator it = m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				(*it)->getdest()->signal_disconnect(this);
-				delete *it;
-
-				++it;
-			}
-
-			m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());
-		}
-
-#ifdef _DEBUG
-			bool connected(has_slots<mt_policy>* pclass)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator itNext, it = m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = m_connected_slots.end();
-			while(it != itEnd)
-			{
-				itNext = it;
-				++itNext;
-				if ((*it)->getdest() == pclass)
-					return true;
-				it = itNext;
-			}
-			return false;
-		}
-#endif
-
-		void disconnect(has_slots<mt_policy>* pclass)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::iterator it = m_connected_slots.begin();
-			typename connections_list::iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				if((*it)->getdest() == pclass)
-				{
-					delete *it;
-					m_connected_slots.erase(it);
-					pclass->signal_disconnect(this);
-					return;
-				}
-
-				++it;
-			}
-		}
-
-		void slot_disconnect(has_slots<mt_policy>* pslot)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::iterator it = m_connected_slots.begin();
-			typename connections_list::iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				typename connections_list::iterator itNext = it;
-				++itNext;
-
-				if((*it)->getdest() == pslot)
-				{
-					delete *it;
-					m_connected_slots.erase(it);
-				}
-
-				it = itNext;
-			}
-		}
-
-	protected:
-		connections_list m_connected_slots;   
-	};
-
-	template<class arg1_type, class arg2_type, class arg3_type, class arg4_type,
-	class arg5_type, class arg6_type, class arg7_type, class mt_policy>
-	class _signal_base7 : public _signal_base<mt_policy>
-	{
-	public:
-		typedef std::list<_connection_base7<arg1_type, arg2_type, arg3_type, 
-			arg4_type, arg5_type, arg6_type, arg7_type, mt_policy> *>  connections_list;
-
-		_signal_base7()
-		{
-			;
-		}
-
-		_signal_base7(const _signal_base7<arg1_type, arg2_type, arg3_type, arg4_type,
-			arg5_type, arg6_type, arg7_type, mt_policy>& s)
-			: _signal_base<mt_policy>(s)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator it = s.m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = s.m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				(*it)->getdest()->signal_connect(this);
-				m_connected_slots.push_back((*it)->clone());
-
-				++it;
-			}
-		}
-
-		void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::iterator it = m_connected_slots.begin();
-			typename connections_list::iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				if((*it)->getdest() == oldtarget)
-				{
-					m_connected_slots.push_back((*it)->duplicate(newtarget));
-				}
-
-				++it;
-			}
-		}
-
-		~_signal_base7()
-		{
-			disconnect_all();
-		}
-
-		bool is_empty()
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator it = m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = m_connected_slots.end();
-			return it == itEnd;
-		}
-
-		void disconnect_all()
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator it = m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				(*it)->getdest()->signal_disconnect(this);
-				delete *it;
-
-				++it;
-			}
-
-			m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());
-		}
-
-#ifdef _DEBUG
-			bool connected(has_slots<mt_policy>* pclass)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator itNext, it = m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = m_connected_slots.end();
-			while(it != itEnd)
-			{
-				itNext = it;
-				++itNext;
-				if ((*it)->getdest() == pclass)
-					return true;
-				it = itNext;
-			}
-			return false;
-		}
-#endif
-
-		void disconnect(has_slots<mt_policy>* pclass)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::iterator it = m_connected_slots.begin();
-			typename connections_list::iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				if((*it)->getdest() == pclass)
-				{
-					delete *it;
-					m_connected_slots.erase(it);
-					pclass->signal_disconnect(this);
-					return;
-				}
-
-				++it;
-			}
-		}
-
-		void slot_disconnect(has_slots<mt_policy>* pslot)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::iterator it = m_connected_slots.begin();
-			typename connections_list::iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				typename connections_list::iterator itNext = it;
-				++itNext;
-
-				if((*it)->getdest() == pslot)
-				{
-					delete *it;
-					m_connected_slots.erase(it);
-				}
-
-				it = itNext;
-			}
-		}
-
-	protected:
-		connections_list m_connected_slots;   
-	};
-
-	template<class arg1_type, class arg2_type, class arg3_type, class arg4_type,
-	class arg5_type, class arg6_type, class arg7_type, class arg8_type, class mt_policy>
-	class _signal_base8 : public _signal_base<mt_policy>
-	{
-	public:
-		typedef std::list<_connection_base8<arg1_type, arg2_type, arg3_type, 
-			arg4_type, arg5_type, arg6_type, arg7_type, arg8_type, mt_policy> *>
-			connections_list;
-
-		_signal_base8()
-		{
-			;
-		}
-
-		_signal_base8(const _signal_base8<arg1_type, arg2_type, arg3_type, arg4_type,
-			arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>& s)
-			: _signal_base<mt_policy>(s)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator it = s.m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = s.m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				(*it)->getdest()->signal_connect(this);
-				m_connected_slots.push_back((*it)->clone());
-
-				++it;
-			}
-		}
-
-		void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::iterator it = m_connected_slots.begin();
-			typename connections_list::iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				if((*it)->getdest() == oldtarget)
-				{
-					m_connected_slots.push_back((*it)->duplicate(newtarget));
-				}
-
-				++it;
-			}
-		}
-
-		~_signal_base8()
-		{
-			disconnect_all();
-		}
-
-		bool is_empty()
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator it = m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = m_connected_slots.end();
-			return it == itEnd;
-		}
-
-		void disconnect_all()
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator it = m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				(*it)->getdest()->signal_disconnect(this);
-				delete *it;
-
-				++it;
-			}
-
-			m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());
-		}
-
-#ifdef _DEBUG
-			bool connected(has_slots<mt_policy>* pclass)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator itNext, it = m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = m_connected_slots.end();
-			while(it != itEnd)
-			{
-				itNext = it;
-				++itNext;
-				if ((*it)->getdest() == pclass)
-					return true;
-				it = itNext;
-			}
-			return false;
-		}
-#endif
-
-		void disconnect(has_slots<mt_policy>* pclass)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::iterator it = m_connected_slots.begin();
-			typename connections_list::iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				if((*it)->getdest() == pclass)
-				{
-					delete *it;
-					m_connected_slots.erase(it);
-					pclass->signal_disconnect(this);
-					return;
-				}
-
-				++it;
-			}
-		}
-
-		void slot_disconnect(has_slots<mt_policy>* pslot)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::iterator it = m_connected_slots.begin();
-			typename connections_list::iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				typename connections_list::iterator itNext = it;
-				++itNext;
-
-				if((*it)->getdest() == pslot)
-				{
-					delete *it;
-					m_connected_slots.erase(it);
-				}
-
-				it = itNext;
-			}
-		}
-
-	protected:
-		connections_list m_connected_slots;   
-	};
-
-
-	template<class dest_type, class mt_policy>
-	class _connection0 : public _connection_base0<mt_policy>
-	{
-	public:
-		_connection0()
-		{
-			m_pobject = NULL;
-			m_pmemfun = NULL;
-		}
-
-		_connection0(dest_type* pobject, void (dest_type::*pmemfun)())
-		{
-			m_pobject = pobject;
-			m_pmemfun = pmemfun;
-		}
-
-		virtual ~_connection0()
-		{
-                }
-
-		virtual _connection_base0<mt_policy>* clone()
-		{
-			return new _connection0<dest_type, mt_policy>(*this);
-		}
-
-		virtual _connection_base0<mt_policy>* duplicate(has_slots<mt_policy>* pnewdest)
-		{
-			return new _connection0<dest_type, mt_policy>((dest_type *)pnewdest, m_pmemfun);
-		}
-
-		virtual void emit()
-		{
-			(m_pobject->*m_pmemfun)();
-		}
-
-		virtual has_slots<mt_policy>* getdest() const
-		{
-			return m_pobject;
-		}
-
-	private:
-		dest_type* m_pobject;
-		void (dest_type::* m_pmemfun)();
-	};
-
-	template<class dest_type, class arg1_type, class mt_policy>
-	class _connection1 : public _connection_base1<arg1_type, mt_policy>
-	{
-	public:
-		_connection1()
-		{
-			m_pobject = NULL;
-			m_pmemfun = NULL;
-		}
-
-		_connection1(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type))
-		{
-			m_pobject = pobject;
-			m_pmemfun = pmemfun;
-		}
-
-		virtual ~_connection1()
-		{
-                }
-
-		virtual _connection_base1<arg1_type, mt_policy>* clone()
-		{
-			return new _connection1<dest_type, arg1_type, mt_policy>(*this);
-		}
-
-		virtual _connection_base1<arg1_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest)
-		{
-			return new _connection1<dest_type, arg1_type, mt_policy>((dest_type *)pnewdest, m_pmemfun);
-		}
-
-		virtual void emit(arg1_type a1)
-		{
-			(m_pobject->*m_pmemfun)(a1);
-		}
-
-		virtual has_slots<mt_policy>* getdest() const
-		{
-			return m_pobject;
-		}
-
-	private:
-		dest_type* m_pobject;
-		void (dest_type::* m_pmemfun)(arg1_type);
-	};
-
-	template<class dest_type, class arg1_type, class arg2_type, class mt_policy>
-	class _connection2 : public _connection_base2<arg1_type, arg2_type, mt_policy>
-	{
-	public:
-		_connection2()
-		{
-			m_pobject = NULL;
-			m_pmemfun = NULL;
-		}
-
-		_connection2(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type,
-			arg2_type))
-		{
-			m_pobject = pobject;
-			m_pmemfun = pmemfun;
-		}
-
-		virtual ~_connection2()
-		{
-                }
-
-		virtual _connection_base2<arg1_type, arg2_type, mt_policy>* clone()
-		{
-			return new _connection2<dest_type, arg1_type, arg2_type, mt_policy>(*this);
-		}
-
-		virtual _connection_base2<arg1_type, arg2_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest)
-		{
-			return new _connection2<dest_type, arg1_type, arg2_type, mt_policy>((dest_type *)pnewdest, m_pmemfun);
-		}
-
-		virtual void emit(arg1_type a1, arg2_type a2)
-		{
-			(m_pobject->*m_pmemfun)(a1, a2);
-		}
-
-		virtual has_slots<mt_policy>* getdest() const
-		{
-			return m_pobject;
-		}
-
-	private:
-		dest_type* m_pobject;
-		void (dest_type::* m_pmemfun)(arg1_type, arg2_type);
-	};
-
-	template<class dest_type, class arg1_type, class arg2_type, class arg3_type, class mt_policy>
-	class _connection3 : public _connection_base3<arg1_type, arg2_type, arg3_type, mt_policy>
-	{
-	public:
-		_connection3()
-		{
-			m_pobject = NULL;
-			m_pmemfun = NULL;
-		}
-
-		_connection3(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type,
-			arg2_type, arg3_type))
-		{
-			m_pobject = pobject;
-			m_pmemfun = pmemfun;
-		}
-
-		virtual ~_connection3()
-		{
-                }
-
-		virtual _connection_base3<arg1_type, arg2_type, arg3_type, mt_policy>* clone()
-		{
-			return new _connection3<dest_type, arg1_type, arg2_type, arg3_type, mt_policy>(*this);
-		}
-
-		virtual _connection_base3<arg1_type, arg2_type, arg3_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest)
-		{
-			return new _connection3<dest_type, arg1_type, arg2_type, arg3_type, mt_policy>((dest_type *)pnewdest, m_pmemfun);
-		}
-
-		virtual void emit(arg1_type a1, arg2_type a2, arg3_type a3)
-		{
-			(m_pobject->*m_pmemfun)(a1, a2, a3);
-		}
-
-		virtual has_slots<mt_policy>* getdest() const
-		{
-			return m_pobject;
-		}
-
-	private:
-		dest_type* m_pobject;
-		void (dest_type::* m_pmemfun)(arg1_type, arg2_type, arg3_type);
-	};
-
-	template<class dest_type, class arg1_type, class arg2_type, class arg3_type,
-	class arg4_type, class mt_policy>
-	class _connection4 : public _connection_base4<arg1_type, arg2_type,
-		arg3_type, arg4_type, mt_policy>
-	{
-	public:
-		_connection4()
-		{
-			m_pobject = NULL;
-			m_pmemfun = NULL;
-		}
-
-		_connection4(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type,
-			arg2_type, arg3_type, arg4_type))
-		{
-			m_pobject = pobject;
-			m_pmemfun = pmemfun;
-		}
-
-		virtual ~_connection4()
-		{
-                }
-
-		virtual _connection_base4<arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>* clone()
-		{
-			return new _connection4<dest_type, arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>(*this);
-		}
-
-		virtual _connection_base4<arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest)
-		{
-			return new _connection4<dest_type, arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>((dest_type *)pnewdest, m_pmemfun);
-		}
-
-		virtual void emit(arg1_type a1, arg2_type a2, arg3_type a3, 
-			arg4_type a4)
-		{
-			(m_pobject->*m_pmemfun)(a1, a2, a3, a4);
-		}
-
-		virtual has_slots<mt_policy>* getdest() const
-		{
-			return m_pobject;
-		}
-
-	private:
-		dest_type* m_pobject;
-		void (dest_type::* m_pmemfun)(arg1_type, arg2_type, arg3_type,
-			arg4_type);
-	};
-
-	template<class dest_type, class arg1_type, class arg2_type, class arg3_type,
-	class arg4_type, class arg5_type, class mt_policy>
-	class _connection5 : public _connection_base5<arg1_type, arg2_type,
-		arg3_type, arg4_type, arg5_type, mt_policy>
-	{
-	public:
-		_connection5()
-		{
-			m_pobject = NULL;
-			m_pmemfun = NULL;
-		}
-
-		_connection5(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type,
-			arg2_type, arg3_type, arg4_type, arg5_type))
-		{
-			m_pobject = pobject;
-			m_pmemfun = pmemfun;
-		}
-
-		virtual ~_connection5()
-		{
-                }
-
-		virtual _connection_base5<arg1_type, arg2_type, arg3_type, arg4_type, 
-			arg5_type, mt_policy>* clone()
-		{
-			return new _connection5<dest_type, arg1_type, arg2_type, arg3_type, arg4_type, 
-				arg5_type, mt_policy>(*this);
-		}
-
-		virtual _connection_base5<arg1_type, arg2_type, arg3_type, arg4_type, 
-			arg5_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest)
-		{
-			return new _connection5<dest_type, arg1_type, arg2_type, arg3_type, arg4_type, 
-				arg5_type, mt_policy>((dest_type *)pnewdest, m_pmemfun);
-		}
-
-		virtual void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4,
-			arg5_type a5)
-		{
-			(m_pobject->*m_pmemfun)(a1, a2, a3, a4, a5);
-		}
-
-		virtual has_slots<mt_policy>* getdest() const
-		{
-			return m_pobject;
-		}
-
-	private:
-		dest_type* m_pobject;
-		void (dest_type::* m_pmemfun)(arg1_type, arg2_type, arg3_type, arg4_type,
-			arg5_type);
-	};
-
-	template<class dest_type, class arg1_type, class arg2_type, class arg3_type,
-	class arg4_type, class arg5_type, class arg6_type, class mt_policy>
-	class _connection6 : public _connection_base6<arg1_type, arg2_type,
-		arg3_type, arg4_type, arg5_type, arg6_type, mt_policy>
-	{
-	public:
-		_connection6()
-		{
-			m_pobject = NULL;
-			m_pmemfun = NULL;
-		}
-
-		_connection6(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type,
-			arg2_type, arg3_type, arg4_type, arg5_type, arg6_type))
-		{
-			m_pobject = pobject;
-			m_pmemfun = pmemfun;
-		}
-
-		virtual ~_connection6()
-		{
-                }
-
-		virtual _connection_base6<arg1_type, arg2_type, arg3_type, arg4_type, 
-			arg5_type, arg6_type, mt_policy>* clone()
-		{
-			return new _connection6<dest_type, arg1_type, arg2_type, arg3_type, arg4_type, 
-				arg5_type, arg6_type, mt_policy>(*this);
-		}
-
-		virtual _connection_base6<arg1_type, arg2_type, arg3_type, arg4_type, 
-			arg5_type, arg6_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest)
-		{
-			return new _connection6<dest_type, arg1_type, arg2_type, arg3_type, arg4_type, 
-				arg5_type, arg6_type, mt_policy>((dest_type *)pnewdest, m_pmemfun);
-		}
-
-		virtual void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4,
-			arg5_type a5, arg6_type a6)
-		{
-			(m_pobject->*m_pmemfun)(a1, a2, a3, a4, a5, a6);
-		}
-
-		virtual has_slots<mt_policy>* getdest() const
-		{
-			return m_pobject;
-		}
-
-	private:
-		dest_type* m_pobject;
-		void (dest_type::* m_pmemfun)(arg1_type, arg2_type, arg3_type, arg4_type,
-			arg5_type, arg6_type);
-	};
-
-	template<class dest_type, class arg1_type, class arg2_type, class arg3_type,
-	class arg4_type, class arg5_type, class arg6_type, class arg7_type, class mt_policy>
-	class _connection7 : public _connection_base7<arg1_type, arg2_type,
-		arg3_type, arg4_type, arg5_type, arg6_type, arg7_type, mt_policy>
-	{
-	public:
-		_connection7()
-		{
-			m_pobject = NULL;
-			m_pmemfun = NULL;
-		}
-
-		_connection7(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type,
-			arg2_type, arg3_type, arg4_type, arg5_type, arg6_type, arg7_type))
-		{
-			m_pobject = pobject;
-			m_pmemfun = pmemfun;
-		}
-
-		virtual ~_connection7()
-		{
-                }
-
-		virtual _connection_base7<arg1_type, arg2_type, arg3_type, arg4_type, 
-			arg5_type, arg6_type, arg7_type, mt_policy>* clone()
-		{
-			return new _connection7<dest_type, arg1_type, arg2_type, arg3_type, arg4_type, 
-				arg5_type, arg6_type, arg7_type, mt_policy>(*this);
-		}
-
-		virtual _connection_base7<arg1_type, arg2_type, arg3_type, arg4_type, 
-			arg5_type, arg6_type, arg7_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest)
-		{
-			return new _connection7<dest_type, arg1_type, arg2_type, arg3_type, arg4_type, 
-				arg5_type, arg6_type, arg7_type, mt_policy>((dest_type *)pnewdest, m_pmemfun);
-		}
-
-		virtual void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4,
-			arg5_type a5, arg6_type a6, arg7_type a7)
-		{
-			(m_pobject->*m_pmemfun)(a1, a2, a3, a4, a5, a6, a7);
-		}
-
-		virtual has_slots<mt_policy>* getdest() const
-		{
-			return m_pobject;
-		}
-
-	private:
-		dest_type* m_pobject;
-		void (dest_type::* m_pmemfun)(arg1_type, arg2_type, arg3_type, arg4_type,
-			arg5_type, arg6_type, arg7_type);
-	};
-
-	template<class dest_type, class arg1_type, class arg2_type, class arg3_type,
-	class arg4_type, class arg5_type, class arg6_type, class arg7_type, 
-	class arg8_type, class mt_policy>
-	class _connection8 : public _connection_base8<arg1_type, arg2_type,
-		arg3_type, arg4_type, arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>
-	{
-	public:
-		_connection8()
-		{
-			m_pobject = NULL;
-			m_pmemfun = NULL;
-		}
-
-		_connection8(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type,
-			arg2_type, arg3_type, arg4_type, arg5_type, arg6_type, 
-			arg7_type, arg8_type))
-		{
-			m_pobject = pobject;
-			m_pmemfun = pmemfun;
-		}
-
-		virtual ~_connection8()
-		{
-                }
-
-		virtual _connection_base8<arg1_type, arg2_type, arg3_type, arg4_type, 
-			arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>* clone()
-		{
-			return new _connection8<dest_type, arg1_type, arg2_type, arg3_type, arg4_type, 
-				arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>(*this);
-		}
-
-		virtual _connection_base8<arg1_type, arg2_type, arg3_type, arg4_type, 
-			arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest)
-		{
-			return new _connection8<dest_type, arg1_type, arg2_type, arg3_type, arg4_type, 
-				arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>((dest_type *)pnewdest, m_pmemfun);
-		}
-
-		virtual void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4,
-			arg5_type a5, arg6_type a6, arg7_type a7, arg8_type a8)
-		{
-			(m_pobject->*m_pmemfun)(a1, a2, a3, a4, a5, a6, a7, a8);
-		}
-
-		virtual has_slots<mt_policy>* getdest() const
-		{
-			return m_pobject;
-		}
-
-	private:
-		dest_type* m_pobject;
-		void (dest_type::* m_pmemfun)(arg1_type, arg2_type, arg3_type, arg4_type,
-			arg5_type, arg6_type, arg7_type, arg8_type);
-	};
-
-	template<class mt_policy = SIGSLOT_DEFAULT_MT_POLICY>
-	class signal0 : public _signal_base0<mt_policy>
-	{
-	public:
-		typedef _signal_base0<mt_policy> base;
-		typedef typename base::connections_list connections_list;
-		using base::m_connected_slots;
-
-		signal0()
-		{
-			;
-		}
-
-		signal0(const signal0<mt_policy>& s)
-			: _signal_base0<mt_policy>(s)
-		{
-			;
-		}
-
-		template<class desttype>
-			void connect(desttype* pclass, void (desttype::*pmemfun)())
-		{
-			lock_block<mt_policy> lock(this);
-			_connection0<desttype, mt_policy>* conn = 
-				new _connection0<desttype, mt_policy>(pclass, pmemfun);
-			m_connected_slots.push_back(conn);
-			pclass->signal_connect(this);
-		}
-
-		void emit()
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator itNext, it = m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				itNext = it;
-				++itNext;
-
-				(*it)->emit();
-
-				it = itNext;
-			}
-		}
-
-		void operator()()
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator itNext, it = m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				itNext = it;
-				++itNext;
-
-				(*it)->emit();
-
-				it = itNext;
-			}
-		}
-	};
-
-	template<class arg1_type, class mt_policy = SIGSLOT_DEFAULT_MT_POLICY>
-	class signal1 : public _signal_base1<arg1_type, mt_policy>
-	{
-	public:
-		typedef _signal_base1<arg1_type, mt_policy> base;
-		typedef typename base::connections_list connections_list;
-		using base::m_connected_slots;
-
-		signal1()
-		{
-			;
-		}
-
-		signal1(const signal1<arg1_type, mt_policy>& s)
-			: _signal_base1<arg1_type, mt_policy>(s)
-		{
-			;
-		}
-
-		template<class desttype>
-			void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type))
-		{
-			lock_block<mt_policy> lock(this);
-			_connection1<desttype, arg1_type, mt_policy>* conn = 
-				new _connection1<desttype, arg1_type, mt_policy>(pclass, pmemfun);
-			m_connected_slots.push_back(conn);
-			pclass->signal_connect(this);
-		}
-
-		void emit(arg1_type a1)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator itNext, it = m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				itNext = it;
-				++itNext;
-
-				(*it)->emit(a1);
-
-				it = itNext;
-			}
-		}
-
-		void operator()(arg1_type a1)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator itNext, it = m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				itNext = it;
-				++itNext;
-
-				(*it)->emit(a1);
-
-				it = itNext;
-			}
-		}
-	};
-
-	template<class arg1_type, class arg2_type, class mt_policy = SIGSLOT_DEFAULT_MT_POLICY>
-	class signal2 : public _signal_base2<arg1_type, arg2_type, mt_policy>
-	{
-	public:
-		typedef _signal_base2<arg1_type, arg2_type, mt_policy> base;
-		typedef typename base::connections_list connections_list;
-		using base::m_connected_slots;
-
-		signal2()
-		{
-			;
-		}
-
-		signal2(const signal2<arg1_type, arg2_type, mt_policy>& s)
-			: _signal_base2<arg1_type, arg2_type, mt_policy>(s)
-		{
-			;
-		}
-
-		template<class desttype>
-			void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type,
-			arg2_type))
-		{
-			lock_block<mt_policy> lock(this);
-			_connection2<desttype, arg1_type, arg2_type, mt_policy>* conn = new
-				_connection2<desttype, arg1_type, arg2_type, mt_policy>(pclass, pmemfun);
-			m_connected_slots.push_back(conn);
-			pclass->signal_connect(this);
-		}
-
-		void emit(arg1_type a1, arg2_type a2)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator itNext, it = m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				itNext = it;
-				++itNext;
-
-				(*it)->emit(a1, a2);
-
-				it = itNext;
-			}
-		}
-
-		void operator()(arg1_type a1, arg2_type a2)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator itNext, it = m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				itNext = it;
-				++itNext;
-
-				(*it)->emit(a1, a2);
-
-				it = itNext;
-			}
-		}
-	};
-
-	template<class arg1_type, class arg2_type, class arg3_type, class mt_policy = SIGSLOT_DEFAULT_MT_POLICY>
-	class signal3 : public _signal_base3<arg1_type, arg2_type, arg3_type, mt_policy>
-	{
-	public:
-		typedef _signal_base3<arg1_type, arg2_type, arg3_type, mt_policy> base;
-		typedef typename base::connections_list connections_list;
-		using base::m_connected_slots;
-
-		signal3()
-		{
-			;
-		}
-
-		signal3(const signal3<arg1_type, arg2_type, arg3_type, mt_policy>& s)
-			: _signal_base3<arg1_type, arg2_type, arg3_type, mt_policy>(s)
-		{
-			;
-		}
-
-		template<class desttype>
-			void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type,
-			arg2_type, arg3_type))
-		{
-			lock_block<mt_policy> lock(this);
-			_connection3<desttype, arg1_type, arg2_type, arg3_type, mt_policy>* conn = 
-				new _connection3<desttype, arg1_type, arg2_type, arg3_type, mt_policy>(pclass,
-				pmemfun);
-			m_connected_slots.push_back(conn);
-			pclass->signal_connect(this);
-		}
-
-		void emit(arg1_type a1, arg2_type a2, arg3_type a3)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator itNext, it = m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				itNext = it;
-				++itNext;
-
-				(*it)->emit(a1, a2, a3);
-
-				it = itNext;
-			}
-		}
-
-		void operator()(arg1_type a1, arg2_type a2, arg3_type a3)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator itNext, it = m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				itNext = it;
-				++itNext;
-
-				(*it)->emit(a1, a2, a3);
-
-				it = itNext;
-			}
-		}
-	};
-
-	template<class arg1_type, class arg2_type, class arg3_type, class arg4_type, class mt_policy = SIGSLOT_DEFAULT_MT_POLICY>
-	class signal4 : public _signal_base4<arg1_type, arg2_type, arg3_type,
-		arg4_type, mt_policy>
-	{
-	public:
-		typedef _signal_base4<arg1_type, arg2_type, arg3_type, arg4_type, mt_policy> base;
-		typedef typename base::connections_list connections_list;
-		using base::m_connected_slots;
-
-		signal4()
-		{
-			;
-		}
-
-		signal4(const signal4<arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>& s)
-			: _signal_base4<arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>(s)
-		{
-			;
-		}
-
-		template<class desttype>
-			void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type,
-			arg2_type, arg3_type, arg4_type))
-		{
-			lock_block<mt_policy> lock(this);
-			_connection4<desttype, arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>*
-				conn = new _connection4<desttype, arg1_type, arg2_type, arg3_type,
-				arg4_type, mt_policy>(pclass, pmemfun);
-			m_connected_slots.push_back(conn);
-			pclass->signal_connect(this);
-		}
-
-		void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator itNext, it = m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				itNext = it;
-				++itNext;
-
-				(*it)->emit(a1, a2, a3, a4);
-
-				it = itNext;
-			}
-		}
-
-		void operator()(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator itNext, it = m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				itNext = it;
-				++itNext;
-
-				(*it)->emit(a1, a2, a3, a4);
-
-				it = itNext;
-			}
-		}
-	};
-
-	template<class arg1_type, class arg2_type, class arg3_type, class arg4_type,
-	class arg5_type, class mt_policy = SIGSLOT_DEFAULT_MT_POLICY>
-	class signal5 : public _signal_base5<arg1_type, arg2_type, arg3_type,
-		arg4_type, arg5_type, mt_policy>
-	{
-	public:
-		typedef _signal_base5<arg1_type, arg2_type, arg3_type, arg4_type, arg5_type, mt_policy> base;
-		typedef typename base::connections_list connections_list;
-		using base::m_connected_slots;
-
-		signal5()
-		{
-			;
-		}
-
-		signal5(const signal5<arg1_type, arg2_type, arg3_type, arg4_type,
-			arg5_type, mt_policy>& s)
-			: _signal_base5<arg1_type, arg2_type, arg3_type, arg4_type,
-			arg5_type, mt_policy>(s)
-		{
-			;
-		}
-
-		template<class desttype>
-			void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type,
-			arg2_type, arg3_type, arg4_type, arg5_type))
-		{
-			lock_block<mt_policy> lock(this);
-			_connection5<desttype, arg1_type, arg2_type, arg3_type, arg4_type,
-				arg5_type, mt_policy>* conn = new _connection5<desttype, arg1_type, arg2_type,
-				arg3_type, arg4_type, arg5_type, mt_policy>(pclass, pmemfun);
-			m_connected_slots.push_back(conn);
-			pclass->signal_connect(this);
-		}
-
-		void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4,
-			arg5_type a5)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator itNext, it = m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				itNext = it;
-				++itNext;
-
-				(*it)->emit(a1, a2, a3, a4, a5);
-
-				it = itNext;
-			}
-		}
-
-		void operator()(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4,
-			arg5_type a5)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator itNext, it = m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				itNext = it;
-				++itNext;
-
-				(*it)->emit(a1, a2, a3, a4, a5);
-
-				it = itNext;
-			}
-		}
-	};
-
-
-	template<class arg1_type, class arg2_type, class arg3_type, class arg4_type,
-	class arg5_type, class arg6_type, class mt_policy = SIGSLOT_DEFAULT_MT_POLICY>
-	class signal6 : public _signal_base6<arg1_type, arg2_type, arg3_type,
-		arg4_type, arg5_type, arg6_type, mt_policy>
-	{
-	public:
-		typedef _signal_base6<arg1_type, arg2_type, arg3_type, arg4_type, arg5_type, arg6_type, mt_policy> base;
-		typedef typename base::connections_list connections_list;
-		using base::m_connected_slots;
-
-		signal6()
-		{
-			;
-		}
-
-		signal6(const signal6<arg1_type, arg2_type, arg3_type, arg4_type,
-			arg5_type, arg6_type, mt_policy>& s)
-			: _signal_base6<arg1_type, arg2_type, arg3_type, arg4_type,
-			arg5_type, arg6_type, mt_policy>(s)
-		{
-			;
-		}
-
-		template<class desttype>
-			void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type,
-			arg2_type, arg3_type, arg4_type, arg5_type, arg6_type))
-		{
-			lock_block<mt_policy> lock(this);
-			_connection6<desttype, arg1_type, arg2_type, arg3_type, arg4_type,
-				arg5_type, arg6_type, mt_policy>* conn = 
-				new _connection6<desttype, arg1_type, arg2_type, arg3_type,
-				arg4_type, arg5_type, arg6_type, mt_policy>(pclass, pmemfun);
-			m_connected_slots.push_back(conn);
-			pclass->signal_connect(this);
-		}
-
-		void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4,
-			arg5_type a5, arg6_type a6)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator itNext, it = m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				itNext = it;
-				++itNext;
-
-				(*it)->emit(a1, a2, a3, a4, a5, a6);
-
-				it = itNext;
-			}
-		}
-
-		void operator()(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4,
-			arg5_type a5, arg6_type a6)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator itNext, it = m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				itNext = it;
-				++itNext;
-
-				(*it)->emit(a1, a2, a3, a4, a5, a6);
-
-				it = itNext;
-			}
-		}
-	};
-
-	template<class arg1_type, class arg2_type, class arg3_type, class arg4_type,
-	class arg5_type, class arg6_type, class arg7_type, class mt_policy = SIGSLOT_DEFAULT_MT_POLICY>
-	class signal7 : public _signal_base7<arg1_type, arg2_type, arg3_type,
-		arg4_type, arg5_type, arg6_type, arg7_type, mt_policy>
-	{
-	public:
-		typedef _signal_base7<arg1_type, arg2_type, arg3_type, arg4_type, 
-			arg5_type, arg6_type, arg7_type, mt_policy> base;
-		typedef typename base::connections_list connections_list;
-		using base::m_connected_slots;
-
-		signal7()
-		{
-			;
-		}
-
-		signal7(const signal7<arg1_type, arg2_type, arg3_type, arg4_type,
-			arg5_type, arg6_type, arg7_type, mt_policy>& s)
-			: _signal_base7<arg1_type, arg2_type, arg3_type, arg4_type,
-			arg5_type, arg6_type, arg7_type, mt_policy>(s)
-		{
-			;
-		}
-
-		template<class desttype>
-			void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type,
-			arg2_type, arg3_type, arg4_type, arg5_type, arg6_type, 
-			arg7_type))
-		{
-			lock_block<mt_policy> lock(this);
-			_connection7<desttype, arg1_type, arg2_type, arg3_type, arg4_type,
-				arg5_type, arg6_type, arg7_type, mt_policy>* conn = 
-				new _connection7<desttype, arg1_type, arg2_type, arg3_type,
-				arg4_type, arg5_type, arg6_type, arg7_type, mt_policy>(pclass, pmemfun);
-			m_connected_slots.push_back(conn);
-			pclass->signal_connect(this);
-		}
-
-		void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4,
-			arg5_type a5, arg6_type a6, arg7_type a7)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator itNext, it = m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				itNext = it;
-				++itNext;
-
-				(*it)->emit(a1, a2, a3, a4, a5, a6, a7);
-
-				it = itNext;
-			}
-		}
-
-		void operator()(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4,
-			arg5_type a5, arg6_type a6, arg7_type a7)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator itNext, it = m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				itNext = it;
-				++itNext;
-
-				(*it)->emit(a1, a2, a3, a4, a5, a6, a7);
-
-				it = itNext;
-			}
-		}
-	};
-
-	template<class arg1_type, class arg2_type, class arg3_type, class arg4_type,
-	class arg5_type, class arg6_type, class arg7_type, class arg8_type, class mt_policy = SIGSLOT_DEFAULT_MT_POLICY>
-	class signal8 : public _signal_base8<arg1_type, arg2_type, arg3_type,
-		arg4_type, arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>
-	{
-	public:
-		typedef _signal_base8<arg1_type, arg2_type, arg3_type, arg4_type, 
-			arg5_type, arg6_type, arg7_type, arg8_type, mt_policy> base;
-		typedef typename base::connections_list connections_list;
-		using base::m_connected_slots;
-
-		signal8()
-		{
-			;
-		}
-
-		signal8(const signal8<arg1_type, arg2_type, arg3_type, arg4_type,
-			arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>& s)
-			: _signal_base8<arg1_type, arg2_type, arg3_type, arg4_type,
-			arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>(s)
-		{
-			;
-		}
-
-		template<class desttype>
-			void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type,
-			arg2_type, arg3_type, arg4_type, arg5_type, arg6_type, 
-			arg7_type, arg8_type))
-		{
-			lock_block<mt_policy> lock(this);
-			_connection8<desttype, arg1_type, arg2_type, arg3_type, arg4_type,
-				arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>* conn = 
-				new _connection8<desttype, arg1_type, arg2_type, arg3_type,
-				arg4_type, arg5_type, arg6_type, arg7_type, 
-				arg8_type, mt_policy>(pclass, pmemfun);
-			m_connected_slots.push_back(conn);
-			pclass->signal_connect(this);
-		}
-
-		void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4,
-			arg5_type a5, arg6_type a6, arg7_type a7, arg8_type a8)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator itNext, it = m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				itNext = it;
-				++itNext;
-
-				(*it)->emit(a1, a2, a3, a4, a5, a6, a7, a8);
-
-				it = itNext;
-			}
-		}
-
-		void operator()(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4,
-			arg5_type a5, arg6_type a6, arg7_type a7, arg8_type a8)
-		{
-			lock_block<mt_policy> lock(this);
-			typename connections_list::const_iterator itNext, it = m_connected_slots.begin();
-			typename connections_list::const_iterator itEnd = m_connected_slots.end();
-
-			while(it != itEnd)
-			{
-				itNext = it;
-				++itNext;
-
-				(*it)->emit(a1, a2, a3, a4, a5, a6, a7, a8);
-
-				it = itNext;
-			}
-		}
-	};
-
-}; // namespace sigslot
-
-#endif // TALK_BASE_SIGSLOT_H__
diff --git a/third_party/libjingle/source/talk/base/sigslotrepeater.h b/third_party/libjingle/source/talk/base/sigslotrepeater.h
deleted file mode 100644
index 3bcdc95..0000000
--- a/third_party/libjingle/source/talk/base/sigslotrepeater.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * libjingle
- * Copyright 2006, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_SIGSLOTREPEATER_H__
-#define TALK_BASE_SIGSLOTREPEATER_H__
-
-// repeaters are both signals and slots, which are designed as intermediate
-// pass-throughs for signals and slots which don't know about each other (for
-// modularity or encapsulation).  This eliminates the need to declare a signal
-// handler whose sole purpose is to fire another signal.  The repeater connects
-// to the originating signal using the 'repeat' method.  When the repeated
-// signal fires, the repeater will also fire.
-
-#include "talk/base/sigslot.h"
-
-namespace sigslot {
-
-  template<class mt_policy = SIGSLOT_DEFAULT_MT_POLICY>
-  class repeater0 : public signal0<mt_policy>,
-                    public has_slots<mt_policy>
-  {
-  public:
-    typedef signal0<mt_policy> base_type;
-    typedef repeater0<mt_policy> this_type;
-
-    repeater0() { }
-    repeater0(const this_type& s) : base_type(s) { }
-
-    void reemit() { signal0<mt_policy>::emit(); }
-    void repeat(base_type &s) { s.connect(this, &this_type::reemit); }
-  };
-
-  template<class arg1_type, class mt_policy = SIGSLOT_DEFAULT_MT_POLICY>
-  class repeater1 : public signal1<arg1_type, mt_policy>,
-                    public has_slots<mt_policy>
-  {
-  public:
-    typedef signal1<arg1_type, mt_policy> base_type;
-    typedef repeater1<arg1_type, mt_policy> this_type;
-
-    repeater1() { }
-    repeater1(const this_type& s) : base_type(s) { }
-
-    void reemit(arg1_type a1) { signal1<arg1_type, mt_policy>::emit(a1); }
-    void repeat(base_type& s) { s.connect(this, &this_type::reemit); }
-  };
-
-  template<class arg1_type, class arg2_type, class mt_policy = SIGSLOT_DEFAULT_MT_POLICY>
-  class repeater2 : public signal2<arg1_type, arg2_type, mt_policy>,
-                    public has_slots<mt_policy>
-  {
-  public:
-    typedef signal2<arg1_type, arg2_type, mt_policy> base_type;
-    typedef repeater2<arg1_type, arg2_type, mt_policy> this_type;
-
-    repeater2() { }
-    repeater2(const this_type& s) : base_type(s) { }
-
-    void reemit(arg1_type a1, arg2_type a2) { signal2<arg1_type, arg2_type, mt_policy>::emit(a1,a2); }
-    void repeat(base_type& s) { s.connect(this, &this_type::reemit); }
-  };
-
-  template<class arg1_type, class arg2_type, class arg3_type, 
-           class mt_policy = SIGSLOT_DEFAULT_MT_POLICY>
-  class repeater3 : public signal3<arg1_type, arg2_type, arg3_type, mt_policy>,
-                    public has_slots<mt_policy>
-  {
-  public:
-    typedef signal3<arg1_type, arg2_type, arg3_type, mt_policy> base_type;
-    typedef repeater3<arg1_type, arg2_type, arg3_type, mt_policy> this_type;
-
-    repeater3() { }
-    repeater3(const this_type& s) : base_type(s) { }
-
-    void reemit(arg1_type a1, arg2_type a2, arg3_type a3) { 
-            signal3<arg1_type, arg2_type, arg3_type, mt_policy>::emit(a1,a2,a3);
-    }
-    void repeat(base_type& s) { s.connect(this, &this_type::reemit); }
-  };
-
-}  // namespace sigslot
-
-#endif  // TALK_BASE_SIGSLOTREPEATER_H__
diff --git a/third_party/libjingle/source/talk/base/socket.h b/third_party/libjingle/source/talk/base/socket.h
deleted file mode 100644
index a55b3dc..0000000
--- a/third_party/libjingle/source/talk/base/socket.h
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_SOCKET_H__
-#define TALK_BASE_SOCKET_H__
-
-#include <errno.h>
-
-#ifdef POSIX
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-#include <netinet/in.h>
-#define SOCKET_EACCES EACCES
-#endif
-
-#ifdef WIN32
-#include "talk/base/win32.h"
-#endif
-
-#include "talk/base/basictypes.h"
-#include "talk/base/socketaddress.h"
-
-// Rather than converting errors into a private namespace,
-// Reuse the POSIX socket api errors. Note this depends on
-// Win32 compatibility.
-
-#ifdef WIN32
-#undef EWOULDBLOCK  // Remove errno.h's definition for each macro below.
-#define EWOULDBLOCK WSAEWOULDBLOCK
-#undef EINPROGRESS
-#define EINPROGRESS WSAEINPROGRESS
-#undef EALREADY
-#define EALREADY WSAEALREADY
-#undef ENOTSOCK
-#define ENOTSOCK WSAENOTSOCK
-#undef EDESTADDRREQ
-#define EDESTADDRREQ WSAEDESTADDRREQ
-#undef EMSGSIZE
-#define EMSGSIZE WSAEMSGSIZE
-#undef EPROTOTYPE
-#define EPROTOTYPE WSAEPROTOTYPE
-#undef ENOPROTOOPT
-#define ENOPROTOOPT WSAENOPROTOOPT
-#undef EPROTONOSUPPORT
-#define EPROTONOSUPPORT WSAEPROTONOSUPPORT
-#undef ESOCKTNOSUPPORT
-#define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT
-#undef EOPNOTSUPP
-#define EOPNOTSUPP WSAEOPNOTSUPP
-#undef EPFNOSUPPORT
-#define EPFNOSUPPORT WSAEPFNOSUPPORT
-#undef EAFNOSUPPORT
-#define EAFNOSUPPORT WSAEAFNOSUPPORT
-#undef EADDRINUSE
-#define EADDRINUSE WSAEADDRINUSE
-#undef EADDRNOTAVAIL
-#define EADDRNOTAVAIL WSAEADDRNOTAVAIL
-#undef ENETDOWN
-#define ENETDOWN WSAENETDOWN
-#undef ENETUNREACH
-#define ENETUNREACH WSAENETUNREACH
-#undef ENETRESET
-#define ENETRESET WSAENETRESET
-#undef ECONNABORTED
-#define ECONNABORTED WSAECONNABORTED
-#undef ECONNRESET
-#define ECONNRESET WSAECONNRESET
-#undef ENOBUFS
-#define ENOBUFS WSAENOBUFS
-#undef EISCONN
-#define EISCONN WSAEISCONN
-#undef ENOTCONN
-#define ENOTCONN WSAENOTCONN
-#undef ESHUTDOWN
-#define ESHUTDOWN WSAESHUTDOWN
-#undef ETOOMANYREFS
-#define ETOOMANYREFS WSAETOOMANYREFS
-#undef ETIMEDOUT
-#define ETIMEDOUT WSAETIMEDOUT
-#undef ECONNREFUSED
-#define ECONNREFUSED WSAECONNREFUSED
-#undef ELOOP
-#define ELOOP WSAELOOP
-#undef ENAMETOOLONG
-#define ENAMETOOLONG WSAENAMETOOLONG
-#undef EHOSTDOWN
-#define EHOSTDOWN WSAEHOSTDOWN
-#undef EHOSTUNREACH
-#define EHOSTUNREACH WSAEHOSTUNREACH
-#undef ENOTEMPTY
-#define ENOTEMPTY WSAENOTEMPTY
-#undef EPROCLIM
-#define EPROCLIM WSAEPROCLIM
-#undef EUSERS
-#define EUSERS WSAEUSERS
-#undef EDQUOT
-#define EDQUOT WSAEDQUOT
-#undef ESTALE
-#define ESTALE WSAESTALE
-#undef EREMOTE
-#define EREMOTE WSAEREMOTE
-#undef EACCES
-#define SOCKET_EACCES WSAEACCES
-#endif  // WIN32
-
-#ifdef POSIX
-#define INVALID_SOCKET (-1)
-#define SOCKET_ERROR (-1)
-#define closesocket(s) close(s)
-#endif  // POSIX
-
-namespace talk_base {
-
-inline bool IsBlockingError(int e) {
-  return (e == EWOULDBLOCK) || (e == EAGAIN) || (e == EINPROGRESS);
-}
-
-// General interface for the socket implementations of various networks.  The
-// methods match those of normal UNIX sockets very closely.
-class Socket {
- public:
-  virtual ~Socket() {}
-
-  // Returns the address to which the socket is bound.  If the socket is not
-  // bound, then the any-address is returned.
-  virtual SocketAddress GetLocalAddress() const = 0;
-
-  // Returns the address to which the socket is connected.  If the socket is
-  // not connected, then the any-address is returned.
-  virtual SocketAddress GetRemoteAddress() const = 0;
-
-  virtual int Bind(const SocketAddress& addr) = 0;
-  virtual int Connect(const SocketAddress& addr) = 0;
-  virtual int Send(const void *pv, size_t cb) = 0;
-  virtual int SendTo(const void *pv, size_t cb, const SocketAddress& addr) = 0;
-  virtual int Recv(void *pv, size_t cb) = 0;
-  virtual int RecvFrom(void *pv, size_t cb, SocketAddress *paddr) = 0;
-  virtual int Listen(int backlog) = 0;
-  virtual Socket *Accept(SocketAddress *paddr) = 0;
-  virtual int Close() = 0;
-  virtual int GetError() const = 0;
-  virtual void SetError(int error) = 0;
-  inline bool IsBlocking() const { return IsBlockingError(GetError()); }
-
-  enum ConnState {
-    CS_CLOSED,
-    CS_CONNECTING,
-    CS_CONNECTED
-  };
-  virtual ConnState GetState() const = 0;
-
-  // Fills in the given uint16 with the current estimate of the MTU along the
-  // path to the address to which this socket is connected.
-  virtual int EstimateMTU(uint16* mtu) = 0;
-
-  enum Option {
-    OPT_DONTFRAGMENT,
-    OPT_RCVBUF,  // receive buffer size
-    OPT_SNDBUF,  // send buffer size
-    OPT_NODELAY  // whether Nagle algorithm is enabled
-  };
-  virtual int GetOption(Option opt, int* value) = 0;
-  virtual int SetOption(Option opt, int value) = 0;
-
- protected:
-  Socket() {}
-
- private:
-  DISALLOW_EVIL_CONSTRUCTORS(Socket);
-};
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_SOCKET_H__
diff --git a/third_party/libjingle/source/talk/base/socket_unittest.cc b/third_party/libjingle/source/talk/base/socket_unittest.cc
deleted file mode 100644
index 8d5b3c5..0000000
--- a/third_party/libjingle/source/talk/base/socket_unittest.cc
+++ /dev/null
@@ -1,731 +0,0 @@
-/*
- * libjingle
- * Copyright 2007, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/socket_unittest.h"
-
-#include "talk/base/asyncudpsocket.h"
-#include "talk/base/gunit.h"
-#include "talk/base/socketserver.h"
-#include "talk/base/testclient.h"
-#include "talk/base/testutils.h"
-#include "talk/base/thread.h"
-
-namespace talk_base {
-
-static const SocketAddress kEmptyAddr;
-static const SocketAddress kLoopbackAddr(IPAddress(INADDR_LOOPBACK), 0);
-
-void SocketTest::TestConnect() {
-  testing::StreamSink sink;
-  SocketAddress accept_addr;
-
-  // Create client.
-  scoped_ptr<AsyncSocket> client(ss_->CreateAsyncSocket(SOCK_STREAM));
-  sink.Monitor(client.get());
-  EXPECT_EQ(AsyncSocket::CS_CLOSED, client->GetState());
-  EXPECT_EQ(kEmptyAddr, client->GetLocalAddress());
-
-  // Create server and listen.
-  scoped_ptr<AsyncSocket> server(ss_->CreateAsyncSocket(SOCK_STREAM));
-  sink.Monitor(server.get());
-  EXPECT_EQ(0, server->Bind(kLoopbackAddr));
-  EXPECT_EQ(0, server->Listen(5));
-  EXPECT_EQ(AsyncSocket::CS_CONNECTING, server->GetState());
-
-  // Ensure no pending server connections, since we haven't done anything yet.
-  EXPECT_FALSE(sink.Check(server.get(), testing::SSE_READ));
-  EXPECT_TRUE(NULL == server->Accept(&accept_addr));
-  EXPECT_EQ(kEmptyAddr, accept_addr);
-
-  // Attempt connect to listening socket.
-  EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
-  EXPECT_NE(kEmptyAddr, client->GetLocalAddress());  // Implicit Bind
-  EXPECT_NE(server->GetLocalAddress(), client->GetLocalAddress());
-
-  // Client is connecting, outcome not yet determined.
-  EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
-  EXPECT_FALSE(sink.Check(client.get(), testing::SSE_OPEN));
-  EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
-
-  // Server has pending connection, accept it.
-  EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
-  scoped_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
-  ASSERT_TRUE(NULL != accepted.get());
-  EXPECT_NE(kEmptyAddr, accept_addr);
-  EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr);
-
-  // Connected from server perspective, check the addresses are correct.
-  EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
-  EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
-  EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
-
-  // Connected from client perspective, check the addresses are correct.
-  EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
-  EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
-  EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
-  EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
-  EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
-}
-
-void SocketTest::TestConnectWithDnsLookup() {
-  testing::StreamSink sink;
-  SocketAddress accept_addr;
-
-  // Create client.
-  scoped_ptr<AsyncSocket> client(ss_->CreateAsyncSocket(SOCK_STREAM));
-  sink.Monitor(client.get());
-
-  // Create server and listen.
-  scoped_ptr<AsyncSocket> server(ss_->CreateAsyncSocket(SOCK_STREAM));
-  sink.Monitor(server.get());
-  EXPECT_EQ(0, server->Bind(kLoopbackAddr));
-  EXPECT_EQ(0, server->Listen(5));
-
-  // Attempt connect to listening socket.
-  SocketAddress dns_addr(server->GetLocalAddress());
-  dns_addr.SetIP("localhost");
-  EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
-  // TODO: Bind when doing DNS lookup.
-  //EXPECT_NE(kEmptyAddr, client->GetLocalAddress());  // Implicit Bind
-
-  // Client is connecting, outcome not yet determined.
-  EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
-  EXPECT_FALSE(sink.Check(client.get(), testing::SSE_OPEN));
-  EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
-
-  // Server has pending connection, accept it.
-  EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
-  scoped_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
-  ASSERT_TRUE(NULL != accepted.get());
-  EXPECT_NE(kEmptyAddr, accept_addr);
-  EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr);
-
-  // Connected from server perspective, check the addresses are correct.
-  EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
-  EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
-  EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
-
-  // Connected from client perspective, check the addresses are correct.
-  EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
-  EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
-  EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
-  EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
-  EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
-}
-
-void SocketTest::TestConnectFail() {
-  testing::StreamSink sink;
-  SocketAddress accept_addr;
-
-  // Create client.
-  scoped_ptr<AsyncSocket> client(ss_->CreateAsyncSocket(SOCK_STREAM));
-  sink.Monitor(client.get());
-
-  // Create server, but don't listen yet.
-  scoped_ptr<AsyncSocket> server(ss_->CreateAsyncSocket(SOCK_STREAM));
-  sink.Monitor(server.get());
-  EXPECT_EQ(0, server->Bind(kLoopbackAddr));
-
-  // Attempt connect to a non-existent socket.
-  // We don't connect to the server socket created above, since on
-  // MacOS it takes about 75 seconds to get back an error!
-  SocketAddress bogus_addr(IPAddress(INADDR_LOOPBACK), 65535);
-  EXPECT_EQ(0, client->Connect(bogus_addr));
-
-  // Wait for connection to fail (ECONNREFUSED).
-  EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
-  EXPECT_FALSE(sink.Check(client.get(), testing::SSE_OPEN));
-  EXPECT_TRUE(sink.Check(client.get(), testing::SSE_ERROR));
-  EXPECT_EQ(kEmptyAddr, client->GetRemoteAddress());
-
-  // Should be no pending server connections.
-  EXPECT_FALSE(sink.Check(server.get(), testing::SSE_READ));
-  EXPECT_TRUE(NULL == server->Accept(&accept_addr));
-  EXPECT_EQ(kEmptyAddr, accept_addr);
-}
-
-void SocketTest::TestConnectWithDnsLookupFail() {
-  testing::StreamSink sink;
-  SocketAddress accept_addr;
-
-  // Create client.
-  scoped_ptr<AsyncSocket> client(ss_->CreateAsyncSocket(SOCK_STREAM));
-  sink.Monitor(client.get());
-
-  // Create server, but don't listen yet.
-  scoped_ptr<AsyncSocket> server(ss_->CreateAsyncSocket(SOCK_STREAM));
-  sink.Monitor(server.get());
-  EXPECT_EQ(0, server->Bind(kLoopbackAddr));
-
-  // Attempt connect to a non-existent host.
-  // We don't connect to the server socket created above, since on
-  // MacOS it takes about 75 seconds to get back an error!
-  SocketAddress bogus_dns_addr("not-a-real-hostname", 65535);
-  EXPECT_EQ(0, client->Connect(bogus_dns_addr));
-
-  // Wait for connection to fail (EHOSTNOTFOUND).
-  EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
-  EXPECT_FALSE(sink.Check(client.get(), testing::SSE_OPEN));
-  EXPECT_TRUE(sink.Check(client.get(), testing::SSE_ERROR));
-  EXPECT_EQ(kEmptyAddr, client->GetRemoteAddress());
-
-  // Should be no pending server connections.
-  EXPECT_FALSE(sink.Check(server.get(), testing::SSE_READ));
-  EXPECT_TRUE(NULL == server->Accept(&accept_addr));
-  EXPECT_EQ(kEmptyAddr, accept_addr);
-}
-
-void SocketTest::TestConnectWithClosedSocket() {
-  // Create server and listen.
-  scoped_ptr<AsyncSocket> server(ss_->CreateAsyncSocket(SOCK_STREAM));
-  EXPECT_EQ(0, server->Bind(kLoopbackAddr));
-  EXPECT_EQ(0, server->Listen(5));
-
-  // Create a client and put in to CS_CLOSED state.
-  scoped_ptr<AsyncSocket> client(ss_->CreateAsyncSocket(SOCK_STREAM));
-  EXPECT_EQ(0, client->Close());
-  EXPECT_EQ(AsyncSocket::CS_CLOSED, client->GetState());
-
-  // Connect() should reinitialize the socket, and put it in to CS_CONNECTING.
-  EXPECT_EQ(0, client->Connect(SocketAddress(server->GetLocalAddress())));
-  EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
-}
-
-void SocketTest::TestServerCloseDuringConnect() {
-  testing::StreamSink sink;
-  SocketAddress accept_addr;
-
-  // Create client.
-  scoped_ptr<AsyncSocket> client(ss_->CreateAsyncSocket(SOCK_STREAM));
-  sink.Monitor(client.get());
-
-  // Create server and listen.
-  scoped_ptr<AsyncSocket> server(ss_->CreateAsyncSocket(SOCK_STREAM));
-  sink.Monitor(server.get());
-  EXPECT_EQ(0, server->Bind(kLoopbackAddr));
-  EXPECT_EQ(0, server->Listen(5));
-
-  // Attempt connect to listening socket.
-  EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
-
-  // Close down the server while the socket is in the accept queue.
-  EXPECT_TRUE_WAIT(sink.Check(server.get(), testing::SSE_READ), kTimeout);
-  server->Close();
-
-  // This should fail the connection for the client. Clean up.
-  EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
-  EXPECT_TRUE(sink.Check(client.get(), testing::SSE_ERROR));
-  client->Close();
-}
-
-void SocketTest::TestClientCloseDuringConnect() {
-  testing::StreamSink sink;
-  SocketAddress accept_addr;
-
-  // Create client.
-  scoped_ptr<AsyncSocket> client(ss_->CreateAsyncSocket(SOCK_STREAM));
-  sink.Monitor(client.get());
-
-  // Create server and listen.
-  scoped_ptr<AsyncSocket> server(ss_->CreateAsyncSocket(SOCK_STREAM));
-  sink.Monitor(server.get());
-  EXPECT_EQ(0, server->Bind(kLoopbackAddr));
-  EXPECT_EQ(0, server->Listen(5));
-
-  // Attempt connect to listening socket.
-  EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
-
-  // Close down the client while the socket is in the accept queue.
-  EXPECT_TRUE_WAIT(sink.Check(server.get(), testing::SSE_READ), kTimeout);
-  client->Close();
-
-  // The connection should still be able to be accepted.
-  scoped_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
-  ASSERT_TRUE(NULL != accepted.get());
-  sink.Monitor(accepted.get());
-  EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
-
-  // The accepted socket should then close (possibly with err, timing-related)
-  EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, accepted->GetState(), kTimeout);
-  EXPECT_TRUE(sink.Check(accepted.get(), testing::SSE_CLOSE) ||
-              sink.Check(accepted.get(), testing::SSE_ERROR));
-
-  // The client should not get a close event.
-  EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
-}
-
-void SocketTest::TestServerClose() {
-  testing::StreamSink sink;
-  SocketAddress accept_addr;
-
-  // Create client.
-  scoped_ptr<AsyncSocket> client(ss_->CreateAsyncSocket(SOCK_STREAM));
-  sink.Monitor(client.get());
-
-  // Create server and listen.
-  scoped_ptr<AsyncSocket> server(ss_->CreateAsyncSocket(SOCK_STREAM));
-  sink.Monitor(server.get());
-  EXPECT_EQ(0, server->Bind(kLoopbackAddr));
-  EXPECT_EQ(0, server->Listen(5));
-
-  // Attempt connection.
-  EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
-
-  // Accept connection.
-  EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
-  scoped_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
-  ASSERT_TRUE(NULL != accepted.get());
-  sink.Monitor(accepted.get());
-
-  // Both sides are now connected.
-  EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
-  EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
-  EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
-  EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
-
-  // Send data to the client, and then close the connection.
-  EXPECT_EQ(1, accepted->Send("a", 1));
-  accepted->Close();
-  EXPECT_EQ(AsyncSocket::CS_CLOSED, accepted->GetState());
-
-  // Expect that the client is notified, and has not yet closed.
-  EXPECT_TRUE_WAIT(sink.Check(client.get(), testing::SSE_READ), kTimeout);
-  EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
-  EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
-
-  // Ensure the data can be read.
-  char buffer[10];
-  EXPECT_EQ(1, client->Recv(buffer, sizeof(buffer)));
-  EXPECT_EQ('a', buffer[0]);
-
-  // Now we should close, but the remote address will remain.
-  EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
-  EXPECT_TRUE(sink.Check(client.get(), testing::SSE_CLOSE));
-  EXPECT_NE(kEmptyAddr, client->GetRemoteAddress());
-
-  // The closer should not get a close signal.
-  EXPECT_FALSE(sink.Check(accepted.get(), testing::SSE_CLOSE));
-  EXPECT_EQ(kEmptyAddr, accepted->GetRemoteAddress());
-
-  // And the closee should only get a single signal.
-  Thread::Current()->ProcessMessages(0);
-  EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
-
-  // Close down the client and ensure all is good.
-  client->Close();
-  EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
-  EXPECT_EQ(kEmptyAddr, client->GetRemoteAddress());
-}
-
-class SocketCloser : public sigslot::has_slots<> {
- public:
-  void OnClose(AsyncSocket* socket, int error) {
-    socket->Close();  // Deleting here would blow up the vector of handlers
-                      // for the socket's signal.
-  }
-};
-
-void SocketTest::TestCloseInClosedCallback() {
-  testing::StreamSink sink;
-  SocketCloser closer;
-  SocketAddress accept_addr;
-
-  // Create client.
-  scoped_ptr<AsyncSocket> client(ss_->CreateAsyncSocket(SOCK_STREAM));
-  sink.Monitor(client.get());
-  client->SignalCloseEvent.connect(&closer, &SocketCloser::OnClose);
-
-  // Create server and listen.
-  scoped_ptr<AsyncSocket> server(ss_->CreateAsyncSocket(SOCK_STREAM));
-  sink.Monitor(server.get());
-  EXPECT_EQ(0, server->Bind(kLoopbackAddr));
-  EXPECT_EQ(0, server->Listen(5));
-
-  // Attempt connection.
-  EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
-
-  // Accept connection.
-  EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
-  scoped_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
-  ASSERT_TRUE(NULL != accepted.get());
-  sink.Monitor(accepted.get());
-
-  // Both sides are now connected.
-  EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
-  EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
-  EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
-  EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
-
-  // Send data to the client, and then close the connection.
-  accepted->Close();
-  EXPECT_EQ(AsyncSocket::CS_CLOSED, accepted->GetState());
-
-  // Expect that the client is notified, and has not yet closed.
-  EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
-  EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
-
-  // Now we should be closed and invalidated
-  EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
-  EXPECT_TRUE(sink.Check(client.get(), testing::SSE_CLOSE));
-  EXPECT_TRUE(Socket::CS_CLOSED == client->GetState());
-}
-
-class Sleeper : public MessageHandler {
- public:
-  Sleeper() {}
-  void OnMessage(Message* msg) {
-    Thread::Current()->SleepMs(500);
-  }
-};
-
-void SocketTest::TestSocketServerWait() {
-  testing::StreamSink sink;
-  SocketAddress accept_addr;
-
-  // Create & connect server and client sockets.
-  scoped_ptr<AsyncSocket> client(ss_->CreateAsyncSocket(SOCK_STREAM));
-  scoped_ptr<AsyncSocket> server(ss_->CreateAsyncSocket(SOCK_STREAM));
-  sink.Monitor(client.get());
-  sink.Monitor(server.get());
-  EXPECT_EQ(0, server->Bind(kLoopbackAddr));
-  EXPECT_EQ(0, server->Listen(5));
-
-  EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
-  EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
-
-  scoped_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
-  ASSERT_TRUE(NULL != accepted.get());
-  sink.Monitor(accepted.get());
-  EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
-  EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
-  EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
-
-  EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
-  EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
-  EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
-  EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
-  EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
-
-  // Do an i/o operation, triggering an eventual callback.
-  EXPECT_FALSE(sink.Check(accepted.get(), testing::SSE_READ));
-  char buf[1024] = {0};
-  
-  EXPECT_EQ(1024, client->Send(buf, 1024));
-  EXPECT_FALSE(sink.Check(accepted.get(), testing::SSE_READ));
-
-  // Shouldn't signal when blocked in a thread Send, where process_io is false.
-  scoped_ptr<Thread> thread(new Thread());
-  thread->Start();
-  Sleeper sleeper;
-  TypedMessageData<AsyncSocket*> data(client.get());
-  thread->Send(&sleeper, 0, &data);
-  EXPECT_FALSE(sink.Check(accepted.get(), testing::SSE_READ));
-
-  // But should signal when process_io is true.
-  EXPECT_TRUE_WAIT((sink.Check(accepted.get(), testing::SSE_READ)), kTimeout);
-  EXPECT_LT(0, accepted->Recv(buf, 1024));
-}
-
-void SocketTest::TestTcp() {
-  testing::StreamSink sink;
-  SocketAddress accept_addr;
-
-  // Create test data.
-  const size_t kDataSize = 1024 * 1024;
-  scoped_array<char> send_buffer(new char[kDataSize]);
-  scoped_array<char> recv_buffer(new char[kDataSize]);
-  size_t send_pos = 0, recv_pos = 0;
-  for (size_t i = 0; i < kDataSize; ++i) {
-    send_buffer[i] = i;
-    recv_buffer[i] = 0;
-  }
-
-  // Create client.
-  scoped_ptr<AsyncSocket> client(ss_->CreateAsyncSocket(SOCK_STREAM));
-  sink.Monitor(client.get());
-
-  // Create server and listen.
-  scoped_ptr<AsyncSocket> server(ss_->CreateAsyncSocket(SOCK_STREAM));
-  sink.Monitor(server.get());
-  EXPECT_EQ(0, server->Bind(kLoopbackAddr));
-  EXPECT_EQ(0, server->Listen(5));
-
-  // Attempt connection.
-  EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
-
-  // Accept connection.
-  EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
-  scoped_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
-  ASSERT_TRUE(NULL != accepted.get());
-  sink.Monitor(accepted.get());
-
-  // Both sides are now connected.
-  EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
-  EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
-  EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
-  EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
-
-  // Send and receive a bunch of data.
-  bool send_waiting_for_writability = false;
-  bool send_expect_success = true;
-  bool recv_waiting_for_readability = true;
-  bool recv_expect_success = false;
-  int data_in_flight = 0;
-  while (recv_pos < kDataSize) {
-    // Send as much as we can if we've been cleared to send.
-    while (!send_waiting_for_writability && send_pos < kDataSize) {
-      int tosend = kDataSize - send_pos;
-      int sent = accepted->Send(send_buffer.get() + send_pos, tosend);
-      if (send_expect_success) {
-        // The first Send() after connecting or getting writability should
-        // succeed and send some data.
-        EXPECT_GT(sent, 0);
-        send_expect_success = false;
-      }
-      if (sent >= 0) {
-        EXPECT_LE(sent, tosend);
-        send_pos += sent;
-        data_in_flight += sent;
-      } else {
-        ASSERT_TRUE(accepted->IsBlocking());
-        send_waiting_for_writability = true;
-      }
-    }
-
-    // Read all the sent data.
-    while (data_in_flight > 0) {
-      if (recv_waiting_for_readability) {
-        // Wait until data is available.
-        EXPECT_TRUE_WAIT(sink.Check(client.get(), testing::SSE_READ), kTimeout);
-        recv_waiting_for_readability = false;
-        recv_expect_success = true;
-      }
-
-      // Receive as much as we can get in a single recv call.
-      int rcvd = client->Recv(recv_buffer.get() + recv_pos,
-                              kDataSize - recv_pos);
-
-      if (recv_expect_success) {
-        // The first Recv() after getting readability should succeed and receive
-        // some data.
-        EXPECT_GT(rcvd, 0);
-        recv_expect_success = false;
-      }
-      if (rcvd >= 0) {
-        EXPECT_LE(rcvd, data_in_flight);
-        recv_pos += rcvd;
-        data_in_flight -= rcvd;
-      } else {
-        ASSERT_TRUE(client->IsBlocking());
-        recv_waiting_for_readability = true;
-      }
-    }
-
-    // Once all that we've sent has been rcvd, expect to be able to send again.
-    if (send_waiting_for_writability) {
-      EXPECT_TRUE_WAIT(sink.Check(accepted.get(), testing::SSE_WRITE),
-                       kTimeout);
-      send_waiting_for_writability = false;
-      send_expect_success = true;
-    }
-  }
-
-  // The received data matches the sent data.
-  EXPECT_EQ(kDataSize, send_pos);
-  EXPECT_EQ(kDataSize, recv_pos);
-  EXPECT_EQ(0, memcmp(recv_buffer.get(), send_buffer.get(), kDataSize));
-
-  // Close down.
-  accepted->Close();
-  EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
-  EXPECT_TRUE(sink.Check(client.get(), testing::SSE_CLOSE));
-  client->Close();
-}
-
-void SocketTest::TestSingleFlowControlCallback() {
-  testing::StreamSink sink;
-  SocketAddress accept_addr;
-
-  // Create client.
-  scoped_ptr<AsyncSocket> client(ss_->CreateAsyncSocket(SOCK_STREAM));
-  sink.Monitor(client.get());
-
-  // Create server and listen.
-  scoped_ptr<AsyncSocket> server(ss_->CreateAsyncSocket(SOCK_STREAM));
-  sink.Monitor(server.get());
-  EXPECT_EQ(0, server->Bind(kLoopbackAddr));
-  EXPECT_EQ(0, server->Listen(5));
-
-  // Attempt connection.
-  EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
-
-  // Accept connection.
-  EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
-  scoped_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
-  ASSERT_TRUE(NULL != accepted.get());
-  sink.Monitor(accepted.get());
-
-  // Both sides are now connected.
-  EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
-  EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
-  EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
-  EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
-
-  // Fill the socket buffer.
-  char buf[1024 * 16] = {0};
-  while (accepted->Send(&buf, ARRAY_SIZE(buf)) != -1) {}
-  EXPECT_TRUE(accepted->IsBlocking());
-
-  // Expect no writable callbacks
-  EXPECT_FALSE(sink.Check(accepted.get(), testing::SSE_WRITE));
-
-  // Wait until data is available.
-  EXPECT_TRUE_WAIT(sink.Check(client.get(), testing::SSE_READ), kTimeout);
-
-  // Pull some data.
-  client->Recv(buf, ARRAY_SIZE(buf));
-
-  // Expect at least one additional writable callback.
-  EXPECT_TRUE_WAIT(sink.Check(accepted.get(), testing::SSE_WRITE), kTimeout);
-
-  // Adding data in response to the writeable callback shouldn't cause infinite
-  // callbacks.
-  int extras = 0;
-  for (int i = 0; i < 100; ++i) {
-    accepted->Send(&buf, ARRAY_SIZE(buf));
-    talk_base::Thread::Current()->ProcessMessages(1);
-    if (sink.Check(accepted.get(), testing::SSE_WRITE)) {
-      extras++;
-    }
-  }
-  EXPECT_LT(extras, 2);
-
-  // Close down.
-  accepted->Close();
-  client->Close();
-}
-
-void SocketTest::TestUdp() {
-  // Test basic bind and connect behavior.
-  SocketAddress addr1(kLoopbackAddr);
-  AsyncSocket* socket = ss_->CreateAsyncSocket(SOCK_DGRAM);
-  EXPECT_EQ(AsyncSocket::CS_CLOSED, socket->GetState());
-  EXPECT_EQ(0, socket->Bind(addr1));
-  addr1 = socket->GetLocalAddress();
-  EXPECT_EQ(0, socket->Connect(addr1));
-  EXPECT_EQ(AsyncSocket::CS_CONNECTED, socket->GetState());
-  socket->Close();
-  EXPECT_EQ(AsyncSocket::CS_CLOSED, socket->GetState());
-  delete socket;
-
-  // Test send/receive behavior.
-  scoped_ptr<TestClient> client1(new TestClient(
-      AsyncUDPSocket::Create(ss_, addr1)));
-  scoped_ptr<TestClient> client2(new TestClient(
-      AsyncUDPSocket::Create(ss_, SocketAddress())));
-
-  SocketAddress addr2;
-  EXPECT_EQ(3, client2->SendTo("foo", 3, addr1));
-  EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr2));
-
-  SocketAddress addr3;
-  EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr2));
-  EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &addr3));
-  EXPECT_EQ(addr3, addr1);
-
-  // TODO: figure out what the intent is here
-  for (int i = 0; i < 10; ++i) {
-    client2.reset(new TestClient(AsyncUDPSocket::Create(ss_, SocketAddress())));
-
-    SocketAddress addr4;
-    EXPECT_EQ(3, client2->SendTo("foo", 3, addr1));
-    EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr4));
-    EXPECT_EQ(addr4.ipaddr(), addr2.ipaddr());
-
-    SocketAddress addr5;
-    EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr4));
-    EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &addr5));
-    EXPECT_EQ(addr5, addr1);
-
-    addr2 = addr4;
-  }
-}
-
-void SocketTest::TestGetSetOptions() {
-  talk_base::scoped_ptr<AsyncSocket> socket(ss_->CreateAsyncSocket(SOCK_DGRAM));
-  socket->Bind(kLoopbackAddr);
-
-  // Check SNDBUF/RCVBUF.
-  const int desired_size = 12345;
-#if defined(LINUX) || defined(ANDROID)
-  // Yes, really.  It's in the kernel source.
-  const int expected_size = desired_size * 2;
-#else   // !LINUX && !ANDROID
-  const int expected_size = desired_size;
-#endif  // !LINUX && !ANDROID
-  int recv_size = 0;
-  int send_size = 0;
-  // get the initial sizes
-  ASSERT_NE(-1, socket->GetOption(Socket::OPT_RCVBUF, &recv_size));
-  ASSERT_NE(-1, socket->GetOption(Socket::OPT_SNDBUF, &send_size));
-  // set our desired sizes
-  ASSERT_NE(-1, socket->SetOption(Socket::OPT_RCVBUF, desired_size));
-  ASSERT_NE(-1, socket->SetOption(Socket::OPT_SNDBUF, desired_size));
-  // get the sizes again
-  ASSERT_NE(-1, socket->GetOption(Socket::OPT_RCVBUF, &recv_size));
-  ASSERT_NE(-1, socket->GetOption(Socket::OPT_SNDBUF, &send_size));
-  // make sure they are right
-  ASSERT_EQ(expected_size, recv_size);
-  ASSERT_EQ(expected_size, send_size);
-
-  // Check that we can't set NODELAY on a UDP socket.
-  int current_nd, desired_nd = 1;
-  ASSERT_EQ(-1, socket->GetOption(Socket::OPT_NODELAY, &current_nd));
-  ASSERT_EQ(-1, socket->SetOption(Socket::OPT_NODELAY, desired_nd));
-
-  // Try estimating MTU.
-  talk_base::scoped_ptr<AsyncSocket>
-      mtu_socket(ss_->CreateAsyncSocket(SOCK_DGRAM));
-  mtu_socket->Bind(kLoopbackAddr);
-  uint16 mtu;
-  // should fail until we connect
-  ASSERT_EQ(-1, mtu_socket->EstimateMTU(&mtu));
-  mtu_socket->Connect(kLoopbackAddr);
-#if defined(WIN32)
-  // now it should succeed
-  ASSERT_NE(-1, mtu_socket->EstimateMTU(&mtu));
-  ASSERT_GE(mtu, 1492);  // should be at least the 1492 "plateau" on localhost
-#elif defined(OSX)
-  // except on OSX, where it's not yet implemented
-  ASSERT_EQ(-1, mtu_socket->EstimateMTU(&mtu));
-#else
-  // and the behavior seems unpredictable on Linux, failing on the build machine
-  // but succeeding on my Ubiquity instance.
-#endif
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/socket_unittest.h b/third_party/libjingle/source/talk/base/socket_unittest.h
deleted file mode 100644
index 481f073..0000000
--- a/third_party/libjingle/source/talk/base/socket_unittest.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * libjingle
- * Copyright 2009, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_SOCKET_UNITTEST_H_
-#define TALK_BASE_SOCKET_UNITTEST_H_
-
-#include "talk/base/gunit.h"
-#include "talk/base/thread.h"
-
-namespace talk_base {
-
-// Generic socket tests, to be used when testing individual socketservers.
-// Derive your specific test class from SocketTest, install your
-// socketserver, and call the SocketTest test methods.
-class SocketTest : public testing::Test {
- protected:
-  SocketTest() : ss_(NULL) {}
-  virtual void SetUp() { ss_ = Thread::Current()->socketserver(); }
-  void TestConnect();
-  void TestConnectWithDnsLookup();
-  void TestConnectFail();
-  void TestConnectWithDnsLookupFail();
-  void TestConnectWithClosedSocket();
-  void TestServerCloseDuringConnect();
-  void TestClientCloseDuringConnect();
-  void TestServerClose();
-  void TestCloseInClosedCallback();
-  void TestSocketServerWait();
-  void TestTcp();
-  void TestSingleFlowControlCallback();
-  void TestUdp();
-  void TestGetSetOptions();
-
-  static const int kTimeout = 5000;  // ms
-  SocketServer* ss_;
-};
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_SOCKET_UNITTEST_H_
diff --git a/third_party/libjingle/source/talk/base/socketadapters.cc b/third_party/libjingle/source/talk/base/socketadapters.cc
deleted file mode 100644
index 427ebdc..0000000
--- a/third_party/libjingle/source/talk/base/socketadapters.cc
+++ /dev/null
@@ -1,910 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#if defined(_MSC_VER) && _MSC_VER < 1300
-#pragma warning(disable:4786)
-#endif
-
-#include <time.h>
-#include <errno.h>
-
-#ifdef WIN32
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#define SECURITY_WIN32
-#include <security.h>
-#endif
-
-#include "talk/base/bytebuffer.h"
-#include "talk/base/common.h"
-#include "talk/base/httpcommon.h"
-#include "talk/base/logging.h"
-#include "talk/base/socketadapters.h"
-#include "talk/base/stringencode.h"
-#include "talk/base/stringutils.h"
-
-#ifdef WIN32
-#include "talk/base/sec_buffer.h"
-#endif  // WIN32
-
-namespace talk_base {
-
-BufferedReadAdapter::BufferedReadAdapter(AsyncSocket* socket, size_t size)
-    : AsyncSocketAdapter(socket), buffer_size_(size),
-      data_len_(0), buffering_(false) {
-  buffer_ = new char[buffer_size_];
-}
-
-BufferedReadAdapter::~BufferedReadAdapter() {
-  delete [] buffer_;
-}
-
-int BufferedReadAdapter::Send(const void *pv, size_t cb) {
-  if (buffering_) {
-    // TODO: Spoof error better; Signal Writeable
-    socket_->SetError(EWOULDBLOCK);
-    return -1;
-  }
-  return AsyncSocketAdapter::Send(pv, cb);
-}
-
-int BufferedReadAdapter::Recv(void *pv, size_t cb) {
-  if (buffering_) {
-    socket_->SetError(EWOULDBLOCK);
-    return -1;
-  }
-
-  size_t read = 0;
-
-  if (data_len_) {
-    read = _min(cb, data_len_);
-    memcpy(pv, buffer_, read);
-    data_len_ -= read;
-    if (data_len_ > 0) {
-      memmove(buffer_, buffer_ + read, data_len_);
-    }
-    pv = static_cast<char *>(pv) + read;
-    cb -= read;
-  }
-
-  // FIX: If cb == 0, we won't generate another read event
-
-  int res = AsyncSocketAdapter::Recv(pv, cb);
-  if (res < 0)
-    return res;
-
-  return res + static_cast<int>(read);
-}
-
-void BufferedReadAdapter::BufferInput(bool on) {
-  buffering_ = on;
-}
-
-void BufferedReadAdapter::OnReadEvent(AsyncSocket * socket) {
-  ASSERT(socket == socket_);
-
-  if (!buffering_) {
-    AsyncSocketAdapter::OnReadEvent(socket);
-    return;
-  }
-
-  if (data_len_ >= buffer_size_) {
-    LOG(INFO) << "Input buffer overflow";
-    ASSERT(false);
-    data_len_ = 0;
-  }
-
-  int len = socket_->Recv(buffer_ + data_len_, buffer_size_ - data_len_);
-  if (len < 0) {
-    // TODO: Do something better like forwarding the error to the user.
-    LOG_ERR(INFO) << "Recv";
-    return;
-  }
-
-  data_len_ += len;
-
-  ProcessInput(buffer_, &data_len_);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-// This is a SSL v2 CLIENT_HELLO message.
-// TODO: Should this have a session id? The response doesn't have a
-// certificate, so the hello should have a session id.
-static const uint8 kSslClientHello[] = {
-  0x80, 0x46,                                            // msg len
-  0x01,                                                  // CLIENT_HELLO
-  0x03, 0x01,                                            // SSL 3.1
-  0x00, 0x2d,                                            // ciphersuite len
-  0x00, 0x00,                                            // session id len
-  0x00, 0x10,                                            // challenge len
-  0x01, 0x00, 0x80, 0x03, 0x00, 0x80, 0x07, 0x00, 0xc0,  // ciphersuites
-  0x06, 0x00, 0x40, 0x02, 0x00, 0x80, 0x04, 0x00, 0x80,  //
-  0x00, 0x00, 0x04, 0x00, 0xfe, 0xff, 0x00, 0x00, 0x0a,  //
-  0x00, 0xfe, 0xfe, 0x00, 0x00, 0x09, 0x00, 0x00, 0x64,  //
-  0x00, 0x00, 0x62, 0x00, 0x00, 0x03, 0x00, 0x00, 0x06,  //
-  0x1f, 0x17, 0x0c, 0xa6, 0x2f, 0x00, 0x78, 0xfc,        // challenge
-  0x46, 0x55, 0x2e, 0xb1, 0x83, 0x39, 0xf1, 0xea         //
-};
-
-// This is a TLSv1 SERVER_HELLO message.
-static const uint8 kSslServerHello[] = {
-  0x16,                                            // handshake message
-  0x03, 0x01,                                      // SSL 3.1
-  0x00, 0x4a,                                      // message len
-  0x02,                                            // SERVER_HELLO
-  0x00, 0x00, 0x46,                                // handshake len
-  0x03, 0x01,                                      // SSL 3.1
-  0x42, 0x85, 0x45, 0xa7, 0x27, 0xa9, 0x5d, 0xa0,  // server random
-  0xb3, 0xc5, 0xe7, 0x53, 0xda, 0x48, 0x2b, 0x3f,  //
-  0xc6, 0x5a, 0xca, 0x89, 0xc1, 0x58, 0x52, 0xa1,  //
-  0x78, 0x3c, 0x5b, 0x17, 0x46, 0x00, 0x85, 0x3f,  //
-  0x20,                                            // session id len
-  0x0e, 0xd3, 0x06, 0x72, 0x5b, 0x5b, 0x1b, 0x5f,  // session id
-  0x15, 0xac, 0x13, 0xf9, 0x88, 0x53, 0x9d, 0x9b,  //
-  0xe8, 0x3d, 0x7b, 0x0c, 0x30, 0x32, 0x6e, 0x38,  //
-  0x4d, 0xa2, 0x75, 0x57, 0x41, 0x6c, 0x34, 0x5c,  //
-  0x00, 0x04,                                      // RSA/RC4-128/MD5
-  0x00                                             // null compression
-};
-
-AsyncSSLSocket::AsyncSSLSocket(AsyncSocket* socket)
-    : BufferedReadAdapter(socket, 1024) {
-}
-
-int AsyncSSLSocket::Connect(const SocketAddress& addr) {
-  // Begin buffering before we connect, so that there isn't a race condition
-  // between potential senders and receiving the OnConnectEvent signal
-  BufferInput(true);
-  return BufferedReadAdapter::Connect(addr);
-}
-
-void AsyncSSLSocket::OnConnectEvent(AsyncSocket * socket) {
-  ASSERT(socket == socket_);
-  // TODO: we could buffer output too...
-  VERIFY(sizeof(kSslClientHello) ==
-      DirectSend(kSslClientHello, sizeof(kSslClientHello)));
-}
-
-void AsyncSSLSocket::ProcessInput(char* data, size_t* len) {
-  if (*len < sizeof(kSslServerHello))
-    return;
-
-  if (memcmp(kSslServerHello, data, sizeof(kSslServerHello)) != 0) {
-    Close();
-    SignalCloseEvent(this, 0);  // TODO: error code?
-    return;
-  }
-
-  *len -= sizeof(kSslServerHello);
-  if (*len > 0) {
-    memmove(data, data + sizeof(kSslServerHello), *len);
-  }
-
-  bool remainder = (*len > 0);
-  BufferInput(false);
-  SignalConnectEvent(this);
-
-  // FIX: if SignalConnect causes the socket to be destroyed, we are in trouble
-  if (remainder)
-    SignalReadEvent(this);
-}
-
-AsyncSSLServerSocket::AsyncSSLServerSocket(AsyncSocket* socket)
-     : BufferedReadAdapter(socket, 1024) {
-  BufferInput(true);
-}
-
-void AsyncSSLServerSocket::ProcessInput(char* data, size_t* len) {
-  // We only accept client hello messages.
-  if (*len < sizeof(kSslClientHello)) {
-    return;
-  }
-
-  if (memcmp(kSslClientHello, data, sizeof(kSslClientHello)) != 0) {
-    Close();
-    SignalCloseEvent(this, 0);
-    return;
-  }
-
-  *len -= sizeof(kSslClientHello);
-
-  // Clients should not send more data until the handshake is completed.
-  ASSERT(*len == 0);
-
-  // Send a server hello back to the client.
-  DirectSend(kSslServerHello, sizeof(kSslServerHello));
-
-  // Handshake completed for us, redirect input to our parent.
-  BufferInput(false);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-AsyncHttpsProxySocket::AsyncHttpsProxySocket(AsyncSocket* socket,
-                                             const std::string& user_agent,
-                                             const SocketAddress& proxy,
-                                             const std::string& username,
-                                             const CryptString& password)
-  : BufferedReadAdapter(socket, 1024), proxy_(proxy), agent_(user_agent),
-    user_(username), pass_(password), force_connect_(false), state_(PS_ERROR),
-    context_(0) {
-}
-
-AsyncHttpsProxySocket::~AsyncHttpsProxySocket() {
-  delete context_;
-}
-
-int AsyncHttpsProxySocket::Connect(const SocketAddress& addr) {
-  int ret;
-  LOG(LS_VERBOSE) << "AsyncHttpsProxySocket::Connect("
-                  << proxy_.ToString() << ")";
-  dest_ = addr;
-  state_ = PS_INIT;
-  if (ShouldIssueConnect()) {
-    BufferInput(true);
-  }
-  ret = BufferedReadAdapter::Connect(proxy_);
-  // TODO: Set state_ appropriately if Connect fails.
-  return ret;
-}
-
-SocketAddress AsyncHttpsProxySocket::GetRemoteAddress() const {
-  return dest_;
-}
-
-int AsyncHttpsProxySocket::Close() {
-  headers_.clear();
-  state_ = PS_ERROR;
-  dest_.Clear();
-  delete context_;
-  context_ = NULL;
-  return BufferedReadAdapter::Close();
-}
-
-Socket::ConnState AsyncHttpsProxySocket::GetState() const {
-  if (state_ < PS_TUNNEL) {
-    return CS_CONNECTING;
-  } else if (state_ == PS_TUNNEL) {
-    return CS_CONNECTED;
-  } else {
-    return CS_CLOSED;
-  }
-}
-
-void AsyncHttpsProxySocket::OnConnectEvent(AsyncSocket * socket) {
-  LOG(LS_VERBOSE) << "AsyncHttpsProxySocket::OnConnectEvent";
-  if (!ShouldIssueConnect()) {
-    state_ = PS_TUNNEL;
-    BufferedReadAdapter::OnConnectEvent(socket);
-    return;
-  }
-  SendRequest();
-}
-
-void AsyncHttpsProxySocket::OnCloseEvent(AsyncSocket * socket, int err) {
-  LOG(LS_VERBOSE) << "AsyncHttpsProxySocket::OnCloseEvent(" << err << ")";
-  if ((state_ == PS_WAIT_CLOSE) && (err == 0)) {
-    state_ = PS_ERROR;
-    Connect(dest_);
-  } else {
-    BufferedReadAdapter::OnCloseEvent(socket, err);
-  }
-}
-
-void AsyncHttpsProxySocket::ProcessInput(char* data, size_t* len) {
-  size_t start = 0;
-  for (size_t pos = start; state_ < PS_TUNNEL && pos < *len;) {
-    if (state_ == PS_SKIP_BODY) {
-      size_t consume = _min(*len - pos, content_length_);
-      pos += consume;
-      start = pos;
-      content_length_ -= consume;
-      if (content_length_ == 0) {
-        EndResponse();
-      }
-      continue;
-    }
-
-    if (data[pos++] != '\n')
-      continue;
-
-    size_t len = pos - start - 1;
-    if ((len > 0) && (data[start + len - 1] == '\r'))
-      --len;
-
-    data[start + len] = 0;
-    ProcessLine(data + start, len);
-    start = pos;
-  }
-
-  *len -= start;
-  if (*len > 0) {
-    memmove(data, data + start, *len);
-  }
-
-  if (state_ != PS_TUNNEL)
-    return;
-
-  bool remainder = (*len > 0);
-  BufferInput(false);
-  SignalConnectEvent(this);
-
-  // FIX: if SignalConnect causes the socket to be destroyed, we are in trouble
-  if (remainder)
-    SignalReadEvent(this);  // TODO: signal this??
-}
-
-bool AsyncHttpsProxySocket::ShouldIssueConnect() const {
-  // TODO: Think about whether a more sophisticated test
-  // than dest port == 80 is needed.
-  return force_connect_ || (dest_.port() != 80);
-}
-
-void AsyncHttpsProxySocket::SendRequest() {
-  std::stringstream ss;
-  ss << "CONNECT " << dest_.ToString() << " HTTP/1.0\r\n";
-  ss << "User-Agent: " << agent_ << "\r\n";
-  ss << "Host: " << dest_.IPAsString() << "\r\n";
-  ss << "Content-Length: 0\r\n";
-  ss << "Proxy-Connection: Keep-Alive\r\n";
-  ss << headers_;
-  ss << "\r\n";
-  std::string str = ss.str();
-  DirectSend(str.c_str(), str.size());
-  state_ = PS_LEADER;
-  expect_close_ = true;
-  content_length_ = 0;
-  headers_.clear();
-
-  LOG(LS_VERBOSE) << "AsyncHttpsProxySocket >> " << str;
-}
-
-void AsyncHttpsProxySocket::ProcessLine(char * data, size_t len) {
-  LOG(LS_VERBOSE) << "AsyncHttpsProxySocket << " << data;
-
-  if (len == 0) {
-    if (state_ == PS_TUNNEL_HEADERS) {
-      state_ = PS_TUNNEL;
-    } else if (state_ == PS_ERROR_HEADERS) {
-      Error(defer_error_);
-      return;
-    } else if (state_ == PS_SKIP_HEADERS) {
-      if (content_length_) {
-        state_ = PS_SKIP_BODY;
-      } else {
-        EndResponse();
-        return;
-      }
-    } else {
-      static bool report = false;
-      if (!unknown_mechanisms_.empty() && !report) {
-        report = true;
-        std::string msg(
-          "Unable to connect to the Google Talk service due to an incompatibility "
-          "with your proxy.\r\nPlease help us resolve this issue by submitting the "
-          "following information to us using our technical issue submission form "
-          "at:\r\n\r\n"
-          "http://www.google.com/support/talk/bin/request.py\r\n\r\n"
-          "We apologize for the inconvenience.\r\n\r\n"
-          "Information to submit to Google: "
-          );
-        //std::string msg("Please report the following information to foo@bar.com:\r\nUnknown methods: ");
-        msg.append(unknown_mechanisms_);
-#ifdef WIN32
-        MessageBoxA(0, msg.c_str(), "Oops!", MB_OK);
-#endif
-#ifdef POSIX
-        // TODO: Raise a signal so the UI can be separated.
-        LOG(LS_ERROR) << "Oops!\n\n" << msg;
-#endif
-      }
-      // Unexpected end of headers
-      Error(0);
-      return;
-    }
-  } else if (state_ == PS_LEADER) {
-    unsigned int code;
-    if (sscanf(data, "HTTP/%*u.%*u %u", &code) != 1) {
-      Error(0);
-      return;
-    }
-    switch (code) {
-    case 200:
-      // connection good!
-      state_ = PS_TUNNEL_HEADERS;
-      return;
-#if defined(HTTP_STATUS_PROXY_AUTH_REQ) && (HTTP_STATUS_PROXY_AUTH_REQ != 407)
-#error Wrong code for HTTP_STATUS_PROXY_AUTH_REQ
-#endif
-    case 407:  // HTTP_STATUS_PROXY_AUTH_REQ
-      state_ = PS_AUTHENTICATE;
-      return;
-    default:
-      defer_error_ = 0;
-      state_ = PS_ERROR_HEADERS;
-      return;
-    }
-  } else if ((state_ == PS_AUTHENTICATE)
-             && (_strnicmp(data, "Proxy-Authenticate:", 19) == 0)) {
-    std::string response, auth_method;
-    switch (HttpAuthenticate(data + 19, len - 19,
-                             proxy_, "CONNECT", "/",
-                             user_, pass_, context_, response, auth_method)) {
-    case HAR_IGNORE:
-      LOG(LS_VERBOSE) << "Ignoring Proxy-Authenticate: " << auth_method;
-      if (!unknown_mechanisms_.empty())
-        unknown_mechanisms_.append(", ");
-      unknown_mechanisms_.append(auth_method);
-      break;
-    case HAR_RESPONSE:
-      headers_ = "Proxy-Authorization: ";
-      headers_.append(response);
-      headers_.append("\r\n");
-      state_ = PS_SKIP_HEADERS;
-      unknown_mechanisms_.clear();
-      break;
-    case HAR_CREDENTIALS:
-      defer_error_ = SOCKET_EACCES;
-      state_ = PS_ERROR_HEADERS;
-      unknown_mechanisms_.clear();
-      break;
-    case HAR_ERROR:
-      defer_error_ = 0;
-      state_ = PS_ERROR_HEADERS;
-      unknown_mechanisms_.clear();
-      break;
-    }
-  } else if (_strnicmp(data, "Content-Length:", 15) == 0) {
-    content_length_ = strtoul(data + 15, 0, 0);
-  } else if (_strnicmp(data, "Proxy-Connection: Keep-Alive", 28) == 0) {
-    expect_close_ = false;
-    /*
-  } else if (_strnicmp(data, "Connection: close", 17) == 0) {
-    expect_close_ = true;
-    */
-  }
-}
-
-void AsyncHttpsProxySocket::EndResponse() {
-  if (!expect_close_) {
-    SendRequest();
-    return;
-  }
-
-  // No point in waiting for the server to close... let's close now
-  // TODO: Refactor out PS_WAIT_CLOSE
-  state_ = PS_WAIT_CLOSE;
-  BufferedReadAdapter::Close();
-  OnCloseEvent(this, 0);
-}
-
-void AsyncHttpsProxySocket::Error(int error) {
-  BufferInput(false);
-  Close();
-  SetError(error);
-  SignalCloseEvent(this, error);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-AsyncSocksProxySocket::AsyncSocksProxySocket(AsyncSocket* socket,
-                                             const SocketAddress& proxy,
-                                             const std::string& username,
-                                             const CryptString& password)
-    : BufferedReadAdapter(socket, 1024), state_(SS_ERROR), proxy_(proxy),
-      user_(username), pass_(password) {
-}
-
-int AsyncSocksProxySocket::Connect(const SocketAddress& addr) {
-  int ret;
-  dest_ = addr;
-  state_ = SS_INIT;
-  BufferInput(true);
-  ret = BufferedReadAdapter::Connect(proxy_);
-  // TODO: Set state_ appropriately if Connect fails.
-  return ret;
-}
-
-SocketAddress AsyncSocksProxySocket::GetRemoteAddress() const {
-  return dest_;
-}
-
-int AsyncSocksProxySocket::Close() {
-  state_ = SS_ERROR;
-  dest_.Clear();
-  return BufferedReadAdapter::Close();
-}
-
-Socket::ConnState AsyncSocksProxySocket::GetState() const {
-  if (state_ < SS_TUNNEL) {
-    return CS_CONNECTING;
-  } else if (state_ == SS_TUNNEL) {
-    return CS_CONNECTED;
-  } else {
-    return CS_CLOSED;
-  }
-}
-
-void AsyncSocksProxySocket::OnConnectEvent(AsyncSocket* socket) {
-  SendHello();
-}
-
-void AsyncSocksProxySocket::ProcessInput(char* data, size_t* len) {
-  ASSERT(state_ < SS_TUNNEL);
-
-  ByteBuffer response(data, *len);
-
-  if (state_ == SS_HELLO) {
-    uint8 ver, method;
-    if (!response.ReadUInt8(&ver) ||
-        !response.ReadUInt8(&method))
-      return;
-
-    if (ver != 5) {
-      Error(0);
-      return;
-    }
-
-    if (method == 0) {
-      SendConnect();
-    } else if (method == 2) {
-      SendAuth();
-    } else {
-      Error(0);
-      return;
-    }
-  } else if (state_ == SS_AUTH) {
-    uint8 ver, status;
-    if (!response.ReadUInt8(&ver) ||
-        !response.ReadUInt8(&status))
-      return;
-
-    if ((ver != 1) || (status != 0)) {
-      Error(SOCKET_EACCES);
-      return;
-    }
-
-    SendConnect();
-  } else if (state_ == SS_CONNECT) {
-    uint8 ver, rep, rsv, atyp;
-    if (!response.ReadUInt8(&ver) ||
-        !response.ReadUInt8(&rep) ||
-        !response.ReadUInt8(&rsv) ||
-        !response.ReadUInt8(&atyp))
-      return;
-
-    if ((ver != 5) || (rep != 0)) {
-      Error(0);
-      return;
-    }
-
-    uint16 port;
-    if (atyp == 1) {
-      uint32 addr;
-      if (!response.ReadUInt32(&addr) ||
-          !response.ReadUInt16(&port))
-        return;
-      LOG(LS_VERBOSE) << "Bound on " << addr << ":" << port;
-    } else if (atyp == 3) {
-      uint8 len;
-      std::string addr;
-      if (!response.ReadUInt8(&len) ||
-          !response.ReadString(&addr, len) ||
-          !response.ReadUInt16(&port))
-        return;
-      LOG(LS_VERBOSE) << "Bound on " << addr << ":" << port;
-    } else if (atyp == 4) {
-      std::string addr;
-      if (!response.ReadString(&addr, 16) ||
-          !response.ReadUInt16(&port))
-        return;
-      LOG(LS_VERBOSE) << "Bound on <IPV6>:" << port;
-    } else {
-      Error(0);
-      return;
-    }
-
-    state_ = SS_TUNNEL;
-  }
-
-  // Consume parsed data
-  *len = response.Length();
-  memcpy(data, response.Data(), *len);
-
-  if (state_ != SS_TUNNEL)
-    return;
-
-  bool remainder = (*len > 0);
-  BufferInput(false);
-  SignalConnectEvent(this);
-
-  // FIX: if SignalConnect causes the socket to be destroyed, we are in trouble
-  if (remainder)
-    SignalReadEvent(this);  // TODO: signal this??
-}
-
-void AsyncSocksProxySocket::SendHello() {
-  ByteBuffer request;
-  request.WriteUInt8(5);    // Socks Version
-  if (user_.empty()) {
-    request.WriteUInt8(1);  // Authentication Mechanisms
-    request.WriteUInt8(0);  // No authentication
-  } else {
-    request.WriteUInt8(2);  // Authentication Mechanisms
-    request.WriteUInt8(0);  // No authentication
-    request.WriteUInt8(2);  // Username/Password
-  }
-  DirectSend(request.Data(), request.Length());
-  state_ = SS_HELLO;
-}
-
-void AsyncSocksProxySocket::SendAuth() {
-  ByteBuffer request;
-  request.WriteUInt8(1);           // Negotiation Version
-  request.WriteUInt8(static_cast<uint8>(user_.size()));
-  request.WriteString(user_);      // Username
-  request.WriteUInt8(static_cast<uint8>(pass_.GetLength()));
-  size_t len = pass_.GetLength() + 1;
-  char * sensitive = new char[len];
-  pass_.CopyTo(sensitive, true);
-  request.WriteString(sensitive);  // Password
-  memset(sensitive, 0, len);
-  delete [] sensitive;
-  DirectSend(request.Data(), request.Length());
-  state_ = SS_AUTH;
-}
-
-void AsyncSocksProxySocket::SendConnect() {
-  ByteBuffer request;
-  request.WriteUInt8(5);              // Socks Version
-  request.WriteUInt8(1);              // CONNECT
-  request.WriteUInt8(0);              // Reserved
-  if (dest_.IsUnresolved()) {
-    std::string hostname = dest_.IPAsString();
-    request.WriteUInt8(3);            // DOMAINNAME
-    request.WriteUInt8(static_cast<uint8>(hostname.size()));
-    request.WriteString(hostname);    // Destination Hostname
-  } else {
-    request.WriteUInt8(1);            // IPV4
-    request.WriteUInt32(dest_.ip());  // Destination IP
-  }
-  request.WriteUInt16(dest_.port());  // Destination Port
-  DirectSend(request.Data(), request.Length());
-  state_ = SS_CONNECT;
-}
-
-void AsyncSocksProxySocket::Error(int error) {
-  state_ = SS_ERROR;
-  BufferInput(false);
-  Close();
-  SetError(SOCKET_EACCES);
-  SignalCloseEvent(this, error);
-}
-
-AsyncSocksProxyServerSocket::AsyncSocksProxyServerSocket(AsyncSocket* socket)
-    : AsyncProxyServerSocket(socket, kBufferSize), state_(SS_HELLO) {
-  BufferInput(true);
-}
-
-void AsyncSocksProxyServerSocket::ProcessInput(char* data, size_t* len) {
-  // TODO: See if the whole message has arrived
-  ASSERT(state_ < SS_CONNECT_PENDING);
-
-  ByteBuffer response(data, *len);
-  if (state_ == SS_HELLO) {
-    HandleHello(&response);
-  } else if (state_ == SS_AUTH) {
-    HandleAuth(&response);
-  } else if (state_ == SS_CONNECT) {
-    HandleConnect(&response);
-  }
-
-  // Consume parsed data
-  *len = response.Length();
-  memcpy(data, response.Data(), *len);
-}
-
-void AsyncSocksProxyServerSocket::DirectSend(const ByteBuffer& buf) {
-  BufferedReadAdapter::DirectSend(buf.Data(), buf.Length());
-}
-
-void AsyncSocksProxyServerSocket::HandleHello(ByteBuffer* request) {
-  uint8 ver, num_methods;
-  if (!request->ReadUInt8(&ver) ||
-      !request->ReadUInt8(&num_methods)) {
-    Error(0);
-    return;
-  }
-
-  if (ver != 5) {
-    Error(0);
-    return;
-  }
-
-  // Handle either no-auth (0) or user/pass auth (2)
-  uint8 method = 0xFF;
-  if (num_methods > 0 && !request->ReadUInt8(&method)) {
-    Error(0);
-    return;
-  }
-
-  // TODO: Ask the server which method to use.
-  SendHelloReply(method);
-  if (method == 0) {
-    state_ = SS_CONNECT;
-  } else if (method == 2) {
-    state_ = SS_AUTH;
-  } else {
-    state_ = SS_ERROR;
-  }
-}
-
-void AsyncSocksProxyServerSocket::SendHelloReply(int method) {
-  ByteBuffer response;
-  response.WriteUInt8(5);  // Socks Version
-  response.WriteUInt8(method);  // Auth method
-  DirectSend(response);
-}
-
-void AsyncSocksProxyServerSocket::HandleAuth(ByteBuffer* request) {
-  uint8 ver, user_len, pass_len;
-  std::string user, pass;
-  if (!request->ReadUInt8(&ver) ||
-      !request->ReadUInt8(&user_len) ||
-      !request->ReadString(&user, user_len) ||
-      !request->ReadUInt8(&pass_len) ||
-      !request->ReadString(&pass, pass_len)) {
-    Error(0);
-    return;
-  }
-
-  // TODO: Allow for checking of credentials.
-  SendAuthReply(0);
-  state_ = SS_CONNECT;
-}
-
-void AsyncSocksProxyServerSocket::SendAuthReply(int result) {
-  ByteBuffer response;
-  response.WriteUInt8(1);  // Negotiation Version
-  response.WriteUInt8(result);
-  DirectSend(response);
-}
-
-void AsyncSocksProxyServerSocket::HandleConnect(ByteBuffer* request) {
-  uint8 ver, command, reserved, addr_type;
-  uint32 ip;
-  uint16 port;
-  if (!request->ReadUInt8(&ver) ||
-      !request->ReadUInt8(&command) ||
-      !request->ReadUInt8(&reserved) ||
-      !request->ReadUInt8(&addr_type) ||
-      !request->ReadUInt32(&ip) ||
-      !request->ReadUInt16(&port)) {
-      Error(0);
-      return;
-  }
-
-  if (ver != 5 || command != 1 ||
-      reserved != 0 || addr_type != 1) {
-      Error(0);
-      return;
-  }
-
-  SignalConnectRequest(this, SocketAddress(ip, port));
-  state_ = SS_CONNECT_PENDING;
-}
-
-void AsyncSocksProxyServerSocket::SendConnectResult(int result,
-                                                    const SocketAddress& addr) {
-  if (state_ != SS_CONNECT_PENDING)
-    return;
-
-  ByteBuffer response;
-  response.WriteUInt8(5);  // Socks version
-  response.WriteUInt8((result != 0));  // 0x01 is generic error
-  response.WriteUInt8(0);  // reserved
-  response.WriteUInt8(1);  // IPv4 address
-  response.WriteUInt32(addr.ip());
-  response.WriteUInt16(addr.port());
-  DirectSend(response);
-  BufferInput(false);
-  state_ = SS_TUNNEL;
-}
-
-void AsyncSocksProxyServerSocket::Error(int error) {
-  state_ = SS_ERROR;
-  BufferInput(false);
-  Close();
-  SetError(SOCKET_EACCES);
-  SignalCloseEvent(this, error);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-LoggingSocketAdapter::LoggingSocketAdapter(AsyncSocket* socket,
-                                           LoggingSeverity level,
-                                           const char * label, bool hex_mode)
-    : AsyncSocketAdapter(socket), level_(level), hex_mode_(hex_mode) {
-  label_.append("[");
-  label_.append(label);
-  label_.append("]");
-}
-
-int LoggingSocketAdapter::Send(const void *pv, size_t cb) {
-  int res = AsyncSocketAdapter::Send(pv, cb);
-  if (res > 0)
-    LogMultiline(level_, label_.c_str(), false, pv, res, hex_mode_, &lms_);
-  return res;
-}
-
-int LoggingSocketAdapter::SendTo(const void *pv, size_t cb,
-                             const SocketAddress& addr) {
-  int res = AsyncSocketAdapter::SendTo(pv, cb, addr);
-  if (res > 0)
-    LogMultiline(level_, label_.c_str(), false, pv, res, hex_mode_, &lms_);
-  return res;
-}
-
-int LoggingSocketAdapter::Recv(void *pv, size_t cb) {
-  int res = AsyncSocketAdapter::Recv(pv, cb);
-  if (res > 0)
-    LogMultiline(level_, label_.c_str(), true, pv, res, hex_mode_, &lms_);
-  return res;
-}
-
-int LoggingSocketAdapter::RecvFrom(void *pv, size_t cb, SocketAddress *paddr) {
-  int res = AsyncSocketAdapter::RecvFrom(pv, cb, paddr);
-  if (res > 0)
-    LogMultiline(level_, label_.c_str(), true, pv, res, hex_mode_, &lms_);
-  return res;
-}
-
-int LoggingSocketAdapter::Close() {
-  LogMultiline(level_, label_.c_str(), false, NULL, 0, hex_mode_, &lms_);
-  LogMultiline(level_, label_.c_str(), true, NULL, 0, hex_mode_, &lms_);
-  LOG_V(level_) << label_ << " Closed locally";
-  return socket_->Close();
-}
-
-void LoggingSocketAdapter::OnConnectEvent(AsyncSocket * socket) {
-  LOG_V(level_) << label_ << " Connected";
-  AsyncSocketAdapter::OnConnectEvent(socket);
-}
-
-void LoggingSocketAdapter::OnCloseEvent(AsyncSocket * socket, int err) {
-  LogMultiline(level_, label_.c_str(), false, NULL, 0, hex_mode_, &lms_);
-  LogMultiline(level_, label_.c_str(), true, NULL, 0, hex_mode_, &lms_);
-  LOG_V(level_) << label_ << " Closed with error: " << err;
-  AsyncSocketAdapter::OnCloseEvent(socket, err);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/socketadapters.h b/third_party/libjingle/source/talk/base/socketadapters.h
deleted file mode 100644
index 320da6f..0000000
--- a/third_party/libjingle/source/talk/base/socketadapters.h
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_SOCKETADAPTERS_H_
-#define TALK_BASE_SOCKETADAPTERS_H_
-
-#include <map>
-#include <string>
-
-#include "talk/base/asyncsocket.h"
-#include "talk/base/cryptstring.h"
-#include "talk/base/logging.h"
-
-namespace talk_base {
-
-struct HttpAuthContext;
-class ByteBuffer;
-
-///////////////////////////////////////////////////////////////////////////////
-
-// Implements a socket adapter that can buffer and process data internally,
-// as in the case of connecting to a proxy, where you must speak the proxy
-// protocol before commencing normal socket behavior.
-class BufferedReadAdapter : public AsyncSocketAdapter {
- public:
-  BufferedReadAdapter(AsyncSocket* socket, size_t buffer_size);
-  virtual ~BufferedReadAdapter();
-
-  virtual int Send(const void* pv, size_t cb);
-  virtual int Recv(void* pv, size_t cb);
-
- protected:
-  int DirectSend(const void* pv, size_t cb) {
-    return AsyncSocketAdapter::Send(pv, cb);
-  }
-
-  void BufferInput(bool on = true);
-  virtual void ProcessInput(char* data, size_t* len) = 0;
-
-  virtual void OnReadEvent(AsyncSocket * socket);
-
- private:
-  char * buffer_;
-  size_t buffer_size_, data_len_;
-  bool buffering_;
-  DISALLOW_EVIL_CONSTRUCTORS(BufferedReadAdapter);
-};
-
-///////////////////////////////////////////////////////////////////////////////
-
-// Interface for implementing proxy server sockets.
-class AsyncProxyServerSocket : public BufferedReadAdapter {
- public:
-  AsyncProxyServerSocket(AsyncSocket* socket, size_t buffer_size)
-      : BufferedReadAdapter(socket, buffer_size) {}
-  sigslot::signal2<AsyncProxyServerSocket*,
-                   const SocketAddress&>  SignalConnectRequest;
-  virtual void SendConnectResult(int err, const SocketAddress& addr) = 0;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-
-// Implements a socket adapter that performs the client side of a
-// fake SSL handshake. Used for "ssltcp" P2P functionality.
-class AsyncSSLSocket : public BufferedReadAdapter {
- public:
-  explicit AsyncSSLSocket(AsyncSocket* socket);
-
-  virtual int Connect(const SocketAddress& addr);
-
- protected:
-  virtual void OnConnectEvent(AsyncSocket* socket);
-  virtual void ProcessInput(char* data, size_t* len);
-  DISALLOW_EVIL_CONSTRUCTORS(AsyncSSLSocket);
-};
-
-// Implements a socket adapter that performs the server side of a
-// fake SSL handshake. Used when implementing a relay server that does "ssltcp".
-class AsyncSSLServerSocket : public BufferedReadAdapter {
- public:
-  explicit AsyncSSLServerSocket(AsyncSocket* socket);
-
- protected:
-  virtual void ProcessInput(char* data, size_t* len);
-  DISALLOW_EVIL_CONSTRUCTORS(AsyncSSLServerSocket);
-};
-
-///////////////////////////////////////////////////////////////////////////////
-
-// Implements a socket adapter that speaks the HTTP/S proxy protocol.
-class AsyncHttpsProxySocket : public BufferedReadAdapter {
- public:
-  AsyncHttpsProxySocket(AsyncSocket* socket, const std::string& user_agent,
-    const SocketAddress& proxy,
-    const std::string& username, const CryptString& password);
-  virtual ~AsyncHttpsProxySocket();
-
-  // If connect is forced, the adapter will always issue an HTTP CONNECT to the
-  // target address.  Otherwise, it will connect only if the destination port
-  // is not port 80.
-  void SetForceConnect(bool force) { force_connect_ = force; }
-
-  virtual int Connect(const SocketAddress& addr);
-  virtual SocketAddress GetRemoteAddress() const;
-  virtual int Close();
-  virtual ConnState GetState() const;
-
- protected:
-  virtual void OnConnectEvent(AsyncSocket* socket);
-  virtual void OnCloseEvent(AsyncSocket* socket, int err);
-  virtual void ProcessInput(char* data, size_t* len);
-
-  bool ShouldIssueConnect() const;
-  void SendRequest();
-  void ProcessLine(char* data, size_t len);
-  void EndResponse();
-  void Error(int error);
-
- private:
-  SocketAddress proxy_, dest_;
-  std::string agent_, user_, headers_;
-  CryptString pass_;
-  bool force_connect_;
-  size_t content_length_;
-  int defer_error_;
-  bool expect_close_;
-  enum ProxyState {
-    PS_INIT, PS_LEADER, PS_AUTHENTICATE, PS_SKIP_HEADERS, PS_ERROR_HEADERS,
-    PS_TUNNEL_HEADERS, PS_SKIP_BODY, PS_TUNNEL, PS_WAIT_CLOSE, PS_ERROR
-  } state_;
-  HttpAuthContext * context_;
-  std::string unknown_mechanisms_;
-  DISALLOW_EVIL_CONSTRUCTORS(AsyncHttpsProxySocket);
-};
-
-/* TODO: Implement this.
-class AsyncHttpsProxyServerSocket : public AsyncProxyServerSocket {
- public:
-  explicit AsyncHttpsProxyServerSocket(AsyncSocket* socket);
-
- private:
-  virtual void ProcessInput(char * data, size_t& len);
-  void Error(int error);
-  DISALLOW_EVIL_CONSTRUCTORS(AsyncHttpsProxyServerSocket);
-};
-*/
-
-///////////////////////////////////////////////////////////////////////////////
-
-// Implements a socket adapter that speaks the SOCKS proxy protocol.
-class AsyncSocksProxySocket : public BufferedReadAdapter {
- public:
-  AsyncSocksProxySocket(AsyncSocket* socket, const SocketAddress& proxy,
-    const std::string& username, const CryptString& password);
-
-  virtual int Connect(const SocketAddress& addr);
-  virtual SocketAddress GetRemoteAddress() const;
-  virtual int Close();
-  virtual ConnState GetState() const;
-
- protected:
-  virtual void OnConnectEvent(AsyncSocket* socket);
-  virtual void ProcessInput(char* data, size_t* len);
-
-  void SendHello();
-  void SendConnect();
-  void SendAuth();
-  void Error(int error);
-
- private:
-  enum State {
-    SS_INIT, SS_HELLO, SS_AUTH, SS_CONNECT, SS_TUNNEL, SS_ERROR
-  };
-  State state_;
-  SocketAddress proxy_, dest_;
-  std::string user_;
-  CryptString pass_;
-  DISALLOW_EVIL_CONSTRUCTORS(AsyncSocksProxySocket);
-};
-
-// Implements a proxy server socket for the SOCKS protocol.
-class AsyncSocksProxyServerSocket : public AsyncProxyServerSocket {
- public:
-  explicit AsyncSocksProxyServerSocket(AsyncSocket* socket);
-
- private:
-  virtual void ProcessInput(char* data, size_t* len);
-  void DirectSend(const ByteBuffer& buf);
-
-  void HandleHello(ByteBuffer* request);
-  void SendHelloReply(int method);
-  void HandleAuth(ByteBuffer* request);
-  void SendAuthReply(int result);
-  void HandleConnect(ByteBuffer* request);
-  virtual void SendConnectResult(int result, const SocketAddress& addr);
-
-  void Error(int error);
-
-  static const int kBufferSize = 1024;
-  enum State {
-    SS_HELLO, SS_AUTH, SS_CONNECT, SS_CONNECT_PENDING, SS_TUNNEL, SS_ERROR
-  };
-  State state_;
-  DISALLOW_EVIL_CONSTRUCTORS(AsyncSocksProxyServerSocket);
-};
-
-///////////////////////////////////////////////////////////////////////////////
-
-// Implements a socket adapter that logs everything that it sends and receives.
-class LoggingSocketAdapter : public AsyncSocketAdapter {
- public:
-  LoggingSocketAdapter(AsyncSocket* socket, LoggingSeverity level,
-                 const char * label, bool hex_mode = false);
-
-  virtual int Send(const void *pv, size_t cb);
-  virtual int SendTo(const void *pv, size_t cb, const SocketAddress& addr);
-  virtual int Recv(void *pv, size_t cb);
-  virtual int RecvFrom(void *pv, size_t cb, SocketAddress *paddr);
-  virtual int Close();
-
- protected:
-  virtual void OnConnectEvent(AsyncSocket * socket);
-  virtual void OnCloseEvent(AsyncSocket * socket, int err);
-
- private:
-  LoggingSeverity level_;
-  std::string label_;
-  bool hex_mode_;
-  LogMultilineState lms_;
-  DISALLOW_EVIL_CONSTRUCTORS(LoggingSocketAdapter);
-};
-
-///////////////////////////////////////////////////////////////////////////////
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_SOCKETADAPTERS_H_
diff --git a/third_party/libjingle/source/talk/base/socketaddress.cc b/third_party/libjingle/source/talk/base/socketaddress.cc
deleted file mode 100644
index 42143f5..0000000
--- a/third_party/libjingle/source/talk/base/socketaddress.cc
+++ /dev/null
@@ -1,486 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/socketaddress.h"
-
-#ifdef POSIX
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#if defined(OPENBSD)
-#include <netinet/in_systm.h>
-#endif
-#include <netinet/ip.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <unistd.h>
-#endif
-
-#include <sstream>
-
-#include "talk/base/byteorder.h"
-#include "talk/base/common.h"
-#include "talk/base/logging.h"
-#include "talk/base/nethelpers.h"
-
-#ifdef WIN32
-#include "talk/base/win32.h"
-#endif
-
-namespace talk_base {
-
-// Address family constants for STUN (see RFC 5389).
-static const int kStunFamilyIPv4 = 1;
-static const int kStunFamilyIPv6 = 2;
-
-SocketAddress::SocketAddress() {
-  Clear();
-}
-
-SocketAddress::SocketAddress(const std::string& hostname, int port) {
-  SetIP(hostname);
-  SetPort(port);
-}
-
-SocketAddress::SocketAddress(uint32 ip_as_host_order_integer, int port) {
-  SetIP(IPAddress(ip_as_host_order_integer));
-  SetPort(port);
-}
-
-SocketAddress::SocketAddress(const IPAddress& ip, int port) {
-  SetIP(ip);
-  SetPort(port);
-}
-
-SocketAddress::SocketAddress(const SocketAddress& addr) {
-  this->operator=(addr);
-}
-
-void SocketAddress::Clear() {
-  hostname_.clear();
-  literal_ = false;
-  ip_ = IPAddress(INADDR_ANY);
-  port_ = 0;
-}
-
-bool SocketAddress::IsNil() const {
-  return hostname_.empty() && IPIsAny(ip_) && 0 == port_;
-}
-
-bool SocketAddress::IsComplete() const {
-  return (!IPIsAny(ip_)) && (0 != port_);
-}
-
-SocketAddress& SocketAddress::operator=(const SocketAddress& addr) {
-  hostname_ = addr.hostname_;
-  ip_ = addr.ip_;
-  port_ = addr.port_;
-  literal_ = addr.literal_;
-  return *this;
-}
-
-void SocketAddress::SetIP(uint32 ip_as_host_order_integer) {
-  hostname_.clear();
-  literal_ = false;
-  ip_ = IPAddress(ip_as_host_order_integer);
-}
-
-void SocketAddress::SetIP(const IPAddress& ip) {
-  hostname_.clear();
-  literal_ = false;
-  ip_ = ip;
-}
-
-void SocketAddress::SetIP(const std::string& hostname) {
-  hostname_ = hostname;
-  literal_ = IPFromString(hostname, &ip_);
-  if (!literal_) {
-    ip_ = IPAddress(INADDR_ANY);
-  }
-}
-
-void SocketAddress::SetResolvedIP(uint32 ip_as_host_order_integer) {
-  ip_ = IPAddress(ip_as_host_order_integer);
-}
-
-void SocketAddress::SetResolvedIP(const IPAddress& ip) {
-  ip_ = ip;
-}
-
-void SocketAddress::SetPort(int port) {
-  ASSERT((0 <= port) && (port < 65536));
-  port_ = port;
-}
-
-uint32 SocketAddress::ip() const {
-  return ip_.v4AddressAsHostOrderInteger();
-}
-
-IPAddress SocketAddress::ipaddr() const {
-  return ip_;
-}
-
-uint16 SocketAddress::port() const {
-  return port_;
-}
-
-std::string SocketAddress::IPAsString() const {
-  // If the hostname was a literal IP string, it may need to have square
-  // brackets added (for SocketAddress::ToString()).
-  if (!literal_ && !hostname_.empty())
-    return hostname_;
-  if (ip_.family() == AF_INET6) {
-    return "[" + ip_.ToString() + "]";
-  } else {
-    return ip_.ToString();
-  }
-}
-
-std::string SocketAddress::PortAsString() const {
-  std::ostringstream ost;
-  ost << port_;
-  return ost.str();
-}
-
-std::string SocketAddress::ToString() const {
-  std::ostringstream ost;
-  ost << IPAsString();
-  ost << ":";
-  ost << port();
-  return ost.str();
-}
-
-bool SocketAddress::FromString(const std::string& str) {
-  if (str.at(0) == '[') {
-    std::string::size_type closebracket = str.rfind(']');
-    if (closebracket != std::string::npos) {
-      std::string::size_type colon = str.find(':', closebracket);
-      if (colon != std::string::npos && colon > closebracket) {
-        SetPort(strtoul(str.substr(colon + 1).c_str(), NULL, 10));
-        SetIP(str.substr(1, closebracket - 1));
-      } else {
-        return false;
-      }
-    }
-  } else {
-    std::string::size_type pos = str.find(':');
-    if (std::string::npos == pos)
-      return false;
-    SetPort(strtoul(str.substr(pos + 1).c_str(), NULL, 10));
-    SetIP(str.substr(0, pos));
-  }
-  return true;
-}
-
-std::ostream& operator<<(std::ostream& os, const SocketAddress& addr) {
-  os << addr.IPAsString() << ":" << addr.port();
-  return os;
-}
-
-bool SocketAddress::IsAnyIP() const {
-  return IPIsAny(ip_);
-}
-
-bool SocketAddress::IsLoopbackIP() const {
-  return IPIsLoopback(ip_) || (IPIsAny(ip_) &&
-                               0 == strcmp(hostname_.c_str(), "localhost"));
-}
-
-bool SocketAddress::IsLocalIP() const {
-  if (IsLoopbackIP())
-    return true;
-
-  std::vector<IPAddress> ips;
-  if (IPIsAny(ip_)) {
-    if (!hostname_.empty()
-        && (0 == stricmp(hostname_.c_str(), GetHostname().c_str()))) {
-      return true;
-    }
-  } else if (GetLocalIPs(&ips)) {
-    for (size_t i = 0; i < ips.size(); ++i) {
-      if (ips[i] == ip_) {
-        return true;
-      }
-    }
-  }
-  return false;
-}
-
-bool SocketAddress::IsPrivateIP() const {
-  return IPIsPrivate(ip_);
-}
-
-bool SocketAddress::IsUnresolvedIP() const {
-  return IsAny() && !literal_ && !hostname_.empty();
-}
-
-bool SocketAddress::ResolveIP(bool force, int* error) {
-  if (hostname_.empty()) {
-    // nothing to resolve
-  } else if (!force && !IsAny()) {
-    // already resolved
-  } else {
-    LOG_F(LS_VERBOSE) << "(" << hostname_ << ")";
-    int errcode = 0;
-    if (hostent* pHost = SafeGetHostByName(hostname_.c_str(), &errcode)) {
-      if (IPFromHostEnt(pHost, &ip_)) {
-        LOG_F(LS_VERBOSE) << "(" << hostname_ << ") resolved to: "
-                          << ip_.ToString();
-      }
-      FreeHostEnt(pHost);
-    } else {
-      LOG_F(LS_ERROR) << "(" << hostname_ << ") err: " << errcode;
-    }
-    if (error) {
-      *error = errcode;
-    }
-  }
-  return (!IPIsAny(ip_));
-}
-
-bool SocketAddress::operator==(const SocketAddress& addr) const {
-  return EqualIPs(addr) && EqualPorts(addr);
-}
-
-bool SocketAddress::operator<(const SocketAddress& addr) const {
-  if (ip_ < addr.ip_)
-    return true;
-  else if (addr.ip_ < ip_)
-    return false;
-
-  // We only check hostnames if both IPs are zero.  This matches EqualIPs()
-  if (addr.IsAnyIP()) {
-    if (hostname_ < addr.hostname_)
-      return true;
-    else if (addr.hostname_ < hostname_)
-      return false;
-  }
-
-  return port_ < addr.port_;
-}
-
-bool SocketAddress::EqualIPs(const SocketAddress& addr) const {
-  return (ip_ == addr.ip_) &&
-      ((!IPIsAny(ip_)) || (hostname_ == addr.hostname_));
-}
-
-bool SocketAddress::EqualPorts(const SocketAddress& addr) const {
-  return (port_ == addr.port_);
-}
-
-size_t SocketAddress::Hash() const {
-  size_t h = 0;
-  h ^= HashIP(ip_);
-  h ^= port_ | (port_ << 16);
-  return h;
-}
-
-size_t SocketAddress::Size_() const {
-  return ip_.Size() + sizeof(port_) + 2;
-}
-
-bool SocketAddress::Write_(char* buf, int len) const {
-  if (len < static_cast<int>(Size_()))
-    return false;
-  int family = ip_.family();
-  if (family != AF_INET && family != AF_INET6) {
-    return false;
-  }
-  buf[0] = 0;
-  SetBE16(buf + 2, port_);
-  if (family == AF_INET) {
-    buf[1] = kStunFamilyIPv4;
-    SetBE32(buf + 4, ip_.v4AddressAsHostOrderInteger());
-  } else if (family == AF_INET6) {
-    buf[1] = kStunFamilyIPv6;
-    in6_addr addr = ip_.ipv6_address();
-    memcpy((buf + 4), &addr.s6_addr, sizeof(addr.s6_addr));
-  }
-  return true;
-}
-
-bool SocketAddress::Read_(const char* buf, int len) {
-  if (len < static_cast<int>(Size_()) ||
-      (buf[1] != kStunFamilyIPv4 && buf[1] != kStunFamilyIPv6))
-    return false;
-  port_ = GetBE16(buf + 2);
-  if (buf[1] == kStunFamilyIPv4) {
-    ip_ = IPAddress(GetBE32(buf + 4));
-  } else if (buf[1] == kStunFamilyIPv6) {
-    in6_addr addr;
-    memcpy(&addr.s6_addr, (buf + 4), sizeof(addr.s6_addr));
-    ip_ = IPAddress(addr);
-  }
-  return true;
-}
-
-void SocketAddress::ToSockAddr(sockaddr_in* saddr) const {
-  memset(saddr, 0, sizeof(*saddr));
-  if (ip_.family() != AF_INET) {
-    saddr->sin_family = AF_UNSPEC;
-    return;
-  }
-  saddr->sin_family = AF_INET;
-  saddr->sin_port = HostToNetwork16(port_);
-  if (IPIsAny(ip_)) {
-    saddr->sin_addr.s_addr = INADDR_ANY;
-  } else {
-    saddr->sin_addr = ip_.ipv4_address();
-  }
-}
-
-bool SocketAddress::FromSockAddr(const sockaddr_in& saddr) {
-  if (saddr.sin_family != AF_INET)
-    return false;
-  SetIP(NetworkToHost32(saddr.sin_addr.s_addr));
-  SetPort(NetworkToHost16(saddr.sin_port));
-  literal_ = false;
-  return true;
-}
-
-static size_t ToSockAddrStorageHelper(sockaddr_storage* addr,
-                                    IPAddress ip, int port) {
-  memset(addr, 0, sizeof(sockaddr_storage));
-  addr->ss_family = ip.family();
-  if (addr->ss_family == AF_INET6) {
-    sockaddr_in6* saddr = reinterpret_cast<sockaddr_in6*>(addr);
-    saddr->sin6_addr = ip.ipv6_address();
-    saddr->sin6_port = HostToNetwork16(port);
-    return sizeof(sockaddr_in6);
-  } else if (addr->ss_family == AF_INET) {
-    sockaddr_in* saddr = reinterpret_cast<sockaddr_in*>(addr);
-    saddr->sin_addr = ip.ipv4_address();
-    saddr->sin_port = HostToNetwork16(port);
-    return sizeof(sockaddr_in);
-  }
-  return 0;
-}
-
-size_t SocketAddress::ToDualStackSockAddrStorage(sockaddr_storage *addr) const {
-  return ToSockAddrStorageHelper(addr, ip_.AsIPv6Address(), port_);
-}
-
-size_t SocketAddress::ToSockAddrStorage(sockaddr_storage* addr) const {
-  return ToSockAddrStorageHelper(addr, ip_, port_);
-}
-
-std::string SocketAddress::IPToString(uint32 ip_as_host_order_integer) {
-  std::ostringstream ost;
-  ost << ((ip_as_host_order_integer >> 24) & 0xff);
-  ost << '.';
-  ost << ((ip_as_host_order_integer >> 16) & 0xff);
-  ost << '.';
-  ost << ((ip_as_host_order_integer >> 8) & 0xff);
-  ost << '.';
-  ost << ((ip_as_host_order_integer >> 0) & 0xff);
-  return ost.str();
-}
-
-bool SocketAddress::StringToIP(const std::string& hostname, uint32* ip) {
-  in_addr addr;
-  if (talk_base::inet_pton(AF_INET, hostname.c_str(), &addr) == 0)
-    return false;
-  *ip = NetworkToHost32(addr.s_addr);
-  return true;
-}
-
-bool SocketAddress::StringToIP(const std::string& hostname, IPAddress* ip) {
-  in_addr addr4;
-  if (talk_base::inet_pton(AF_INET, hostname.c_str(), &addr4) > 0) {
-    if (ip) {
-      *ip = IPAddress(addr4);
-    }
-    return true;
-  }
-
-  in6_addr addr6;
-  if (talk_base::inet_pton(AF_INET6, hostname.c_str(), &addr6) > 0) {
-    if (ip) {
-      *ip = IPAddress(addr6);
-    }
-    return true;
-  }
-  return false;
-}
-
-uint32 SocketAddress::StringToIP(const std::string& hostname) {
-  uint32 ip = 0;
-  StringToIP(hostname, &ip);
-  return ip;
-}
-
-std::string SocketAddress::GetHostname() {
-  char hostname[256];
-  if (gethostname(hostname, ARRAY_SIZE(hostname)) == 0)
-    return hostname;
-  return "";
-}
-
-bool SocketAddress::GetLocalIPs(std::vector<IPAddress>* ips) {
-  if (!ips) {
-    return false;
-  }
-  ips->clear();
-
-  const std::string hostname = SocketAddress::GetHostname();
-  if (hostname.empty())
-    return false;
-
-  int errcode;
-  if (hostent* pHost = SafeGetHostByName(hostname.c_str(), &errcode)) {
-    for (size_t i = 0; pHost->h_addr_list[i]; ++i) {
-      IPAddress ip;
-      if (IPFromHostEnt(pHost, i, &ip)) {
-        ips->push_back(ip);
-      }
-    }
-    FreeHostEnt(pHost);
-    return !ips->empty();
-  }
-  LOG(LS_ERROR) << "gethostbyname err: " << errcode;
-  return false;
-}
-
-bool SocketAddressFromSockAddrStorage(const sockaddr_storage& addr,
-                                      SocketAddress* out) {
-  if (!out) {
-    return false;
-  }
-  if (addr.ss_family == AF_INET) {
-    const sockaddr_in* saddr = reinterpret_cast<const sockaddr_in*>(&addr);
-    *out = SocketAddress(IPAddress(saddr->sin_addr),
-                         NetworkToHost16(saddr->sin_port));
-    return true;
-  } else if (addr.ss_family == AF_INET6) {
-    const sockaddr_in6* saddr = reinterpret_cast<const sockaddr_in6*>(&addr);
-    *out = SocketAddress(IPAddress(saddr->sin6_addr),
-                         NetworkToHost16(saddr->sin6_port));
-    return true;
-  }
-  return false;
-}
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/socketaddress.h b/third_party/libjingle/source/talk/base/socketaddress.h
deleted file mode 100644
index 3ebf556..0000000
--- a/third_party/libjingle/source/talk/base/socketaddress.h
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_SOCKETADDRESS_H_
-#define TALK_BASE_SOCKETADDRESS_H_
-
-#include <string>
-#include <vector>
-#include <iosfwd>
-#include "talk/base/basictypes.h"
-#include "talk/base/ipaddress.h"
-
-#undef SetPort
-
-struct sockaddr_in;
-struct sockaddr_storage;
-
-namespace talk_base {
-
-// Records an IP address and port.
-class SocketAddress {
- public:
-  // Creates a nil address.
-  SocketAddress();
-
-  // Creates the address with the given host and port. Host may be a
-  // literal IP string or a hostname to be resolved later with ResolveIP().
-  SocketAddress(const std::string& hostname, int port);
-
-  // Creates the address with the given IP and port.
-  // IP is given as an integer in host byte order. V4 only, to be deprecated.
-  SocketAddress(uint32 ip_as_host_order_integer, int port);
-
-  // Creates the address with the given IP and port.
-  SocketAddress(const IPAddress& ip, int port);
-
-  // Creates a copy of the given address.
-  SocketAddress(const SocketAddress& addr);
-
-  // Resets to the nil address.
-  void Clear();
-
-  // Determines if this is a nil address (empty hostname, any IP, null port)
-  bool IsNil() const;
-
-  // Returns true if ip and port are set.
-  bool IsComplete() const;
-
-  // Replaces our address with the given one.
-  SocketAddress& operator=(const SocketAddress& addr);
-
-  // Changes the IP of this address to the given one, and clears the hostname
-  // IP is given as an integer in host byte order. V4 only, to be deprecated..
-  void SetIP(uint32 ip_as_host_order_integer);
-
-  // Changes the IP of this address to the given one, and clears the hostname.
-  void SetIP(const IPAddress& ip);
-
-  // Changes the hostname of this address to the given one.
-  // Does not resolve the address; use Resolve to do so.
-  void SetIP(const std::string& hostname);
-
-  // Sets the IP address while retaining the hostname.  Useful for bypassing
-  // DNS for a pre-resolved IP.
-  // IP is given as an integer in host byte order. V4 only, to be deprecated.
-  void SetResolvedIP(uint32 ip_as_host_order_integer);
-
-  // Sets the IP address while retaining the hostname.  Useful for bypassing
-  // DNS for a pre-resolved IP.
-  void SetResolvedIP(const IPAddress& ip);
-
-  // Changes the port of this address to the given one.
-  void SetPort(int port);
-
-  // Returns the hostname.
-  const std::string& hostname() const { return hostname_; }
-
-  // Returns the IP address as a host byte order integer.
-  // Returns 0 for non-v4 addresses.
-  uint32 ip() const;
-
-  IPAddress ipaddr() const;
-
-  // Returns the port part of this address.
-  uint16 port() const;
-
-  // Returns the IP address (or hostname) in printable form.
-  std::string IPAsString() const;
-
-  // Returns the port as a string.
-  std::string PortAsString() const;
-
-  // Returns hostname:port or [hostname]:port.
-  std::string ToString() const;
-
-  // Parses hostname:port and [hostname]:port.
-  bool FromString(const std::string& str);
-
-  friend std::ostream& operator<<(std::ostream& os, const SocketAddress& addr);
-
-  // Determines whether this represents a missing / any IP address.
-  // That is, 0.0.0.0 or ::.
-  // Hostname and/or port may be set.
-  bool IsAnyIP() const;
-  inline bool IsAny() const { return IsAnyIP(); }  // deprecated
-
-  // Determines whether the IP address refers to a loopback address.
-  // For v4 addresses this means the address is in the range 127.0.0.0/8.
-  // For v6 addresses this means the address is ::1.
-  bool IsLoopbackIP() const;
-
-  // Determines wither the IP address refers to any adapter on the local
-  // machine, including the loopback adapter.
-  bool IsLocalIP() const;
-
-  // Determines whether the IP address is in one of the private ranges:
-  // For v4: 127.0.0.0/8 10.0.0.0/8 192.168.0.0/16 172.16.0.0/12.
-  // For v6: FE80::/16 and ::1.
-  bool IsPrivateIP() const;
-
-  // Determines whether the hostname has been resolved to an IP.
-  bool IsUnresolvedIP() const;
-  inline bool IsUnresolved() const { return IsUnresolvedIP(); }  // deprecated
-
-  // Attempt to resolve a hostname to IP address.
-  // Returns false if resolution is required but failed, and sets error.
-  // 'force' will cause re-resolution of hostname.
-  // TODO: Deprecate this function.
-  bool ResolveIP(bool force = false, int* error = NULL);
-
-  // Determines whether this address is identical to the given one.
-  bool operator ==(const SocketAddress& addr) const;
-  inline bool operator !=(const SocketAddress& addr) const {
-    return !this->operator ==(addr);
-  }
-
-  // Compares based on IP and then port.
-  bool operator <(const SocketAddress& addr) const;
-
-  // Determines whether this address has the same IP as the one given.
-  bool EqualIPs(const SocketAddress& addr) const;
-
-  // Determines whether this address has the same port as the one given.
-  bool EqualPorts(const SocketAddress& addr) const;
-
-  // Hashes this address into a small number.
-  size_t Hash() const;
-
-  // Returns the size of this address when written (for STUN).
-  // TODO: Move STUN functions( Size_/Write_/Read_) out of this class.
-  size_t Size_() const;
-
-  // Writes this address into the given buffer, according to RFC 5389.
-  bool Write_(char* buf, int len) const;
-
-  // Reads this address from the given buffer, according to RFC 5389.
-  bool Read_(const char* buf, int len);
-
-  // Write this address to a sockaddr_in.
-  // If IPv6, will zero out the sockaddr_in and sets family to AF_UNSPEC.
-  void ToSockAddr(sockaddr_in* saddr) const;
-
-  // Read this address from a sockaddr_in.
-  bool FromSockAddr(const sockaddr_in& saddr);
-
-  // Read and write the address to/from a sockaddr_storage.
-  // Dual stack version always sets family to AF_INET6, and maps v4 addresses.
-  // The other version doesn't map, and outputs an AF_INET address for
-  // v4 or mapped addresses, and AF_INET6 addresses for others.
-  // Returns the size of the sockaddr_in or sockaddr_in6 structure that is
-  // written to the sockaddr_storage, or zero on failure.
-  size_t ToDualStackSockAddrStorage(sockaddr_storage* saddr) const;
-  size_t ToSockAddrStorage(sockaddr_storage* saddr) const;
-
-  // Converts the IP address given in 'compact form' into dotted form.
-  // IP is given as an integer in host byte order. V4 only, to be deprecated.
-  // TODO: Deprecate this.
-  static std::string IPToString(uint32 ip_as_host_order_integer);
-
-  // Converts the IP address given in dotted form into compact form.
-  // Only dotted names (A.B.C.D) are  converted.
-  // Output integer is returned in host byte order.
-  // TODO: Deprecate, replace wth agnostic versions.
-  static bool StringToIP(const std::string& str, uint32* ip);
-  static uint32 StringToIP(const std::string& str);
-
-  // Converts the IP address given in printable form into an IPAddress.
-  static bool StringToIP(const std::string& str, IPAddress* ip);
-
-  // Get a list of the local machine's ip addresses.
-  // TODO: Move to nethelpers or similar (doesn't belong in socketaddress).
-  static bool GetLocalIPs(std::vector<IPAddress>* ips);
-
- private:
-  // Get local machine's hostname.
-  static std::string GetHostname();
-  std::string hostname_;
-  IPAddress ip_;
-  uint16 port_;
-  bool literal_;  // Indicates that 'hostname_' contains a literal IP string.
-};
-
-bool SocketAddressFromSockAddrStorage(const sockaddr_storage& saddr,
-                                      SocketAddress* out);
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_SOCKETADDRESS_H_
diff --git a/third_party/libjingle/source/talk/base/socketaddress_unittest.cc b/third_party/libjingle/source/talk/base/socketaddress_unittest.cc
deleted file mode 100644
index fcfd89c..0000000
--- a/third_party/libjingle/source/talk/base/socketaddress_unittest.cc
+++ /dev/null
@@ -1,354 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifdef POSIX
-#include <netinet/in.h>  // for sockaddr_in
-#endif
-
-#include "talk/base/gunit.h"
-#include "talk/base/socketaddress.h"
-#include "talk/base/ipaddress.h"
-
-namespace talk_base {
-
-const in6_addr kTestV6Addr =  { { {0x20, 0x01, 0x0d, 0xb8,
-                                   0x10, 0x20, 0x30, 0x40,
-                                   0x50, 0x60, 0x70, 0x80,
-                                   0x90, 0xA0, 0xB0, 0xC0} } };
-const in6_addr kMappedV4Addr = { { {0x00, 0x00, 0x00, 0x00,
-                                    0x00, 0x00, 0x00, 0x00,
-                                    0x00, 0x00, 0xFF, 0xFF,
-                                    0x01, 0x02, 0x03, 0x04} } };
-const std::string kTestV6AddrString = "2001:db8:1020:3040:5060:7080:90a0:b0c0";
-const std::string kTestV6AddrFullString =
-    "[2001:db8:1020:3040:5060:7080:90a0:b0c0]:5678";
-
-TEST(SocketAddressTest, TestDefaultCtor) {
-  SocketAddress addr;
-  EXPECT_FALSE(addr.IsUnresolvedIP());
-  EXPECT_EQ(IPAddress(INADDR_ANY), addr.ipaddr());
-  EXPECT_EQ(0, addr.port());
-  EXPECT_EQ("", addr.hostname());
-  EXPECT_EQ("0.0.0.0:0", addr.ToString());
-}
-
-TEST(SocketAddressTest, TestIPPortCtor) {
-  SocketAddress addr(IPAddress(0x01020304), 5678);
-  EXPECT_FALSE(addr.IsUnresolvedIP());
-  EXPECT_EQ(IPAddress(0x01020304U), addr.ipaddr());
-  EXPECT_EQ(5678, addr.port());
-  EXPECT_EQ("", addr.hostname());
-  EXPECT_EQ("1.2.3.4:5678", addr.ToString());
-}
-
-TEST(SocketAddressTest, TestIPv4StringPortCtor) {
-  SocketAddress addr("1.2.3.4", 5678);
-  EXPECT_FALSE(addr.IsUnresolvedIP());
-  EXPECT_EQ(IPAddress(0x01020304U), addr.ipaddr());
-  EXPECT_EQ(5678, addr.port());
-  EXPECT_EQ("1.2.3.4", addr.hostname());
-  EXPECT_EQ("1.2.3.4:5678", addr.ToString());
-}
-
-TEST(SocketAddressTest, TestIPv6StringPortCtor) {
-  SocketAddress addr2(kTestV6AddrString, 1234);
-  IPAddress tocheck(kTestV6Addr);
-
-  EXPECT_FALSE(addr2.IsUnresolvedIP());
-  EXPECT_EQ(tocheck, addr2.ipaddr());
-  EXPECT_EQ(1234, addr2.port());
-  EXPECT_EQ(kTestV6AddrString, addr2.hostname());
-  EXPECT_EQ("[" + kTestV6AddrString + "]:1234", addr2.ToString());
-}
-
-TEST(SocketAddressTest, TestSpecialStringPortCtor) {
-  // inet_addr doesn't handle this address properly.
-  SocketAddress addr("255.255.255.255", 5678);
-  EXPECT_FALSE(addr.IsUnresolvedIP());
-  EXPECT_EQ(IPAddress(0xFFFFFFFFU), addr.ipaddr());
-  EXPECT_EQ(5678, addr.port());
-  EXPECT_EQ("255.255.255.255", addr.hostname());
-  EXPECT_EQ("255.255.255.255:5678", addr.ToString());
-}
-
-TEST(SocketAddressTest, TestHostnamePortCtor) {
-  SocketAddress addr("a.b.com", 5678);
-  EXPECT_TRUE(addr.IsUnresolvedIP());
-  EXPECT_EQ(IPAddress(INADDR_ANY), addr.ipaddr());
-  EXPECT_EQ(5678, addr.port());
-  EXPECT_EQ("a.b.com", addr.hostname());
-  EXPECT_EQ("a.b.com:5678", addr.ToString());
-}
-
-TEST(SocketAddressTest, TestCopyCtor) {
-  SocketAddress from("1.2.3.4", 5678);
-  SocketAddress addr(from);
-  EXPECT_FALSE(addr.IsUnresolvedIP());
-  EXPECT_EQ(IPAddress(0x01020304U), addr.ipaddr());
-  EXPECT_EQ(5678, addr.port());
-  EXPECT_EQ("1.2.3.4", addr.hostname());
-  EXPECT_EQ("1.2.3.4:5678", addr.ToString());
-}
-
-TEST(SocketAddressTest, TestAssign) {
-  SocketAddress from("1.2.3.4", 5678);
-  SocketAddress addr(IPAddress(0x88888888), 9999);
-  addr = from;
-  EXPECT_FALSE(addr.IsUnresolvedIP());
-  EXPECT_EQ(IPAddress(0x01020304U), addr.ipaddr());
-  EXPECT_EQ(5678, addr.port());
-  EXPECT_EQ("1.2.3.4", addr.hostname());
-  EXPECT_EQ("1.2.3.4:5678", addr.ToString());
-}
-
-TEST(SocketAddressTest, TestSetIPPort) {
-  SocketAddress addr(IPAddress(0x88888888), 9999);
-  addr.SetIP(IPAddress(0x01020304));
-  addr.SetPort(5678);
-  EXPECT_FALSE(addr.IsUnresolvedIP());
-  EXPECT_EQ(IPAddress(0x01020304U), addr.ipaddr());
-  EXPECT_EQ(5678, addr.port());
-  EXPECT_EQ("", addr.hostname());
-  EXPECT_EQ("1.2.3.4:5678", addr.ToString());
-}
-
-TEST(SocketAddressTest, TestSetIPFromString) {
-  SocketAddress addr(IPAddress(0x88888888), 9999);
-  addr.SetIP("1.2.3.4");
-  addr.SetPort(5678);
-  EXPECT_FALSE(addr.IsUnresolvedIP());
-  EXPECT_EQ(IPAddress(0x01020304U), addr.ipaddr());
-  EXPECT_EQ(5678, addr.port());
-  EXPECT_EQ("1.2.3.4", addr.hostname());
-  EXPECT_EQ("1.2.3.4:5678", addr.ToString());
-}
-
-TEST(SocketAddressTest, TestSetIPFromHostname) {
-  SocketAddress addr(IPAddress(0x88888888), 9999);
-  addr.SetIP("a.b.com");
-  addr.SetPort(5678);
-  EXPECT_TRUE(addr.IsUnresolvedIP());
-  EXPECT_EQ(IPAddress(INADDR_ANY), addr.ipaddr());
-  EXPECT_EQ(5678, addr.port());
-  EXPECT_EQ("a.b.com", addr.hostname());
-  EXPECT_EQ("a.b.com:5678", addr.ToString());
-  addr.SetResolvedIP(IPAddress(0x01020304));
-  EXPECT_FALSE(addr.IsUnresolvedIP());
-  EXPECT_EQ(IPAddress(0x01020304U), addr.ipaddr());
-  EXPECT_EQ("a.b.com", addr.hostname());
-  EXPECT_EQ("a.b.com:5678", addr.ToString());
-}
-
-TEST(SocketAddressTest, TestFromIPv4String) {
-  SocketAddress addr;
-  EXPECT_TRUE(addr.FromString("1.2.3.4:5678"));
-  EXPECT_FALSE(addr.IsUnresolvedIP());
-  EXPECT_EQ(IPAddress(0x01020304U), addr.ipaddr());
-  EXPECT_EQ(5678, addr.port());
-  EXPECT_EQ("1.2.3.4", addr.hostname());
-  EXPECT_EQ("1.2.3.4:5678", addr.ToString());
-}
-
-TEST(SocketAddressTest, TestFromIPv6String) {
-  SocketAddress addr;
-  EXPECT_TRUE(addr.FromString(kTestV6AddrFullString));
-  EXPECT_FALSE(addr.IsUnresolvedIP());
-  EXPECT_EQ(5678, addr.port());
-  EXPECT_EQ(kTestV6AddrString, addr.hostname());
-  EXPECT_EQ(kTestV6AddrFullString, addr.ToString());
-}
-
-TEST(SocketAddressTest, TestFromHostname) {
-  SocketAddress addr;
-  EXPECT_TRUE(addr.FromString("a.b.com:5678"));
-  EXPECT_TRUE(addr.IsUnresolvedIP());
-  EXPECT_EQ(IPAddress(INADDR_ANY), addr.ipaddr());
-  EXPECT_EQ(5678, addr.port());
-  EXPECT_EQ("a.b.com", addr.hostname());
-  EXPECT_EQ("a.b.com:5678", addr.ToString());
-}
-
-TEST(SocketAddressTest, TestToFromSockAddr) {
-  SocketAddress from("1.2.3.4", 5678), addr;
-  sockaddr_in addr_in;
-  from.ToSockAddr(&addr_in);
-  EXPECT_TRUE(addr.FromSockAddr(addr_in));
-  EXPECT_FALSE(addr.IsUnresolvedIP());
-  EXPECT_EQ(IPAddress(0x01020304U), addr.ipaddr());
-  EXPECT_EQ(5678, addr.port());
-  EXPECT_EQ("", addr.hostname());
-  EXPECT_EQ("1.2.3.4:5678", addr.ToString());
-}
-
-TEST(SocketAddressTest, TestToFromSockAddrStorage) {
-  SocketAddress from("1.2.3.4", 5678), addr;
-  sockaddr_storage addr_storage;
-  from.ToSockAddrStorage(&addr_storage);
-  EXPECT_TRUE(SocketAddressFromSockAddrStorage(addr_storage, &addr));
-  EXPECT_FALSE(addr.IsUnresolvedIP());
-  EXPECT_EQ(IPAddress(0x01020304U), addr.ipaddr());
-  EXPECT_EQ(5678, addr.port());
-  EXPECT_EQ("", addr.hostname());
-  EXPECT_EQ("1.2.3.4:5678", addr.ToString());
-
-  addr.Clear();
-  from.ToDualStackSockAddrStorage(&addr_storage);
-  EXPECT_TRUE(SocketAddressFromSockAddrStorage(addr_storage, &addr));
-  EXPECT_FALSE(addr.IsUnresolvedIP());
-  EXPECT_EQ(IPAddress(kMappedV4Addr), addr.ipaddr());
-  EXPECT_EQ(5678, addr.port());
-  EXPECT_EQ("", addr.hostname());
-  EXPECT_EQ("[::ffff:1.2.3.4]:5678", addr.ToString());
-
-  addr = from;
-  addr_storage.ss_family = AF_UNSPEC;
-  EXPECT_FALSE(SocketAddressFromSockAddrStorage(addr_storage, &addr));
-  EXPECT_EQ(from, addr);
-
-  EXPECT_FALSE(SocketAddressFromSockAddrStorage(addr_storage, NULL));
-}
-
-TEST(SocketAddressTest, TestIPv4ToFromBuffer) {
-  SocketAddress from("1.2.3.4", 5678), addr;
-  char buf[20];
-  EXPECT_TRUE(from.Write_(buf, sizeof(buf)));
-  EXPECT_TRUE(addr.Read_(buf, sizeof(buf)));
-  EXPECT_FALSE(addr.IsUnresolvedIP());
-  EXPECT_EQ(AF_INET, addr.ipaddr().family());
-  EXPECT_EQ(IPAddress(0x01020304U), addr.ipaddr());
-  EXPECT_EQ(5678, addr.port());
-  EXPECT_EQ("", addr.hostname());
-  EXPECT_EQ("1.2.3.4:5678", addr.ToString());
-}
-
-TEST(SocketAddressTest, TestIPv6ToFromBuffer) {
-  SocketAddress from6(kTestV6AddrString, 5678), addr;
-  char buf[20];
-  EXPECT_TRUE(from6.Write_(buf, sizeof(buf)));
-  EXPECT_TRUE(addr.Read_(buf, sizeof(buf)));
-  EXPECT_FALSE(addr.IsUnresolvedIP());
-  EXPECT_EQ(AF_INET6, addr.ipaddr().family());
-  EXPECT_EQ(IPAddress(kTestV6Addr), addr.ipaddr());
-  EXPECT_EQ(5678, addr.port());
-  EXPECT_EQ("", addr.hostname());
-  EXPECT_EQ(kTestV6AddrFullString, addr.ToString());
-}
-
-TEST(SocketAddressTest, TestGoodResolve) {
-  SocketAddress addr("localhost", 5678);
-  int error;
-  EXPECT_TRUE(addr.IsUnresolvedIP());
-  EXPECT_TRUE(addr.ResolveIP(false, &error));
-  EXPECT_EQ(0, error);
-  EXPECT_FALSE(addr.IsUnresolvedIP());
-  EXPECT_TRUE(addr.IsLoopbackIP());
-  EXPECT_EQ(IPAddress(INADDR_LOOPBACK), addr.ipaddr());
-  EXPECT_EQ(5678, addr.port());
-  EXPECT_EQ("localhost", addr.hostname());
-  EXPECT_EQ("localhost:5678", addr.ToString());
-}
-
-TEST(SocketAddressTest, TestBadResolve) {
-  SocketAddress addr("address.bad", 5678);
-  int error;
-  EXPECT_TRUE(addr.IsUnresolvedIP());
-  EXPECT_FALSE(addr.ResolveIP(false, &error));
-  EXPECT_NE(0, error);
-  EXPECT_TRUE(addr.IsUnresolvedIP());
-}
-
-bool AreEqual(const SocketAddress& addr1,
-              const SocketAddress& addr2) {
-  return addr1 == addr2 && addr2 == addr1 &&
-      !(addr1 != addr2) && !(addr2 != addr1);
-}
-
-bool AreUnequal(const SocketAddress& addr1,
-                const SocketAddress& addr2) {
-  return !(addr1 == addr2) && !(addr2 == addr1) &&
-      addr1 != addr2 && addr2 != addr1;
-}
-
-TEST(SocketAddressTest, TestEqualityOperators) {
-  SocketAddress addr1("1.2.3.4", 5678);
-  SocketAddress addr2("1.2.3.4", 5678);
-  EXPECT_PRED2(AreEqual, addr1, addr2);
-
-  addr2 = SocketAddress("0.0.0.1", 5678);
-  EXPECT_PRED2(AreUnequal, addr1, addr2);
-
-  addr2 = SocketAddress("1.2.3.4", 1234);
-  EXPECT_PRED2(AreUnequal, addr1, addr2);
-
-  addr2 = SocketAddress(kTestV6AddrString, 5678);
-  EXPECT_PRED2(AreUnequal, addr1, addr2);
-
-  addr1 = SocketAddress(kTestV6AddrString, 5678);
-  EXPECT_PRED2(AreEqual, addr1, addr2);
-
-  addr2 = SocketAddress(kTestV6AddrString, 1234);
-  EXPECT_PRED2(AreUnequal, addr1, addr2);
-
-  addr2 = SocketAddress("fe80::1", 5678);
-  EXPECT_PRED2(AreUnequal, addr1, addr2);
-}
-
-bool IsLessThan(const SocketAddress& addr1,
-                                      const SocketAddress& addr2) {
-  return addr1 < addr2 &&
-      !(addr2 < addr1) &&
-      !(addr1 == addr2);
-}
-
-TEST(SocketAddressTest, TestComparisonOperator) {
-  SocketAddress addr1("1.2.3.4", 5678);
-  SocketAddress addr2("1.2.3.4", 5678);
-
-  EXPECT_FALSE(addr1 < addr2);
-  EXPECT_FALSE(addr2 < addr1);
-
-  addr2 = SocketAddress("1.2.3.4", 5679);
-  EXPECT_PRED2(IsLessThan, addr1, addr2);
-
-  addr2 = SocketAddress("2.2.3.4", 49152);
-  EXPECT_PRED2(IsLessThan, addr1, addr2);
-
-  addr2 = SocketAddress(kTestV6AddrString, 5678);
-  EXPECT_PRED2(IsLessThan, addr1, addr2);
-
-  addr1 = SocketAddress("fe80::1", 5678);
-  EXPECT_PRED2(IsLessThan, addr2, addr1);
-
-  addr2 = SocketAddress("fe80::1", 5679);
-  EXPECT_PRED2(IsLessThan, addr1, addr2);
-
-  addr2 = SocketAddress("fe80::1", 5678);
-  EXPECT_FALSE(addr1 < addr2);
-  EXPECT_FALSE(addr2 < addr1);
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/socketaddresspair.cc b/third_party/libjingle/source/talk/base/socketaddresspair.cc
deleted file mode 100644
index 7f190a9..0000000
--- a/third_party/libjingle/source/talk/base/socketaddresspair.cc
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/socketaddresspair.h"
-
-namespace talk_base {
-
-SocketAddressPair::SocketAddressPair(
-    const SocketAddress& src, const SocketAddress& dest)
-    : src_(src), dest_(dest) {
-}
-
-
-bool SocketAddressPair::operator ==(const SocketAddressPair& p) const {
-  return (src_ == p.src_) && (dest_ == p.dest_);
-}
-
-bool SocketAddressPair::operator <(const SocketAddressPair& p) const {
-  if (src_ < p.src_)
-    return true;
-  if (p.src_ < src_)
-    return false;
-  if (dest_ < p.dest_)
-    return true;
-  if (p.dest_ < dest_)
-    return false;
-  return false;
-}
-
-size_t SocketAddressPair::Hash() const {
-  return src_.Hash() ^ dest_.Hash();
-}
-
-} // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/socketaddresspair.h b/third_party/libjingle/source/talk/base/socketaddresspair.h
deleted file mode 100644
index 10f5d30..0000000
--- a/third_party/libjingle/source/talk/base/socketaddresspair.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_SOCKETADDRESSPAIR_H__
-#define TALK_BASE_SOCKETADDRESSPAIR_H__
-
-#include "talk/base/socketaddress.h"
-
-namespace talk_base {
-
-// Records a pair (source,destination) of socket addresses.  The two addresses
-// identify a connection between two machines.  (For UDP, this "connection" is
-// not maintained explicitly in a socket.)
-class SocketAddressPair {
-public:
-  SocketAddressPair() {}
-  SocketAddressPair(const SocketAddress& srs, const SocketAddress& dest);
-
-  const SocketAddress& source() const { return src_; }
-  const SocketAddress& destination() const { return dest_; }
-
-  bool operator ==(const SocketAddressPair& r) const;
-  bool operator <(const SocketAddressPair& r) const;
-
-  size_t Hash() const;
-
-private:
-  SocketAddress src_;
-  SocketAddress dest_;
-};
-
-} // namespace talk_base
-
-#endif // TALK_BASE_SOCKETADDRESSPAIR_H__
diff --git a/third_party/libjingle/source/talk/base/socketfactory.h b/third_party/libjingle/source/talk/base/socketfactory.h
deleted file mode 100644
index 2a4aee2..0000000
--- a/third_party/libjingle/source/talk/base/socketfactory.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_SOCKETFACTORY_H__
-#define TALK_BASE_SOCKETFACTORY_H__
-
-#include "talk/base/socket.h"
-#include "talk/base/asyncsocket.h"
-
-namespace talk_base {
-
-class SocketFactory {
-public:
-  virtual ~SocketFactory() {}
-
-  // Returns a new socket for blocking communication.  The type can be
-  // SOCK_DGRAM and SOCK_STREAM.
-  virtual Socket* CreateSocket(int type) = 0;
-
-  // Returns a new socket for nonblocking communication.  The type can be
-  // SOCK_DGRAM and SOCK_STREAM.
-  virtual AsyncSocket* CreateAsyncSocket(int type) = 0;
-};
-
-} // namespace talk_base
-
-#endif // TALK_BASE_SOCKETFACTORY_H__
diff --git a/third_party/libjingle/source/talk/base/socketpool.cc b/third_party/libjingle/source/talk/base/socketpool.cc
deleted file mode 100644
index a5e3bcc..0000000
--- a/third_party/libjingle/source/talk/base/socketpool.cc
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <iomanip>
-
-#include "talk/base/asyncsocket.h"
-#include "talk/base/logging.h"
-#include "talk/base/socketfactory.h"
-#include "talk/base/socketpool.h"
-#include "talk/base/socketstream.h"
-#include "talk/base/thread.h"
-
-namespace talk_base {
-
-///////////////////////////////////////////////////////////////////////////////
-// StreamCache - Caches a set of open streams, defers creation to a separate
-//  StreamPool.
-///////////////////////////////////////////////////////////////////////////////
-
-StreamCache::StreamCache(StreamPool* pool) : pool_(pool) {
-}
-
-StreamCache::~StreamCache() {
-  for (ConnectedList::iterator it = active_.begin(); it != active_.end();
-       ++it) {
-    delete it->second;
-  }
-  for (ConnectedList::iterator it = cached_.begin(); it != cached_.end();
-       ++it) {
-    delete it->second;
-  }
-}
-
-StreamInterface* StreamCache::RequestConnectedStream(
-    const SocketAddress& remote, int* err) {
-  LOG_F(LS_VERBOSE) << "(" << remote << ")";
-  for (ConnectedList::iterator it = cached_.begin(); it != cached_.end();
-       ++it) {
-    if (remote == it->first) {
-      it->second->SignalEvent.disconnect(this);
-      // Move from cached_ to active_
-      active_.push_front(*it);
-      cached_.erase(it);
-      if (err)
-        *err = 0;
-      LOG_F(LS_VERBOSE) << "Providing cached stream";
-      return active_.front().second;
-    }
-  }
-  if (StreamInterface* stream = pool_->RequestConnectedStream(remote, err)) {
-    // We track active streams so that we can remember their address
-    active_.push_front(ConnectedStream(remote, stream));
-    LOG_F(LS_VERBOSE) << "Providing new stream";
-    return active_.front().second;
-  }
-  return NULL;
-}
-
-void StreamCache::ReturnConnectedStream(StreamInterface* stream) {
-  for (ConnectedList::iterator it = active_.begin(); it != active_.end();
-       ++it) {
-    if (stream == it->second) {
-      LOG_F(LS_VERBOSE) << "(" << it->first << ")";
-      if (stream->GetState() == SS_CLOSED) {
-        // Return closed streams
-        LOG_F(LS_VERBOSE) << "Returning closed stream";
-        pool_->ReturnConnectedStream(it->second);
-      } else {
-        // Monitor open streams
-        stream->SignalEvent.connect(this, &StreamCache::OnStreamEvent);
-        LOG_F(LS_VERBOSE) << "Caching stream";
-        cached_.push_front(*it);
-      }
-      active_.erase(it);
-      return;
-    }
-  }
-  ASSERT(false);
-}
-
-void StreamCache::OnStreamEvent(StreamInterface* stream, int events, int err) {
-  if ((events & SE_CLOSE) == 0) {
-    LOG_F(LS_WARNING) << "(" << events << ", " << err
-                      << ") received non-close event";
-    return;
-  }
-  for (ConnectedList::iterator it = cached_.begin(); it != cached_.end();
-       ++it) {
-    if (stream == it->second) {
-      LOG_F(LS_VERBOSE) << "(" << it->first << ")";
-      // We don't cache closed streams, so return it.
-      it->second->SignalEvent.disconnect(this);
-      LOG_F(LS_VERBOSE) << "Returning closed stream";
-      pool_->ReturnConnectedStream(it->second);
-      cached_.erase(it);
-      return;
-    }
-  }
-  ASSERT(false);
-}
-
-//////////////////////////////////////////////////////////////////////
-// NewSocketPool
-//////////////////////////////////////////////////////////////////////
-
-NewSocketPool::NewSocketPool(SocketFactory* factory) : factory_(factory) {
-}
-
-NewSocketPool::~NewSocketPool() {
-}
-
-StreamInterface* 
-NewSocketPool::RequestConnectedStream(const SocketAddress& remote, int* err) {
-  AsyncSocket* socket = factory_->CreateAsyncSocket(SOCK_STREAM);
-  if (!socket) {
-    ASSERT(false);
-    if (err)
-      *err = -1;
-    return NULL;
-  }
-  if ((socket->Connect(remote) != 0) && !socket->IsBlocking()) {
-    if (err)
-      *err = socket->GetError();
-    delete socket;
-    return NULL;
-  }
-  if (err)
-    *err = 0;
-  return new SocketStream(socket);
-}
-
-void
-NewSocketPool::ReturnConnectedStream(StreamInterface* stream) {
-  Thread::Current()->Dispose(stream);
-}
-
-//////////////////////////////////////////////////////////////////////
-// ReuseSocketPool
-//////////////////////////////////////////////////////////////////////
-
-ReuseSocketPool::ReuseSocketPool(SocketFactory* factory)
-: factory_(factory), stream_(NULL), checked_out_(false) {
-}
-
-ReuseSocketPool::~ReuseSocketPool() {
-  ASSERT(!checked_out_);
-  delete stream_;
-}
-
-StreamInterface* 
-ReuseSocketPool::RequestConnectedStream(const SocketAddress& remote, int* err) {
-  // Only one socket can be used from this "pool" at a time
-  ASSERT(!checked_out_);
-  if (!stream_) {
-    LOG_F(LS_VERBOSE) << "Creating new socket";
-    AsyncSocket* socket = factory_->CreateAsyncSocket(SOCK_STREAM);
-    if (!socket) {
-      ASSERT(false);
-      if (err)
-        *err = -1;
-      return NULL;
-    }
-    stream_ = new SocketStream(socket);
-  }
-  if ((stream_->GetState() == SS_OPEN) && (remote == remote_)) {
-    LOG_F(LS_VERBOSE) << "Reusing connection to: " << remote_;
-  } else {
-    remote_ = remote;
-    stream_->Close();
-    if ((stream_->GetSocket()->Connect(remote_) != 0)
-        && !stream_->GetSocket()->IsBlocking()) {
-      if (err)
-        *err = stream_->GetSocket()->GetError();
-      return NULL;
-    } else {
-      LOG_F(LS_VERBOSE) << "Opening connection to: " << remote_;
-    }
-  }
-  stream_->SignalEvent.disconnect(this);
-  checked_out_ = true;
-  if (err)
-    *err = 0;
-  return stream_;
-}
-
-void
-ReuseSocketPool::ReturnConnectedStream(StreamInterface* stream) {
-  ASSERT(stream == stream_);
-  ASSERT(checked_out_);
-  checked_out_ = false;
-  // Until the socket is reused, monitor it to determine if it closes.
-  stream_->SignalEvent.connect(this, &ReuseSocketPool::OnStreamEvent);
-}
-
-void
-ReuseSocketPool::OnStreamEvent(StreamInterface* stream, int events, int err) {
-  ASSERT(stream == stream_);
-  ASSERT(!checked_out_);
-
-  // If the stream was written to and then immediately returned to us then
-  // we may get a writable notification for it, which we should ignore.
-  if (events == SE_WRITE) {
-    LOG_F(LS_VERBOSE) << "Pooled Socket unexpectedly writable: ignoring";
-    return;
-  }
-
-  // If the peer sent data, we can't process it, so drop the connection.
-  // If the socket has closed, clean it up.
-  // In either case, we'll reconnect it the next time it is used.
-  ASSERT(0 != (events & (SE_READ|SE_CLOSE)));
-  if (0 != (events & SE_CLOSE)) {
-    LOG_F(LS_VERBOSE) << "Connection closed with error: " << err;
-  } else {
-    LOG_F(LS_VERBOSE) << "Pooled Socket unexpectedly readable: closing";
-  }
-  stream_->Close();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// LoggingPoolAdapter - Adapts a StreamPool to supply streams with attached
-// LoggingAdapters.
-///////////////////////////////////////////////////////////////////////////////
-
-LoggingPoolAdapter::LoggingPoolAdapter(
-    StreamPool* pool, LoggingSeverity level, const std::string& label,
-    bool binary_mode)
-  : pool_(pool), level_(level), label_(label), binary_mode_(binary_mode) {
-}
-
-LoggingPoolAdapter::~LoggingPoolAdapter() {
-  for (StreamList::iterator it = recycle_bin_.begin();
-       it != recycle_bin_.end(); ++it) {
-    delete *it;
-  }
-}
-
-StreamInterface* LoggingPoolAdapter::RequestConnectedStream(
-    const SocketAddress& remote, int* err) {
-  if (StreamInterface* stream = pool_->RequestConnectedStream(remote, err)) {
-    ASSERT(SS_CLOSED != stream->GetState());
-    std::stringstream ss;
-    ss << label_ << "(0x" << std::setfill('0') << std::hex << std::setw(8)
-       << stream << ")";
-    LOG_V(level_) << ss.str()
-                  << ((SS_OPEN == stream->GetState()) ? " Connected"
-                                                      : " Connecting")
-                  << " to " << remote;
-    if (recycle_bin_.empty()) {
-      return new LoggingAdapter(stream, level_, ss.str(), binary_mode_);
-    }
-    LoggingAdapter* logging = recycle_bin_.front();
-    recycle_bin_.pop_front();
-    logging->set_label(ss.str());
-    logging->Attach(stream);
-    return logging;
-  }
-  return NULL;
-}
-
-void LoggingPoolAdapter::ReturnConnectedStream(StreamInterface* stream) {
-  LoggingAdapter* logging = static_cast<LoggingAdapter*>(stream);
-  pool_->ReturnConnectedStream(logging->Detach());
-  recycle_bin_.push_back(logging);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-} // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/socketpool.h b/third_party/libjingle/source/talk/base/socketpool.h
deleted file mode 100644
index 847d8ff..0000000
--- a/third_party/libjingle/source/talk/base/socketpool.h
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_SOCKETPOOL_H_
-#define TALK_BASE_SOCKETPOOL_H_
-
-#include <deque>
-#include <list>
-#include "talk/base/logging.h"
-#include "talk/base/sigslot.h"
-#include "talk/base/socketaddress.h"
-
-namespace talk_base {
-
-class AsyncSocket;
-class LoggingAdapter;
-class SocketFactory;
-class SocketStream;
-class StreamInterface;
-
-//////////////////////////////////////////////////////////////////////
-// StreamPool
-//////////////////////////////////////////////////////////////////////
-
-class StreamPool {
-public:
-  virtual ~StreamPool() { }
-
-  virtual StreamInterface* RequestConnectedStream(const SocketAddress& remote,
-                                                  int* err) = 0;
-  virtual void ReturnConnectedStream(StreamInterface* stream) = 0;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// StreamCache - Caches a set of open streams, defers creation/destruction to
-//  the supplied StreamPool.
-///////////////////////////////////////////////////////////////////////////////
-
-class StreamCache : public StreamPool, public sigslot::has_slots<> {
-public:
-  StreamCache(StreamPool* pool);
-  virtual ~StreamCache();
-
-  // StreamPool Interface
-  virtual StreamInterface* RequestConnectedStream(const SocketAddress& remote,
-                                                  int* err);
-  virtual void ReturnConnectedStream(StreamInterface* stream);
-
-private:
-  typedef std::pair<SocketAddress, StreamInterface*> ConnectedStream;
-  typedef std::list<ConnectedStream> ConnectedList;
-
-  void OnStreamEvent(StreamInterface* stream, int events, int err);
-
-  // We delegate stream creation and deletion to this pool.
-  StreamPool* pool_;
-  // Streams that are in use (returned from RequestConnectedStream).
-  ConnectedList active_;
-  // Streams which were returned to us, but are still open.
-  ConnectedList cached_;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// NewSocketPool
-// Creates a new stream on every request
-///////////////////////////////////////////////////////////////////////////////
-
-class NewSocketPool : public StreamPool {
-public:
-  NewSocketPool(SocketFactory* factory);
-  virtual ~NewSocketPool();
-  
-  // StreamPool Interface
-  virtual StreamInterface* RequestConnectedStream(const SocketAddress& remote,
-                                                  int* err);
-  virtual void ReturnConnectedStream(StreamInterface* stream);
-  
-private:
-  SocketFactory* factory_;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// ReuseSocketPool
-// Maintains a single socket at a time, and will reuse it without closing if
-// the destination address is the same.
-///////////////////////////////////////////////////////////////////////////////
-
-class ReuseSocketPool : public StreamPool, public sigslot::has_slots<> {
-public:
-  ReuseSocketPool(SocketFactory* factory);
-  virtual ~ReuseSocketPool();
-
-  // StreamPool Interface
-  virtual StreamInterface* RequestConnectedStream(const SocketAddress& remote,
-                                                  int* err);
-  virtual void ReturnConnectedStream(StreamInterface* stream);
-  
-private:
-  void OnStreamEvent(StreamInterface* stream, int events, int err);
-
-  SocketFactory* factory_;
-  SocketStream* stream_;
-  SocketAddress remote_;
-  bool checked_out_;  // Whether the stream is currently checked out
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// LoggingPoolAdapter - Adapts a StreamPool to supply streams with attached
-// LoggingAdapters.
-///////////////////////////////////////////////////////////////////////////////
-
-class LoggingPoolAdapter : public StreamPool {
-public:
-  LoggingPoolAdapter(StreamPool* pool, LoggingSeverity level,
-                     const std::string& label, bool binary_mode);
-  virtual ~LoggingPoolAdapter();
-
-  // StreamPool Interface
-  virtual StreamInterface* RequestConnectedStream(const SocketAddress& remote,
-                                                  int* err);
-  virtual void ReturnConnectedStream(StreamInterface* stream);
-
-private:
-  StreamPool* pool_;
-  LoggingSeverity level_;
-  std::string label_;
-  bool binary_mode_;
-  typedef std::deque<LoggingAdapter*> StreamList;
-  StreamList recycle_bin_;
-};
-
-//////////////////////////////////////////////////////////////////////
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_SOCKETPOOL_H_
diff --git a/third_party/libjingle/source/talk/base/socketserver.h b/third_party/libjingle/source/talk/base/socketserver.h
deleted file mode 100644
index 151ce61..0000000
--- a/third_party/libjingle/source/talk/base/socketserver.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_SOCKETSERVER_H_
-#define TALK_BASE_SOCKETSERVER_H_
-
-#include "talk/base/socketfactory.h"
-
-namespace talk_base {
-
-class MessageQueue;
-
-// Provides the ability to wait for activity on a set of sockets.  The Thread
-// class provides a nice wrapper on a socket server.
-//
-// The server is also a socket factory.  The sockets it creates will be
-// notified of asynchronous I/O from this server's Wait method.
-class SocketServer : public SocketFactory {
- public:
-  // When the socket server is installed into a Thread, this function is
-  // called to allow the socket server to use the thread's message queue for
-  // any messaging that it might need to perform.
-  virtual void SetMessageQueue(MessageQueue* queue) {}
-
-  // Sleeps until:
-  //  1) cms milliseconds have elapsed (unless cms == kForever)
-  //  2) WakeUp() is called
-  // While sleeping, I/O is performed if process_io is true.
-  virtual bool Wait(int cms, bool process_io) = 0;
-
-  // Causes the current wait (if one is in progress) to wake up.
-  virtual void WakeUp() = 0;
-};
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_SOCKETSERVER_H_
diff --git a/third_party/libjingle/source/talk/base/socketstream.cc b/third_party/libjingle/source/talk/base/socketstream.cc
deleted file mode 100644
index 3dc5a95..0000000
--- a/third_party/libjingle/source/talk/base/socketstream.cc
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * libjingle
- * Copyright 2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/socketstream.h"
-
-namespace talk_base {
-
-SocketStream::SocketStream(AsyncSocket* socket) : socket_(NULL) {
-  Attach(socket);
-}
-
-SocketStream::~SocketStream() {
-  delete socket_;
-}
-
-void SocketStream::Attach(AsyncSocket* socket) {
-  if (socket_)
-    delete socket_;
-  socket_ = socket;
-  if (socket_) {
-    socket_->SignalConnectEvent.connect(this, &SocketStream::OnConnectEvent);
-    socket_->SignalReadEvent.connect(this,    &SocketStream::OnReadEvent);
-    socket_->SignalWriteEvent.connect(this,   &SocketStream::OnWriteEvent);
-    socket_->SignalCloseEvent.connect(this,   &SocketStream::OnCloseEvent);
-  }
-}
-
-AsyncSocket* SocketStream::Detach() {
-  AsyncSocket* socket = socket_;
-  if (socket_) {
-    socket_->SignalConnectEvent.disconnect(this);
-    socket_->SignalReadEvent.disconnect(this);
-    socket_->SignalWriteEvent.disconnect(this);
-    socket_->SignalCloseEvent.disconnect(this);
-    socket_ = NULL;
-  }
-  return socket;
-}
-
-StreamState SocketStream::GetState() const {
-  ASSERT(socket_ != NULL);
-  switch (socket_->GetState()) {
-    case Socket::CS_CONNECTED:
-      return SS_OPEN;
-    case Socket::CS_CONNECTING:
-      return SS_OPENING;
-    case Socket::CS_CLOSED:
-    default:
-      return SS_CLOSED;
-  }
-}
-
-StreamResult SocketStream::Read(void* buffer, size_t buffer_len,
-                                size_t* read, int* error) {
-  ASSERT(socket_ != NULL);
-  int result = socket_->Recv(buffer, buffer_len);
-  if (result < 0) {
-    if (socket_->IsBlocking())
-      return SR_BLOCK;
-    if (error)
-      *error = socket_->GetError();
-    return SR_ERROR;
-  }
-  if ((result > 0) || (buffer_len == 0)) {
-    if (read)
-      *read = result;
-    return SR_SUCCESS;
-  }
-  return SR_EOS;
-}
-
-StreamResult SocketStream::Write(const void* data, size_t data_len,
-                                 size_t* written, int* error) {
-  ASSERT(socket_ != NULL);
-  int result = socket_->Send(data, data_len);
-  if (result < 0) {
-    if (socket_->IsBlocking())
-      return SR_BLOCK;
-    if (error)
-      *error = socket_->GetError();
-    return SR_ERROR;
-  }
-  if (written)
-    *written = result;
-  return SR_SUCCESS;
-}
-
-void SocketStream::Close() {
-  ASSERT(socket_ != NULL);
-  socket_->Close();
-}
-
-void SocketStream::OnConnectEvent(AsyncSocket* socket) {
-  ASSERT(socket == socket_);
-  SignalEvent(this, SE_OPEN | SE_READ | SE_WRITE, 0);
-}
-
-void SocketStream::OnReadEvent(AsyncSocket* socket) {
-  ASSERT(socket == socket_);
-  SignalEvent(this, SE_READ, 0);
-}
-
-void SocketStream::OnWriteEvent(AsyncSocket* socket) {
-  ASSERT(socket == socket_);
-  SignalEvent(this, SE_WRITE, 0);
-}
-
-void SocketStream::OnCloseEvent(AsyncSocket* socket, int err) {
-  ASSERT(socket == socket_);
-  SignalEvent(this, SE_CLOSE, err);
-}
-
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/socketstream.h b/third_party/libjingle/source/talk/base/socketstream.h
deleted file mode 100644
index 591dc4c..0000000
--- a/third_party/libjingle/source/talk/base/socketstream.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * libjingle
- * Copyright 2005--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_SOCKETSTREAM_H_
-#define TALK_BASE_SOCKETSTREAM_H_
-
-#include "talk/base/asyncsocket.h"
-#include "talk/base/common.h"
-#include "talk/base/stream.h"
-
-namespace talk_base {
-
-///////////////////////////////////////////////////////////////////////////////
-
-class SocketStream : public StreamInterface, public sigslot::has_slots<> {
- public:
-  explicit SocketStream(AsyncSocket* socket);
-  virtual ~SocketStream();
-
-  void Attach(AsyncSocket* socket);
-  AsyncSocket* Detach();
-
-  AsyncSocket* GetSocket() { return socket_; }
-
-  virtual StreamState GetState() const;
-
-  virtual StreamResult Read(void* buffer, size_t buffer_len,
-                            size_t* read, int* error);
-
-  virtual StreamResult Write(const void* data, size_t data_len,
-                             size_t* written, int* error);
-
-  virtual void Close();
-
- private:
-  void OnConnectEvent(AsyncSocket* socket);
-  void OnReadEvent(AsyncSocket* socket);
-  void OnWriteEvent(AsyncSocket* socket);
-  void OnCloseEvent(AsyncSocket* socket, int err);
-
-  AsyncSocket* socket_;
-
-  DISALLOW_EVIL_CONSTRUCTORS(SocketStream);
-};
-
-///////////////////////////////////////////////////////////////////////////////
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_SOCKETSTREAM_H_
diff --git a/third_party/libjingle/source/talk/base/ssladapter.cc b/third_party/libjingle/source/talk/base/ssladapter.cc
deleted file mode 100644
index 2368e7a..0000000
--- a/third_party/libjingle/source/talk/base/ssladapter.cc
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#if HAVE_CONFIG_H
-#include "config.h"
-#endif  // HAVE_CONFIG_H
-
-// Decide which (if any) implementation of SSL we will use.
-#if !defined(SSL_USE_SCHANNEL) && !defined(SSL_USE_OPENSSL)
-#ifdef WIN32
-#define SSL_USE_SCHANNEL 1
-#else  // !WIN32
-#define SSL_USE_OPENSSL HAVE_OPENSSL_SSL_H
-#endif  // !WIN32
-#endif
-
-#include "talk/base/ssladapter.h"
-
-#if SSL_USE_SCHANNEL
-
-#include "schanneladapter.h"
-
-#elif SSL_USE_OPENSSL  // && !SSL_USE_SCHANNEL
-
-#include "openssladapter.h"
-
-#endif  // SSL_USE_OPENSSL && !SSL_USE_SCHANNEL
-
-///////////////////////////////////////////////////////////////////////////////
-
-namespace talk_base {
-
-SSLAdapter*
-SSLAdapter::Create(AsyncSocket* socket) {
-#if SSL_USE_SCHANNEL
-  return new SChannelAdapter(socket);
-#elif SSL_USE_OPENSSL  // && !SSL_USE_SCHANNEL
-  return new OpenSSLAdapter(socket);
-#else  // !SSL_USE_OPENSSL && !SSL_USE_SCHANNEL
-  return NULL;
-#endif  // !SSL_USE_OPENSSL && !SSL_USE_SCHANNEL
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-#if SSL_USE_OPENSSL
-
-bool InitializeSSL(VerificationCallback callback) {
-  return OpenSSLAdapter::InitializeSSL(callback);
-}
-
-bool InitializeSSLThread() {
-  return OpenSSLAdapter::InitializeSSLThread();
-}
-
-bool CleanupSSL() {
-  return OpenSSLAdapter::CleanupSSL();
-}
-
-#else  // !SSL_USE_OPENSSL
-
-bool InitializeSSL(VerificationCallback callback) {
-  return true;
-}
-
-bool InitializeSSLThread() {
-  return true;
-}
-
-bool CleanupSSL() {
-  return true;
-}
-
-#endif  // !SSL_USE_OPENSSL
-
-///////////////////////////////////////////////////////////////////////////////
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/ssladapter.h b/third_party/libjingle/source/talk/base/ssladapter.h
deleted file mode 100644
index 1583dc2..0000000
--- a/third_party/libjingle/source/talk/base/ssladapter.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_SSLADAPTER_H_
-#define TALK_BASE_SSLADAPTER_H_
-
-#include "talk/base/asyncsocket.h"
-
-namespace talk_base {
-
-///////////////////////////////////////////////////////////////////////////////
-
-class SSLAdapter : public AsyncSocketAdapter {
- public:
-  explicit SSLAdapter(AsyncSocket* socket)
-    : AsyncSocketAdapter(socket), ignore_bad_cert_(false) { }
-
-  bool ignore_bad_cert() const { return ignore_bad_cert_; }
-  void set_ignore_bad_cert(bool ignore) { ignore_bad_cert_ = ignore; }
-
-  // StartSSL returns 0 if successful.
-  // If StartSSL is called while the socket is closed or connecting, the SSL
-  // negotiation will begin as soon as the socket connects.
-  virtual int StartSSL(const char* hostname, bool restartable) = 0;
-
-  // Create the default SSL adapter for this platform
-  static SSLAdapter* Create(AsyncSocket* socket);
-
- private:
-  // If true, the server certificate need not match the configured hostname.
-  bool ignore_bad_cert_;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-
-typedef bool (*VerificationCallback)(void* cert);
-
-// Call this on the main thread, before using SSL.
-// Call CleanupSSLThread when finished with SSL.
-bool InitializeSSL(VerificationCallback callback = NULL);
-
-// Call to initialize additional threads.
-bool InitializeSSLThread();
-
-// Call to cleanup additional threads, and also the main thread.
-bool CleanupSSL();
-
-///////////////////////////////////////////////////////////////////////////////
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_SSLADAPTER_H_
diff --git a/third_party/libjingle/source/talk/base/sslidentity.cc b/third_party/libjingle/source/talk/base/sslidentity.cc
deleted file mode 100644
index 0cb52f1..0000000
--- a/third_party/libjingle/source/talk/base/sslidentity.cc
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2008, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// Handling of certificates and keypairs for SSLStreamAdapter's peer mode.
-
-#include <string>
-
-#if HAVE_CONFIG_H
-#include "config.h"
-#endif  // HAVE_CONFIG_H
-
-// Decide which (if any) implementation of SSL we will use.
-#if !defined(SSL_USE_SCHANNEL) && !defined(SSL_USE_OPENSSL)
-#ifdef WIN32
-#define SSL_USE_SCHANNEL 1
-#else  // !WIN32
-#define SSL_USE_OPENSSL HAVE_OPENSSL_SSL_H
-#endif  // !WIN32
-#endif
-
-#include "talk/base/sslidentity.h"
-
-#if SSL_USE_SCHANNEL
-
-#error "Not implemented yet"
-
-#elif SSL_USE_OPENSSL  // && !SSL_USE_SCHANNEL
-
-#include "talk/base/opensslidentity.h"
-
-namespace talk_base {
-
-// From RFC 4572
-const char DIGEST_SHA_1[] = "sha-1";
-const char DIGEST_SHA_224[] = "sha-224";
-const char DIGEST_SHA_256[] = "sha-256";
-const char DIGEST_SHA_384[] = "sha-384";
-const char DIGEST_SHA_512[] = "sha-512";
-
-SSLCertificate* SSLCertificate::FromPEMString(const std::string& pem_string,
-                                              int* pem_length) {
-  return OpenSSLCertificate::FromPEMString(pem_string, pem_length);
-}
-
-SSLIdentity* SSLIdentity::Generate(const std::string& common_name) {
-  return OpenSSLIdentity::Generate(common_name);
-}
-
-}  // namespace talk_base
-
-#else  // !SSL_USE_OPENSSL && !SSL_USE_SCHANNEL
-
-#error "No SSL implementation"
-
-#endif  // SSL_USE_OPENSSL/!SSL_USE_SCHANNEL
diff --git a/third_party/libjingle/source/talk/base/sslidentity.h b/third_party/libjingle/source/talk/base/sslidentity.h
deleted file mode 100644
index 37e3080..0000000
--- a/third_party/libjingle/source/talk/base/sslidentity.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2008, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// Handling of certificates and keypairs for SSLStreamAdapter's peer mode.
-
-#ifndef TALK_BASE_SSLIDENTITY_H__
-#define TALK_BASE_SSLIDENTITY_H__
-
-#include <string>
-
-namespace talk_base {
-
-// Definitions for the digest algorithms
-extern const char DIGEST_SHA_1[];
-extern const char DIGEST_SHA_224[];
-extern const char DIGEST_SHA_256[];
-extern const char DIGEST_SHA_384[];
-extern const char DIGEST_SHA_512[];
-
-// Abstract interface overridden by SSL library specific
-// implementations.
-
-// A somewhat opaque type used to encapsulate a certificate.
-// Wraps the SSL library's notion of a certificate, with reference counting.
-// The SSLCertificate object is pretty much immutable once created.
-// (The OpenSSL implementation only does reference counting and
-// possibly caching of intermediate results.)
-class SSLCertificate {
- public:
-  // Parses and build a certificate from a PEM encoded string.
-  // Returns NULL on failure.
-  // The length of the string representation of the certificate is
-  // stored in *pem_length if it is non-NULL, and only if
-  // parsing was successful.
-  // Caller is responsible for freeing the returned object.
-  static SSLCertificate* FromPEMString(const std::string& pem_string,
-                                             int* pem_length);
-  virtual ~SSLCertificate() {}
-
-  // Returns a new SSLCertificate object instance wrapping the same
-  // underlying certificate.
-  // Caller is responsible for freeing the returned object.
-  virtual SSLCertificate* GetReference() = 0;
-
-  // Returns a PEM encoded string representation of the certificate.
-  virtual std::string ToPEMString() const = 0;
-
-  // Compute the digest of the certificate given algorithm
-  virtual bool ComputeDigest(const std::string &algorithm,
-                             unsigned char *digest, std::size_t size,
-                             std::size_t *length) const = 0;
-};
-
-// Our identity in an SSL negotiation: a keypair and certificate (both
-// with the same public key).
-// This too is pretty much immutable once created.
-class SSLIdentity {
- public:
-  // Generates an identity (keypair and self-signed certificate). If
-  // common_name is non-empty, it will be used for the certificate's
-  // subject and issuer name, otherwise a random string will be used.
-  // Returns NULL on failure.
-  // Caller is responsible for freeing the returned object.
-  static SSLIdentity* Generate(const std::string& common_name);
-
-  virtual ~SSLIdentity() {}
-
-  // Returns a new SSLIdentity object instance wrapping the same
-  // identity information.
-  // Caller is responsible for freeing the returned object.
-  virtual SSLIdentity* GetReference() = 0;
-
-  // Returns a temporary reference to the certificate.
-  virtual SSLCertificate& certificate() const = 0;
-};
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_SSLIDENTITY_H__
diff --git a/third_party/libjingle/source/talk/base/sslidentity_unittest.cc b/third_party/libjingle/source/talk/base/sslidentity_unittest.cc
deleted file mode 100644
index b6200cd..0000000
--- a/third_party/libjingle/source/talk/base/sslidentity_unittest.cc
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * libjingle
- * Copyright 2011, Google Inc.
- * Portions Copyright 2011, RTFM, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string>
-
-#include "talk/base/gunit.h"
-#include "talk/base/sslidentity.h"
-
-const char kTestCertificate[] = "-----BEGIN CERTIFICATE-----\n"
-    "MIIB6TCCAVICAQYwDQYJKoZIhvcNAQEEBQAwWzELMAkGA1UEBhMCQVUxEzARBgNV\n"
-    "BAgTClF1ZWVuc2xhbmQxGjAYBgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMRswGQYD\n"
-    "VQQDExJUZXN0IENBICgxMDI0IGJpdCkwHhcNMDAxMDE2MjIzMTAzWhcNMDMwMTE0\n"
-    "MjIzMTAzWjBjMQswCQYDVQQGEwJBVTETMBEGA1UECBMKUXVlZW5zbGFuZDEaMBgG\n"
-    "A1UEChMRQ3J5cHRTb2Z0IFB0eSBMdGQxIzAhBgNVBAMTGlNlcnZlciB0ZXN0IGNl\n"
-    "cnQgKDUxMiBiaXQpMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJ+zw4Qnlf8SMVIP\n"
-    "Fe9GEcStgOY2Ww/dgNdhjeD8ckUJNP5VZkVDTGiXav6ooKXfX3j/7tdkuD8Ey2//\n"
-    "Kv7+ue0CAwEAATANBgkqhkiG9w0BAQQFAAOBgQCT0grFQeZaqYb5EYfk20XixZV4\n"
-    "GmyAbXMftG1Eo7qGiMhYzRwGNWxEYojf5PZkYZXvSqZ/ZXHXa4g59jK/rJNnaVGM\n"
-    "k+xIX8mxQvlV0n5O9PIha5BX5teZnkHKgL8aKKLKW1BK7YTngsfSzzaeame5iKfz\n"
-    "itAE+OjGF+PFKbwX8Q==\n"
-    "-----END CERTIFICATE-----\n";
-
-const unsigned char kTestCertSha1[] = {0xA6, 0xC8, 0x59, 0xEA,
-                                       0xC3, 0x7E, 0x6D, 0x33,
-                                       0xCF, 0xE2, 0x69, 0x9D,
-                                       0x74, 0xE6, 0xF6, 0x8A,
-                                       0x9E, 0x47, 0xA7, 0xCA};
-
-class SSLIdentityTest : public testing::Test {
- public:
-  SSLIdentityTest() :
-      identity1_(NULL), identity2_(NULL) {
-  }
-
-  ~SSLIdentityTest() {
-  }
-
-  virtual void SetUp() {
-    identity1_.reset(talk_base::SSLIdentity::Generate("test1"));
-    identity2_.reset(talk_base::SSLIdentity::Generate("test2"));
-
-    ASSERT_TRUE(identity1_.get() != NULL);
-    ASSERT_TRUE(identity2_.get() != NULL);
-
-    test_cert_.reset(
-        talk_base::SSLCertificate::FromPEMString(kTestCertificate, 0));
-    ASSERT_TRUE(test_cert_.get() != NULL);
-  }
-
-  void TestDigest(const std::string &algorithm, size_t expected_len,
-                  const unsigned char *expected_digest = NULL) {
-    unsigned char digest1[64];
-    unsigned char digest1b[64];
-    unsigned char digest2[64];
-    size_t digest1_len;
-    size_t digest1b_len;
-    size_t digest2_len;
-    bool rv;
-
-    rv = identity1_->certificate().ComputeDigest(algorithm,
-                                                 digest1, sizeof(digest1),
-                                                 &digest1_len);
-    EXPECT_TRUE(rv);
-    EXPECT_EQ(expected_len, digest1_len);
-
-    rv = identity1_->certificate().ComputeDigest(algorithm,
-                                                 digest1b, sizeof(digest1b),
-                                                 &digest1b_len);
-    EXPECT_TRUE(rv);
-    EXPECT_EQ(expected_len, digest1b_len);
-    EXPECT_EQ(0, memcmp(digest1, digest1b, expected_len));
-
-
-    rv = identity2_->certificate().ComputeDigest(algorithm,
-                                                 digest2, sizeof(digest2),
-                                                 &digest2_len);
-    EXPECT_TRUE(rv);
-    EXPECT_EQ(expected_len, digest2_len);
-    EXPECT_NE(0, memcmp(digest1, digest2, expected_len));
-
-    // If we have an expected hash for the test cert, check it.
-    if (expected_digest != NULL) {
-      unsigned char digest3[64];
-      size_t digest3_len;
-
-      rv = test_cert_->ComputeDigest(algorithm, digest3, sizeof(digest3),
-                                    &digest3_len);
-      EXPECT_TRUE(rv);
-      EXPECT_EQ(expected_len, digest3_len);
-      EXPECT_EQ(0, memcmp(digest3, expected_digest, expected_len));
-    }
-  }
-
- private:
-  talk_base::scoped_ptr<talk_base::SSLIdentity> identity1_;
-  talk_base::scoped_ptr<talk_base::SSLIdentity> identity2_;
-  talk_base::scoped_ptr<talk_base::SSLCertificate> test_cert_;
-};
-
-TEST_F(SSLIdentityTest, DigestSHA1) {
-  TestDigest(talk_base::DIGEST_SHA_1, 20, kTestCertSha1);
-}
-
-TEST_F(SSLIdentityTest, DigestSHA224) {
-  TestDigest(talk_base::DIGEST_SHA_224, 28);
-}
-
-TEST_F(SSLIdentityTest, DigestSHA256) {
-  TestDigest(talk_base::DIGEST_SHA_256, 32);
-}
-
-TEST_F(SSLIdentityTest, DigestSHA384) {
-  TestDigest(talk_base::DIGEST_SHA_384, 48);
-}
-
-TEST_F(SSLIdentityTest, DigestSHA512) {
-  TestDigest(talk_base::DIGEST_SHA_512, 64);
-}
diff --git a/third_party/libjingle/source/talk/base/sslroots.h b/third_party/libjingle/source/talk/base/sslroots.h
deleted file mode 100644
index e59eba3..0000000
--- a/third_party/libjingle/source/talk/base/sslroots.h
+++ /dev/null
@@ -1,83 +0,0 @@
-// This file is the Equifax root certificate in C form.
-
-// It was generated with the following command line:
-// > openssl x509 -in Equifax_Secure_Certificate_Authority.cer -noout -C
-
-// The certificate was retrieved from:
-// http://www.geotrust.com/resources/root_certificates/certificates/Equifax_Secure_Certificate_Authority.cer
-
-/* subject:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority */
-/* issuer :/C=US/O=Equifax/OU=Equifax Secure Certificate Authority */
-unsigned char Equifax_Secure_Certificate_Authority_subject_name[80]={
-0x30,0x4E,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,
-0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x0A,0x13,0x07,0x45,0x71,0x75,0x69,0x66,0x61,
-0x78,0x31,0x2D,0x30,0x2B,0x06,0x03,0x55,0x04,0x0B,0x13,0x24,0x45,0x71,0x75,0x69,
-0x66,0x61,0x78,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x43,0x65,0x72,0x74,0x69,
-0x66,0x69,0x63,0x61,0x74,0x65,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,
-};
-unsigned char Equifax_Secure_Certificate_Authority_public_key[162]={
-0x30,0x81,0x9F,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,
-0x05,0x00,0x03,0x81,0x8D,0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xC1,0x5D,0xB1,
-0x58,0x67,0x08,0x62,0xEE,0xA0,0x9A,0x2D,0x1F,0x08,0x6D,0x91,0x14,0x68,0x98,0x0A,
-0x1E,0xFE,0xDA,0x04,0x6F,0x13,0x84,0x62,0x21,0xC3,0xD1,0x7C,0xCE,0x9F,0x05,0xE0,
-0xB8,0x01,0xF0,0x4E,0x34,0xEC,0xE2,0x8A,0x95,0x04,0x64,0xAC,0xF1,0x6B,0x53,0x5F,
-0x05,0xB3,0xCB,0x67,0x80,0xBF,0x42,0x02,0x8E,0xFE,0xDD,0x01,0x09,0xEC,0xE1,0x00,
-0x14,0x4F,0xFC,0xFB,0xF0,0x0C,0xDD,0x43,0xBA,0x5B,0x2B,0xE1,0x1F,0x80,0x70,0x99,
-0x15,0x57,0x93,0x16,0xF1,0x0F,0x97,0x6A,0xB7,0xC2,0x68,0x23,0x1C,0xCC,0x4D,0x59,
-0x30,0xAC,0x51,0x1E,0x3B,0xAF,0x2B,0xD6,0xEE,0x63,0x45,0x7B,0xC5,0xD9,0x5F,0x50,
-0xD2,0xE3,0x50,0x0F,0x3A,0x88,0xE7,0xBF,0x14,0xFD,0xE0,0xC7,0xB9,0x02,0x03,0x01,
-0x00,0x01,
-};
-unsigned char Equifax_Secure_Certificate_Authority_certificate[804]={
-0x30,0x82,0x03,0x20,0x30,0x82,0x02,0x89,0xA0,0x03,0x02,0x01,0x02,0x02,0x04,0x35,
-0xDE,0xF4,0xCF,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,
-0x05,0x00,0x30,0x4E,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,
-0x53,0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x0A,0x13,0x07,0x45,0x71,0x75,0x69,
-0x66,0x61,0x78,0x31,0x2D,0x30,0x2B,0x06,0x03,0x55,0x04,0x0B,0x13,0x24,0x45,0x71,
-0x75,0x69,0x66,0x61,0x78,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x43,0x65,0x72,
-0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,
-0x74,0x79,0x30,0x1E,0x17,0x0D,0x39,0x38,0x30,0x38,0x32,0x32,0x31,0x36,0x34,0x31,
-0x35,0x31,0x5A,0x17,0x0D,0x31,0x38,0x30,0x38,0x32,0x32,0x31,0x36,0x34,0x31,0x35,
-0x31,0x5A,0x30,0x4E,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,
-0x53,0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x0A,0x13,0x07,0x45,0x71,0x75,0x69,
-0x66,0x61,0x78,0x31,0x2D,0x30,0x2B,0x06,0x03,0x55,0x04,0x0B,0x13,0x24,0x45,0x71,
-0x75,0x69,0x66,0x61,0x78,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x43,0x65,0x72,
-0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,
-0x74,0x79,0x30,0x81,0x9F,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,
-0x01,0x01,0x05,0x00,0x03,0x81,0x8D,0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xC1,
-0x5D,0xB1,0x58,0x67,0x08,0x62,0xEE,0xA0,0x9A,0x2D,0x1F,0x08,0x6D,0x91,0x14,0x68,
-0x98,0x0A,0x1E,0xFE,0xDA,0x04,0x6F,0x13,0x84,0x62,0x21,0xC3,0xD1,0x7C,0xCE,0x9F,
-0x05,0xE0,0xB8,0x01,0xF0,0x4E,0x34,0xEC,0xE2,0x8A,0x95,0x04,0x64,0xAC,0xF1,0x6B,
-0x53,0x5F,0x05,0xB3,0xCB,0x67,0x80,0xBF,0x42,0x02,0x8E,0xFE,0xDD,0x01,0x09,0xEC,
-0xE1,0x00,0x14,0x4F,0xFC,0xFB,0xF0,0x0C,0xDD,0x43,0xBA,0x5B,0x2B,0xE1,0x1F,0x80,
-0x70,0x99,0x15,0x57,0x93,0x16,0xF1,0x0F,0x97,0x6A,0xB7,0xC2,0x68,0x23,0x1C,0xCC,
-0x4D,0x59,0x30,0xAC,0x51,0x1E,0x3B,0xAF,0x2B,0xD6,0xEE,0x63,0x45,0x7B,0xC5,0xD9,
-0x5F,0x50,0xD2,0xE3,0x50,0x0F,0x3A,0x88,0xE7,0xBF,0x14,0xFD,0xE0,0xC7,0xB9,0x02,
-0x03,0x01,0x00,0x01,0xA3,0x82,0x01,0x09,0x30,0x82,0x01,0x05,0x30,0x70,0x06,0x03,
-0x55,0x1D,0x1F,0x04,0x69,0x30,0x67,0x30,0x65,0xA0,0x63,0xA0,0x61,0xA4,0x5F,0x30,
-0x5D,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x10,
-0x30,0x0E,0x06,0x03,0x55,0x04,0x0A,0x13,0x07,0x45,0x71,0x75,0x69,0x66,0x61,0x78,
-0x31,0x2D,0x30,0x2B,0x06,0x03,0x55,0x04,0x0B,0x13,0x24,0x45,0x71,0x75,0x69,0x66,
-0x61,0x78,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x43,0x65,0x72,0x74,0x69,0x66,
-0x69,0x63,0x61,0x74,0x65,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x31,
-0x0D,0x30,0x0B,0x06,0x03,0x55,0x04,0x03,0x13,0x04,0x43,0x52,0x4C,0x31,0x30,0x1A,
-0x06,0x03,0x55,0x1D,0x10,0x04,0x13,0x30,0x11,0x81,0x0F,0x32,0x30,0x31,0x38,0x30,
-0x38,0x32,0x32,0x31,0x36,0x34,0x31,0x35,0x31,0x5A,0x30,0x0B,0x06,0x03,0x55,0x1D,
-0x0F,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,
-0x30,0x16,0x80,0x14,0x48,0xE6,0x68,0xF9,0x2B,0xD2,0xB2,0x95,0xD7,0x47,0xD8,0x23,
-0x20,0x10,0x4F,0x33,0x98,0x90,0x9F,0xD4,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,
-0x16,0x04,0x14,0x48,0xE6,0x68,0xF9,0x2B,0xD2,0xB2,0x95,0xD7,0x47,0xD8,0x23,0x20,
-0x10,0x4F,0x33,0x98,0x90,0x9F,0xD4,0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x04,0x05,
-0x30,0x03,0x01,0x01,0xFF,0x30,0x1A,0x06,0x09,0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,
-0x41,0x00,0x04,0x0D,0x30,0x0B,0x1B,0x05,0x56,0x33,0x2E,0x30,0x63,0x03,0x02,0x06,
-0xC0,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,
-0x03,0x81,0x81,0x00,0x58,0xCE,0x29,0xEA,0xFC,0xF7,0xDE,0xB5,0xCE,0x02,0xB9,0x17,
-0xB5,0x85,0xD1,0xB9,0xE3,0xE0,0x95,0xCC,0x25,0x31,0x0D,0x00,0xA6,0x92,0x6E,0x7F,
-0xB6,0x92,0x63,0x9E,0x50,0x95,0xD1,0x9A,0x6F,0xE4,0x11,0xDE,0x63,0x85,0x6E,0x98,
-0xEE,0xA8,0xFF,0x5A,0xC8,0xD3,0x55,0xB2,0x66,0x71,0x57,0xDE,0xC0,0x21,0xEB,0x3D,
-0x2A,0xA7,0x23,0x49,0x01,0x04,0x86,0x42,0x7B,0xFC,0xEE,0x7F,0xA2,0x16,0x52,0xB5,
-0x67,0x67,0xD3,0x40,0xDB,0x3B,0x26,0x58,0xB2,0x28,0x77,0x3D,0xAE,0x14,0x77,0x61,
-0xD6,0xFA,0x2A,0x66,0x27,0xA0,0x0D,0xFA,0xA7,0x73,0x5C,0xEA,0x70,0xF1,0x94,0x21,
-0x65,0x44,0x5F,0xFA,0xFC,0xEF,0x29,0x68,0xA9,0xA2,0x87,0x79,0xEF,0x79,0xEF,0x4F,
-0xAC,0x07,0x77,0x38,
-};
diff --git a/third_party/libjingle/source/talk/base/sslsocketfactory.cc b/third_party/libjingle/source/talk/base/sslsocketfactory.cc
deleted file mode 100644
index fcb2c0c..0000000
--- a/third_party/libjingle/source/talk/base/sslsocketfactory.cc
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * libjingle
- * Copyright 2007, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/autodetectproxy.h"
-#include "talk/base/httpcommon.h"
-#include "talk/base/httpcommon-inl.h"
-#include "talk/base/socketadapters.h"
-#include "talk/base/ssladapter.h"
-#include "talk/base/sslsocketfactory.h"
-
-namespace talk_base {
-
-///////////////////////////////////////////////////////////////////////////////
-// ProxySocketAdapter
-// TODO: Consider combining AutoDetectProxy and ProxySocketAdapter.  I think
-// the socket adapter is the more appropriate idiom for automatic proxy
-// detection.  We may or may not want to combine proxydetect.* as well.
-///////////////////////////////////////////////////////////////////////////////
-
-class ProxySocketAdapter : public AsyncSocketAdapter {
- public:
-  ProxySocketAdapter(SslSocketFactory* factory, int type)
-      : AsyncSocketAdapter(NULL), factory_(factory), type_(type),
-        detect_(NULL) {
-  }
-  virtual ~ProxySocketAdapter() {
-    Close();
-  }
-
-  virtual int Connect(const SocketAddress& addr) {
-    ASSERT(NULL == detect_);
-    ASSERT(NULL == socket_);
-    remote_ = addr;
-    if (remote_.IsAnyIP() && remote_.hostname().empty()) {
-      LOG_F(LS_ERROR) << "Empty address";
-      return SOCKET_ERROR;
-    }
-    Url<char> url("/", remote_.IPAsString(), remote_.port());
-    detect_ = new AutoDetectProxy(factory_->agent_);
-    detect_->set_server_url(url.url());
-    detect_->SignalWorkDone.connect(this,
-        &ProxySocketAdapter::OnProxyDetectionComplete);
-    detect_->Start();
-    return SOCKET_ERROR;
-  }
-  virtual int GetError() const {
-    if (socket_) {
-      return socket_->GetError();
-    }
-    return detect_ ? EWOULDBLOCK : EADDRNOTAVAIL;
-  }
-  virtual int Close() {
-    if (socket_) {
-      return socket_->Close();
-    }
-    if (detect_) {
-      detect_->Destroy(false);
-      detect_ = NULL;
-    }
-    return 0;
-  }
-  virtual ConnState GetState() const {
-    if (socket_) {
-      return socket_->GetState();
-    }
-    return detect_ ? CS_CONNECTING : CS_CLOSED;
-  }
-
-private:
-  // AutoDetectProxy Slots
-  void OnProxyDetectionComplete(SignalThread* thread) {
-    ASSERT(detect_ == thread);
-    Attach(factory_->CreateProxySocket(detect_->proxy(), type_));
-    detect_->Release();
-    detect_ = NULL;
-    if (0 == AsyncSocketAdapter::Connect(remote_)) {
-      SignalConnectEvent(this);
-    } else if (!IsBlockingError(socket_->GetError())) {
-      SignalCloseEvent(this, socket_->GetError());
-    }
-  }
-
-  SslSocketFactory* factory_;
-  int type_;
-  SocketAddress remote_;
-  AutoDetectProxy* detect_;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// SslSocketFactory
-///////////////////////////////////////////////////////////////////////////////
-
-Socket* SslSocketFactory::CreateSocket(int type) {
-  return factory_->CreateSocket(type);
-}
-
-AsyncSocket* SslSocketFactory::CreateAsyncSocket(int type) {
-  if (autodetect_proxy_) {
-    return new ProxySocketAdapter(this, type);
-  } else {
-    return CreateProxySocket(proxy_, type);
-  }
-}
-
-AsyncSocket* SslSocketFactory::CreateProxySocket(const ProxyInfo& proxy,
-                                                 int type) {
-  AsyncSocket* socket = factory_->CreateAsyncSocket(type);
-  if (!socket)
-    return NULL;
-
-  // Binary logging happens at the lowest level 
-  if (!logging_label_.empty() && binary_mode_) {
-    socket = new LoggingSocketAdapter(socket, logging_level_,
-                                      logging_label_.c_str(), binary_mode_);
-  }
-
-  if (proxy.type) {
-    AsyncSocket* proxy_socket = 0;
-    if (proxy_.type == PROXY_SOCKS5) {
-      proxy_socket = new AsyncSocksProxySocket(socket, proxy.address,
-                                               proxy.username, proxy.password);
-    } else {
-      // Note: we are trying unknown proxies as HTTPS currently
-      AsyncHttpsProxySocket* http_proxy =
-          new AsyncHttpsProxySocket(socket, agent_, proxy.address,
-                                    proxy.username, proxy.password);
-      http_proxy->SetForceConnect(force_connect_ || !hostname_.empty());
-      proxy_socket = http_proxy;
-    }
-    if (!proxy_socket) {
-      delete socket;
-      return NULL;
-    }
-    socket = proxy_socket;  // for our purposes the proxy is now the socket
-  }
-
-  if (!hostname_.empty()) {
-    if (SSLAdapter* ssl_adapter = SSLAdapter::Create(socket)) {
-      ssl_adapter->set_ignore_bad_cert(ignore_bad_cert_);
-      ssl_adapter->StartSSL(hostname_.c_str(), true);
-      socket = ssl_adapter;
-    } else {
-      LOG_F(LS_ERROR) << "SSL unavailable";
-    }
-  }
-
-  // Regular logging occurs at the highest level
-  if (!logging_label_.empty() && !binary_mode_) {
-    socket = new LoggingSocketAdapter(socket, logging_level_, 
-                                      logging_label_.c_str(), binary_mode_);
-  }
-  return socket;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/sslsocketfactory.h b/third_party/libjingle/source/talk/base/sslsocketfactory.h
deleted file mode 100644
index d42689a..0000000
--- a/third_party/libjingle/source/talk/base/sslsocketfactory.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * libjingle
- * Copyright 2007, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_SSLSOCKETFACTORY_H__
-#define TALK_BASE_SSLSOCKETFACTORY_H__
-
-#include "talk/base/proxyinfo.h"
-#include "talk/base/socketserver.h"
-
-namespace talk_base {
-
-///////////////////////////////////////////////////////////////////////////////
-// SslSocketFactory
-///////////////////////////////////////////////////////////////////////////////
-
-class SslSocketFactory : public SocketFactory {
- public:
-  SslSocketFactory(SocketFactory* factory, const std::string& user_agent)
-     : factory_(factory), agent_(user_agent), autodetect_proxy_(true),
-       force_connect_(false), logging_level_(LS_VERBOSE), binary_mode_(false) {
-  }
-
-  void SetAutoDetectProxy() {
-    autodetect_proxy_ = true;
-  }
-  void SetForceConnect(bool force) {
-    force_connect_ = force;
-  }
-  void SetProxy(const ProxyInfo& proxy) {
-    autodetect_proxy_ = false;
-    proxy_ = proxy;
-  }
-  bool autodetect_proxy() const { return autodetect_proxy_; }
-  const ProxyInfo& proxy() const { return proxy_; }
-
-  void UseSSL(const char* hostname) { hostname_ = hostname; }
-  void DisableSSL() { hostname_.clear(); }
-  void SetIgnoreBadCert(bool ignore) { ignore_bad_cert_ = ignore; }
-  bool ignore_bad_cert() const { return ignore_bad_cert_; }
-
-  void SetLogging(LoggingSeverity level, const std::string& label, 
-                  bool binary_mode = false) {
-    logging_level_ = level;
-    logging_label_ = label;
-    binary_mode_ = binary_mode;
-  }
-
-  // SocketFactory Interface
-  virtual Socket* CreateSocket(int type);
-  virtual AsyncSocket* CreateAsyncSocket(int type);
-
- private:
-  friend class ProxySocketAdapter;
-  AsyncSocket* CreateProxySocket(const ProxyInfo& proxy, int type);
-
-  SocketFactory* factory_;
-  std::string agent_;
-  bool autodetect_proxy_, force_connect_;
-  ProxyInfo proxy_;
-  std::string hostname_, logging_label_;
-  LoggingSeverity logging_level_;
-  bool binary_mode_;
-  bool ignore_bad_cert_;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_SSLSOCKETFACTORY_H__
diff --git a/third_party/libjingle/source/talk/base/sslstreamadapter.cc b/third_party/libjingle/source/talk/base/sslstreamadapter.cc
deleted file mode 100644
index 17121fd..0000000
--- a/third_party/libjingle/source/talk/base/sslstreamadapter.cc
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2008, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#if HAVE_CONFIG_H
-#include "config.h"
-#endif  // HAVE_CONFIG_H
-
-// Decide which (if any) implementation of SSL we will use.
-#if !defined(SSL_USE_SCHANNEL) && !defined(SSL_USE_OPENSSL)
-#ifdef WIN32
-#define SSL_USE_SCHANNEL 1
-#else  // !WIN32
-#define SSL_USE_OPENSSL HAVE_OPENSSL_SSL_H
-#endif  // !WIN32
-#endif
-
-#include "talk/base/sslstreamadapter.h"
-
-#if SSL_USE_SCHANNEL
-
-#error "Not implemented yet"
-
-#elif SSL_USE_OPENSSL  // && !SSL_USE_SCHANNEL
-
-#include "talk/base/opensslstreamadapter.h"
-
-#endif  // SSL_USE_OPENSSL && !SSL_USE_SCHANNEL
-
-///////////////////////////////////////////////////////////////////////////////
-
-namespace talk_base {
-
-SSLStreamAdapter* SSLStreamAdapter::Create(StreamInterface* stream) {
-#if SSL_USE_SCHANNEL
-  // not implemented yet
-  // return new SChannelStreamAdapter(stream);
-#elif SSL_USE_OPENSSL  // && !SSL_USE_SCHANNEL
-  return new OpenSSLStreamAdapter(stream);
-#else  // !SSL_USE_OPENSSL && !SSL_USE_SCHANNEL
-  return NULL;
-#endif  // !SSL_USE_OPENSSL && !SSL_USE_SCHANNEL
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/sslstreamadapter.h b/third_party/libjingle/source/talk/base/sslstreamadapter.h
deleted file mode 100644
index 28870b3..0000000
--- a/third_party/libjingle/source/talk/base/sslstreamadapter.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2008, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_SSLSTREAMADAPTER_H__
-#define TALK_BASE_SSLSTREAMADAPTER_H__
-
-#include <string>
-
-#include "talk/base/stream.h"
-#include "talk/base/sslidentity.h"
-
-namespace talk_base {
-
-// SSLStreamAdapter : A StreamInterfaceAdapter that does SSL/TLS.
-// After SSL has been started, the stream will only open on successful
-// SSL verification of certificates, and the communication is
-// encrypted of course.
-//
-// This class was written with SSLAdapter as a starting point. It
-// offers a similar interface, with two differences: there is no
-// support for a restartable SSL connection, and this class has a
-// peer-to-peer mode.
-//
-// The SSL library requires initialization and cleanup. Static method
-// for doing this are in SSLAdapter. They should possibly be moved out
-// to a neutral class.
-
-
-enum SSLRole { SSL_CLIENT, SSL_SERVER };
-enum SSLMode { SSL_MODE_TLS, SSL_MODE_DTLS };
-
-// Errors for Read -- in the high range so no conflict with OpenSSL.
-enum { SSE_MSG_TRUNC = 0xff0001 };
-
-class SSLStreamAdapter : public StreamAdapterInterface {
- public:
-  // Instantiate an SSLStreamAdapter wrapping the given stream,
-  // (using the selected implementation for the platform).
-  // Caller is responsible for freeing the returned object.
-  static SSLStreamAdapter* Create(StreamInterface* stream);
-
-  explicit SSLStreamAdapter(StreamInterface* stream)
-      : StreamAdapterInterface(stream), ignore_bad_cert_(false) { }
-
-  void set_ignore_bad_cert(bool ignore) { ignore_bad_cert_ = ignore; }
-  bool ignore_bad_cert() const { return ignore_bad_cert_; }
-
-  // Specify our SSL identity: key and certificate. Mostly this is
-  // only used in the peer-to-peer mode (unless we actually want to
-  // provide a client certificate to a server).
-  // SSLStream takes ownership of the SSLIdentity object and will
-  // free it when appropriate. Should be called no more than once on a
-  // given SSLStream instance.
-  virtual void SetIdentity(SSLIdentity* identity) = 0;
-
-  // Call this to indicate that we are to play the server's role in
-  // the peer-to-peer mode.
-  // The default argument is for backward compatibility
-  // TODO(ekr@rtfm.com): rename this SetRole to reflect its new function
-  virtual void SetServerRole(SSLRole role = SSL_SERVER) = 0;
-
-  // Do DTLS or TLS
-  virtual void SetMode(SSLMode mode) = 0;
-
-  // The mode of operation is selected by calling either
-  // StartSSLWithServer or StartSSLWithPeer.
-  // Use of the stream prior to calling either of these functions will
-  // pass data in clear text.
-  // Calling one of these functions causes SSL negotiation to begin as
-  // soon as possible: right away if the underlying wrapped stream is
-  // already opened, or else as soon as it opens.
-  //
-  // These functions return a negative error code on failure.
-  // Returning 0 means success so far, but negotiation is probably not
-  // complete and will continue asynchronously.  In that case, the
-  // exposed stream will open after successful negotiation and
-  // verification, or an SE_CLOSE event will be raised if negotiation
-  // fails.
-
-  // StartSSLWithServer starts SSL negotiation with a server in
-  // traditional mode. server_name specifies the expected server name
-  // which the server's certificate needs to specify.
-  virtual int StartSSLWithServer(const char* server_name) = 0;
-
-  // StartSSLWithPeer starts negotiation in the special peer-to-peer
-  // mode.
-  // Generally, SetIdentity() and possibly SetServerRole() should have
-  // been called before this.
-  // SetPeerCertificate() must also be called. It may be called after
-  // StartSSLWithPeer() but must be called before the underlying
-  // stream opens.
-  virtual int StartSSLWithPeer() = 0;
-
-  // Specify the certificate that our peer is expected to use in
-  // peer-to-peer mode. Only this certificate will be accepted during
-  // SSL verification. The certificate is assumed to have been
-  // obtained through some other secure channel (such as the XMPP
-  // channel). (This could also specify the certificate authority that
-  // will sign the peer's certificate.)
-  // SSLStream takes ownership of the SSLCertificate object and will
-  // free it when appropriate. Should be called no more than once on a
-  // given SSLStream instance.
-  virtual void SetPeerCertificate(SSLCertificate* cert) = 0;
-
-  // Specify the digest of the certificate that our peer is expected to use in
-  // peer-to-peer mode. Only this certificate will be accepted during
-  // SSL verification. The certificate is assumed to have been
-  // obtained through some other secure channel (such as the XMPP
-  // channel). Unlike SetPeerCertificate(), this must specify the
-  // terminal certificate, not just a CA.
-  // SSLStream makes a copy of the digest value.
-  virtual bool SetPeerCertificateDigest(const std::string& digest_alg,
-                                        const unsigned char* digest_val,
-                                        size_t digest_len) = 0;
-
-  // If true, the server certificate need not match the configured
-  // server_name, and in fact missing certificate authority and other
-  // verification errors are ignored.
-  bool ignore_bad_cert_;
-};
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_SSLSTREAMADAPTER_H__
diff --git a/third_party/libjingle/source/talk/base/sslstreamadapter_unittest.cc b/third_party/libjingle/source/talk/base/sslstreamadapter_unittest.cc
deleted file mode 100644
index 0206f87..0000000
--- a/third_party/libjingle/source/talk/base/sslstreamadapter_unittest.cc
+++ /dev/null
@@ -1,610 +0,0 @@
-/*
- * libjingle
- * Copyright 2011, Google Inc.
- * Portions Copyright 2011, RTFM, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-#include <string>
-#include <set>
-
-#include "talk/base/gunit.h"
-#include "talk/base/helpers.h"
-#include "talk/base/ssladapter.h"
-#include "talk/base/sslidentity.h"
-#include "talk/base/sslstreamadapter.h"
-#include "talk/base/stream.h"
-
-static const int kBlockSize = 4096;
-
-class SSLStreamAdapterTestBase;
-
-class SSLDummyStream : public talk_base::StreamInterface,
-                       public sigslot::has_slots<> {
- public:
-  explicit SSLDummyStream(SSLStreamAdapterTestBase *test,
-                          const std::string &side,
-                          talk_base::FifoBuffer *in,
-                          talk_base::FifoBuffer *out) :
-      test_(test),
-      side_(side),
-      in_(in),
-      out_(out),
-      first_packet_(true) {
-    in_->SignalEvent.connect(this, &SSLDummyStream::OnEventIn);
-    out_->SignalEvent.connect(this, &SSLDummyStream::OnEventOut);
-  }
-
-  virtual talk_base::StreamState GetState() const { return talk_base::SS_OPEN; }
-
-  virtual talk_base::StreamResult Read(void* buffer, size_t buffer_len,
-                                       size_t* read, int* error) {
-    talk_base::StreamResult r;
-
-    r = in_->Read(buffer, buffer_len, read, error);
-    if (r == talk_base::SR_BLOCK)
-      return talk_base::SR_BLOCK;
-    if (r == talk_base::SR_EOS)
-      return talk_base::SR_EOS;
-
-    if (r != talk_base::SR_SUCCESS) {
-      ADD_FAILURE();
-      return talk_base::SR_ERROR;
-    }
-
-    return talk_base::SR_SUCCESS;
-  }
-
-  // Catch readability events on in and pass them up.
-  virtual void OnEventIn(talk_base::StreamInterface *stream, int sig,
-                         int err) {
-    int mask = (talk_base::SE_READ | talk_base::SE_CLOSE);
-
-    if (sig & mask) {
-      LOG(LS_INFO) << "SSLDummyStream::OnEvent side=" << side_ <<  " sig="
-        << sig << " forwarding upward";
-      PostEvent(sig & mask, 0);
-    }
-  }
-
-  // Catch writeability events on out and pass them up.
-  virtual void OnEventOut(talk_base::StreamInterface *stream, int sig,
-                          int err) {
-    if (sig & talk_base::SE_WRITE) {
-      LOG(LS_INFO) << "SSLDummyStream::OnEvent side=" << side_ <<  " sig="
-        << sig << " forwarding upward";
-
-      PostEvent(sig & talk_base::SE_WRITE, 0);
-    }
-  }
-
-  // Write to the outgoing FifoBuffer
-  talk_base::StreamResult WriteData(const void* data, size_t data_len,
-                                    size_t* written, int* error) {
-    return out_->Write(data, data_len, written, error);
-  }
-
-  // Defined later
-  virtual talk_base::StreamResult Write(const void* data, size_t data_len,
-                                        size_t* written, int* error);
-
-  virtual void Close() {
-    LOG(LS_INFO) << "Closing outbound stream";
-    out_->Close();
-  }
-
- private:
-  SSLStreamAdapterTestBase *test_;
-  const std::string side_;
-  talk_base::FifoBuffer *in_;
-  talk_base::FifoBuffer *out_;
-  bool first_packet_;
-};
-
-class SSLStreamAdapterTestBase : public testing::Test,
-                                 public sigslot::has_slots<> {
- public:
-  explicit SSLStreamAdapterTestBase(bool dtls) :
-      client_buffer_(4096), server_buffer_(4096),
-      client_stream_(
-          new SSLDummyStream(this, "c2s", &client_buffer_, &server_buffer_)),
-      server_stream_(
-          new SSLDummyStream(this, "s2c", &server_buffer_, &client_buffer_)),
-      client_ssl_(talk_base::SSLStreamAdapter::Create(client_stream_)),
-      server_ssl_(talk_base::SSLStreamAdapter::Create(server_stream_)),
-      client_identity_(NULL), server_identity_(NULL),
-      delay_(0), mtu_(1460), loss_(0), lose_first_packet_(false), dtls_(dtls),
-      handshake_wait_(5000), identities_set_(false) {
-    // Set use of the test RNG to get predictable loss patterns.
-    talk_base::SetRandomTestMode(true);
-
-    LOG(LS_INFO) << "Setup";
-    talk_base::InitializeSSL();
-
-    // Set up the slots
-    client_ssl_->SignalEvent.connect(this, &SSLStreamAdapterTestBase::OnEvent);
-    server_ssl_->SignalEvent.connect(this, &SSLStreamAdapterTestBase::OnEvent);
-
-    client_identity_ = talk_base::SSLIdentity::Generate("client");
-    server_identity_ = talk_base::SSLIdentity::Generate("server");
-
-    client_ssl_->SetIdentity(client_identity_);
-    server_ssl_->SetIdentity(server_identity_);
-  }
-
-  ~SSLStreamAdapterTestBase() {
-    // Put it back for the next test.
-    talk_base::SetRandomTestMode(false);
-  }
-
-  virtual void OnEvent(talk_base::StreamInterface *stream, int sig, int err) {
-    LOG(LS_INFO) << "SSLStreamAdapterTestBase::OnEvent sig=" << sig;
-
-    if (sig & talk_base::SE_READ) {
-      ReadData(stream);
-    }
-
-    if ((stream == client_ssl_.get()) && (sig & talk_base::SE_WRITE)) {
-      WriteData();
-    }
-  }
-
-  void SetPeerIdentitiesByCertificate(bool correct) {
-    LOG(LS_INFO) << "Setting peer identities by certificate";
-
-    if (correct) {
-      client_ssl_->SetPeerCertificate(server_identity_->certificate().
-                                           GetReference());
-      server_ssl_->SetPeerCertificate(client_identity_->certificate().
-                                           GetReference());
-    } else {
-      // If incorrect, set up to expect our own certificate at the peer
-      client_ssl_->SetPeerCertificate(client_identity_->certificate().
-                                           GetReference());
-      server_ssl_->SetPeerCertificate(server_identity_->certificate().
-                                           GetReference());
-    }
-    identities_set_ = true;
-  }
-
-  void SetPeerIdentitiesByDigest(bool correct) {
-    unsigned char digest[20];
-    size_t digest_len;
-    bool rv;
-
-    LOG(LS_INFO) << "Setting peer identities by digest";
-
-    rv = server_identity_->certificate().ComputeDigest(talk_base::DIGEST_SHA_1,
-                                                      digest, 20,
-                                                      &digest_len);
-    ASSERT_TRUE(rv);
-    if (!correct) {
-      LOG(LS_INFO) << "Setting bogus digest for server cert";
-      digest[0]++;
-    }
-    rv = client_ssl_->SetPeerCertificateDigest(talk_base::DIGEST_SHA_1, digest,
-                                               digest_len);
-    ASSERT_TRUE(rv);
-
-
-    rv = client_identity_->certificate().ComputeDigest(talk_base::DIGEST_SHA_1,
-                                                      digest, 20, &digest_len);
-    ASSERT_TRUE(rv);
-    if (!correct) {
-      LOG(LS_INFO) << "Setting bogus digest for client cert";
-      digest[0]++;
-    }
-    rv = server_ssl_->SetPeerCertificateDigest(talk_base::DIGEST_SHA_1, digest,
-                                               digest_len);
-    ASSERT_TRUE(rv);
-
-    identities_set_ = true;
-  }
-
-  void TestHandshake(bool expect_success = true) {
-    server_ssl_->SetMode(dtls_ ? talk_base::SSL_MODE_DTLS :
-                         talk_base::SSL_MODE_TLS);
-    client_ssl_->SetMode(dtls_ ? talk_base::SSL_MODE_DTLS :
-                         talk_base::SSL_MODE_TLS);
-
-    if (!dtls_) {
-      // Make sure we simulate a reliable network for TLS.
-      // This is just a check to make sure that people don't write wrong
-      // tests.
-      ASSERT((mtu_ == 1460) && (loss_ == 0) && (lose_first_packet_ == 0));
-    }
-
-    if (!identities_set_)
-      SetPeerIdentitiesByDigest(true);
-
-    // Start the handshake
-    int rv;
-
-    server_ssl_->SetServerRole();
-    rv = server_ssl_->StartSSLWithPeer();
-    ASSERT_EQ(0, rv);
-
-    rv = client_ssl_->StartSSLWithPeer();
-    ASSERT_EQ(0, rv);
-
-    // Now run the handshake
-    if (expect_success) {
-      EXPECT_TRUE_WAIT((client_ssl_->GetState() == talk_base::SS_OPEN)
-                       && (server_ssl_->GetState() == talk_base::SS_OPEN),
-                       handshake_wait_);
-    } else {
-      EXPECT_TRUE_WAIT(client_ssl_->GetState() == talk_base::SS_CLOSED,
-                       handshake_wait_);
-    }
-  }
-
-  talk_base::StreamResult DataWritten(SSLDummyStream *from, const void *data,
-                                      size_t data_len, size_t *written,
-                                      int *error) {
-    // Randomly drop loss_ percent of packets
-    if (talk_base::CreateRandomId() % 100 < static_cast<uint32>(loss_)) {
-      LOG(LS_INFO) << "Randomly dropping packet, size=" << data_len;
-      *written = data_len;
-      return talk_base::SR_SUCCESS;
-    }
-    if (dtls_ && (data_len > mtu_)) {
-      LOG(LS_INFO) << "Dropping packet > mtu, size=" << data_len;
-      *written = data_len;
-      return talk_base::SR_SUCCESS;
-    }
-
-    return from->WriteData(data, data_len, written, error);
-  }
-
-  void SetDelay(int delay) {
-    delay_ = delay;
-  }
-  int GetDelay() { return delay_; }
-
-  void SetLoseFirstPacket(bool lose) {
-    lose_first_packet_ = lose;
-  }
-  bool GetLoseFirstPacket() { return lose_first_packet_; }
-
-  void SetLoss(int percent) {
-    loss_ = percent;
-  }
-
-  void SetMtu(size_t mtu) {
-    mtu_ = mtu;
-  }
-
-  void SetHandshakeWait(int wait) {
-    handshake_wait_ = wait;
-  }
-
-  // To be implemented by subclasses.
-  virtual void WriteData() = 0;
-  virtual void ReadData(talk_base::StreamInterface *stream) = 0;
-  virtual void TestTransfer(int size) = 0;
-
- protected:
-  talk_base::FifoBuffer client_buffer_;
-  talk_base::FifoBuffer server_buffer_;
-  SSLDummyStream *client_stream_;  // freed by client_ssl_ destructor
-  SSLDummyStream *server_stream_;  // freed by server_ssl_ destructor
-  talk_base::scoped_ptr<talk_base::SSLStreamAdapter> client_ssl_;
-  talk_base::scoped_ptr<talk_base::SSLStreamAdapter> server_ssl_;
-  talk_base::SSLIdentity *client_identity_;  // freed by client_ssl_ destructor
-  talk_base::SSLIdentity *server_identity_;  // freed by server_ssl_ destructor
-  int delay_;
-  size_t mtu_;
-  int loss_;
-  bool lose_first_packet_;
-  bool dtls_;
-  int handshake_wait_;
-  bool identities_set_;
-};
-
-
-class SSLStreamAdapterTestTLS : public SSLStreamAdapterTestBase {
- public:
-  SSLStreamAdapterTestTLS() :
-      SSLStreamAdapterTestBase(false) {
-  };
-
-  // Test data transfer for TLS
-  virtual void TestTransfer(int size) {
-    LOG(LS_INFO) << "Starting transfer test with " << size << " bytes";
-    // Create some dummy data to send.
-    size_t received;
-
-    send_stream_.ReserveSize(size);
-    for (int i = 0; i < size; ++i) {
-      char ch = static_cast<char>(i);
-      send_stream_.Write(&ch, 1, NULL, NULL);
-    }
-    send_stream_.Rewind();
-
-    // Prepare the receive stream.
-    recv_stream_.ReserveSize(size);
-
-    // Start sending
-    WriteData();
-
-    // Wait for the client to close
-    EXPECT_TRUE_WAIT(server_ssl_->GetState() == talk_base::SS_CLOSED, 10000);
-
-    // Now check the data
-    recv_stream_.GetSize(&received);
-    EXPECT_EQ(static_cast<size_t>(size), received);
-    EXPECT_EQ(0, memcmp(send_stream_.GetBuffer(),
-                        recv_stream_.GetBuffer(), size));
-  }
-
-  void WriteData() {
-    size_t position, tosend, size;
-    talk_base::StreamResult rv;
-    size_t sent;
-    char block[kBlockSize];
-
-    send_stream_.GetSize(&size);
-    if (!size)
-      return;
-
-    for (;;) {
-      send_stream_.GetPosition(&position);
-      if (send_stream_.Read(block, sizeof(block), &tosend, NULL) !=
-          talk_base::SR_EOS) {
-        rv = client_ssl_->Write(block, tosend, &sent, 0);
-
-        if (rv == talk_base::SR_SUCCESS) {
-          send_stream_.SetPosition(position + sent);
-          LOG(LS_VERBOSE) << "Sent: " << position + sent;
-        } else if (rv == talk_base::SR_BLOCK) {
-          LOG(LS_VERBOSE) << "Blocked...";
-          send_stream_.SetPosition(position);
-          break;
-        } else {
-          ADD_FAILURE();
-          break;
-        }
-      } else {
-        // Now close
-        LOG(LS_INFO) << "Wrote " << position << " bytes. Closing";
-        client_ssl_->Close();
-        break;
-      }
-    }
-  };
-
-  virtual void ReadData(talk_base::StreamInterface *stream) {
-    char buffer[1600];
-    size_t bread;
-    int err2;
-    talk_base::StreamResult r;
-
-    for (;;) {
-      r = stream->Read(buffer, sizeof(buffer), &bread, &err2);
-
-      if (r == talk_base::SR_ERROR) {
-        // Unfortunately, errors are the way that the stream adapter
-        // signals close right now
-        stream->Close();
-        return;
-      }
-
-      if (r == talk_base::SR_BLOCK)
-        break;
-
-      ASSERT_EQ(talk_base::SR_SUCCESS, r);
-      LOG(LS_INFO) << "Read " << bread;
-
-      recv_stream_.Write(buffer, bread, NULL, NULL);
-    }
-  }
-
- private:
-  talk_base::MemoryStream send_stream_;
-  talk_base::MemoryStream recv_stream_;
-};
-
-
-class SSLStreamAdapterTestDTLS : public SSLStreamAdapterTestBase {
- public:
-  SSLStreamAdapterTestDTLS() :
-      SSLStreamAdapterTestBase(true),
-      packet_size_(1000), count_(0), sent_(0) {
-  }
-
-  virtual void WriteData() {
-    unsigned char *packet = new unsigned char[1600];
-
-    do {
-      memset(packet, sent_ & 0xff, sizeof(packet));
-      *(reinterpret_cast<uint32_t *>(packet)) = sent_;
-
-      size_t sent;
-      int rv = client_ssl_->Write(packet, packet_size_, &sent, 0);
-      if (rv == talk_base::SR_SUCCESS) {
-        LOG(LS_VERBOSE) << "Sent: " << sent_;
-        sent_++;
-      } else if (rv == talk_base::SR_BLOCK) {
-        LOG(LS_VERBOSE) << "Blocked...";
-        break;
-      } else {
-        ADD_FAILURE();
-        break;
-      }
-    } while (sent_ < count_);
-
-    delete [] packet;
-  }
-
-  virtual void ReadData(talk_base::StreamInterface *stream) {
-    unsigned char *buffer = new unsigned char[1600];
-    size_t bread;
-    int err2;
-    talk_base::StreamResult r;
-
-    for (;;) {
-      r = stream->Read(buffer, sizeof(buffer),
-                       &bread, &err2);
-
-      if (r == talk_base::SR_ERROR) {
-        // Unfortunately, errors are the way that the stream adapter
-        // signals close right now
-        stream->Close();
-        return;
-      }
-
-      if (r == talk_base::SR_BLOCK)
-        break;
-
-      ASSERT_EQ(talk_base::SR_SUCCESS, r);
-      LOG(LS_INFO) << "Read " << bread;
-
-      // Now parse the datagram
-      ASSERT_EQ(packet_size_, bread);
-      uint32_t packet_num = *(reinterpret_cast<uint32_t *>(buffer));
-
-      for (size_t i = 4; i < packet_size_; i++) {
-        ASSERT_EQ((packet_num & 0xff), buffer[i]);
-      }
-      received_.insert(packet_num);
-    }
-  }
-
-  virtual void TestTransfer(int count) {
-    count_ = count;
-
-    WriteData();
-
-    EXPECT_TRUE_WAIT(sent_ == count_, 10000);
-    LOG(LS_INFO) << "sent_ == " << sent_;
-
-    if (loss_ == 0) {
-      EXPECT_TRUE_WAIT(static_cast<size_t>(sent_) == received_.size(), 1000);
-    } else {
-      LOG(LS_INFO) << "Sent " << sent_ << " packets; received " <<
-          received_.size();
-    }
-  };
-
- private:
-  size_t packet_size_;
-  int count_;
-  int sent_;
-  std::set<int> received_;
-};
-
-
-talk_base::StreamResult SSLDummyStream::Write(const void* data, size_t data_len,
-                                              size_t* written, int* error) {
-  *written = data_len;
-
-  LOG(LS_INFO) << "Writing to loopback " << data_len;
-
-  if (first_packet_) {
-    first_packet_ = false;
-    if (test_->GetLoseFirstPacket()) {
-      LOG(LS_INFO) << "Losing initial packet of length " << data_len;
-      return talk_base::SR_SUCCESS;
-    }
-  }
-
-  return test_->DataWritten(this, data, data_len, written, error);
-
-  return talk_base::SR_SUCCESS;
-};
-
-
-// Basic tests: TLS
-// Test that we can make a handshake work
-TEST_F(SSLStreamAdapterTestTLS, TestTLSConnect) {
-  TestHandshake();
-};
-
-// Test transfer -- trivial
-TEST_F(SSLStreamAdapterTestTLS, TestTLSTransfer) {
-  TestHandshake();
-  TestTransfer(100000);
-};
-
-// Test a handshake with a bogus peer digest
-TEST_F(SSLStreamAdapterTestTLS, TestTLSBogusDigest) {
-  SetPeerIdentitiesByDigest(false);
-  TestHandshake(false);
-};
-
-// Test a handshake with a peer certificate
-TEST_F(SSLStreamAdapterTestTLS, TestTLSPeerCertificate) {
-  SetPeerIdentitiesByCertificate(true);
-  TestHandshake();
-};
-
-// Test a handshake with a bogus peer certificate
-TEST_F(SSLStreamAdapterTestTLS, TestTLSBogusPeerCertificate) {
-  SetPeerIdentitiesByCertificate(false);
-  TestHandshake(false);
-};
-// Test moving a bunch of data
-
-// Basic tests: DTLS
-// Test that we can make a handshake work
-TEST_F(SSLStreamAdapterTestDTLS, DISABLED_TestDTLSConnect) {
-  TestHandshake();
-};
-
-// Test that we can make a handshake work if the first packet in
-// each direction is lost. This gives us predictable loss
-// rather than having to tune random
-TEST_F(SSLStreamAdapterTestDTLS, DISABLED_TestDTLSConnectWithLostFirstPacket) {
-  SetLoseFirstPacket(true);
-  TestHandshake();
-};
-
-// Test a handshake with loss and delay
-TEST_F(SSLStreamAdapterTestDTLS,
-       DISABLED_TestDTLSConnectWithLostFirstPacketDelay2s) {
-  SetLoseFirstPacket(true);
-  SetDelay(2000);
-  SetHandshakeWait(20000);
-  TestHandshake();
-};
-
-// Test a handshake with small MTU
-TEST_F(SSLStreamAdapterTestDTLS, TestDTLSConnectWithSmallMtu) {
-  SetMtu(700);
-  TestHandshake();
-};
-
-// Test transfer -- trivial
-TEST_F(SSLStreamAdapterTestDTLS, DISABLED_TestDTLSTransfer) {
-  TestHandshake();
-  TestTransfer(100);
-};
-
-TEST_F(SSLStreamAdapterTestDTLS, DISABLED_TestDTLSTransferWithLoss) {
-  TestHandshake();
-  SetLoss(10);
-  TestTransfer(100);
-};
-
diff --git a/third_party/libjingle/source/talk/base/stream.cc b/third_party/libjingle/source/talk/base/stream.cc
deleted file mode 100644
index d283e9d..0000000
--- a/third_party/libjingle/source/talk/base/stream.cc
+++ /dev/null
@@ -1,1167 +0,0 @@
-/*
- * libjingle
- * Copyright 2004 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#if defined(POSIX)
-#include <sys/file.h>
-#endif  // POSIX
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <string>
-#include "talk/base/basictypes.h"
-#include "talk/base/common.h"
-#include "talk/base/messagequeue.h"
-#include "talk/base/stream.h"
-#include "talk/base/stringencode.h"
-#include "talk/base/stringutils.h"
-#include "talk/base/thread.h"
-
-#ifdef WIN32
-#include "talk/base/win32.h"
-#define fileno _fileno
-#endif
-
-namespace talk_base {
-
-///////////////////////////////////////////////////////////////////////////////
-// StreamInterface
-///////////////////////////////////////////////////////////////////////////////
-StreamInterface::~StreamInterface() {
-}
-
-struct PostEventData : public MessageData {
-  int events, error;
-  PostEventData(int ev, int er) : events(ev), error(er) { }
-};
-
-StreamResult StreamInterface::WriteAll(const void* data, size_t data_len,
-                                       size_t* written, int* error) {
-  StreamResult result = SR_SUCCESS;
-  size_t total_written = 0, current_written;
-  while (total_written < data_len) {
-    result = Write(static_cast<const char*>(data) + total_written,
-                   data_len - total_written, &current_written, error);
-    if (result != SR_SUCCESS)
-      break;
-    total_written += current_written;
-  }
-  if (written)
-    *written = total_written;
-  return result;
-}
-
-StreamResult StreamInterface::ReadAll(void* buffer, size_t buffer_len,
-                                      size_t* read, int* error) {
-  StreamResult result = SR_SUCCESS;
-  size_t total_read = 0, current_read;
-  while (total_read < buffer_len) {
-    result = Read(static_cast<char*>(buffer) + total_read,
-                  buffer_len - total_read, &current_read, error);
-    if (result != SR_SUCCESS)
-      break;
-    total_read += current_read;
-  }
-  if (read)
-    *read = total_read;
-  return result;
-}
-
-StreamResult StreamInterface::ReadLine(std::string* line) {
-  line->clear();
-  StreamResult result = SR_SUCCESS;
-  while (true) {
-    char ch;
-    result = Read(&ch, sizeof(ch), NULL, NULL);
-    if (result != SR_SUCCESS) {
-      break;
-    }
-    if (ch == '\n') {
-      break;
-    }
-    line->push_back(ch);
-  }
-  if (!line->empty()) {   // give back the line we've collected so far with
-    result = SR_SUCCESS;  // a success code.  Otherwise return the last code
-  }
-  return result;
-}
-
-void StreamInterface::PostEvent(Thread* t, int events, int err) {
-  t->Post(this, MSG_POST_EVENT, new PostEventData(events, err));
-}
-
-void StreamInterface::PostEvent(int events, int err) {
-  PostEvent(Thread::Current(), events, err);
-}
-
-StreamInterface::StreamInterface() {
-}
-
-void StreamInterface::OnMessage(Message* msg) {
-  if (MSG_POST_EVENT == msg->message_id) {
-    PostEventData* pe = static_cast<PostEventData*>(msg->pdata);
-    SignalEvent(this, pe->events, pe->error);
-    delete msg->pdata;
-  }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// StreamAdapterInterface
-///////////////////////////////////////////////////////////////////////////////
-
-StreamAdapterInterface::StreamAdapterInterface(StreamInterface* stream,
-                                               bool owned)
-    : stream_(stream), owned_(owned) {
-  if (NULL != stream_)
-    stream_->SignalEvent.connect(this, &StreamAdapterInterface::OnEvent);
-}
-
-void StreamAdapterInterface::Attach(StreamInterface* stream, bool owned) {
-  if (NULL != stream_)
-    stream_->SignalEvent.disconnect(this);
-  if (owned_)
-    delete stream_;
-  stream_ = stream;
-  owned_ = owned;
-  if (NULL != stream_)
-    stream_->SignalEvent.connect(this, &StreamAdapterInterface::OnEvent);
-}
-
-StreamInterface* StreamAdapterInterface::Detach() {
-  if (NULL != stream_)
-    stream_->SignalEvent.disconnect(this);
-  StreamInterface* stream = stream_;
-  stream_ = NULL;
-  return stream;
-}
-
-StreamAdapterInterface::~StreamAdapterInterface() {
-  if (owned_)
-    delete stream_;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// StreamTap
-///////////////////////////////////////////////////////////////////////////////
-
-StreamTap::StreamTap(StreamInterface* stream, StreamInterface* tap)
-: StreamAdapterInterface(stream), tap_(NULL), tap_result_(SR_SUCCESS),
-  tap_error_(0)
-{
-  AttachTap(tap);
-}
-
-void StreamTap::AttachTap(StreamInterface* tap) {
-  tap_.reset(tap);
-}
-
-StreamInterface* StreamTap::DetachTap() {
-  return tap_.release();
-}
-
-StreamResult StreamTap::GetTapResult(int* error) {
-  if (error) {
-    *error = tap_error_;
-  }
-  return tap_result_;
-}
-
-StreamResult StreamTap::Read(void* buffer, size_t buffer_len,
-                             size_t* read, int* error) {
-  size_t backup_read;
-  if (!read) {
-    read = &backup_read;
-  }
-  StreamResult res = StreamAdapterInterface::Read(buffer, buffer_len,
-                                                  read, error);
-  if ((res == SR_SUCCESS) && (tap_result_ == SR_SUCCESS)) {
-    tap_result_ = tap_->WriteAll(buffer, *read, NULL, &tap_error_);
-  }
-  return res;
-}
-
-StreamResult StreamTap::Write(const void* data, size_t data_len,
-                              size_t* written, int* error) {
-  size_t backup_written;
-  if (!written) {
-    written = &backup_written;
-  }
-  StreamResult res = StreamAdapterInterface::Write(data, data_len,
-                                                   written, error);
-  if ((res == SR_SUCCESS) && (tap_result_ == SR_SUCCESS)) {
-    tap_result_ = tap_->WriteAll(data, *written, NULL, &tap_error_);
-  }
-  return res;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// StreamSegment
-///////////////////////////////////////////////////////////////////////////////
-
-StreamSegment::StreamSegment(StreamInterface* stream)
-: StreamAdapterInterface(stream), start_(SIZE_UNKNOWN), pos_(0),
-  length_(SIZE_UNKNOWN)
-{
-  // It's ok for this to fail, in which case start_ is left as SIZE_UNKNOWN.
-  stream->GetPosition(&start_);
-}
-
-StreamSegment::StreamSegment(StreamInterface* stream, size_t length)
-: StreamAdapterInterface(stream), start_(SIZE_UNKNOWN), pos_(0),
-  length_(length)
-{
-  // It's ok for this to fail, in which case start_ is left as SIZE_UNKNOWN.
-  stream->GetPosition(&start_);
-}
-
-StreamResult StreamSegment::Read(void* buffer, size_t buffer_len,
-                                 size_t* read, int* error)
-{
-  if (SIZE_UNKNOWN != length_) {
-    if (pos_ >= length_)
-      return SR_EOS;
-    buffer_len = _min(buffer_len, length_ - pos_);
-  }
-  size_t backup_read;
-  if (!read) {
-    read = &backup_read;
-  }
-  StreamResult result = StreamAdapterInterface::Read(buffer, buffer_len,
-                                                     read, error);
-  if (SR_SUCCESS == result) {
-    pos_ += *read;
-  }
-  return result;
-}
-
-bool StreamSegment::SetPosition(size_t position) {
-  if (SIZE_UNKNOWN == start_)
-    return false;  // Not seekable
-  if ((SIZE_UNKNOWN != length_) && (position > length_))
-    return false;  // Seek past end of segment
-  if (!StreamAdapterInterface::SetPosition(start_ + position))
-    return false;
-  pos_ = position;
-  return true;
-}
-
-bool StreamSegment::GetPosition(size_t* position) const {
-  if (SIZE_UNKNOWN == start_)
-    return false;  // Not seekable
-  if (!StreamAdapterInterface::GetPosition(position))
-    return false;
-  if (position) {
-    ASSERT(*position >= start_);
-    *position -= start_;
-  }
-  return true;
-}
-
-bool StreamSegment::GetSize(size_t* size) const {
-  if (!StreamAdapterInterface::GetSize(size))
-    return false;
-  if (size) {
-    if (SIZE_UNKNOWN != start_) {
-      ASSERT(*size >= start_);
-      *size -= start_;
-    }
-    if (SIZE_UNKNOWN != length_) {
-      *size = _min(*size, length_);
-    }
-  }
-  return true;
-}
-
-bool StreamSegment::GetAvailable(size_t* size) const {
-  if (!StreamAdapterInterface::GetAvailable(size))
-    return false;
-  if (size && (SIZE_UNKNOWN != length_))
-    *size = _min(*size, length_ - pos_);
-  return true;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// NullStream
-///////////////////////////////////////////////////////////////////////////////
-
-NullStream::NullStream() {
-}
-
-NullStream::~NullStream() {
-}
-
-StreamState NullStream::GetState() const {
-  return SS_OPEN;
-}
-
-StreamResult NullStream::Read(void* buffer, size_t buffer_len,
-                              size_t* read, int* error) {
-  if (error) *error = -1;
-  return SR_ERROR;
-}
-
-StreamResult NullStream::Write(const void* data, size_t data_len,
-                               size_t* written, int* error) {
-  if (written) *written = data_len;
-  return SR_SUCCESS;
-}
-
-void NullStream::Close() {
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// FileStream
-///////////////////////////////////////////////////////////////////////////////
-
-FileStream::FileStream() : file_(NULL) {
-}
-
-FileStream::~FileStream() {
-  FileStream::Close();
-}
-
-bool FileStream::Open(const std::string& filename, const char* mode,
-                      int* error) {
-  Close();
-#ifdef WIN32
-  std::wstring wfilename;
-  if (Utf8ToWindowsFilename(filename, &wfilename)) {
-    file_ = _wfopen(wfilename.c_str(), ToUtf16(mode).c_str());
-  } else {
-    if (error) {
-      *error = -1;
-      return false;
-    }
-  }
-#else
-  file_ = fopen(filename.c_str(), mode);
-#endif
-  if (!file_ && error) {
-    *error = errno;
-  }
-  return (file_ != NULL);
-}
-
-bool FileStream::OpenShare(const std::string& filename, const char* mode,
-                           int shflag, int* error) {
-  Close();
-#ifdef WIN32
-  std::wstring wfilename;
-  if (Utf8ToWindowsFilename(filename, &wfilename)) {
-    file_ = _wfsopen(wfilename.c_str(), ToUtf16(mode).c_str(), shflag);
-    if (!file_ && error) {
-      *error = errno;
-      return false;
-    }
-    return file_ != NULL;
-  } else {
-    if (error) {
-      *error = -1;
-    }
-    return false;
-  }
-#else
-  return Open(filename, mode, error);
-#endif
-}
-
-bool FileStream::DisableBuffering() {
-  if (!file_)
-    return false;
-  return (setvbuf(file_, NULL, _IONBF, 0) == 0);
-}
-
-StreamState FileStream::GetState() const {
-  return (file_ == NULL) ? SS_CLOSED : SS_OPEN;
-}
-
-StreamResult FileStream::Read(void* buffer, size_t buffer_len,
-                              size_t* read, int* error) {
-  if (!file_)
-    return SR_EOS;
-  size_t result = fread(buffer, 1, buffer_len, file_);
-  if ((result == 0) && (buffer_len > 0)) {
-    if (feof(file_))
-      return SR_EOS;
-    if (error)
-      *error = errno;
-    return SR_ERROR;
-  }
-  if (read)
-    *read = result;
-  return SR_SUCCESS;
-}
-
-StreamResult FileStream::Write(const void* data, size_t data_len,
-                               size_t* written, int* error) {
-  if (!file_)
-    return SR_EOS;
-  size_t result = fwrite(data, 1, data_len, file_);
-  if ((result == 0) && (data_len > 0)) {
-    if (error)
-      *error = errno;
-    return SR_ERROR;
-  }
-  if (written)
-    *written = result;
-  return SR_SUCCESS;
-}
-
-void FileStream::Close() {
-  if (file_) {
-    DoClose();
-    file_ = NULL;
-  }
-}
-
-bool FileStream::SetPosition(size_t position) {
-  if (!file_)
-    return false;
-  return (fseek(file_, position, SEEK_SET) == 0);
-}
-
-bool FileStream::GetPosition(size_t* position) const {
-  ASSERT(NULL != position);
-  if (!file_)
-    return false;
-  long result = ftell(file_);
-  if (result < 0)
-    return false;
-  if (position)
-    *position = result;
-  return true;
-}
-
-bool FileStream::GetSize(size_t* size) const {
-  ASSERT(NULL != size);
-  if (!file_)
-    return false;
-  struct stat file_stats;
-  if (fstat(fileno(file_), &file_stats) != 0)
-    return false;
-  if (size)
-    *size = file_stats.st_size;
-  return true;
-}
-
-bool FileStream::GetAvailable(size_t* size) const {
-  ASSERT(NULL != size);
-  if (!GetSize(size))
-    return false;
-  long result = ftell(file_);
-  if (result < 0)
-    return false;
-  if (size)
-    *size -= result;
-  return true;
-}
-
-bool FileStream::ReserveSize(size_t size) {
-  // TODO: extend the file to the proper length
-  return true;
-}
-
-bool FileStream::GetSize(const std::string& filename, size_t* size) {
-  struct stat file_stats;
-  if (stat(filename.c_str(), &file_stats) != 0)
-    return false;
-  *size = file_stats.st_size;
-  return true;
-}
-
-bool FileStream::Flush() {
-  if (file_) {
-    return (0 == fflush(file_));
-  }
-  // try to flush empty file?
-  ASSERT(false);
-  return false;
-}
-
-#if defined(POSIX)
-
-bool FileStream::TryLock() {
-  if (file_ == NULL) {
-    // Stream not open.
-    ASSERT(false);
-    return false;
-  }
-
-  return flock(fileno(file_), LOCK_EX|LOCK_NB) == 0;
-}
-
-bool FileStream::Unlock() {
-  if (file_ == NULL) {
-    // Stream not open.
-    ASSERT(false);
-    return false;
-  }
-
-  return flock(fileno(file_), LOCK_UN) == 0;
-}
-
-#endif
-
-void FileStream::DoClose() {
-  fclose(file_);
-}
-
-#ifdef POSIX
-
-// Have to identically rewrite the FileStream destructor or else it would call
-// the base class's Close() instead of the sub-class's.
-POpenStream::~POpenStream() {
-  POpenStream::Close();
-}
-
-bool POpenStream::Open(const std::string& subcommand,
-                       const char* mode,
-                       int *error) {
-  Close();
-  file_ = popen(subcommand.c_str(), mode);
-  if (file_ == NULL) {
-    if (error)
-      *error = errno;
-    return false;
-  }
-  return true;
-}
-
-bool POpenStream::OpenShare(const std::string& subcommand, const char* mode,
-                            int shflag, int* error) {
-  return Open(subcommand, mode, error);
-}
-
-void POpenStream::DoClose() {
-  wait_status_ = pclose(file_);
-}
-
-#endif
-
-///////////////////////////////////////////////////////////////////////////////
-// MemoryStream
-///////////////////////////////////////////////////////////////////////////////
-
-MemoryStreamBase::MemoryStreamBase()
-  : buffer_(NULL), buffer_length_(0), data_length_(0),
-    seek_position_(0) {
-}
-
-StreamState MemoryStreamBase::GetState() const {
-  return SS_OPEN;
-}
-
-StreamResult MemoryStreamBase::Read(void* buffer, size_t bytes,
-                                    size_t* bytes_read, int* error) {
-  if (seek_position_ >= data_length_) {
-    return SR_EOS;
-  }
-  size_t available = data_length_ - seek_position_;
-  if (bytes > available) {
-    // Read partial buffer
-    bytes = available;
-  }
-  memcpy(buffer, &buffer_[seek_position_], bytes);
-  seek_position_ += bytes;
-  if (bytes_read) {
-    *bytes_read = bytes;
-  }
-  return SR_SUCCESS;
-}
-
-StreamResult MemoryStreamBase::Write(const void* buffer, size_t bytes,
-                                     size_t* bytes_written, int* error) {
-  size_t available = buffer_length_ - seek_position_;
-  if (0 == available) {
-    // Increase buffer size to the larger of:
-    // a) new position rounded up to next 256 bytes
-    // b) double the previous length
-    size_t new_buffer_length = _max(((seek_position_ + bytes) | 0xFF) + 1,
-                                    buffer_length_ * 2);
-    StreamResult result = DoReserve(new_buffer_length, error);
-    if (SR_SUCCESS != result) {
-      return result;
-    }
-    ASSERT(buffer_length_ >= new_buffer_length);
-    available = buffer_length_ - seek_position_;
-  }
-
-  if (bytes > available) {
-    bytes = available;
-  }
-  memcpy(&buffer_[seek_position_], buffer, bytes);
-  seek_position_ += bytes;
-  if (data_length_ < seek_position_) {
-    data_length_ = seek_position_;
-  }
-  if (bytes_written) {
-    *bytes_written = bytes;
-  }
-  return SR_SUCCESS;
-}
-
-void MemoryStreamBase::Close() {
-  // nothing to do
-}
-
-bool MemoryStreamBase::SetPosition(size_t position) {
-  if (position > data_length_)
-    return false;
-  seek_position_ = position;
-  return true;
-}
-
-bool MemoryStreamBase::GetPosition(size_t *position) const {
-  if (position)
-    *position = seek_position_;
-  return true;
-}
-
-bool MemoryStreamBase::GetSize(size_t *size) const {
-  if (size)
-    *size = data_length_;
-  return true;
-}
-
-bool MemoryStreamBase::GetAvailable(size_t *size) const {
-  if (size)
-    *size = data_length_ - seek_position_;
-  return true;
-}
-
-bool MemoryStreamBase::ReserveSize(size_t size) {
-  return (SR_SUCCESS == DoReserve(size, NULL));
-}
-
-StreamResult MemoryStreamBase::DoReserve(size_t size, int* error) {
-  return (buffer_length_ >= size) ? SR_SUCCESS : SR_EOS;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-MemoryStream::MemoryStream()
-  : buffer_alloc_(NULL) {
-}
-
-MemoryStream::MemoryStream(const char* data)
-  : buffer_alloc_(NULL) {
-  SetData(data, strlen(data));
-}
-
-MemoryStream::MemoryStream(const void* data, size_t length)
-  : buffer_alloc_(NULL) {
-  SetData(data, length);
-}
-
-MemoryStream::~MemoryStream() {
-  delete [] buffer_alloc_;
-}
-
-void MemoryStream::SetData(const void* data, size_t length) {
-  data_length_ = buffer_length_ = length;
-  delete [] buffer_alloc_;
-  buffer_alloc_ = new char[buffer_length_ + kAlignment];
-  buffer_ = reinterpret_cast<char*>(ALIGNP(buffer_alloc_, kAlignment));
-  memcpy(buffer_, data, data_length_);
-  seek_position_ = 0;
-}
-
-StreamResult MemoryStream::DoReserve(size_t size, int* error) {
-  if (buffer_length_ >= size)
-    return SR_SUCCESS;
-
-  if (char* new_buffer_alloc = new char[size + kAlignment]) {
-    char* new_buffer = reinterpret_cast<char*>(
-        ALIGNP(new_buffer_alloc, kAlignment));
-    memcpy(new_buffer, buffer_, data_length_);
-    delete [] buffer_alloc_;
-    buffer_alloc_ = new_buffer_alloc;
-    buffer_ = new_buffer;
-    buffer_length_ = size;
-    return SR_SUCCESS;
-  }
-
-  if (error) {
-    *error = ENOMEM;
-  }
-  return SR_ERROR;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-ExternalMemoryStream::ExternalMemoryStream() {
-}
-
-ExternalMemoryStream::ExternalMemoryStream(void* data, size_t length) {
-  SetData(data, length);
-}
-
-ExternalMemoryStream::~ExternalMemoryStream() {
-}
-
-void ExternalMemoryStream::SetData(void* data, size_t length) {
-  data_length_ = buffer_length_ = length;
-  buffer_ = static_cast<char*>(data);
-  seek_position_ = 0;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// FifoBuffer
-///////////////////////////////////////////////////////////////////////////////
-
-FifoBuffer::FifoBuffer(size_t size)
-    : state_(SS_OPEN), buffer_(new char[size]), buffer_length_(size),
-      data_length_(0), read_position_(0), owner_(Thread::Current()) {
-  // all events are done on the owner_ thread
-}
-
-FifoBuffer::~FifoBuffer() {
-}
-
-bool FifoBuffer::GetBuffered(size_t* size) const {
-  CritScope cs(&crit_);
-  *size = data_length_;
-  return true;
-}
-
-bool FifoBuffer::SetCapacity(size_t size) {
-  CritScope cs(&crit_);
-  if (data_length_ > size) {
-    return false;
-  }
-
-  if (size != buffer_length_) {
-    char* buffer = new char[size];
-    const size_t copy = data_length_;
-    const size_t tail_copy = _min(copy, buffer_length_ - read_position_);
-    memcpy(buffer, &buffer_[read_position_], tail_copy);
-    memcpy(buffer + tail_copy, &buffer_[0], copy - tail_copy);
-    buffer_.reset(buffer);
-    read_position_ = 0;
-    buffer_length_ = size;
-  }
-  return true;
-}
-
-StreamResult FifoBuffer::ReadOffset(void* buffer, size_t bytes,
-                                    size_t offset, size_t* bytes_read) {
-  CritScope cs(&crit_);
-  return ReadOffsetLocked(buffer, bytes, offset, bytes_read);
-}
-
-StreamResult FifoBuffer::WriteOffset(const void* buffer, size_t bytes,
-                                     size_t offset, size_t* bytes_written) {
-  CritScope cs(&crit_);
-  return WriteOffsetLocked(buffer, bytes, offset, bytes_written);
-}
-
-StreamState FifoBuffer::GetState() const {
-  return state_;
-}
-
-StreamResult FifoBuffer::Read(void* buffer, size_t bytes,
-                              size_t* bytes_read, int* error) {
-  CritScope cs(&crit_);
-  const bool was_writable = data_length_ < buffer_length_;
-  size_t copy = 0;
-  StreamResult result = ReadOffsetLocked(buffer, bytes, 0, &copy);
-
-  if (result == SR_SUCCESS) {
-    // If read was successful then adjust the read position and number of
-    // bytes buffered.
-    read_position_ = (read_position_ + copy) % buffer_length_;
-    data_length_ -= copy;
-    if (bytes_read) {
-      *bytes_read = copy;
-    }
-
-    // if we were full before, and now we're not, post an event
-    if (!was_writable && copy > 0) {
-      PostEvent(owner_, SE_WRITE, 0);
-    }
-  }
-  return result;
-}
-
-StreamResult FifoBuffer::Write(const void* buffer, size_t bytes,
-                               size_t* bytes_written, int* error) {
-  CritScope cs(&crit_);
-
-  const bool was_readable = (data_length_ > 0);
-  size_t copy = 0;
-  StreamResult result = WriteOffsetLocked(buffer, bytes, 0, &copy);
-
-  if (result == SR_SUCCESS) {
-    // If write was successful then adjust the number of readable bytes.
-    data_length_ += copy;
-    if (bytes_written) {
-      *bytes_written = copy;
-    }
-
-    // if we didn't have any data to read before, and now we do, post an event
-    if (!was_readable && copy > 0) {
-      PostEvent(owner_, SE_READ, 0);
-    }
-  }
-  return result;
-}
-
-void FifoBuffer::Close() {
-  CritScope cs(&crit_);
-  state_ = SS_CLOSED;
-}
-
-const void* FifoBuffer::GetReadData(size_t* size) {
-  CritScope cs(&crit_);
-  *size = (read_position_ + data_length_ <= buffer_length_) ?
-      data_length_ : buffer_length_ - read_position_;
-  return &buffer_[read_position_];
-}
-
-void FifoBuffer::ConsumeReadData(size_t size) {
-  CritScope cs(&crit_);
-  ASSERT(size <= data_length_);
-  const bool was_writable = data_length_ < buffer_length_;
-  read_position_ = (read_position_ + size) % buffer_length_;
-  data_length_ -= size;
-  if (!was_writable && size > 0) {
-    PostEvent(owner_, SE_WRITE, 0);
-  }
-}
-
-void* FifoBuffer::GetWriteBuffer(size_t* size) {
-  CritScope cs(&crit_);
-  if (state_ == SS_CLOSED) {
-    return NULL;
-  }
-
-  // if empty, reset the write position to the beginning, so we can get
-  // the biggest possible block
-  if (data_length_ == 0) {
-    read_position_ = 0;
-  }
-
-  const size_t write_position = (read_position_ + data_length_)
-      % buffer_length_;
-  *size = (write_position >= read_position_) ?
-      buffer_length_ - write_position : read_position_ - write_position;
-  return &buffer_[write_position];
-}
-
-void FifoBuffer::ConsumeWriteBuffer(size_t size) {
-  CritScope cs(&crit_);
-  ASSERT(size <= buffer_length_ - data_length_);
-  const bool was_readable = (data_length_ > 0);
-  data_length_ += size;
-  if (!was_readable && size > 0) {
-    PostEvent(owner_, SE_READ, 0);
-  }
-}
-
-bool FifoBuffer::GetWriteRemaining(size_t* size) const {
-  CritScope cs(&crit_);
-  *size = buffer_length_ - data_length_;
-  return true;
-}
-
-StreamResult FifoBuffer::ReadOffsetLocked(void* buffer,
-                                          size_t bytes,
-                                          size_t offset,
-                                          size_t* bytes_read) {
-  if (offset >= data_length_) {
-    return (state_ != SS_CLOSED) ? SR_BLOCK : SR_EOS;
-  }
-
-  const size_t available = data_length_ - offset;
-  const size_t read_position = (read_position_ + offset) % buffer_length_;
-  const size_t copy = _min(bytes, available);
-  const size_t tail_copy = _min(copy, buffer_length_ - read_position);
-  char* const p = static_cast<char*>(buffer);
-  memcpy(p, &buffer_[read_position], tail_copy);
-  memcpy(p + tail_copy, &buffer_[0], copy - tail_copy);
-
-  if (bytes_read) {
-    *bytes_read = copy;
-  }
-  return SR_SUCCESS;
-}
-
-StreamResult FifoBuffer::WriteOffsetLocked(const void* buffer,
-                                           size_t bytes,
-                                           size_t offset,
-                                           size_t* bytes_written) {
-  if (state_ == SS_CLOSED) {
-    return SR_EOS;
-  }
-
-  if (data_length_ + offset >= buffer_length_) {
-    return SR_BLOCK;
-  }
-
-  const size_t available = buffer_length_ - data_length_ - offset;
-  const size_t write_position = (read_position_ + data_length_ + offset)
-      % buffer_length_;
-  const size_t copy = _min(bytes, available);
-  const size_t tail_copy = _min(copy, buffer_length_ - write_position);
-  const char* const p = static_cast<const char*>(buffer);
-  memcpy(&buffer_[write_position], p, tail_copy);
-  memcpy(&buffer_[0], p + tail_copy, copy - tail_copy);
-
-  if (bytes_written) {
-    *bytes_written = copy;
-  }
-  return SR_SUCCESS;
-}
-
-
-
-///////////////////////////////////////////////////////////////////////////////
-// LoggingAdapter
-///////////////////////////////////////////////////////////////////////////////
-
-LoggingAdapter::LoggingAdapter(StreamInterface* stream, LoggingSeverity level,
-                               const std::string& label, bool hex_mode)
-: StreamAdapterInterface(stream), level_(level), hex_mode_(hex_mode)
-{
-  set_label(label);
-}
-
-void LoggingAdapter::set_label(const std::string& label) {
-  label_.assign("[");
-  label_.append(label);
-  label_.append("]");
-}
-
-StreamResult LoggingAdapter::Read(void* buffer, size_t buffer_len,
-                                  size_t* read, int* error) {
-  size_t local_read; if (!read) read = &local_read;
-  StreamResult result = StreamAdapterInterface::Read(buffer, buffer_len, read,
-                                                     error);
-  if (result == SR_SUCCESS) {
-    LogMultiline(level_, label_.c_str(), true, buffer, *read, hex_mode_, &lms_);
-  }
-  return result;
-}
-
-StreamResult LoggingAdapter::Write(const void* data, size_t data_len,
-                                   size_t* written, int* error) {
-  size_t local_written; if (!written) written = &local_written;
-  StreamResult result = StreamAdapterInterface::Write(data, data_len, written,
-                                                      error);
-  if (result == SR_SUCCESS) {
-    LogMultiline(level_, label_.c_str(), false, data, *written, hex_mode_,
-                 &lms_);
-  }
-  return result;
-}
-
-void LoggingAdapter::Close() {
-  LogMultiline(level_, label_.c_str(), false, NULL, 0, hex_mode_, &lms_);
-  LogMultiline(level_, label_.c_str(), true, NULL, 0, hex_mode_, &lms_);
-  LOG_V(level_) << label_ << " Closed locally";
-  StreamAdapterInterface::Close();
-}
-
-void LoggingAdapter::OnEvent(StreamInterface* stream, int events, int err) {
-  if (events & SE_OPEN) {
-    LOG_V(level_) << label_ << " Open";
-  } else if (events & SE_CLOSE) {
-    LogMultiline(level_, label_.c_str(), false, NULL, 0, hex_mode_, &lms_);
-    LogMultiline(level_, label_.c_str(), true, NULL, 0, hex_mode_, &lms_);
-    LOG_V(level_) << label_ << " Closed with error: " << err;
-  }
-  StreamAdapterInterface::OnEvent(stream, events, err);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// StringStream - Reads/Writes to an external std::string
-///////////////////////////////////////////////////////////////////////////////
-
-StringStream::StringStream(std::string& str)
-: str_(str), read_pos_(0), read_only_(false)
-{
-}
-
-StringStream::StringStream(const std::string& str)
-: str_(const_cast<std::string&>(str)), read_pos_(0), read_only_(true)
-{
-}
-
-StreamState StringStream::GetState() const {
-  return SS_OPEN;
-}
-
-StreamResult StringStream::Read(void* buffer, size_t buffer_len,
-                                      size_t* read, int* error) {
-  size_t available = _min(buffer_len, str_.size() - read_pos_);
-  if (!available)
-    return SR_EOS;
-  memcpy(buffer, str_.data() + read_pos_, available);
-  read_pos_ += available;
-  if (read)
-    *read = available;
-  return SR_SUCCESS;
-}
-
-StreamResult StringStream::Write(const void* data, size_t data_len,
-                                      size_t* written, int* error) {
-  if (read_only_) {
-    if (error) {
-      *error = -1;
-    }
-    return SR_ERROR;
-  }
-  str_.append(static_cast<const char*>(data),
-              static_cast<const char*>(data) + data_len);
-  if (written)
-    *written = data_len;
-  return SR_SUCCESS;
-}
-
-void StringStream::Close() {
-}
-
-bool StringStream::SetPosition(size_t position) {
-  if (position > str_.size())
-    return false;
-  read_pos_ = position;
-  return true;
-}
-
-bool StringStream::GetPosition(size_t* position) const {
-  if (position)
-    *position = read_pos_;
-  return true;
-}
-
-bool StringStream::GetSize(size_t* size) const {
-  if (size)
-    *size = str_.size();
-  return true;
-}
-
-bool StringStream::GetAvailable(size_t* size) const {
-  if (size)
-    *size = str_.size() - read_pos_;
-  return true;
-}
-
-bool StringStream::ReserveSize(size_t size) {
-  if (read_only_)
-    return false;
-  str_.reserve(size);
-  return true;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// StreamReference
-///////////////////////////////////////////////////////////////////////////////
-
-StreamReference::StreamReference(StreamInterface* stream)
-    : StreamAdapterInterface(stream, false) {
-  // owner set to false so the destructor does not free the stream.
-  stream_ref_count_ = new StreamRefCount(stream);
-}
-
-StreamInterface* StreamReference::NewReference() {
-  stream_ref_count_->AddReference();
-  return new StreamReference(stream_ref_count_, stream());
-}
-
-StreamReference::~StreamReference() {
-  stream_ref_count_->Release();
-}
-
-StreamReference::StreamReference(StreamRefCount* stream_ref_count,
-                                 StreamInterface* stream)
-    : StreamAdapterInterface(stream, false),
-      stream_ref_count_(stream_ref_count) {
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-StreamResult Flow(StreamInterface* source,
-                  char* buffer, size_t buffer_len,
-                  StreamInterface* sink,
-                  size_t* data_len /* = NULL */) {
-  ASSERT(buffer_len > 0);
-
-  StreamResult result;
-  size_t count, read_pos, write_pos;
-  if (data_len) {
-    read_pos = *data_len;
-  } else {
-    read_pos = 0;
-  }
-
-  bool end_of_stream = false;
-  do {
-    // Read until buffer is full, end of stream, or error
-    while (!end_of_stream && (read_pos < buffer_len)) {
-      result = source->Read(buffer + read_pos, buffer_len - read_pos,
-                            &count, NULL);
-      if (result == SR_EOS) {
-        end_of_stream = true;
-      } else if (result != SR_SUCCESS) {
-        if (data_len) {
-          *data_len = read_pos;
-        }
-        return result;
-      } else {
-        read_pos += count;
-      }
-    }
-
-    // Write until buffer is empty, or error (including end of stream)
-    write_pos = 0;
-    while (write_pos < read_pos) {
-      result = sink->Write(buffer + write_pos, read_pos - write_pos,
-                           &count, NULL);
-      if (result != SR_SUCCESS) {
-        if (data_len) {
-          *data_len = read_pos - write_pos;
-          if (write_pos > 0) {
-            memmove(buffer, buffer + write_pos, *data_len);
-          }
-        }
-        return result;
-      }
-      write_pos += count;
-    }
-
-    read_pos = 0;
-  } while (!end_of_stream);
-
-  if (data_len) {
-    *data_len = 0;
-  }
-  return SR_SUCCESS;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-} // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/stream.h b/third_party/libjingle/source/talk/base/stream.h
deleted file mode 100644
index 15a706c..0000000
--- a/third_party/libjingle/source/talk/base/stream.h
+++ /dev/null
@@ -1,750 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_STREAM_H__
-#define TALK_BASE_STREAM_H__
-
-#include "talk/base/basictypes.h"
-#include "talk/base/criticalsection.h"
-#include "talk/base/logging.h"
-#include "talk/base/messagehandler.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/base/sigslot.h"
-
-namespace talk_base {
-
-///////////////////////////////////////////////////////////////////////////////
-// StreamInterface is a generic asynchronous stream interface, supporting read,
-// write, and close operations, and asynchronous signalling of state changes.
-// The interface is designed with file, memory, and socket implementations in
-// mind.  Some implementations offer extended operations, such as seeking.
-///////////////////////////////////////////////////////////////////////////////
-
-// The following enumerations are declared outside of the StreamInterface
-// class for brevity in use.
-
-// The SS_OPENING state indicates that the stream will signal open or closed
-// in the future.
-enum StreamState { SS_CLOSED, SS_OPENING, SS_OPEN };
-
-// Stream read/write methods return this value to indicate various success
-// and failure conditions described below.
-enum StreamResult { SR_ERROR, SR_SUCCESS, SR_BLOCK, SR_EOS };
-
-// StreamEvents are used to asynchronously signal state transitionss.  The flags
-// may be combined.
-//  SE_OPEN: The stream has transitioned to the SS_OPEN state
-//  SE_CLOSE: The stream has transitioned to the SS_CLOSED state
-//  SE_READ: Data is available, so Read is likely to not return SR_BLOCK
-//  SE_WRITE: Data can be written, so Write is likely to not return SR_BLOCK
-enum StreamEvent { SE_OPEN = 1, SE_READ = 2, SE_WRITE = 4, SE_CLOSE = 8 };
-
-class Thread;
-
-class StreamInterface : public MessageHandler {
- public:
-  enum {
-    MSG_POST_EVENT = 0xF1F1, MSG_MAX = MSG_POST_EVENT
-  };
-
-  virtual ~StreamInterface();
-
-  virtual StreamState GetState() const = 0;
-
-  // Read attempts to fill buffer of size buffer_len.  Write attempts to send
-  // data_len bytes stored in data.  The variables read and write are set only
-  // on SR_SUCCESS (see below).  Likewise, error is only set on SR_ERROR.
-  // Read and Write return a value indicating:
-  //  SR_ERROR: an error occurred, which is returned in a non-null error
-  //    argument.  Interpretation of the error requires knowledge of the
-  //    stream's concrete type, which limits its usefulness.
-  //  SR_SUCCESS: some number of bytes were successfully written, which is
-  //    returned in a non-null read/write argument.
-  //  SR_BLOCK: the stream is in non-blocking mode, and the operation would
-  //    block, or the stream is in SS_OPENING state.
-  //  SR_EOS: the end-of-stream has been reached, or the stream is in the
-  //    SS_CLOSED state.
-  virtual StreamResult Read(void* buffer, size_t buffer_len,
-                            size_t* read, int* error) = 0;
-  virtual StreamResult Write(const void* data, size_t data_len,
-                             size_t* written, int* error) = 0;
-  // Attempt to transition to the SS_CLOSED state.  SE_CLOSE will not be
-  // signalled as a result of this call.
-  virtual void Close() = 0;
-
-  // Streams may signal one or more StreamEvents to indicate state changes.
-  // The first argument identifies the stream on which the state change occured.
-  // The second argument is a bit-wise combination of StreamEvents.
-  // If SE_CLOSE is signalled, then the third argument is the associated error
-  // code.  Otherwise, the value is undefined.
-  // Note: Not all streams will support asynchronous event signalling.  However,
-  // SS_OPENING and SR_BLOCK returned from stream member functions imply that
-  // certain events will be raised in the future.
-  sigslot::signal3<StreamInterface*, int, int> SignalEvent;
-
-  // Like calling SignalEvent, but posts a message to the specified thread,
-  // which will call SignalEvent.  This helps unroll the stack and prevent
-  // re-entrancy.
-  void PostEvent(Thread* t, int events, int err);
-  // Like the aforementioned method, but posts to the current thread.
-  void PostEvent(int events, int err);
-
-  //
-  // OPTIONAL OPERATIONS
-  //
-  // Not all implementations will support the following operations.  In general,
-  // a stream will only support an operation if it reasonably efficient to do
-  // so.  For example, while a socket could buffer incoming data to support
-  // seeking, it will not do so.  Instead, a buffering stream adapter should
-  // be used.
-  //
-  // Even though several of these operations are related, you should
-  // always use whichever operation is most relevant.  For example, you may
-  // be tempted to use GetSize() and GetPosition() to deduce the result of
-  // GetAvailable().  However, a stream which is read-once may support the
-  // latter operation but not the former.
-  //
-
-  // The following four methods are used to avoid coping data multiple times.
-
-  // GetReadData returns a pointer to a buffer which is owned by the stream.
-  // The buffer contains data_len bytes.  NULL is returned if no data is
-  // available, or if the method fails.  If the caller processes the data, it
-  // must call ConsumeReadData with the number of processed bytes.  GetReadData
-  // does not require a matching call to ConsumeReadData if the data is not
-  // processed.  Read and ConsumeReadData invalidate the buffer returned by
-  // GetReadData.
-  virtual const void* GetReadData(size_t* data_len) { return NULL; }
-  virtual void ConsumeReadData(size_t used) {}
-
-  // GetWriteBuffer returns a pointer to a buffer which is owned by the stream.
-  // The buffer has a capacity of buf_len bytes.  NULL is returned if there is
-  // no buffer available, or if the method fails.  The call may write data to
-  // the buffer, and then call ConsumeWriteBuffer with the number of bytes
-  // written.  GetWriteBuffer does not require a matching call to
-  // ConsumeWriteData if no data is written.  Write, ForceWrite, and
-  // ConsumeWriteData invalidate the buffer returned by GetWriteBuffer.
-  // TODO: Allow the caller to specify a minimum buffer size.  If the specified
-  // amount of buffer is not yet available, return NULL and Signal SE_WRITE
-  // when it is available.  If the requested amount is too large, return an
-  // error.
-  virtual void* GetWriteBuffer(size_t* buf_len) { return NULL; }
-  virtual void ConsumeWriteBuffer(size_t used) {}
-
-  // Write data_len bytes found in data, circumventing any throttling which
-  // would could cause SR_BLOCK to be returned.  Returns true if all the data
-  // was written.  Otherwise, the method is unsupported, or an unrecoverable
-  // error occurred, and the error value is set.  This method should be used
-  // sparingly to write critical data which should not be throttled.  A stream
-  // which cannot circumvent its blocking constraints should not implement this
-  // method.
-  // NOTE: This interface is being considered experimentally at the moment.  It
-  // would be used by JUDP and BandwidthStream as a way to circumvent certain
-  // soft limits in writing.
-  //virtual bool ForceWrite(const void* data, size_t data_len, int* error) {
-  //  if (error) *error = -1;
-  //  return false;
-  //}
-
-  // Seek to a byte offset from the beginning of the stream.  Returns false if
-  // the stream does not support seeking, or cannot seek to the specified
-  // position.
-  virtual bool SetPosition(size_t position) { return false; }
-
-  // Get the byte offset of the current position from the start of the stream.
-  // Returns false if the position is not known.
-  virtual bool GetPosition(size_t* position) const { return false; }
-
-  // Get the byte length of the entire stream.  Returns false if the length
-  // is not known.
-  virtual bool GetSize(size_t* size) const { return false; }
-
-  // Return the number of Read()-able bytes remaining before end-of-stream.
-  // Returns false if not known.
-  virtual bool GetAvailable(size_t* size) const { return false; }
-
-  // Return the number of Write()-able bytes remaining before end-of-stream.
-  // Returns false if not known.
-  virtual bool GetWriteRemaining(size_t* size) const { return false; }
-
-  // Communicates the amount of data which will be written to the stream.  The
-  // stream may choose to preallocate memory to accomodate this data.  The
-  // stream may return false to indicate that there is not enough room (ie,
-  // Write will return SR_EOS/SR_ERROR at some point).  Note that calling this
-  // function should not affect the existing state of data in the stream.
-  virtual bool ReserveSize(size_t size) { return true; }
-
-  //
-  // CONVENIENCE METHODS
-  //
-  // These methods are implemented in terms of other methods, for convenience.
-  //
-
-  // Seek to the start of the stream.
-  inline bool Rewind() { return SetPosition(0); }
-
-  // WriteAll is a helper function which repeatedly calls Write until all the
-  // data is written, or something other than SR_SUCCESS is returned.  Note that
-  // unlike Write, the argument 'written' is always set, and may be non-zero
-  // on results other than SR_SUCCESS.  The remaining arguments have the
-  // same semantics as Write.
-  StreamResult WriteAll(const void* data, size_t data_len,
-                        size_t* written, int* error);
-
-  // Similar to ReadAll.  Calls Read until buffer_len bytes have been read, or
-  // until a non-SR_SUCCESS result is returned.  'read' is always set.
-  StreamResult ReadAll(void* buffer, size_t buffer_len,
-                       size_t* read, int* error);
-
-  // ReadLine is a helper function which repeatedly calls Read until it hits
-  // the end-of-line character, or something other than SR_SUCCESS.
-  // TODO: this is too inefficient to keep here.  Break this out into a buffered
-  // readline object or adapter
-  StreamResult ReadLine(std::string *line);
-
- protected:
-  StreamInterface();
-
-  // MessageHandler Interface
-  virtual void OnMessage(Message* msg);
-
- private:
-  DISALLOW_EVIL_CONSTRUCTORS(StreamInterface);
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// StreamAdapterInterface is a convenient base-class for adapting a stream.
-// By default, all operations are pass-through.  Override the methods that you
-// require adaptation.  Streams should really be upgraded to reference-counted.
-// In the meantime, use the owned flag to indicate whether the adapter should
-// own the adapted stream.
-///////////////////////////////////////////////////////////////////////////////
-
-class StreamAdapterInterface : public StreamInterface,
-                               public sigslot::has_slots<> {
- public:
-  explicit StreamAdapterInterface(StreamInterface* stream, bool owned = true);
-
-  // Core Stream Interface
-  virtual StreamState GetState() const {
-    return stream_->GetState();
-  }
-  virtual StreamResult Read(void* buffer, size_t buffer_len,
-                            size_t* read, int* error) {
-    return stream_->Read(buffer, buffer_len, read, error);
-  }
-  virtual StreamResult Write(const void* data, size_t data_len,
-                             size_t* written, int* error) {
-    return stream_->Write(data, data_len, written, error);
-  }
-  virtual void Close() {
-    stream_->Close();
-  }
-
-  // Optional Stream Interface
-  /*  Note: Many stream adapters were implemented prior to this Read/Write
-      interface.  Therefore, a simple pass through of data in those cases may
-      be broken.  At a later time, we should do a once-over pass of all
-      adapters, and make them compliant with these interfaces, after which this
-      code can be uncommented.
-  virtual const void* GetReadData(size_t* data_len) {
-    return stream_->GetReadData(data_len);
-  }
-  virtual void ConsumeReadData(size_t used) {
-    stream_->ConsumeReadData(used);
-  }
-
-  virtual void* GetWriteBuffer(size_t* buf_len) {
-    return stream_->GetWriteBuffer(buf_len);
-  }
-  virtual void ConsumeWriteBuffer(size_t used) {
-    stream_->ConsumeWriteBuffer(used);
-  }
-  */
-
-  /*  Note: This interface is currently undergoing evaluation.
-  virtual bool ForceWrite(const void* data, size_t data_len, int* error) {
-    return stream_->ForceWrite(data, data_len, error);
-  }
-  */
-
-  virtual bool SetPosition(size_t position) {
-    return stream_->SetPosition(position);
-  }
-  virtual bool GetPosition(size_t* position) const {
-    return stream_->GetPosition(position);
-  }
-  virtual bool GetSize(size_t* size) const {
-    return stream_->GetSize(size);
-  }
-  virtual bool GetAvailable(size_t* size) const {
-    return stream_->GetAvailable(size);
-  }
-  virtual bool GetWriteRemaining(size_t* size) const {
-    return stream_->GetWriteRemaining(size);
-  }
-  virtual bool ReserveSize(size_t size) {
-    return stream_->ReserveSize(size);
-  }
-
-  void Attach(StreamInterface* stream, bool owned = true);
-  StreamInterface* Detach();
-
- protected:
-  virtual ~StreamAdapterInterface();
-
-  // Note that the adapter presents itself as the origin of the stream events,
-  // since users of the adapter may not recognize the adapted object.
-  virtual void OnEvent(StreamInterface* stream, int events, int err) {
-    SignalEvent(this, events, err);
-  }
-  StreamInterface* stream() { return stream_; }
-
- private:
-  StreamInterface* stream_;
-  bool owned_;
-  DISALLOW_EVIL_CONSTRUCTORS(StreamAdapterInterface);
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// StreamTap is a non-modifying, pass-through adapter, which copies all data
-// in either direction to the tap.  Note that errors or blocking on writing to
-// the tap will prevent further tap writes from occurring.
-///////////////////////////////////////////////////////////////////////////////
-
-class StreamTap : public StreamAdapterInterface {
- public:
-  explicit StreamTap(StreamInterface* stream, StreamInterface* tap);
-
-  void AttachTap(StreamInterface* tap);
-  StreamInterface* DetachTap();
-  StreamResult GetTapResult(int* error);
-
-  // StreamAdapterInterface Interface
-  virtual StreamResult Read(void* buffer, size_t buffer_len,
-                            size_t* read, int* error);
-  virtual StreamResult Write(const void* data, size_t data_len,
-                             size_t* written, int* error);
-
- private:
-  scoped_ptr<StreamInterface> tap_;
-  StreamResult tap_result_;
-  int tap_error_;
-  DISALLOW_EVIL_CONSTRUCTORS(StreamTap);
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// StreamSegment adapts a read stream, to expose a subset of the adapted
-// stream's data.  This is useful for cases where a stream contains multiple
-// documents concatenated together.  StreamSegment can expose a subset of
-// the data as an independent stream, including support for rewinding and
-// seeking.
-///////////////////////////////////////////////////////////////////////////////
-
-class StreamSegment : public StreamAdapterInterface {
- public:
-  // The current position of the adapted stream becomes the beginning of the
-  // segment.  If a length is specified, it bounds the length of the segment.
-  explicit StreamSegment(StreamInterface* stream);
-  explicit StreamSegment(StreamInterface* stream, size_t length);
-
-  // StreamAdapterInterface Interface
-  virtual StreamResult Read(void* buffer, size_t buffer_len,
-                            size_t* read, int* error);
-  virtual bool SetPosition(size_t position);
-  virtual bool GetPosition(size_t* position) const;
-  virtual bool GetSize(size_t* size) const;
-  virtual bool GetAvailable(size_t* size) const;
-
- private:
-  size_t start_, pos_, length_;
-  DISALLOW_EVIL_CONSTRUCTORS(StreamSegment);
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// NullStream gives errors on read, and silently discards all written data.
-///////////////////////////////////////////////////////////////////////////////
-
-class NullStream : public StreamInterface {
- public:
-  NullStream();
-  virtual ~NullStream();
-
-  // StreamInterface Interface
-  virtual StreamState GetState() const;
-  virtual StreamResult Read(void* buffer, size_t buffer_len,
-                            size_t* read, int* error);
-  virtual StreamResult Write(const void* data, size_t data_len,
-                             size_t* written, int* error);
-  virtual void Close();
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// FileStream is a simple implementation of a StreamInterface, which does not
-// support asynchronous notification.
-///////////////////////////////////////////////////////////////////////////////
-
-class FileStream : public StreamInterface {
- public:
-  FileStream();
-  virtual ~FileStream();
-
-  // The semantics of filename and mode are the same as stdio's fopen
-  virtual bool Open(const std::string& filename, const char* mode, int* error);
-  virtual bool OpenShare(const std::string& filename, const char* mode,
-                         int shflag, int* error);
-
-  // By default, reads and writes are buffered for efficiency.  Disabling
-  // buffering causes writes to block until the bytes on disk are updated.
-  virtual bool DisableBuffering();
-
-  virtual StreamState GetState() const;
-  virtual StreamResult Read(void* buffer, size_t buffer_len,
-                            size_t* read, int* error);
-  virtual StreamResult Write(const void* data, size_t data_len,
-                             size_t* written, int* error);
-  virtual void Close();
-  virtual bool SetPosition(size_t position);
-  virtual bool GetPosition(size_t* position) const;
-  virtual bool GetSize(size_t* size) const;
-  virtual bool GetAvailable(size_t* size) const;
-  virtual bool ReserveSize(size_t size);
-
-  bool Flush();
-
-#if defined(POSIX)
-  // Tries to aquire an exclusive lock on the file.
-  // Use OpenShare(...) on win32 to get similar functionality.
-  bool TryLock();
-  bool Unlock();
-#endif
-
-  // Note: Deprecated in favor of Filesystem::GetFileSize().
-  static bool GetSize(const std::string& filename, size_t* size);
-
- protected:
-  virtual void DoClose();
-
-  FILE* file_;
-
- private:
-  DISALLOW_EVIL_CONSTRUCTORS(FileStream);
-};
-
-#ifdef POSIX
-// A FileStream that is actually not a file, but the output or input of a
-// sub-command. See "man 3 popen" for documentation of the underlying OS popen()
-// function.
-class POpenStream : public FileStream {
- public:
-  POpenStream() : wait_status_(-1) {}
-  virtual ~POpenStream();
-
-  virtual bool Open(const std::string& subcommand, const char* mode,
-                    int* error);
-  // Same as Open(). shflag is ignored.
-  virtual bool OpenShare(const std::string& subcommand, const char* mode,
-                         int shflag, int* error);
-
-  // Returns the wait status from the last Close() of an Open()'ed stream, or
-  // -1 if no Open()+Close() has been done on this object. Meaning of the number
-  // is documented in "man 2 wait".
-  int GetWaitStatus() const { return wait_status_; }
-
- protected:
-  virtual void DoClose();
-
- private:
-  int wait_status_;
-};
-#endif  // POSIX
-
-///////////////////////////////////////////////////////////////////////////////
-// MemoryStream is a simple implementation of a StreamInterface over in-memory
-// data.  Data is read and written at the current seek position.  Reads return
-// end-of-stream when they reach the end of data.  Writes actually extend the
-// end of data mark.
-///////////////////////////////////////////////////////////////////////////////
-
-class MemoryStreamBase : public StreamInterface {
- public:
-  virtual StreamState GetState() const;
-  virtual StreamResult Read(void* buffer, size_t bytes, size_t* bytes_read,
-                            int* error);
-  virtual StreamResult Write(const void* buffer, size_t bytes,
-                             size_t* bytes_written, int* error);
-  virtual void Close();
-  virtual bool SetPosition(size_t position);
-  virtual bool GetPosition(size_t* position) const;
-  virtual bool GetSize(size_t* size) const;
-  virtual bool GetAvailable(size_t* size) const;
-  virtual bool ReserveSize(size_t size);
-
-  char* GetBuffer() { return buffer_; }
-  const char* GetBuffer() const { return buffer_; }
-
- protected:
-  MemoryStreamBase();
-
-  virtual StreamResult DoReserve(size_t size, int* error);
-
-  // Invariant: 0 <= seek_position <= data_length_ <= buffer_length_
-  char* buffer_;
-  size_t buffer_length_;
-  size_t data_length_;
-  size_t seek_position_;
-
- private:
-  DISALLOW_EVIL_CONSTRUCTORS(MemoryStreamBase);
-};
-
-// MemoryStream dynamically resizes to accomodate written data.
-
-class MemoryStream : public MemoryStreamBase {
- public:
-  MemoryStream();
-  explicit MemoryStream(const char* data);  // Calls SetData(data, strlen(data))
-  MemoryStream(const void* data, size_t length);  // Calls SetData(data, length)
-  virtual ~MemoryStream();
-
-  void SetData(const void* data, size_t length);
-
- protected:
-  virtual StreamResult DoReserve(size_t size, int* error);
-  // Memory Streams are aligned for efficiency.
-  static const int kAlignment = 16;
-  char* buffer_alloc_;
-};
-
-// ExternalMemoryStream adapts an external memory buffer, so writes which would
-// extend past the end of the buffer will return end-of-stream.
-
-class ExternalMemoryStream : public MemoryStreamBase {
- public:
-  ExternalMemoryStream();
-  ExternalMemoryStream(void* data, size_t length);
-  virtual ~ExternalMemoryStream();
-
-  void SetData(void* data, size_t length);
-};
-
-// FifoBuffer allows for efficient, thread-safe buffering of data between
-// writer and reader. As the data can wrap around the end of the buffer,
-// MemoryStreamBase can't help us here.
-
-class FifoBuffer : public StreamInterface {
- public:
-  // Creates a FIFO buffer with the specified capacity.
-  explicit FifoBuffer(size_t length);
-  virtual ~FifoBuffer();
-  // Gets the amount of data currently readable from the buffer.
-  bool GetBuffered(size_t* data_len) const;
-  // Resizes the buffer to the specified capacity. Fails if data_length_ > size
-  bool SetCapacity(size_t length);
-
-  // Read into |buffer| with an offset from the current read position, offset
-  // is specified in number of bytes.
-  // This method doesn't adjust read position nor the number of available
-  // bytes, user has to call ConsumeReadData() to do this.
-  StreamResult ReadOffset(void* buffer, size_t bytes, size_t offset,
-                          size_t* bytes_read);
-
-  // Write |buffer| with an offset from the current write position, offset is
-  // specified in number of bytes.
-  // This method doesn't adjust the number of buffered bytes, user has to call
-  // ConsumeWriteBuffer() to do this.
-  StreamResult WriteOffset(const void* buffer, size_t bytes, size_t offset,
-                           size_t* bytes_written);
-
-  // StreamInterface methods
-  virtual StreamState GetState() const;
-  virtual StreamResult Read(void* buffer, size_t bytes,
-                            size_t* bytes_read, int* error);
-  virtual StreamResult Write(const void* buffer, size_t bytes,
-                             size_t* bytes_written, int* error);
-  virtual void Close();
-  virtual const void* GetReadData(size_t* data_len);
-  virtual void ConsumeReadData(size_t used);
-  virtual void* GetWriteBuffer(size_t *buf_len);
-  virtual void ConsumeWriteBuffer(size_t used);
-  virtual bool GetWriteRemaining(size_t* size) const;
-
- private:
-  // Helper method that implements ReadOffset. Caller must acquire a lock
-  // when calling this method.
-  StreamResult ReadOffsetLocked(void* buffer, size_t bytes, size_t offset,
-                                size_t* bytes_read);
-
-  // Helper method that implements WriteOffset. Caller must acquire a lock
-  // when calling this method.
-  StreamResult WriteOffsetLocked(const void* buffer, size_t bytes,
-                                 size_t offset, size_t* bytes_written);
-
-  StreamState state_;  // keeps the opened/closed state of the stream
-  scoped_array<char> buffer_;  // the allocated buffer
-  size_t buffer_length_;  // size of the allocated buffer
-  size_t data_length_;  // amount of readable data in the buffer
-  size_t read_position_;  // offset to the readable data
-  Thread* owner_;  // stream callbacks are dispatched on this thread
-  mutable CriticalSection crit_;  // object lock
-  DISALLOW_EVIL_CONSTRUCTORS(FifoBuffer);
-};
-
-///////////////////////////////////////////////////////////////////////////////
-
-class LoggingAdapter : public StreamAdapterInterface {
- public:
-  LoggingAdapter(StreamInterface* stream, LoggingSeverity level,
-                 const std::string& label, bool hex_mode = false);
-
-  void set_label(const std::string& label);
-
-  virtual StreamResult Read(void* buffer, size_t buffer_len,
-                            size_t* read, int* error);
-  virtual StreamResult Write(const void* data, size_t data_len,
-                             size_t* written, int* error);
-  virtual void Close();
-
- protected:
-  virtual void OnEvent(StreamInterface* stream, int events, int err);
-
- private:
-  LoggingSeverity level_;
-  std::string label_;
-  bool hex_mode_;
-  LogMultilineState lms_;
-
-  DISALLOW_EVIL_CONSTRUCTORS(LoggingAdapter);
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// StringStream - Reads/Writes to an external std::string
-///////////////////////////////////////////////////////////////////////////////
-
-class StringStream : public StreamInterface {
- public:
-  explicit StringStream(std::string& str);
-  explicit StringStream(const std::string& str);
-
-  virtual StreamState GetState() const;
-  virtual StreamResult Read(void* buffer, size_t buffer_len,
-                            size_t* read, int* error);
-  virtual StreamResult Write(const void* data, size_t data_len,
-                             size_t* written, int* error);
-  virtual void Close();
-  virtual bool SetPosition(size_t position);
-  virtual bool GetPosition(size_t* position) const;
-  virtual bool GetSize(size_t* size) const;
-  virtual bool GetAvailable(size_t* size) const;
-  virtual bool ReserveSize(size_t size);
-
- private:
-  std::string& str_;
-  size_t read_pos_;
-  bool read_only_;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// StreamReference - A reference counting stream adapter
-///////////////////////////////////////////////////////////////////////////////
-
-// Keep in mind that the streams and adapters defined in this file are
-// not thread-safe, so this has limited uses.
-
-// A StreamRefCount holds the reference count and a pointer to the
-// wrapped stream. It deletes the wrapped stream when there are no
-// more references. We can then have multiple StreamReference
-// instances pointing to one StreamRefCount, all wrapping the same
-// stream.
-
-class StreamReference : public StreamAdapterInterface {
-  class StreamRefCount;
- public:
-  // Constructor for the first reference to a stream
-  // Note: get more references through NewReference(). Use this
-  // constructor only once on a given stream.
-  explicit StreamReference(StreamInterface* stream);
-  StreamInterface* GetStream() { return stream(); }
-  StreamInterface* NewReference();
-  virtual ~StreamReference();
-
- private:
-  class StreamRefCount {
-   public:
-    explicit StreamRefCount(StreamInterface* stream)
-        : stream_(stream), ref_count_(1) {
-    }
-    void AddReference() {
-      CritScope lock(&cs_);
-      ++ref_count_;
-    }
-    void Release() {
-      int ref_count;
-      {  // Atomic ops would have been a better fit here.
-        CritScope lock(&cs_);
-        ref_count = --ref_count_;
-      }
-      if (ref_count == 0) {
-        delete stream_;
-        delete this;
-      }
-    }
-   private:
-    StreamInterface* stream_;
-    int ref_count_;
-    CriticalSection cs_;
-    DISALLOW_EVIL_CONSTRUCTORS(StreamRefCount);
-  };
-
-  // Constructor for adding references
-  explicit StreamReference(StreamRefCount* stream_ref_count,
-                           StreamInterface* stream);
-
-  StreamRefCount* stream_ref_count_;
-  DISALLOW_EVIL_CONSTRUCTORS(StreamReference);
-};
-
-///////////////////////////////////////////////////////////////////////////////
-
-// Flow attempts to move bytes from source to sink via buffer of size
-// buffer_len.  The function returns SR_SUCCESS when source reaches
-// end-of-stream (returns SR_EOS), and all the data has been written successful
-// to sink.  Alternately, if source returns SR_BLOCK or SR_ERROR, or if sink
-// returns SR_BLOCK, SR_ERROR, or SR_EOS, then the function immediately returns
-// with the unexpected StreamResult value.
-// data_len is the length of the valid data in buffer. in case of error
-// this is the data that read from source but can't move to destination.
-// as a pass in parameter, it indicates data in buffer that should move to sink
-StreamResult Flow(StreamInterface* source,
-                  char* buffer, size_t buffer_len,
-                  StreamInterface* sink, size_t* data_len = NULL);
-
-///////////////////////////////////////////////////////////////////////////////
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_STREAM_H__
diff --git a/third_party/libjingle/source/talk/base/stream_unittest.cc b/third_party/libjingle/source/talk/base/stream_unittest.cc
deleted file mode 100644
index d0c5718..0000000
--- a/third_party/libjingle/source/talk/base/stream_unittest.cc
+++ /dev/null
@@ -1,445 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/gunit.h"
-#include "talk/base/stream.h"
-
-namespace talk_base {
-
-///////////////////////////////////////////////////////////////////////////////
-// TestStream
-///////////////////////////////////////////////////////////////////////////////
-
-class TestStream : public StreamInterface {
-public:
-  TestStream() : pos_(0) { }
-
-  virtual StreamState GetState() const { return SS_OPEN; }
-  virtual StreamResult Read(void* buffer, size_t buffer_len,
-                            size_t* read, int* error) {
-    unsigned char* uc_buffer = static_cast<unsigned char*>(buffer);
-    for (size_t i=0; i<buffer_len; ++i) {
-      uc_buffer[i] = pos_++;
-    }
-    if (read)
-      *read = buffer_len;
-    return SR_SUCCESS;
-  }
-  virtual StreamResult Write(const void* data, size_t data_len,
-                             size_t* written, int* error) {
-    if (error)
-      *error = -1;
-    return SR_ERROR;
-  }
-  virtual void Close() { }
-  virtual bool SetPosition(size_t position) {
-    pos_ = position;
-    return true;
-  }
-  virtual bool GetPosition(size_t* position) const {
-    if (position) *position = pos_;
-    return true;
-  }
-  virtual bool GetSize(size_t* size) const {
-    return false;
-  }
-  virtual bool GetAvailable(size_t* size) const {
-    return false;
-  }
-
-private:
-  unsigned char pos_;
-};
-
-bool VerifyTestBuffer(unsigned char* buffer, size_t len,
-                      unsigned char value) {
-  bool passed = true;
-  for (size_t i=0; i<len; ++i) {
-    if (buffer[i] != value++) {
-      passed = false;
-      break;
-    }
-  }
-  // Ensure that we don't pass again without re-writing
-  memset(buffer, 0, len);
-  return passed;
-}
-
-void SeekTest(StreamInterface* stream, const unsigned char value) {
-  size_t bytes;
-  unsigned char buffer[13] = { 0 };
-  const size_t kBufSize = sizeof(buffer);
-
-  EXPECT_EQ(stream->Read(buffer, kBufSize, &bytes, NULL), SR_SUCCESS);
-  EXPECT_EQ(bytes, kBufSize);
-  EXPECT_TRUE(VerifyTestBuffer(buffer, kBufSize, value));
-  EXPECT_TRUE(stream->GetPosition(&bytes));
-  EXPECT_EQ(13U, bytes);
-
-  EXPECT_TRUE(stream->SetPosition(7));
-
-  EXPECT_EQ(stream->Read(buffer, kBufSize, &bytes, NULL), SR_SUCCESS);
-  EXPECT_EQ(bytes, kBufSize);
-  EXPECT_TRUE(VerifyTestBuffer(buffer, kBufSize, value + 7));
-  EXPECT_TRUE(stream->GetPosition(&bytes));
-  EXPECT_EQ(20U, bytes);
-}
-
-TEST(StreamSegment, TranslatesPosition) {
-  TestStream* test = new TestStream;
-  // Verify behavior of original stream
-  SeekTest(test, 0);
-  StreamSegment* segment = new StreamSegment(test);
-  // Verify behavior of adapted stream (all values offset by 20)
-  SeekTest(segment, 20);
-  delete segment;
-}
-
-TEST(StreamSegment, SupportsArtificialTermination) {
-  TestStream* test = new TestStream;
-
-  size_t bytes;
-  unsigned char buffer[5000] = { 0 };
-  const size_t kBufSize = sizeof(buffer);
-
-  {
-    StreamInterface* stream = test;
-
-    // Read a lot of bytes
-    EXPECT_EQ(stream->Read(buffer, kBufSize, &bytes, NULL), SR_SUCCESS);
-    EXPECT_EQ(bytes, kBufSize);
-    EXPECT_TRUE(VerifyTestBuffer(buffer, kBufSize, 0));
-
-    // Test seeking far ahead
-    EXPECT_TRUE(stream->SetPosition(12345));
-
-    // Read a bunch more bytes
-    EXPECT_EQ(stream->Read(buffer, kBufSize, &bytes, NULL), SR_SUCCESS);
-    EXPECT_EQ(bytes, kBufSize);
-    EXPECT_TRUE(VerifyTestBuffer(buffer, kBufSize, 12345 % 256));
-  }
-
-  // Create a segment of test stream in range [100,600)
-  EXPECT_TRUE(test->SetPosition(100));
-  StreamSegment* segment = new StreamSegment(test, 500);
-
-  {
-    StreamInterface* stream = segment;
-
-    EXPECT_EQ(stream->Read(buffer, kBufSize, &bytes, NULL), SR_SUCCESS);
-    EXPECT_EQ(500U, bytes);
-    EXPECT_TRUE(VerifyTestBuffer(buffer, 500, 100));
-    EXPECT_EQ(stream->Read(buffer, kBufSize, &bytes, NULL), SR_EOS);
-
-    // Test seeking past "end" of stream
-    EXPECT_FALSE(stream->SetPosition(12345));
-    EXPECT_FALSE(stream->SetPosition(501));
-
-    // Test seeking to end (edge case)
-    EXPECT_TRUE(stream->SetPosition(500));
-    EXPECT_EQ(stream->Read(buffer, kBufSize, &bytes, NULL), SR_EOS);
-
-    // Test seeking to start
-    EXPECT_TRUE(stream->SetPosition(0));
-    EXPECT_EQ(stream->Read(buffer, kBufSize, &bytes, NULL), SR_SUCCESS);
-    EXPECT_EQ(500U, bytes);
-    EXPECT_TRUE(VerifyTestBuffer(buffer, 500, 100));
-    EXPECT_EQ(stream->Read(buffer, kBufSize, &bytes, NULL), SR_EOS);
-  }
-
-  delete segment;
-}
-
-TEST(FifoBufferTest, TestAll) {
-  const size_t kSize = 16;
-  const char in[kSize * 2 + 1] = "0123456789ABCDEFGHIJKLMNOPQRSTUV";
-  char out[kSize * 2];
-  void* p;
-  const void* q;
-  size_t bytes;
-  FifoBuffer buf(kSize);
-  StreamInterface* stream = &buf;
-
-  // Test assumptions about base state
-  EXPECT_EQ(SS_OPEN, stream->GetState());
-  EXPECT_EQ(SR_BLOCK, stream->Read(out, kSize, &bytes, NULL));
-  EXPECT_TRUE(NULL != stream->GetReadData(&bytes));
-  EXPECT_EQ((size_t)0, bytes);
-  stream->ConsumeReadData(0);
-  EXPECT_TRUE(NULL != stream->GetWriteBuffer(&bytes));
-  EXPECT_EQ(kSize, bytes);
-  stream->ConsumeWriteBuffer(0);
-
-  // Try a full write
-  EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize, &bytes, NULL));
-  EXPECT_EQ(kSize, bytes);
-
-  // Try a write that should block
-  EXPECT_EQ(SR_BLOCK, stream->Write(in, kSize, &bytes, NULL));
-
-  // Try a full read
-  EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize, &bytes, NULL));
-  EXPECT_EQ(kSize, bytes);
-  EXPECT_EQ(0, memcmp(in, out, kSize));
-
-  // Try a read that should block
-  EXPECT_EQ(SR_BLOCK, stream->Read(out, kSize, &bytes, NULL));
-
-  // Try a too-big write
-  EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize * 2, &bytes, NULL));
-  EXPECT_EQ(bytes, kSize);
-
-  // Try a too-big read
-  EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize * 2, &bytes, NULL));
-  EXPECT_EQ(kSize, bytes);
-  EXPECT_EQ(0, memcmp(in, out, kSize));
-
-  // Try some small writes and reads
-  EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize / 2, &bytes, NULL));
-  EXPECT_EQ(kSize / 2, bytes);
-  EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize / 2, &bytes, NULL));
-  EXPECT_EQ(kSize / 2, bytes);
-  EXPECT_EQ(0, memcmp(in, out, kSize / 2));
-  EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize / 2, &bytes, NULL));
-  EXPECT_EQ(kSize / 2, bytes);
-  EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize / 2, &bytes, NULL));
-  EXPECT_EQ(kSize / 2, bytes);
-  EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize / 2, &bytes, NULL));
-  EXPECT_EQ(kSize / 2, bytes);
-  EXPECT_EQ(0, memcmp(in, out, kSize / 2));
-  EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize / 2, &bytes, NULL));
-  EXPECT_EQ(kSize / 2, bytes);
-  EXPECT_EQ(0, memcmp(in, out, kSize / 2));
-
-  // Try wraparound reads and writes in the following pattern
-  // WWWWWWWWWWWW.... 0123456789AB....
-  // RRRRRRRRXXXX.... ........89AB....
-  // WWWW....XXXXWWWW 4567....89AB0123
-  // XXXX....RRRRXXXX 4567........0123
-  // XXXXWWWWWWWWXXXX 4567012345670123
-  // RRRRXXXXXXXXRRRR ....01234567....
-  // ....RRRRRRRR.... ................
-  EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize * 3 / 4, &bytes, NULL));
-  EXPECT_EQ(kSize * 3 / 4, bytes);
-  EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize / 2, &bytes, NULL));
-  EXPECT_EQ(kSize / 2, bytes);
-  EXPECT_EQ(0, memcmp(in, out, kSize / 2));
-  EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize / 2, &bytes, NULL));
-  EXPECT_EQ(kSize / 2, bytes);
-  EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize / 4, &bytes, NULL));
-  EXPECT_EQ(kSize / 4 , bytes);
-  EXPECT_EQ(0, memcmp(in + kSize / 2, out, kSize / 4));
-  EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize / 2, &bytes, NULL));
-  EXPECT_EQ(kSize / 2, bytes);
-  EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize / 2, &bytes, NULL));
-  EXPECT_EQ(kSize / 2 , bytes);
-  EXPECT_EQ(0, memcmp(in, out, kSize / 2));
-  EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize / 2, &bytes, NULL));
-  EXPECT_EQ(kSize / 2 , bytes);
-  EXPECT_EQ(0, memcmp(in, out, kSize / 2));
-
-  // Use GetWriteBuffer to reset the read_position for the next tests
-  stream->GetWriteBuffer(&bytes);
-  stream->ConsumeWriteBuffer(0);
-
-  // Try using GetReadData to do a full read
-  EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize, &bytes, NULL));
-  q = stream->GetReadData(&bytes);
-  EXPECT_TRUE(NULL != q);
-  EXPECT_EQ(kSize, bytes);
-  EXPECT_EQ(0, memcmp(q, in, kSize));
-  stream->ConsumeReadData(kSize);
-  EXPECT_EQ(SR_BLOCK, stream->Read(out, kSize, &bytes, NULL));
-
-  // Try using GetReadData to do some small reads
-  EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize, &bytes, NULL));
-  q = stream->GetReadData(&bytes);
-  EXPECT_TRUE(NULL != q);
-  EXPECT_EQ(kSize, bytes);
-  EXPECT_EQ(0, memcmp(q, in, kSize / 2));
-  stream->ConsumeReadData(kSize / 2);
-  q = stream->GetReadData(&bytes);
-  EXPECT_TRUE(NULL != q);
-  EXPECT_EQ(kSize / 2, bytes);
-  EXPECT_EQ(0, memcmp(q, in + kSize / 2, kSize / 2));
-  stream->ConsumeReadData(kSize / 2);
-  EXPECT_EQ(SR_BLOCK, stream->Read(out, kSize, &bytes, NULL));
-
-  // Try using GetReadData in a wraparound case
-  // WWWWWWWWWWWWWWWW 0123456789ABCDEF
-  // RRRRRRRRRRRRXXXX ............CDEF
-  // WWWWWWWW....XXXX 01234567....CDEF
-  // ............RRRR 01234567........
-  // RRRRRRRR........ ................
-  EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize, &bytes, NULL));
-  EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize * 3 / 4, &bytes, NULL));
-  EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize / 2, &bytes, NULL));
-  q = stream->GetReadData(&bytes);
-  EXPECT_TRUE(NULL != q);
-  EXPECT_EQ(kSize / 4, bytes);
-  EXPECT_EQ(0, memcmp(q, in + kSize * 3 / 4, kSize / 4));
-  stream->ConsumeReadData(kSize / 4);
-  q = stream->GetReadData(&bytes);
-  EXPECT_TRUE(NULL != q);
-  EXPECT_EQ(kSize / 2, bytes);
-  EXPECT_EQ(0, memcmp(q, in, kSize / 2));
-  stream->ConsumeReadData(kSize / 2);
-
-  // Use GetWriteBuffer to reset the read_position for the next tests
-  stream->GetWriteBuffer(&bytes);
-  stream->ConsumeWriteBuffer(0);
-
-  // Try using GetWriteBuffer to do a full write
-  p = stream->GetWriteBuffer(&bytes);
-  EXPECT_TRUE(NULL != p);
-  EXPECT_EQ(kSize, bytes);
-  memcpy(p, in, kSize);
-  stream->ConsumeWriteBuffer(kSize);
-  EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize, &bytes, NULL));
-  EXPECT_EQ(kSize, bytes);
-  EXPECT_EQ(0, memcmp(in, out, kSize));
-
-  // Try using GetWriteBuffer to do some small writes
-  p = stream->GetWriteBuffer(&bytes);
-  EXPECT_TRUE(NULL != p);
-  EXPECT_EQ(kSize, bytes);
-  memcpy(p, in, kSize / 2);
-  stream->ConsumeWriteBuffer(kSize / 2);
-  p = stream->GetWriteBuffer(&bytes);
-  EXPECT_TRUE(NULL != p);
-  EXPECT_EQ(kSize / 2, bytes);
-  memcpy(p, in + kSize / 2, kSize / 2);
-  stream->ConsumeWriteBuffer(kSize / 2);
-  EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize, &bytes, NULL));
-  EXPECT_EQ(kSize, bytes);
-  EXPECT_EQ(0, memcmp(in, out, kSize));
-
-  // Try using GetWriteBuffer in a wraparound case
-  // WWWWWWWWWWWW.... 0123456789AB....
-  // RRRRRRRRXXXX.... ........89AB....
-  // ........XXXXWWWW ........89AB0123
-  // WWWW....XXXXXXXX 4567....89AB0123
-  // RRRR....RRRRRRRR ................
-  EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize * 3 / 4, &bytes, NULL));
-  EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize / 2, &bytes, NULL));
-  p = stream->GetWriteBuffer(&bytes);
-  EXPECT_TRUE(NULL != p);
-  EXPECT_EQ(kSize / 4, bytes);
-  memcpy(p, in, kSize / 4);
-  stream->ConsumeWriteBuffer(kSize / 4);
-  p = stream->GetWriteBuffer(&bytes);
-  EXPECT_TRUE(NULL != p);
-  EXPECT_EQ(kSize / 2, bytes);
-  memcpy(p, in + kSize / 4, kSize / 4);
-  stream->ConsumeWriteBuffer(kSize / 4);
-  EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize * 3 / 4, &bytes, NULL));
-  EXPECT_EQ(kSize * 3 / 4, bytes);
-  EXPECT_EQ(0, memcmp(in + kSize / 2, out, kSize / 4));
-  EXPECT_EQ(0, memcmp(in, out + kSize / 4, kSize / 4));
-
-  // Check that the stream is now empty
-  EXPECT_EQ(SR_BLOCK, stream->Read(out, kSize, &bytes, NULL));
-
-  // Try growing the buffer
-  EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize, &bytes, NULL));
-  EXPECT_EQ(kSize, bytes);
-  EXPECT_TRUE(buf.SetCapacity(kSize * 2));
-  EXPECT_EQ(SR_SUCCESS, stream->Write(in + kSize, kSize, &bytes, NULL));
-  EXPECT_EQ(kSize, bytes);
-  EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize * 2, &bytes, NULL));
-  EXPECT_EQ(kSize * 2, bytes);
-  EXPECT_EQ(0, memcmp(in, out, kSize * 2));
-
-  // Try shrinking the buffer
-  EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize, &bytes, NULL));
-  EXPECT_EQ(kSize, bytes);
-  EXPECT_TRUE(buf.SetCapacity(kSize));
-  EXPECT_EQ(SR_BLOCK, stream->Write(in, kSize, &bytes, NULL));
-  EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize, &bytes, NULL));
-  EXPECT_EQ(kSize, bytes);
-  EXPECT_EQ(0, memcmp(in, out, kSize));
-
-  // Write to the stream, close it, read the remaining bytes
-  EXPECT_EQ(SR_SUCCESS, stream->Write(in, kSize / 2, &bytes, NULL));
-  stream->Close();
-  EXPECT_EQ(SS_CLOSED, stream->GetState());
-  EXPECT_EQ(SR_EOS, stream->Write(in, kSize / 2, &bytes, NULL));
-  EXPECT_EQ(SR_SUCCESS, stream->Read(out, kSize / 2, &bytes, NULL));
-  EXPECT_EQ(0, memcmp(in, out, kSize / 2));
-  EXPECT_EQ(SR_EOS, stream->Read(out, kSize / 2, &bytes, NULL));
-}
-
-TEST(FifoBufferTest, WriteOffsetAndReadOffset) {
-  const size_t kSize = 16;
-  const char in[kSize * 2 + 1] = "0123456789ABCDEFGHIJKLMNOPQRSTUV";
-  char out[kSize * 2];
-  FifoBuffer buf(kSize);
-
-  // Write 14 bytes.
-  EXPECT_EQ(SR_SUCCESS, buf.Write(in, 14, NULL, NULL));
-
-  // Make sure data is in |buf|.
-  size_t buffered;
-  EXPECT_TRUE(buf.GetBuffered(&buffered));
-  EXPECT_EQ(14u, buffered);
-
-  // Read 10 bytes.
-  buf.ConsumeReadData(10);
-
-  // There should be now 12 bytes of available space.
-  size_t remaining;
-  EXPECT_TRUE(buf.GetWriteRemaining(&remaining));
-  EXPECT_EQ(12u, remaining);
-
-  // Write at offset 12, this should fail.
-  EXPECT_EQ(SR_BLOCK, buf.WriteOffset(in, 10, 12, NULL));
-
-  // Write 8 bytes at offset 4, this wraps around the buffer.
-  EXPECT_EQ(SR_SUCCESS, buf.WriteOffset(in, 8, 4, NULL));
-
-  // Number of available space remains the same until we call
-  // ConsumeWriteBuffer().
-  EXPECT_TRUE(buf.GetWriteRemaining(&remaining));
-  EXPECT_EQ(12u, remaining);
-  buf.ConsumeWriteBuffer(12);
-
-  // There's 4 bytes bypassed and 4 bytes no read so skip them and verify the
-  // 8 bytes written.
-  size_t read;
-  EXPECT_EQ(SR_SUCCESS, buf.ReadOffset(out, 8, 8, &read));
-  EXPECT_EQ(8u, read);
-  EXPECT_EQ(0, memcmp(out, in, 8));
-
-  // There should still be 16 bytes available for reading.
-  EXPECT_TRUE(buf.GetBuffered(&buffered));
-  EXPECT_EQ(16u, buffered);
-
-  // Read at offset 16, this should fail since we don't have that much data.
-  EXPECT_EQ(SR_BLOCK, buf.ReadOffset(out, 10, 16, NULL));
-}
-
-} // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/stringdigest.cc b/third_party/libjingle/source/talk/base/stringdigest.cc
deleted file mode 100644
index 1f98124..0000000
--- a/third_party/libjingle/source/talk/base/stringdigest.cc
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-#include "talk/base/md5.h"
-#include "talk/base/stringdigest.h"
-#include "talk/base/stringencode.h"
-
-namespace talk_base {
-
-std::string MD5(const std::string& data) {
-  MD5_CTX ctx;
-  MD5Init(&ctx);
-  MD5Update(&ctx, const_cast<unsigned char *>(reinterpret_cast<const unsigned char *>(data.data())), static_cast<unsigned int>(data.size()));
-  unsigned char digest[16];
-  MD5Final(digest, &ctx);
-  std::string hex_digest;
-  for (int i=0; i<16; ++i) {
-    hex_digest += hex_encode(digest[i] >> 4);
-    hex_digest += hex_encode(digest[i] & 0xf);
-  }
-  return hex_digest;
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/stringdigest.h b/third_party/libjingle/source/talk/base/stringdigest.h
deleted file mode 100644
index d75d845..0000000
--- a/third_party/libjingle/source/talk/base/stringdigest.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-#ifndef TALK_BASE_STRINGDIGEST_H__
-#define TALK_BASE_STRINGDIGEST_H__
-
-#include <string>
-
-namespace talk_base {
-
-//////////////////////////////////////////////////////////////////////
-// Message Digest Utilities
-//////////////////////////////////////////////////////////////////////
-
-// Compute the MD5 message digest of data, and return it in 
-std::string MD5(const std::string& data);
-
-//////////////////////////////////////////////////////////////////////
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_STRINGDIGEST_H__
diff --git a/third_party/libjingle/source/talk/base/stringencode.cc b/third_party/libjingle/source/talk/base/stringencode.cc
deleted file mode 100644
index 49dc42f..0000000
--- a/third_party/libjingle/source/talk/base/stringencode.cc
+++ /dev/null
@@ -1,619 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/stringencode.h"
-
-#include <cstdio>
-#include <cstdlib>
-
-#include "talk/base/basictypes.h"
-#include "talk/base/common.h"
-#include "talk/base/stringutils.h"
-
-namespace talk_base {
-
-/////////////////////////////////////////////////////////////////////////////
-// String Encoding Utilities
-/////////////////////////////////////////////////////////////////////////////
-
-static const char HEX[] = "0123456789abcdef";
-
-char hex_encode(unsigned char val) {
-  ASSERT(val < 16);
-  return (val < 16) ? HEX[val] : '!';
-}
-
-bool hex_decode(char ch, unsigned char* val) {
-  if ((ch >= '0') && (ch <= '9')) {
-    *val = ch - '0';
-  } else if ((ch >= 'A') && (ch <= 'Z')) {
-    *val = (ch - 'A') + 10;
-  } else if ((ch >= 'a') && (ch <= 'z')) {
-    *val = (ch - 'a') + 10;
-  } else {
-    return false;
-  }
-  return true;
-}
-
-size_t escape(char * buffer, size_t buflen,
-              const char * source, size_t srclen,
-              const char * illegal, char escape) {
-  ASSERT(NULL != buffer);  // TODO: estimate output size
-  if (buflen <= 0)
-    return 0;
-
-  size_t srcpos = 0, bufpos = 0;
-  while ((srcpos < srclen) && (bufpos + 1 < buflen)) {
-    char ch = source[srcpos++];
-    if ((ch == escape) || ::strchr(illegal, ch)) {
-      if (bufpos + 2 >= buflen)
-        break;
-      buffer[bufpos++] = escape;
-    }
-    buffer[bufpos++] = ch;
-  }
-
-  buffer[bufpos] = '\0';
-  return bufpos;
-}
-
-size_t unescape(char * buffer, size_t buflen,
-                const char * source, size_t srclen,
-                char escape) {
-  ASSERT(NULL != buffer);  // TODO: estimate output size
-  if (buflen <= 0)
-    return 0;
-
-  size_t srcpos = 0, bufpos = 0;
-  while ((srcpos < srclen) && (bufpos + 1 < buflen)) {
-    char ch = source[srcpos++];
-    if ((ch == escape) && (srcpos < srclen)) {
-      ch = source[srcpos++];
-    }
-    buffer[bufpos++] = ch;
-  }
-  buffer[bufpos] = '\0';
-  return bufpos;
-}
-
-size_t encode(char * buffer, size_t buflen,
-              const char * source, size_t srclen,
-              const char * illegal, char escape) {
-  ASSERT(NULL != buffer);  // TODO: estimate output size
-  if (buflen <= 0)
-    return 0;
-
-  size_t srcpos = 0, bufpos = 0;
-  while ((srcpos < srclen) && (bufpos + 1 < buflen)) {
-    char ch = source[srcpos++];
-    if ((ch != escape) && !::strchr(illegal, ch)) {
-      buffer[bufpos++] = ch;
-    } else if (bufpos + 3 >= buflen) {
-      break;
-    } else {
-      buffer[bufpos+0] = escape;
-      buffer[bufpos+1] = hex_encode((static_cast<unsigned char>(ch) >> 4) & 0xF);
-      buffer[bufpos+2] = hex_encode((static_cast<unsigned char>(ch)     ) & 0xF);
-      bufpos += 3;
-    }
-  }
-  buffer[bufpos] = '\0';
-  return bufpos;
-}
-
-size_t decode(char * buffer, size_t buflen,
-              const char * source, size_t srclen,
-              char escape) {
-  if (buflen <= 0)
-    return 0;
-
-  unsigned char h1, h2;
-  size_t srcpos = 0, bufpos = 0;
-  while ((srcpos < srclen) && (bufpos + 1 < buflen)) {
-    char ch = source[srcpos++];
-    if ((ch == escape)
-        && (srcpos + 1 < srclen)
-        && hex_decode(source[srcpos], &h1)
-        && hex_decode(source[srcpos+1], &h2)) {
-      buffer[bufpos++] = (h1 << 4) | h2;
-      srcpos += 2;
-    } else {
-      buffer[bufpos++] = ch;
-    }
-  }
-  buffer[bufpos] = '\0';
-  return bufpos;
-}
-
-const char* unsafe_filename_characters() {
-  // It might be better to have a single specification which is the union of
-  // all operating systems, unless one system is overly restrictive.
-#ifdef WIN32
-  return "\\/:*?\"<>|";
-#else  // !WIN32
-  // TODO
-  ASSERT(false);
-  return "";
-#endif  // !WIN23
-}
-
-const unsigned char URL_UNSAFE  = 0x1; // 0-33 "#$%&+,/:;<=>?@[\]^`{|} 127
-const unsigned char XML_UNSAFE  = 0x2; // "&'<>
-const unsigned char HTML_UNSAFE = 0x2; // "&'<>
-
-//  ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 6 5 7 8 9 : ; < = > ?
-//@ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _
-//` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~
-
-const unsigned char ASCII_CLASS[128] = {
-  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-  1,0,3,1,1,1,3,2,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,1,1,3,1,3,1,
-  1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,
-  1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,1,
-};
-
-size_t url_encode(char * buffer, size_t buflen,
-                  const char * source, size_t srclen) {
-  if (NULL == buffer)
-    return srclen * 3 + 1;
-  if (buflen <= 0)
-    return 0;
-
-  size_t srcpos = 0, bufpos = 0;
-  while ((srcpos < srclen) && (bufpos + 1 < buflen)) {
-    unsigned char ch = source[srcpos++];
-    if ((ch < 128) && (ASCII_CLASS[ch] & URL_UNSAFE)) {
-      if (bufpos + 3 >= buflen) {
-        break;
-      }
-      buffer[bufpos+0] = '%';
-      buffer[bufpos+1] = hex_encode((ch >> 4) & 0xF);
-      buffer[bufpos+2] = hex_encode((ch     ) & 0xF);
-      bufpos += 3;
-    } else {
-      buffer[bufpos++] = ch;
-    }
-  }
-  buffer[bufpos] = '\0';
-  return bufpos;
-}
-
-size_t url_decode(char * buffer, size_t buflen,
-                  const char * source, size_t srclen) {
-  if (NULL == buffer)
-    return srclen + 1;
-  if (buflen <= 0)
-    return 0;
-
-  unsigned char h1, h2;
-  size_t srcpos = 0, bufpos = 0;
-  while ((srcpos < srclen) && (bufpos + 1 < buflen)) {
-    unsigned char ch = source[srcpos++];
-    if (ch == '+') {
-      buffer[bufpos++] = ' ';
-    } else if ((ch == '%')
-               && (srcpos + 1 < srclen)
-               && hex_decode(source[srcpos], &h1)
-               && hex_decode(source[srcpos+1], &h2))
-    {
-      buffer[bufpos++] = (h1 << 4) | h2;
-      srcpos += 2;
-    } else {
-      buffer[bufpos++] = ch;
-    }
-  }
-  buffer[bufpos] = '\0';
-  return bufpos;
-}
-
-size_t utf8_decode(const char* source, size_t srclen, unsigned long* value) {
-  const unsigned char* s = reinterpret_cast<const unsigned char*>(source);
-  if ((s[0] & 0x80) == 0x00) {                    // Check s[0] == 0xxxxxxx
-    *value = s[0];
-    return 1;
-  }
-  if ((srclen < 2) || ((s[1] & 0xC0) != 0x80)) {  // Check s[1] != 10xxxxxx
-    return 0;
-  }
-  // Accumulate the trailer byte values in value16, and combine it with the
-  // relevant bits from s[0], once we've determined the sequence length.
-  unsigned long value16 = (s[1] & 0x3F);
-  if ((s[0] & 0xE0) == 0xC0) {                    // Check s[0] == 110xxxxx
-    *value = ((s[0] & 0x1F) << 6) | value16;
-    return 2;
-  }
-  if ((srclen < 3) || ((s[2] & 0xC0) != 0x80)) {  // Check s[2] != 10xxxxxx
-    return 0;
-  }
-  value16 = (value16 << 6) | (s[2] & 0x3F);
-  if ((s[0] & 0xF0) == 0xE0) {                    // Check s[0] == 1110xxxx
-    *value = ((s[0] & 0x0F) << 12) | value16;
-    return 3;
-  }
-  if ((srclen < 4) || ((s[3] & 0xC0) != 0x80)) {  // Check s[3] != 10xxxxxx
-    return 0;
-  }
-  value16 = (value16 << 6) | (s[3] & 0x3F);
-  if ((s[0] & 0xF8) == 0xF0) {                    // Check s[0] == 11110xxx
-    *value = ((s[0] & 0x07) << 18) | value16;
-    return 4;
-  }
-  return 0;
-}
-
-size_t utf8_encode(char* buffer, size_t buflen, unsigned long value) {
-  if ((value <= 0x7F) && (buflen >= 1)) {
-    buffer[0] = static_cast<unsigned char>(value);
-    return 1;
-  }
-  if ((value <= 0x7FF) && (buflen >= 2)) {
-    buffer[0] = 0xC0 | static_cast<unsigned char>(value >> 6);
-    buffer[1] = 0x80 | static_cast<unsigned char>(value & 0x3F);
-    return 2;
-  }
-  if ((value <= 0xFFFF) && (buflen >= 3)) {
-    buffer[0] = 0xE0 | static_cast<unsigned char>(value >> 12);
-    buffer[1] = 0x80 | static_cast<unsigned char>((value >> 6) & 0x3F);
-    buffer[2] = 0x80 | static_cast<unsigned char>(value & 0x3F);
-    return 3;
-  }
-  if ((value <= 0x1FFFFF) && (buflen >= 4)) {
-    buffer[0] = 0xF0 | static_cast<unsigned char>(value >> 18);
-    buffer[1] = 0x80 | static_cast<unsigned char>((value >> 12) & 0x3F);
-    buffer[2] = 0x80 | static_cast<unsigned char>((value >> 6) & 0x3F);
-    buffer[3] = 0x80 | static_cast<unsigned char>(value & 0x3F);
-    return 4;
-  }
-  return 0;
-}
-
-size_t html_encode(char * buffer, size_t buflen,
-                   const char * source, size_t srclen) {
-  ASSERT(NULL != buffer);  // TODO: estimate output size
-  if (buflen <= 0)
-    return 0;
-
-  size_t srcpos = 0, bufpos = 0;
-  while ((srcpos < srclen) && (bufpos + 1 < buflen)) {
-    unsigned char ch = source[srcpos];
-    if (ch < 128) {
-      srcpos += 1;
-      if (ASCII_CLASS[ch] & HTML_UNSAFE) {
-        const char * escseq = 0;
-        size_t esclen = 0;
-        switch (ch) {
-          case '<':  escseq = "&lt;";   esclen = 4; break;
-          case '>':  escseq = "&gt;";   esclen = 4; break;
-          case '\'': escseq = "&#39;";  esclen = 5; break;
-          case '\"': escseq = "&quot;"; esclen = 6; break;
-          case '&':  escseq = "&amp;";  esclen = 5; break;
-          default: ASSERT(false);
-        }
-        if (bufpos + esclen >= buflen) {
-          break;
-        }
-        memcpy(buffer + bufpos, escseq, esclen);
-        bufpos += esclen;
-      } else {
-        buffer[bufpos++] = ch;
-      }
-    } else {
-      // Largest value is 0x1FFFFF => &#2097151;  (10 characters)
-      char escseq[11];
-      unsigned long val;
-      if (size_t vallen = utf8_decode(&source[srcpos], srclen - srcpos, &val)) {
-        srcpos += vallen;
-      } else {
-        // Not a valid utf8 sequence, just use the raw character.
-        val = static_cast<unsigned char>(source[srcpos++]);
-      }
-      size_t esclen = sprintfn(escseq, ARRAY_SIZE(escseq), "&#%lu;", val);
-      if (bufpos + esclen >= buflen) {
-        break;
-      }
-      memcpy(buffer + bufpos, escseq, esclen);
-      bufpos += esclen;
-    }
-  }
-  buffer[bufpos] = '\0';
-  return bufpos;
-}
-
-size_t html_decode(char * buffer, size_t buflen,
-                   const char * source, size_t srclen) {
-  ASSERT(NULL != buffer);  // TODO: estimate output size
-  return xml_decode(buffer, buflen, source, srclen);
-}
-
-size_t xml_encode(char * buffer, size_t buflen,
-                  const char * source, size_t srclen) {
-  ASSERT(NULL != buffer);  // TODO: estimate output size
-  if (buflen <= 0)
-    return 0;
-
-  size_t srcpos = 0, bufpos = 0;
-  while ((srcpos < srclen) && (bufpos + 1 < buflen)) {
-    unsigned char ch = source[srcpos++];
-    if ((ch < 128) && (ASCII_CLASS[ch] & XML_UNSAFE)) {
-      const char * escseq = 0;
-      size_t esclen = 0;
-      switch (ch) {
-        case '<':  escseq = "&lt;";   esclen = 4; break;
-        case '>':  escseq = "&gt;";   esclen = 4; break;
-        case '\'': escseq = "&apos;"; esclen = 6; break;
-        case '\"': escseq = "&quot;"; esclen = 6; break;
-        case '&':  escseq = "&amp;";  esclen = 5; break;
-        default: ASSERT(false);
-      }
-      if (bufpos + esclen >= buflen) {
-        break;
-      }
-      memcpy(buffer + bufpos, escseq, esclen);
-      bufpos += esclen;
-    } else {
-      buffer[bufpos++] = ch;
-    }
-  }
-  buffer[bufpos] = '\0';
-  return bufpos;
-}
-
-size_t xml_decode(char * buffer, size_t buflen,
-                  const char * source, size_t srclen) {
-  ASSERT(NULL != buffer);  // TODO: estimate output size
-  if (buflen <= 0)
-    return 0;
-
-  size_t srcpos = 0, bufpos = 0;
-  while ((srcpos < srclen) && (bufpos + 1 < buflen)) {
-    unsigned char ch = source[srcpos++];
-    if (ch != '&') {
-      buffer[bufpos++] = ch;
-    } else if ((srcpos + 2 < srclen)
-               && (memcmp(source + srcpos, "lt;", 3) == 0)) {
-      buffer[bufpos++] = '<';
-      srcpos += 3;
-    } else if ((srcpos + 2 < srclen)
-               && (memcmp(source + srcpos, "gt;", 3) == 0)) {
-      buffer[bufpos++] = '>';
-      srcpos += 3;
-    } else if ((srcpos + 4 < srclen)
-               && (memcmp(source + srcpos, "apos;", 5) == 0)) {
-      buffer[bufpos++] = '\'';
-      srcpos += 5;
-    } else if ((srcpos + 4 < srclen)
-               && (memcmp(source + srcpos, "quot;", 5) == 0)) {
-      buffer[bufpos++] = '\"';
-      srcpos += 5;
-    } else if ((srcpos + 3 < srclen)
-               && (memcmp(source + srcpos, "amp;", 4) == 0)) {
-      buffer[bufpos++] = '&';
-      srcpos += 4;
-    } else if ((srcpos < srclen) && (source[srcpos] == '#')) {
-      int int_base = 10;
-      if ((srcpos + 1 < srclen) && (source[srcpos+1] == 'x')) {
-        int_base = 16;
-        srcpos += 1;
-      }
-      char * ptr;
-      // TODO: Fix hack (ptr may go past end of data)
-      unsigned long val = strtoul(source + srcpos + 1, &ptr, int_base);
-      if ((static_cast<size_t>(ptr - source) < srclen) && (*ptr == ';')) {
-        srcpos = ptr - source + 1;
-      } else {
-        // Not a valid escape sequence.
-        break;
-      }
-      if (size_t esclen = utf8_encode(buffer + bufpos, buflen - bufpos, val)) {
-        bufpos += esclen;
-      } else {
-        // Not enough room to encode the character, or illegal character
-        break;
-      }
-    } else {
-      // Unrecognized escape sequence.
-      break;
-    }
-  }
-  buffer[bufpos] = '\0';
-  return bufpos;
-}
-
-std::string hex_encode(const char * source, size_t srclen) {
-  const size_t kBufferSize = srclen * 2 + 1;
-  char* buffer = STACK_ARRAY(char, kBufferSize);
-  size_t length = hex_encode(buffer, kBufferSize, source, srclen);
-  return std::string(buffer, length);
-}
-
-size_t hex_encode(char * buffer, size_t buflen,
-                  const char * csource, size_t srclen) {
-  ASSERT(NULL != buffer);  // TODO: estimate output size
-  if (buflen <= 0)
-    return 0;
-
-  const unsigned char * bsource =
-    reinterpret_cast<const unsigned char *>(csource);
-
-  size_t srcpos = 0, bufpos = 0;
-  srclen = _min(srclen, (buflen - 1) / 2);
-  while (srcpos < srclen) {
-    unsigned char ch = bsource[srcpos++];
-    buffer[bufpos  ] = hex_encode((ch >> 4) & 0xF);
-    buffer[bufpos+1] = hex_encode((ch     ) & 0xF);
-    bufpos += 2;
-  }
-  buffer[bufpos] = '\0';
-  return bufpos;
-}
-
-size_t hex_decode(char * cbuffer, size_t buflen,
-                  const char * source, size_t srclen) {
-  ASSERT(NULL != cbuffer);  // TODO: estimate output size
-  if (buflen <= 0)
-    return 0;
-
-  unsigned char * bbuffer = reinterpret_cast<unsigned char *>(cbuffer);
-
-  unsigned char h1, h2;
-  size_t srcpos = 0, bufpos = 0;
-  while ((srcpos + 1 < srclen)
-         && (bufpos + 1 < buflen)
-         && hex_decode(source[srcpos], &h1)
-         && hex_decode(source[srcpos+1], &h2))
-  {
-    bbuffer[bufpos++] = (h1 << 4) | h2;
-    srcpos += 2;
-  }
-  bbuffer[bufpos] = '\0';
-  return bufpos;
-}
-
-size_t transform(std::string& value, size_t maxlen, const std::string& source,
-                 Transform t) {
-  char* buffer = STACK_ARRAY(char, maxlen + 1);
-  size_t length = t(buffer, maxlen + 1, source.data(), source.length());
-  value.assign(buffer, length);
-  return length;
-}
-
-std::string s_transform(const std::string& source, Transform t) {
-  // Ask transformation function to approximate the destination size (returns upper bound)
-  size_t maxlen = t(NULL, 0, source.data(), source.length());
-  char * buffer = STACK_ARRAY(char, maxlen);
-  size_t len = t(buffer, maxlen, source.data(), source.length());
-  std::string result(buffer, len);
-  return result;
-}
-
-size_t tokenize(const std::string& source, char delimiter,
-                std::vector<std::string>* fields) {
-  ASSERT(NULL != fields);
-  fields->clear();
-  size_t last = 0;
-  for (size_t i = 0; i < source.length(); ++i) {
-    if (source[i] == delimiter) {
-      if (i != last) {
-        fields->push_back(source.substr(last, i - last));
-      }
-      last = i + 1;
-    }
-  }
-  if (last != source.length()) {
-    fields->push_back(source.substr(last, source.length() - last));
-  }
-  return fields->size();
-}
-
-size_t tokenize_append(const std::string& source, char delimiter,
-                       std::vector<std::string>* fields) {
-  if (!fields) return 0;
-
-  std::vector<std::string> new_fields;
-  tokenize(source, delimiter, &new_fields);
-  fields->insert(fields->end(), new_fields.begin(), new_fields.end());
-  return fields->size();
-}
-
-size_t tokenize(const std::string& source, char delimiter, char start_mark,
-                char end_mark, std::vector<std::string>* fields) {
-  if (!fields) return 0;
-  fields->clear();
-
-  std::string remain_source = source;
-  while (!remain_source.empty()) {
-    size_t start_pos = remain_source.find(start_mark);
-    if (std::string::npos == start_pos) break;
-    std::string pre_mark;
-    if (start_pos > 0) {
-      pre_mark = remain_source.substr(0, start_pos - 1);
-    }
-
-    ++start_pos;
-    size_t end_pos = remain_source.find(end_mark, start_pos);
-    if (std::string::npos == end_pos) break;
-
-    // We have found the matching marks. First tokenize the pre-mask. Then add
-    // the marked part as a single field. Finally, loop back for the post-mark.
-    tokenize_append(pre_mark, delimiter, fields);
-    fields->push_back(remain_source.substr(start_pos, end_pos - start_pos));
-    remain_source = remain_source.substr(end_pos + 1);
-  }
-
-  return tokenize_append(remain_source, delimiter, fields);
-}
-
-size_t split(const std::string& source, char delimiter,
-             std::vector<std::string>* fields) {
-  ASSERT(NULL != fields);
-  fields->clear();
-  size_t last = 0;
-  for (size_t i = 0; i < source.length(); ++i) {
-    if (source[i] == delimiter) {
-      fields->push_back(source.substr(last, i - last));
-      last = i + 1;
-    }
-  }
-  fields->push_back(source.substr(last, source.length() - last));
-  return fields->size();
-}
-
-char make_char_safe_for_filename(char c) {
-  if (c < 32)
-    return '_';
-
-  switch (c) {
-    case '<':
-    case '>':
-    case ':':
-    case '"':
-    case '/':
-    case '\\':
-    case '|':
-    case '*':
-    case '?':
-      return '_';
-
-    default:
-      return c;
-  }
-}
-
-/*
-void sprintf(std::string& value, size_t maxlen, const char * format, ...) {
-  char * buffer = STACK_ARRAY(char, maxlen + 1);
-  va_list args;
-  va_start(args, format);
-  value.assign(buffer, vsprintfn(buffer, maxlen + 1, format, args));
-  va_end(args);
-}
-*/
-
-/////////////////////////////////////////////////////////////////////////////
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/stringencode.h b/third_party/libjingle/source/talk/base/stringencode.h
deleted file mode 100644
index 92c794b..0000000
--- a/third_party/libjingle/source/talk/base/stringencode.h
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_STRINGENCODE_H__
-#define TALK_BASE_STRINGENCODE_H__
-
-#include <string>
-#include <sstream>
-#include <vector>
-
-namespace talk_base {
-
-//////////////////////////////////////////////////////////////////////
-// String Encoding Utilities
-//////////////////////////////////////////////////////////////////////
-
-// Convert an unsigned value from 0 to 15 to the hex character equivalent...
-char hex_encode(unsigned char val);
-// ...and vice-versa.
-bool hex_decode(char ch, unsigned char* val);
-
-// Convert an unsigned value to it's utf8 representation.  Returns the length
-// of the encoded string, or 0 if the encoding is longer than buflen - 1.
-size_t utf8_encode(char* buffer, size_t buflen, unsigned long value);
-// Decode the utf8 encoded value pointed to by source.  Returns the number of
-// bytes used by the encoding, or 0 if the encoding is invalid.
-size_t utf8_decode(const char* source, size_t srclen, unsigned long* value);
-
-// Escaping prefixes illegal characters with the escape character.  Compact, but
-// illegal characters still appear in the string.
-size_t escape(char * buffer, size_t buflen,
-              const char * source, size_t srclen,
-              const char * illegal, char escape);
-// Note: in-place unescaping (buffer == source) is allowed.
-size_t unescape(char * buffer, size_t buflen,
-                const char * source, size_t srclen,
-                char escape);
-
-// Encoding replaces illegal characters with the escape character and 2 hex
-// chars, so it's a little less compact than escape, but completely removes
-// illegal characters.  note that hex digits should not be used as illegal
-// characters.
-size_t encode(char * buffer, size_t buflen,
-              const char * source, size_t srclen,
-              const char * illegal, char escape);
-// Note: in-place decoding (buffer == source) is allowed.
-size_t decode(char * buffer, size_t buflen,
-              const char * source, size_t srclen,
-              char escape);
-
-// Returns a list of characters that may be unsafe for use in the name of a
-// file, suitable for passing to the 'illegal' member of escape or encode.
-const char* unsafe_filename_characters();
-
-// url_encode is an encode operation with a predefined set of illegal characters
-// and escape character (for use in URLs, obviously).
-size_t url_encode(char * buffer, size_t buflen,
-                  const char * source, size_t srclen);
-// Note: in-place decoding (buffer == source) is allowed.
-size_t url_decode(char * buffer, size_t buflen,
-                  const char * source, size_t srclen);
-
-// html_encode prevents data embedded in html from containing markup.
-size_t html_encode(char * buffer, size_t buflen,
-                   const char * source, size_t srclen);
-// Note: in-place decoding (buffer == source) is allowed.
-size_t html_decode(char * buffer, size_t buflen,
-                   const char * source, size_t srclen);
-
-// xml_encode makes data suitable for inside xml attributes and values.
-size_t xml_encode(char * buffer, size_t buflen,
-                  const char * source, size_t srclen);
-// Note: in-place decoding (buffer == source) is allowed.
-size_t xml_decode(char * buffer, size_t buflen,
-                  const char * source, size_t srclen);
-
-// hex_encode shows the hex representation of binary data in ascii.
-size_t hex_encode(char * buffer, size_t buflen,
-                  const char * source, size_t srclen);
-size_t hex_decode(char * buffer, size_t buflen,
-                  const char * source, size_t srclen);
-// helper funtion for hex_encode
-std::string hex_encode(const char * source, size_t srclen);
-
-// Apply any suitable string transform (including the ones above) to an STL
-// string.  Stack-allocated temporary space is used for the transformation,
-// so value and source may refer to the same string.
-typedef size_t (*Transform)(char * buffer, size_t buflen,
-                            const char * source, size_t srclen);
-size_t transform(std::string& value, size_t maxlen, const std::string& source,
-                 Transform t);
-
-// Return the result of applying transform t to source.
-std::string s_transform(const std::string& source, Transform t);
-
-// Convenience wrappers
-inline std::string s_url_encode(const std::string& source) {
-  return s_transform(source, url_encode);
-}
-inline std::string s_url_decode(const std::string& source) {
-  return s_transform(source, url_decode);
-}
-
-// Splits the source string into multiple fields separated by delimiter,
-// with duplicates of delimiter creating empty fields.
-size_t split(const std::string& source, char delimiter,
-             std::vector<std::string>* fields);
-
-// Splits the source string into multiple fields separated by delimiter,
-// with duplicates of delimiter ignored.  Trailing delimiter ignored.
-size_t tokenize(const std::string& source, char delimiter,
-                std::vector<std::string>* fields);
-
-// Tokenize and append the tokens to fields. Return the new size of fields.
-size_t tokenize_append(const std::string& source, char delimiter,
-                       std::vector<std::string>* fields);
-
-// Splits the source string into multiple fields separated by delimiter, with
-// duplicates of delimiter ignored. Trailing delimiter ignored. A substring in
-// between the start_mark and the end_mark is treated as a single field. Return
-// the size of fields. For example, if source is "filename
-// \"/Library/Application Support/media content.txt\"", delimiter is ' ', and
-// the start_mark and end_mark are '"', this method returns two fields:
-// "filename" and "/Library/Application Support/media content.txt".
-size_t tokenize(const std::string& source, char delimiter, char start_mark,
-                char end_mark, std::vector<std::string>* fields);
-
-// Safe sprintf to std::string
-//void sprintf(std::string& value, size_t maxlen, const char * format, ...)
-//     PRINTF_FORMAT(3);
-
-// Convert arbitrary values to/from a string.
-
-template <class T>
-static bool ToString(const T &t, std::string* s) {
-  std::ostringstream oss;
-  oss << t;
-  *s = oss.str();
-  return !oss.fail();
-}
-
-template <class T>
-static bool FromString(const std::string& s, T* t) {
-  std::istringstream iss(s);
-  iss >> *t;
-  return !iss.fail();
-}
-
-// Inline versions of the string conversion routines.
-
-template<typename T>
-static inline std::string ToString(T val) {
-  std::string str; ToString(val, &str); return str;
-}
-
-template<typename T>
-static inline T FromString(const std::string& str) {
-  T val; FromString(str, &val); return val;
-}
-
-template<typename T>
-static inline T FromString(const T& defaultValue, const std::string& str) {
-  T val(defaultValue); FromString(str, &val); return val;
-}
-
-// simple function to strip out characters which shouldn't be
-// used in filenames
-char make_char_safe_for_filename(char c);
-
-//////////////////////////////////////////////////////////////////////
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_STRINGENCODE_H__
diff --git a/third_party/libjingle/source/talk/base/stringencode_unittest.cc b/third_party/libjingle/source/talk/base/stringencode_unittest.cc
deleted file mode 100644
index fc1f481..0000000
--- a/third_party/libjingle/source/talk/base/stringencode_unittest.cc
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/common.h"
-#include "talk/base/gunit.h"
-#include "talk/base/stringencode.h"
-#include "talk/base/stringutils.h"
-
-namespace talk_base {
-
-TEST(utf8_encode, EncodeDecode) {
-  const struct Utf8Test {
-    const char* encoded;
-    size_t encsize, enclen;
-    unsigned long decoded;
-  } kTests[] = {
-    { "a    ",             5, 1, 'a' },
-    { "\x7F    ",          5, 1, 0x7F },
-    { "\xC2\x80   ",       5, 2, 0x80 },
-    { "\xDF\xBF   ",       5, 2, 0x7FF },
-    { "\xE0\xA0\x80  ",    5, 3, 0x800 },
-    { "\xEF\xBF\xBF  ",    5, 3, 0xFFFF },
-    { "\xF0\x90\x80\x80 ", 5, 4, 0x10000 },
-    { "\xF0\x90\x80\x80 ", 3, 0, 0x10000 },
-    { "\xF0\xF0\x80\x80 ", 5, 0, 0 },
-    { "\xF0\x90\x80  ",    5, 0, 0 },
-    { "\x90\x80\x80  ",    5, 0, 0 },
-    { NULL, 0, 0 },
-  };
-  for (size_t i=0; kTests[i].encoded; ++i) {
-    unsigned long val = 0;
-    ASSERT_EQ(kTests[i].enclen, utf8_decode(kTests[i].encoded,
-                                            kTests[i].encsize,
-                                            &val));
-    unsigned long result = (kTests[i].enclen == 0) ? 0 : kTests[i].decoded;
-    ASSERT_EQ(result, val);
-
-    if (kTests[i].decoded == 0) {
-      // Not an interesting encoding test case
-      continue;
-    }
-
-    char buffer[5];
-    memset(buffer, 0x01, ARRAY_SIZE(buffer));
-    ASSERT_EQ(kTests[i].enclen, utf8_encode(buffer,
-                                            kTests[i].encsize,
-                                            kTests[i].decoded));
-    ASSERT_TRUE(memcmp(buffer, kTests[i].encoded, kTests[i].enclen) == 0);
-    // Make sure remainder of buffer is unchanged
-    ASSERT_TRUE(memory_check(buffer + kTests[i].enclen,
-                             0x1,
-                             ARRAY_SIZE(buffer) - kTests[i].enclen));
-  }
-}
-
-// TODO: hex_encode unittest
-
-// Tests counting substrings.
-TEST(tokenizeTest, CountSubstrings) {
-  std::vector<std::string> fields;
-
-  EXPECT_EQ(5ul, tokenize("one two three four five", ' ', &fields));
-  fields.clear();
-  EXPECT_EQ(1ul, tokenize("one", ' ', &fields));
-
-  // Extra spaces should be ignored.
-  fields.clear();
-  EXPECT_EQ(5ul, tokenize("  one    two  three    four five  ", ' ', &fields));
-  fields.clear();
-  EXPECT_EQ(1ul, tokenize("  one  ", ' ', &fields));
-  fields.clear();
-  EXPECT_EQ(0ul, tokenize(" ", ' ', &fields));
-}
-
-// Tests comparing substrings.
-TEST(tokenizeTest, CompareSubstrings) {
-  std::vector<std::string> fields;
-
-  tokenize("find middle one", ' ', &fields);
-  ASSERT_EQ(3ul, fields.size());
-  ASSERT_STREQ("middle", fields.at(1).c_str());
-  fields.clear();
-
-  // Extra spaces should be ignored.
-  tokenize("  find   middle  one    ", ' ', &fields);
-  ASSERT_EQ(3ul, fields.size());
-  ASSERT_STREQ("middle", fields.at(1).c_str());
-  fields.clear();
-  tokenize(" ", ' ', &fields);
-  ASSERT_EQ(0ul, fields.size());
-}
-
-TEST(tokenizeTest, TokenizeAppend) {
-  ASSERT_EQ(0ul, tokenize_append("A B C", ' ', NULL));
-
-  std::vector<std::string> fields;
-
-  tokenize_append("A B C", ' ', &fields);
-  ASSERT_EQ(3ul, fields.size());
-  ASSERT_STREQ("B", fields.at(1).c_str());
-
-  tokenize_append("D E", ' ', &fields);
-  ASSERT_EQ(5ul, fields.size());
-  ASSERT_STREQ("B", fields.at(1).c_str());
-  ASSERT_STREQ("E", fields.at(4).c_str());
-}
-
-TEST(tokenizeTest, TokenizeWithMarks) {
-  ASSERT_EQ(0ul, tokenize("D \"A B", ' ', '(', ')', NULL));
-
-  std::vector<std::string> fields;
-  tokenize("A B C", ' ', '"', '"', &fields);
-  ASSERT_EQ(3ul, fields.size());
-  ASSERT_STREQ("C", fields.at(2).c_str());
-
-  tokenize("\"A B\" C", ' ', '"', '"', &fields);
-  ASSERT_EQ(2ul, fields.size());
-  ASSERT_STREQ("A B", fields.at(0).c_str());
-
-  tokenize("D \"A B\" C", ' ', '"', '"', &fields);
-  ASSERT_EQ(3ul, fields.size());
-  ASSERT_STREQ("D", fields.at(0).c_str());
-  ASSERT_STREQ("A B", fields.at(1).c_str());
-
-  tokenize("D \"A B\" C \"E F\"", ' ', '"', '"', &fields);
-  ASSERT_EQ(4ul, fields.size());
-  ASSERT_STREQ("D", fields.at(0).c_str());
-  ASSERT_STREQ("A B", fields.at(1).c_str());
-  ASSERT_STREQ("E F", fields.at(3).c_str());
-
-  // No matching marks.
-  tokenize("D \"A B", ' ', '"', '"', &fields);
-  ASSERT_EQ(3ul, fields.size());
-  ASSERT_STREQ("D", fields.at(0).c_str());
-  ASSERT_STREQ("\"A", fields.at(1).c_str());
-
-  tokenize("D (A B) C (E F) G", ' ', '(', ')', &fields);
-  ASSERT_EQ(5ul, fields.size());
-  ASSERT_STREQ("D", fields.at(0).c_str());
-  ASSERT_STREQ("A B", fields.at(1).c_str());
-  ASSERT_STREQ("E F", fields.at(3).c_str());
-}
-
-// Tests counting substrings.
-TEST(splitTest, CountSubstrings) {
-  std::vector<std::string> fields;
-
-  EXPECT_EQ(5ul, split("one,two,three,four,five", ',', &fields));
-  fields.clear();
-  EXPECT_EQ(1ul, split("one", ',', &fields));
-
-  // Empty fields between commas count.
-  fields.clear();
-  EXPECT_EQ(5ul, split("one,,three,four,five", ',', &fields));
-  fields.clear();
-  EXPECT_EQ(3ul, split(",three,", ',', &fields));
-  fields.clear();
-  EXPECT_EQ(1ul, split("", ',', &fields));
-}
-
-// Tests comparing substrings.
-TEST(splitTest, CompareSubstrings) {
-  std::vector<std::string> fields;
-
-  split("find,middle,one", ',', &fields);
-  ASSERT_EQ(3ul, fields.size());
-  ASSERT_STREQ("middle", fields.at(1).c_str());
-  fields.clear();
-
-  // Empty fields between commas count.
-  split("find,,middle,one", ',', &fields);
-  ASSERT_EQ(4ul, fields.size());
-  ASSERT_STREQ("middle", fields.at(2).c_str());
-  fields.clear();
-  split("", ',', &fields);
-  ASSERT_EQ(1ul, fields.size());
-  ASSERT_STREQ("", fields.at(0).c_str());
-}
-
-} // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/stringutils.cc b/third_party/libjingle/source/talk/base/stringutils.cc
deleted file mode 100644
index c4c2b2f..0000000
--- a/third_party/libjingle/source/talk/base/stringutils.cc
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/stringutils.h"
-#include "talk/base/common.h"
-
-namespace talk_base {
-
-bool memory_check(const void* memory, int c, size_t count) {
-  const char* char_memory = static_cast<const char*>(memory);
-  char char_c = static_cast<char>(c);
-  for (size_t i = 0; i < count; ++i) {
-    if (char_memory[i] != char_c) {
-      return false;
-    }
-  }
-  return true;
-}
-
-bool string_match(const char* target, const char* pattern) {
-  while (*pattern) {
-    if (*pattern == '*') {
-      if (!*++pattern) {
-        return true;
-      }
-      while (*target) {
-        if ((toupper(*pattern) == toupper(*target))
-            && string_match(target + 1, pattern + 1)) {
-          return true;
-        }
-        ++target;
-      }
-      return false;
-    } else {
-      if (toupper(*pattern) != toupper(*target)) {
-        return false;
-      }
-      ++target;
-      ++pattern;
-    }
-  }
-  return !*target;
-}
-
-#ifdef WIN32
-int ascii_string_compare(const wchar_t* s1, const char* s2, size_t n,
-                         CharacterTransformation transformation) {
-  wchar_t c1, c2;
-  while (true) {
-    if (n-- == 0) return 0;
-    c1 = transformation(*s1);
-    // Double check that characters are not UTF-8
-    ASSERT(static_cast<unsigned char>(*s2) < 128);
-    // Note: *s2 gets implicitly promoted to wchar_t
-    c2 = transformation(*s2);
-    if (c1 != c2) return (c1 < c2) ? -1 : 1;
-    if (!c1) return 0;
-    ++s1;
-    ++s2;
-  }
-}
-
-size_t asccpyn(wchar_t* buffer, size_t buflen,
-               const char* source, size_t srclen) {
-  if (buflen <= 0)
-    return 0;
-
-  if (srclen == SIZE_UNKNOWN) {
-    srclen = strlenn(source, buflen - 1);
-  } else if (srclen >= buflen) {
-    srclen = buflen - 1;
-  }
-#if _DEBUG
-  // Double check that characters are not UTF-8
-  for (size_t pos = 0; pos < srclen; ++pos)
-    ASSERT(static_cast<unsigned char>(source[pos]) < 128);
-#endif  // _DEBUG
-  std::copy(source, source + srclen, buffer);
-  buffer[srclen] = 0;
-  return srclen;
-}
-
-#endif  // WIN32
-
-void replace_substrs(const char *search,
-                     size_t search_len,
-                     const char *replace,
-                     size_t replace_len,
-                     std::string *s) {
-  size_t pos = 0;
-  while ((pos = s->find(search, pos, search_len)) != std::string::npos) {
-    s->replace(pos, search_len, replace, replace_len);
-    pos += replace_len;
-  }
-}
-
-bool starts_with(const char *s1, const char *s2) {
-  return strncmp(s1, s2, strlen(s2)) == 0;
-}
-
-bool ends_with(const char *s1, const char *s2) {
-  size_t s1_length = strlen(s1);
-  size_t s2_length = strlen(s2);
-
-  if (s2_length > s1_length) {
-    return false;
-  }
-
-  const char* start = s1 + (s1_length - s2_length);
-  return strncmp(start, s2, s2_length) == 0;
-}
-
-static const char kWhitespace[] = " \n\r\t";
-
-std::string string_trim(const std::string& s) {
-  std::string::size_type first = s.find_first_not_of(kWhitespace);
-  std::string::size_type last  = s.find_last_not_of(kWhitespace);
-
-  if (first == std::string::npos || last == std::string::npos) {
-    return std::string("");
-  }
-
-  return s.substr(first, last - first + 1);
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/stringutils.h b/third_party/libjingle/source/talk/base/stringutils.h
deleted file mode 100644
index 661a343..0000000
--- a/third_party/libjingle/source/talk/base/stringutils.h
+++ /dev/null
@@ -1,343 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_STRINGUTILS_H__
-#define TALK_BASE_STRINGUTILS_H__
-
-#include <ctype.h>
-#include <stdarg.h>
-#include <stdio.h>
-
-#ifdef WIN32
-#include <malloc.h>
-#include <wchar.h>
-#define alloca _alloca
-#endif  // WIN32
-
-#ifdef POSIX
-#ifdef BSD
-#include <stdlib.h>
-#else  // BSD
-#include <alloca.h>
-#endif  // !BSD
-#endif  // POSIX
-
-#include <cstring>
-#include <string>
-
-#include "talk/base/basictypes.h"
-
-///////////////////////////////////////////////////////////////////////////////
-// Generic string/memory utilities
-///////////////////////////////////////////////////////////////////////////////
-
-#define STACK_ARRAY(TYPE, LEN) static_cast<TYPE*>(::alloca((LEN)*sizeof(TYPE)))
-
-namespace talk_base {
-
-// Complement to memset.  Verifies memory consists of count bytes of value c.
-bool memory_check(const void* memory, int c, size_t count);
-
-// Determines whether the simple wildcard pattern matches target.
-// Alpha characters in pattern match case-insensitively.
-// Asterisks in pattern match 0 or more characters.
-// Ex: string_match("www.TEST.GOOGLE.COM", "www.*.com") -> true
-bool string_match(const char* target, const char* pattern);
-
-}  // namespace talk_base
-
-///////////////////////////////////////////////////////////////////////////////
-// Rename a bunch of common string functions so they are consistent across
-// platforms and between char and wchar_t variants.
-// Here is the full list of functions that are unified:
-//  strlen, strcmp, stricmp, strncmp, strnicmp
-//  strchr, vsnprintf, strtoul, tolowercase
-// tolowercase is like tolower, but not compatible with end-of-file value
-//
-// It's not clear if we will ever use wchar_t strings on unix.  In theory,
-// all strings should be Utf8 all the time, except when interfacing with Win32
-// APIs that require Utf16.
-///////////////////////////////////////////////////////////////////////////////
-
-inline char tolowercase(char c) {
-  return static_cast<char>(tolower(c));
-}
-
-#ifdef WIN32
-
-inline size_t strlen(const wchar_t* s) {
-  return wcslen(s);
-}
-inline int strcmp(const wchar_t* s1, const wchar_t* s2) {
-  return wcscmp(s1, s2);
-}
-inline int stricmp(const wchar_t* s1, const wchar_t* s2) {
-  return _wcsicmp(s1, s2);
-}
-inline int strncmp(const wchar_t* s1, const wchar_t* s2, size_t n) {
-  return wcsncmp(s1, s2, n);
-}
-inline int strnicmp(const wchar_t* s1, const wchar_t* s2, size_t n) {
-  return _wcsnicmp(s1, s2, n);
-}
-inline const wchar_t* strchr(const wchar_t* s, wchar_t c) {
-  return wcschr(s, c);
-}
-inline const wchar_t* strstr(const wchar_t* haystack, const wchar_t* needle) {
-  return wcsstr(haystack, needle);
-}
-#ifndef vsnprintf
-inline int vsnprintf(char* buf, size_t n, const char* fmt, va_list args) {
-  return _vsnprintf(buf, n, fmt, args);
-}
-inline int vsnprintf(wchar_t* buf, size_t n, const wchar_t* fmt, va_list args) {
-  return _vsnwprintf(buf, n, fmt, args);
-}
-#endif // !vsnprintf
-inline unsigned long strtoul(const wchar_t* snum, wchar_t** end, int base) {
-  return wcstoul(snum, end, base);
-}
-inline wchar_t tolowercase(wchar_t c) {
-  return static_cast<wchar_t>(towlower(c));
-}
-
-#endif  // WIN32
-
-#ifdef POSIX
-
-inline int _stricmp(const char* s1, const char* s2) {
-  return strcasecmp(s1, s2);
-}
-inline int _strnicmp(const char* s1, const char* s2, size_t n) {
-  return strncasecmp(s1, s2, n);
-}
-
-#endif // POSIX
-
-///////////////////////////////////////////////////////////////////////////////
-// Traits simplifies porting string functions to be CTYPE-agnostic
-///////////////////////////////////////////////////////////////////////////////
-
-namespace talk_base {
-
-const size_t SIZE_UNKNOWN = static_cast<size_t>(-1);
-
-template<class CTYPE>
-struct Traits {
-  // STL string type
-  //typedef XXX string;
-  // Null-terminated string
-  //inline static const CTYPE* empty_str();
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// String utilities which work with char or wchar_t
-///////////////////////////////////////////////////////////////////////////////
-
-template<class CTYPE>
-inline const CTYPE* nonnull(const CTYPE* str, const CTYPE* def_str = NULL) {
-  return str ? str : (def_str ? def_str : Traits<CTYPE>::empty_str());
-}
-
-template<class CTYPE>
-const CTYPE* strchr(const CTYPE* str, const CTYPE* chs) {
-  for (size_t i=0; str[i]; ++i) {
-    for (size_t j=0; chs[j]; ++j) {
-      if (str[i] == chs[j]) {
-        return str + i;
-      }
-    }
-  }
-  return 0;
-}
-
-template<class CTYPE>
-const CTYPE* strchrn(const CTYPE* str, size_t slen, CTYPE ch) {
-  for (size_t i=0; i<slen && str[i]; ++i) {
-    if (str[i] == ch) {
-      return str + i;
-    }
-  }
-  return 0;
-}
-
-template<class CTYPE>
-size_t strlenn(const CTYPE* buffer, size_t buflen) {
-  size_t bufpos = 0;
-  while (buffer[bufpos] && (bufpos < buflen)) {
-    ++bufpos;
-  }
-  return bufpos;
-}
-
-// Safe versions of strncpy, strncat, snprintf and vsnprintf that always
-// null-terminate.
-
-template<class CTYPE>
-size_t strcpyn(CTYPE* buffer, size_t buflen,
-               const CTYPE* source, size_t srclen = SIZE_UNKNOWN) {
-  if (buflen <= 0)
-    return 0;
-
-  if (srclen == SIZE_UNKNOWN) {
-    srclen = strlenn(source, buflen - 1);
-  } else if (srclen >= buflen) {
-    srclen = buflen - 1;
-  }
-  memcpy(buffer, source, srclen * sizeof(CTYPE));
-  buffer[srclen] = 0;
-  return srclen;
-}
-
-template<class CTYPE>
-size_t strcatn(CTYPE* buffer, size_t buflen,
-               const CTYPE* source, size_t srclen = SIZE_UNKNOWN) {
-  if (buflen <= 0)
-    return 0;
-  
-  size_t bufpos = strlenn(buffer, buflen - 1);
-  return bufpos + strcpyn(buffer + bufpos, buflen - bufpos, source, srclen);
-}
-
-// Some compilers (clang specifically) require vsprintfn be defined before
-// sprintfn.
-template<class CTYPE>
-size_t vsprintfn(CTYPE* buffer, size_t buflen, const CTYPE* format,
-                 va_list args) {
-  int len = vsnprintf(buffer, buflen, format, args);
-  if ((len < 0) || (static_cast<size_t>(len) >= buflen)) {
-    len = static_cast<int>(buflen - 1);
-    buffer[len] = 0;
-  }
-  return len;
-}
-
-template<class CTYPE>
-size_t sprintfn(CTYPE* buffer, size_t buflen, const CTYPE* format, ...);
-/* This works to get GCC to notice printf argument mismatches, but then complains of missing implementation of sprintfn<char>
-template<>
-size_t sprintfn(char* buffer, size_t buflen, const char* format, ...)
-GCC_ATTR(format(printf,3,4));
-*/
-template<class CTYPE>
-size_t sprintfn(CTYPE* buffer, size_t buflen, const CTYPE* format, ...) {
-  va_list args;
-  va_start(args, format);
-  size_t len = vsprintfn(buffer, buflen, format, args);
-  va_end(args);
-  return len;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Allow safe comparing and copying ascii (not UTF-8) with both wide and
-// non-wide character strings.
-///////////////////////////////////////////////////////////////////////////////
-
-inline int asccmp(const char* s1, const char* s2) {
-  return strcmp(s1, s2);
-}
-inline int ascicmp(const char* s1, const char* s2) {
-  return _stricmp(s1, s2);
-}
-inline int ascncmp(const char* s1, const char* s2, size_t n) {
-  return strncmp(s1, s2, n);
-}
-inline int ascnicmp(const char* s1, const char* s2, size_t n) {
-  return _strnicmp(s1, s2, n);
-}
-inline size_t asccpyn(char* buffer, size_t buflen,
-                      const char* source, size_t srclen = SIZE_UNKNOWN) {
-  return strcpyn(buffer, buflen, source, srclen);
-}
-
-#ifdef WIN32
-
-typedef wchar_t(*CharacterTransformation)(wchar_t);
-inline wchar_t identity(wchar_t c) { return c; }
-int ascii_string_compare(const wchar_t* s1, const char* s2, size_t n,
-                         CharacterTransformation transformation);
-
-inline int asccmp(const wchar_t* s1, const char* s2) {
-  return ascii_string_compare(s1, s2, static_cast<size_t>(-1), identity);
-}
-inline int ascicmp(const wchar_t* s1, const char* s2) {
-  return ascii_string_compare(s1, s2, static_cast<size_t>(-1), tolowercase);
-}
-inline int ascncmp(const wchar_t* s1, const char* s2, size_t n) {
-  return ascii_string_compare(s1, s2, n, identity);
-}
-inline int ascnicmp(const wchar_t* s1, const char* s2, size_t n) {
-  return ascii_string_compare(s1, s2, n, tolowercase);
-}
-size_t asccpyn(wchar_t* buffer, size_t buflen,
-               const char* source, size_t srclen = SIZE_UNKNOWN);
-
-#endif  // WIN32
-
-///////////////////////////////////////////////////////////////////////////////
-// Traits<char> specializations
-///////////////////////////////////////////////////////////////////////////////
-
-template<>
-struct Traits<char> {
-  typedef std::string string;
-  inline static const char* empty_str() { return ""; }
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// Traits<wchar_t> specializations (Windows only, currently)
-///////////////////////////////////////////////////////////////////////////////
-
-#ifdef WIN32
-
-template<>
-struct Traits<wchar_t> {
-  typedef std::wstring string;
-  inline static const wchar_t* Traits<wchar_t>::empty_str() { return L""; }
-};
-
-#endif  // WIN32
-
-// Replaces all occurrences of "search" with "replace".
-void replace_substrs(const char *search,
-                     size_t search_len,
-                     const char *replace,
-                     size_t replace_len,
-                     std::string *s);
-
-// True iff s1 starts with s2.
-bool starts_with(const char *s1, const char *s2);
-
-// True iff s1 ends with s2.
-bool ends_with(const char *s1, const char *s2);
-
-// Remove leading and trailing whitespaces.
-std::string string_trim(const std::string& s);
-
-}  // namespace talk_base
-
-#endif // TALK_BASE_STRINGUTILS_H__
diff --git a/third_party/libjingle/source/talk/base/stringutils_unittest.cc b/third_party/libjingle/source/talk/base/stringutils_unittest.cc
deleted file mode 100644
index 5611869..0000000
--- a/third_party/libjingle/source/talk/base/stringutils_unittest.cc
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/gunit.h"
-#include "talk/base/stringutils.h"
-#include "talk/base/common.h"
-
-namespace talk_base {
-
-// Tests for string_match().
-
-TEST(string_matchTest, Matches) {
-  EXPECT_TRUE( string_match("A.B.C.D", "a.b.c.d"));
-  EXPECT_TRUE( string_match("www.TEST.GOOGLE.COM", "www.*.com"));
-  EXPECT_TRUE( string_match("127.0.0.1",  "12*.0.*1"));
-  EXPECT_TRUE( string_match("127.1.0.21", "12*.0.*1"));
-  EXPECT_FALSE(string_match("127.0.0.0",  "12*.0.*1"));
-  EXPECT_FALSE(string_match("127.0.0.0",  "12*.0.*1"));
-  EXPECT_FALSE(string_match("127.1.1.21", "12*.0.*1"));
-}
-
-// It's not clear if we will ever use wchar_t strings on unix.  In theory,
-// all strings should be Utf8 all the time, except when interfacing with Win32
-// APIs that require Utf16.
-
-#ifdef WIN32
-
-// Tests for ascii_string_compare().
-
-// Tests NULL input.
-TEST(ascii_string_compareTest, NullInput) {
-  // The following results in an access violation in
-  // ascii_string_compare.  Is this a bug or by design?  stringutils.h
-  // should document the expected behavior in this case.
-
-  // EXPECT_EQ(0, ascii_string_compare(NULL, NULL, 1, identity));
-}
-
-// Tests comparing two strings of different lengths.
-TEST(ascii_string_compareTest, DifferentLengths) {
-  EXPECT_EQ(-1, ascii_string_compare(L"Test", "Test1", 5, identity));
-}
-
-// Tests the case where the buffer size is smaller than the string
-// lengths.
-TEST(ascii_string_compareTest, SmallBuffer) {
-  EXPECT_EQ(0, ascii_string_compare(L"Test", "Test1", 3, identity));
-}
-
-// Tests the case where the buffer is not full.
-TEST(ascii_string_compareTest, LargeBuffer) {
-  EXPECT_EQ(0, ascii_string_compare(L"Test", "Test", 10, identity));
-}
-
-// Tests comparing two eqaul strings.
-TEST(ascii_string_compareTest, Equal) {
-  EXPECT_EQ(0, ascii_string_compare(L"Test", "Test", 5, identity));
-  EXPECT_EQ(0, ascii_string_compare(L"TeSt", "tEsT", 5, tolowercase));
-}
-
-// Tests comparing a smller string to a larger one.
-TEST(ascii_string_compareTest, LessThan) {
-  EXPECT_EQ(-1, ascii_string_compare(L"abc", "abd", 4, identity));
-  EXPECT_EQ(-1, ascii_string_compare(L"ABC", "abD", 5, tolowercase));
-}
-
-// Tests comparing a larger string to a smaller one.
-TEST(ascii_string_compareTest, GreaterThan) {
-  EXPECT_EQ(1, ascii_string_compare(L"xyz", "xy", 5, identity));
-  EXPECT_EQ(1, ascii_string_compare(L"abc", "ABB", 5, tolowercase));
-}
-#endif  // WIN32
-
-TEST(string_trim_Test, Trimming) {
-  EXPECT_EQ("temp", string_trim("\n\r\t temp \n\r\t"));
-  EXPECT_EQ("temp\n\r\t temp", string_trim(" temp\n\r\t temp "));
-  EXPECT_EQ("temp temp", string_trim("temp temp"));
-  EXPECT_EQ("", string_trim(" \r\n\t"));
-  EXPECT_EQ("", string_trim(""));
-}
-
-TEST(string_startsTest, StartsWith) {
-  EXPECT_TRUE(starts_with("foobar", "foo"));
-  EXPECT_TRUE(starts_with("foobar", "foobar"));
-  EXPECT_TRUE(starts_with("foobar", ""));
-  EXPECT_TRUE(starts_with("", ""));
-  EXPECT_FALSE(starts_with("foobar", "bar"));
-  EXPECT_FALSE(starts_with("foobar", "foobarbaz"));
-  EXPECT_FALSE(starts_with("", "f"));
-}
-
-TEST(string_endsTest, EndsWith) {
-  EXPECT_TRUE(ends_with("foobar", "bar"));
-  EXPECT_TRUE(ends_with("foobar", "foobar"));
-  EXPECT_TRUE(ends_with("foobar", ""));
-  EXPECT_TRUE(ends_with("", ""));
-  EXPECT_FALSE(ends_with("foobar", "foo"));
-  EXPECT_FALSE(ends_with("foobar", "foobarbaz"));
-  EXPECT_FALSE(ends_with("", "f"));
-}
-
-} // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/systeminfo.cc b/third_party/libjingle/source/talk/base/systeminfo.cc
deleted file mode 100644
index 7cbc418..0000000
--- a/third_party/libjingle/source/talk/base/systeminfo.cc
+++ /dev/null
@@ -1,461 +0,0 @@
-/*
- * libjingle
- * Copyright 2008 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifdef WIN32
-#include "talk/base/scoped_ptr.h"
-#include "talk/base/win32.h"  // first because it brings in win32 stuff
-#ifndef EXCLUDE_D3D9
-#include <d3d9.h>
-#endif
-
-#elif defined(OSX)
-#include <ApplicationServices/ApplicationServices.h>
-#include <CoreServices/CoreServices.h>
-#include <sys/sysctl.h>
-#include "talk/base/macconversion.h"
-#elif defined(IOS)
-#include <sys/sysctl.h>
-#elif defined(LINUX) || defined(ANDROID)
-#include <unistd.h>
-#include "talk/base/linux.h"
-#endif
-
-#include "talk/base/common.h"
-#include "talk/base/cpuid.h"
-#include "talk/base/logging.h"
-#include "talk/base/stringutils.h"
-#include "talk/base/systeminfo.h"
-
-namespace talk_base {
-
-// See Also: http://msdn.microsoft.com/en-us/library/ms683194(v=vs.85).aspx
-#ifdef WIN32
-typedef BOOL (WINAPI *LPFN_GLPI)(
-    PSYSTEM_LOGICAL_PROCESSOR_INFORMATION,
-    PDWORD);
-
-static int NumCores() {
-  // GetLogicalProcessorInformation() is available on Windows XP SP3 and beyond.
-  LPFN_GLPI glpi = reinterpret_cast<LPFN_GLPI>(GetProcAddress(
-      GetModuleHandle(L"kernel32"),
-      "GetLogicalProcessorInformation"));
-  if (NULL == glpi) {
-    return -1;
-  }
-  // Determine buffer size, allocate and get processor information.
-  // Size can change between calls (unlikely), so a loop is done.
-  DWORD return_length = 0;
-  scoped_array<SYSTEM_LOGICAL_PROCESSOR_INFORMATION> infos;
-  while (!glpi(infos.get(), &return_length)) {
-    if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
-      infos.reset(new SYSTEM_LOGICAL_PROCESSOR_INFORMATION[
-          return_length / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION)]);
-    } else {
-      return -1;
-    }
-  }
-  int processor_core_count = 0;
-  for (size_t i = 0;
-      i < return_length / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION); ++i) {
-    if (infos[i].Relationship == RelationProcessorCore) {
-      ++processor_core_count;
-    }
-  }
-  return processor_core_count;
-}
-#endif
-
-// Note(fbarchard):
-// Family and model are extended family and extended model.  8 bits each.
-SystemInfo::SystemInfo()
-    : physical_cpus_(1), logical_cpus_(1),
-      cpu_family_(0), cpu_model_(0), cpu_stepping_(0),
-      cpu_speed_(0), memory_(0) {
-  // Initialize the basic information.
-
-#if defined(__arm__)
-  cpu_arch_ = ARCH_ARM;
-#elif defined(CPU_X86)
-  cpu_arch_ = ARCH_X86;
-#else
-#error "Unknown architecture."
-#endif
-
-#ifdef WIN32
-  SYSTEM_INFO si;
-  GetSystemInfo(&si);
-  logical_cpus_ = si.dwNumberOfProcessors;
-  physical_cpus_ = NumCores();
-  if (physical_cpus_ <= 0) {
-    physical_cpus_ = logical_cpus_;
-  }
-  cpu_family_ = si.wProcessorLevel;
-  cpu_model_ = si.wProcessorRevision >> 8;
-  cpu_stepping_ = si.wProcessorRevision & 0xFF;
-#elif defined(OSX) || defined(IOS)
-  uint32_t sysctl_value;
-  size_t length = sizeof(sysctl_value);
-  if (!sysctlbyname("hw.physicalcpu_max", &sysctl_value, &length, NULL, 0)) {
-    physical_cpus_ = static_cast<int>(sysctl_value);
-  }
-  length = sizeof(sysctl_value);
-  if (!sysctlbyname("hw.logicalcpu_max", &sysctl_value, &length, NULL, 0)) {
-    logical_cpus_ = static_cast<int>(sysctl_value);
-  }
-  length = sizeof(sysctl_value);
-  if (!sysctlbyname("machdep.cpu.family", &sysctl_value, &length, NULL, 0)) {
-    cpu_family_ = static_cast<int>(sysctl_value);
-  }
-  length = sizeof(sysctl_value);
-  if (!sysctlbyname("machdep.cpu.model", &sysctl_value, &length, NULL, 0)) {
-    cpu_model_ = static_cast<int>(sysctl_value);
-  }
-  length = sizeof(sysctl_value);
-  if (!sysctlbyname("machdep.cpu.stepping", &sysctl_value, &length, NULL, 0)) {
-    cpu_stepping_ = static_cast<int>(sysctl_value);
-  }
-#else // LINUX || ANDROID
-  ProcCpuInfo proc_info;
-  if (proc_info.LoadFromSystem()) {
-    proc_info.GetNumCpus(&logical_cpus_);
-    proc_info.GetNumPhysicalCpus(&physical_cpus_);
-    proc_info.GetCpuFamily(&cpu_family_);
-#if !defined(__arm__)
-    // These values aren't found on ARM systems.
-    proc_info.GetSectionIntValue(0, "model", &cpu_model_);
-    proc_info.GetSectionIntValue(0, "stepping", &cpu_stepping_);
-    proc_info.GetSectionIntValue(0, "cpu MHz", &cpu_speed_);
-#endif
-  }
-
-  // ProcCpuInfo reads cpu speed from "cpu MHz" under /proc/cpuinfo.
-  // But that number is a moving target which can change on-the-fly according to
-  // many factors including system workload.
-  // See /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors.
-  // The one in /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq is more
-  // accurate. We use it as our cpu speed when it is available.
-  int max_freq = talk_base::ReadCpuMaxFreq();
-  if (max_freq > 0) {
-    cpu_speed_ = max_freq;
-  }
-#endif
-}
-
-// Return the number of cpu threads available to the system.
-int SystemInfo::GetMaxCpus() {
-  return logical_cpus_;
-}
-
-// Return the number of cpu cores available to the system.
-int SystemInfo::GetMaxPhysicalCpus() {
-  return physical_cpus_;
-}
-
-// Return the number of cpus available to the process.  Since affinity can be
-// changed on the fly, do not cache this value.
-// Can be affected by heat.
-int SystemInfo::GetCurCpus() {
-  int cur_cpus;
-#ifdef WIN32
-  DWORD process_mask, system_mask;
-  ::GetProcessAffinityMask(::GetCurrentProcess(), &process_mask, &system_mask);
-  for (cur_cpus = 0; process_mask; ++cur_cpus) {
-    // Sparse-ones algorithm. There are slightly faster methods out there but
-    // they are unintuitive and won't make a difference on a single dword.
-    process_mask &= (process_mask - 1);
-  }
-#elif defined(OSX)
-  // Find number of _available_ cores
-  cur_cpus = MPProcessorsScheduled();
-#elif defined(IOS)
-  uint32_t sysctl_value;
-  size_t length = sizeof(sysctl_value);
-  int error = sysctlbyname("hw.ncpu", &sysctl_value, &length, NULL, 0);
-  cur_cpus = !error ? static_cast<int>(sysctl_value) : 1;
-#else
-  // Linux, Solaris, ANDROID
-  cur_cpus = static_cast<int>(sysconf(_SC_NPROCESSORS_ONLN));
-#endif
-  return cur_cpus;
-}
-
-// Return the type of this CPU.
-SystemInfo::Architecture SystemInfo::GetCpuArchitecture() {
-  return cpu_arch_;
-}
-
-// Returns the vendor string from the cpu, e.g. "GenuineIntel", "AuthenticAMD".
-// See "Intel Processor Identification and the CPUID Instruction"
-// (Intel document number: 241618)
-std::string SystemInfo::GetCpuVendor() {
-  if (cpu_vendor_.empty()) {
-    cpu_vendor_ = talk_base::CpuInfo::GetCpuVendor();
-  }
-  return cpu_vendor_;
-}
-
-// Return the "family" of this CPU.
-int SystemInfo::GetCpuFamily() {
-  return cpu_family_;
-}
-
-// Return the "model" of this CPU.
-int SystemInfo::GetCpuModel() {
-  return cpu_model_;
-}
-
-// Return the "stepping" of this CPU.
-int SystemInfo::GetCpuStepping() {
-  return cpu_stepping_;
-}
-
-// Return the clockrate of the primary processor in Mhz.  This value can be
-// cached.  Returns -1 on error.
-int SystemInfo::GetMaxCpuSpeed() {
-  if (cpu_speed_) {
-    return cpu_speed_;
-  }
-
-#ifdef WIN32
-  HKEY key;
-  static const WCHAR keyName[] =
-      L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0";
-
-  if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyName , 0, KEY_QUERY_VALUE, &key)
-      == ERROR_SUCCESS) {
-    DWORD data, len;
-    len = sizeof(data);
-
-    if (RegQueryValueEx(key, L"~Mhz", 0, 0, reinterpret_cast<LPBYTE>(&data),
-                        &len) == ERROR_SUCCESS) {
-      cpu_speed_ = data;
-    } else {
-      LOG(LS_WARNING) << "Failed to query registry value HKLM\\" << keyName
-                      << "\\~Mhz";
-      cpu_speed_ = -1;
-    }
-
-    RegCloseKey(key);
-  } else {
-    LOG(LS_WARNING) << "Failed to open registry key HKLM\\" << keyName;
-    cpu_speed_ = -1;
-  }
-#elif defined(IOS) || defined(OSX)
-  uint64_t sysctl_value;
-  size_t length = sizeof(sysctl_value);
-  int error = sysctlbyname("hw.cpufrequency_max", &sysctl_value, &length, NULL, 0);
-  cpu_speed_ = !error ? static_cast<int>(sysctl_value/1000000) : -1;
-#else
-  // TODO: Implement using proc/cpuinfo
-  cpu_speed_ = 0;
-#endif
-  return cpu_speed_;
-}
-
-// Dynamically check the current clockrate, which could be reduced because of
-// powersaving profiles.  Eventually for windows we want to query WMI for
-// root\WMI::ProcessorPerformance.InstanceName="Processor_Number_0".frequency
-int SystemInfo::GetCurCpuSpeed() {
-#ifdef WIN32
-  // TODO: Add WMI check, requires COM initialization
-  // NOTE(fbarchard): Testable on Sandy Bridge.
-  return GetMaxCpuSpeed();
-#elif defined(IOS) || defined(OSX)
-  uint64_t sysctl_value;
-  size_t length = sizeof(sysctl_value);
-  int error = sysctlbyname("hw.cpufrequency", &sysctl_value, &length, NULL, 0);
-  return !error ? static_cast<int>(sysctl_value/1000000) : GetMaxCpuSpeed();
-#else // LINUX || ANDROID
-  // TODO: Use proc/cpuinfo for Cur speed on Linux.
-  return GetMaxCpuSpeed();
-#endif
-}
-
-// Returns the amount of installed physical memory in Bytes.  Cacheable.
-// Returns -1 on error.
-int64 SystemInfo::GetMemorySize() {
-  if (memory_) {
-    return memory_;
-  }
-
-#ifdef WIN32
-  MEMORYSTATUSEX status = {0};
-  status.dwLength = sizeof(status);
-
-  if (GlobalMemoryStatusEx(&status)) {
-    memory_ = status.ullTotalPhys;
-  } else {
-    LOG_GLE(LS_WARNING) << "GlobalMemoryStatusEx failed.";
-    memory_ = -1;
-  }
-
-#elif defined(OSX) || defined(IOS)
-  size_t len = sizeof(memory_);
-  int error = sysctlbyname("hw.memsize", &memory_, &len, NULL, 0);
-  if (error || memory_ == 0) {
-    memory_ = -1;
-  }
-#else
-  memory_ = static_cast<int64>(sysconf(_SC_PHYS_PAGES)) *
-      static_cast<int64>(sysconf(_SC_PAGESIZE));
-  if (memory_ < 0) {
-    LOG(LS_WARNING) << "sysconf(_SC_PHYS_PAGES) failed."
-                    << "sysconf(_SC_PHYS_PAGES) " << sysconf(_SC_PHYS_PAGES)
-                    << "sysconf(_SC_PAGESIZE) " << sysconf(_SC_PAGESIZE);
-    memory_ = -1;
-  }
-#endif
-
-  return memory_;
-}
-
-
-// Return the name of the machine model we are currently running on.
-// This is a human readable string that consists of the name and version
-// number of the hardware, i.e 'MacBookAir1,1'. Returns an empty string if
-// model can not be determined. The string is cached for subsequent calls.
-std::string SystemInfo::GetMachineModel() {
-  if (!machine_model_.empty()) {
-    return machine_model_;
-  }
-
-#if defined(OSX) || defined(IOS)
-  char buffer[128];
-  size_t length = sizeof(buffer);
-  int error = sysctlbyname("hw.model", buffer, &length, NULL, 0);
-  if (!error) {
-    machine_model_.assign(buffer, length - 1);
-  } else {
-    machine_model_.clear();
-  }
-#else
-  machine_model_ = "Not available";
-#endif
-
-  return machine_model_;
-}
-
-#ifdef OSX
-// Helper functions to query IOKit for video hardware properties.
-static CFTypeRef SearchForProperty(io_service_t port, CFStringRef name) {
-  return IORegistryEntrySearchCFProperty(port, kIOServicePlane,
-      name, kCFAllocatorDefault,
-      kIORegistryIterateRecursively | kIORegistryIterateParents);
-}
-
-static void GetProperty(io_service_t port, CFStringRef name, int* value) {
-  if (!value) return;
-  CFTypeRef ref = SearchForProperty(port, name);
-  if (ref) {
-    CFTypeID refType = CFGetTypeID(ref);
-    if (CFNumberGetTypeID() == refType) {
-      CFNumberRef number = reinterpret_cast<CFNumberRef>(ref);
-      p_convertCFNumberToInt(number, value);
-    } else if (CFDataGetTypeID() == refType) {
-      CFDataRef data = reinterpret_cast<CFDataRef>(ref);
-      if (CFDataGetLength(data) == sizeof(UInt32)) {
-        *value = *reinterpret_cast<const UInt32*>(CFDataGetBytePtr(data));
-      }
-    }
-    CFRelease(ref);
-  }
-}
-
-static void GetProperty(io_service_t port, CFStringRef name,
-                        std::string* value) {
-  if (!value) return;
-  CFTypeRef ref = SearchForProperty(port, name);
-  if (ref) {
-    CFTypeID refType = CFGetTypeID(ref);
-    if (CFStringGetTypeID() == refType) {
-      CFStringRef stringRef = reinterpret_cast<CFStringRef>(ref);
-      p_convertHostCFStringRefToCPPString(stringRef, *value);
-    } else if (CFDataGetTypeID() == refType) {
-      CFDataRef dataRef = reinterpret_cast<CFDataRef>(ref);
-      *value = std::string(reinterpret_cast<const char*>(
-          CFDataGetBytePtr(dataRef)), CFDataGetLength(dataRef));
-    }
-    CFRelease(ref);
-  }
-}
-#endif
-
-// Fills a struct with information on the graphics adapater and returns true
-// iff successful.
-bool SystemInfo::GetGpuInfo(GpuInfo *info) {
-  if (!info) return false;
-#if defined(WIN32) && !defined(EXCLUDE_D3D9)
-  D3DADAPTER_IDENTIFIER9 identifier;
-  HRESULT hr = E_FAIL;
-  HINSTANCE d3d_lib = LoadLibrary(L"d3d9.dll");
-
-  if (d3d_lib) {
-    typedef IDirect3D9* (WINAPI *D3DCreate9Proc)(UINT);
-    D3DCreate9Proc d3d_create_proc = reinterpret_cast<D3DCreate9Proc>(
-        GetProcAddress(d3d_lib, "Direct3DCreate9"));
-    if (d3d_create_proc) {
-      IDirect3D9* d3d = d3d_create_proc(D3D_SDK_VERSION);
-      if (d3d) {
-        hr = d3d->GetAdapterIdentifier(D3DADAPTER_DEFAULT, 0, &identifier);
-        d3d->Release();
-      }
-    }
-    FreeLibrary(d3d_lib);
-  }
-
-  if (hr != D3D_OK) {
-    LOG(LS_ERROR) << "Failed to access Direct3D9 information.";
-    return false;
-  }
-
-  info->device_name = identifier.DeviceName;
-  info->description = identifier.Description;
-  info->vendor_id = identifier.VendorId;
-  info->device_id = identifier.DeviceId;
-  info->driver = identifier.Driver;
-  // driver_version format: product.version.subversion.build
-  std::stringstream ss;
-  ss << HIWORD(identifier.DriverVersion.HighPart) << "."
-     << LOWORD(identifier.DriverVersion.HighPart) << "."
-     << HIWORD(identifier.DriverVersion.LowPart) << "."
-     << LOWORD(identifier.DriverVersion.LowPart);
-  info->driver_version = ss.str();
-  return true;
-#elif defined(OSX)
-  // We'll query the IOKit for the gpu of the main display.
-  io_service_t display_service_port = CGDisplayIOServicePort(
-      kCGDirectMainDisplay);
-  GetProperty(display_service_port, CFSTR("vendor-id"), &info->vendor_id);
-  GetProperty(display_service_port, CFSTR("device-id"), &info->device_id);
-  GetProperty(display_service_port, CFSTR("model"), &info->description);
-  return true;
-#else // LINUX || ANDROID
-  // TODO: Implement this on Linux
-  return false;
-#endif
-}
-} // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/systeminfo.h b/third_party/libjingle/source/talk/base/systeminfo.h
deleted file mode 100644
index cf8e537..0000000
--- a/third_party/libjingle/source/talk/base/systeminfo.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * libjingle
- * Copyright 2008 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_SYSTEMINFO_H__
-#define TALK_BASE_SYSTEMINFO_H__
-
-#include <string>
-
-#include "talk/base/basictypes.h"
-
-namespace talk_base {
-
-class SystemInfo {
- public:
-  enum Architecture {
-    ARCH_X86 = 0,
-    ARCH_X64 = 1,
-    ARCH_ARM = 2
-  };
-
-  SystemInfo();
-
-  // The number of CPU Cores in the system.
-  int GetMaxPhysicalCpus();
-  // The number of CPU Threads in the system.
-  int GetMaxCpus();
-  // The number of CPU Threads currently available to this process.
-  int GetCurCpus();
-  // Identity of the CPUs.
-  Architecture GetCpuArchitecture();
-  std::string GetCpuVendor();
-  int GetCpuFamily();
-  int GetCpuModel();
-  int GetCpuStepping();
-  // Estimated speed of the CPUs, in MHz.
-  int GetMaxCpuSpeed();
-  int GetCurCpuSpeed();
-  // Total amount of physical memory, in bytes.
-  int64 GetMemorySize();
-  // The model name of the machine, e.g. "MacBookAir1,1"
-  std::string GetMachineModel();
-
-  // The gpu identifier
-  struct GpuInfo {
-    GpuInfo() : vendor_id(0), device_id(0) {}
-    std::string device_name;
-    std::string description;
-    int vendor_id;
-    int device_id;
-    std::string driver;
-    std::string driver_version;
-  };
-  bool GetGpuInfo(GpuInfo *info);
-
- private:
-  int physical_cpus_;
-  int logical_cpus_;
-  Architecture cpu_arch_;
-  std::string cpu_vendor_;
-  int cpu_family_;
-  int cpu_model_;
-  int cpu_stepping_;
-  int cpu_speed_;
-  int64 memory_;
-  std::string machine_model_;
-};
-
-}
-
-#endif  // TALK_BASE_SYSTEMINFO_H__
diff --git a/third_party/libjingle/source/talk/base/systeminfo_unittest.cc b/third_party/libjingle/source/talk/base/systeminfo_unittest.cc
deleted file mode 100644
index 6df0db5..0000000
--- a/third_party/libjingle/source/talk/base/systeminfo_unittest.cc
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * libjingle
- * Copyright 2009, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/gunit.h"
-#include "talk/base/stringutils.h"
-#include "talk/base/systeminfo.h"
-
-#ifdef CPU_X86
-
-// CPUID-based tests only work on X86
-
-// Tests CPUID instruction for Vendor identification.
-TEST(SystemInfoTest, CpuVendorNonEmpty) {
-  talk_base::SystemInfo info;
-  LOG(LS_INFO) << "CpuVendor: " << info.GetCpuVendor();
-  EXPECT_FALSE(info.GetCpuVendor().empty());
-}
-
-// Tests Vendor identification is Intel or AMD.
-// See Also http://en.wikipedia.org/wiki/CPUID
-TEST(SystemInfoTest, CpuVendorIntelAMD) {
-  talk_base::SystemInfo info;
-  EXPECT_TRUE(talk_base::string_match(info.GetCpuVendor().c_str(),
-                                      "GenuineIntel") ||
-              talk_base::string_match(info.GetCpuVendor().c_str(),
-                                      "AuthenticAMD"));
-}
-
-#endif // CPU_X86
-
-// Tests MachineModel is set.
-TEST(SystemInfoTest, MachineModelNonEmpty) {
-  talk_base::SystemInfo info;
-  LOG(LS_INFO) << "MachineModel: " << info.GetMachineModel();
-  EXPECT_FALSE(info.GetMachineModel().empty());
-}
-
-// Tests maximum cpu clockrate.
-TEST(SystemInfoTest, CpuMaxCpuSpeed) {
-  talk_base::SystemInfo info;
-  LOG(LS_INFO) << "MaxCpuSpeed: " << info.GetMaxCpuSpeed();
-  EXPECT_GT(info.GetMaxCpuSpeed(), 0);
-}
-
-// Tests current cpu clockrate.
-TEST(SystemInfoTest, CpuCurCpuSpeed) {
-  talk_base::SystemInfo info;
-  LOG(LS_INFO) << "MaxCurSpeed: " << info.GetCurCpuSpeed();
-  EXPECT_GT(info.GetCurCpuSpeed(), 0);
-}
-
-// Tests physical memory size.
-TEST(SystemInfoTest, MemorySize) {
-  talk_base::SystemInfo info;
-  LOG(LS_INFO) << "MemorySize: " << info.GetMemorySize();
-  EXPECT_GT(info.GetMemorySize(), -1);
-}
-
-// Tests number of logical cpus available to the system.
-TEST(SystemInfoTest, MaxCpus) {
-  talk_base::SystemInfo info;
-  LOG(LS_INFO) << "MaxCpus: " << info.GetMaxCpus();
-  EXPECT_GT(info.GetMaxCpus(), 0);
-}
-
-// Tests number of physical cpus available to the system.
-TEST(SystemInfoTest, MaxPhysicalCpus) {
-  talk_base::SystemInfo info;
-  LOG(LS_INFO) << "MaxPhysicalCpus: " << info.GetMaxPhysicalCpus();
-  EXPECT_GT(info.GetMaxPhysicalCpus(), 0);
-  EXPECT_LE(info.GetMaxPhysicalCpus(), info.GetMaxCpus());
-}
-
-// Tests number of logical cpus available to the process.
-TEST(SystemInfoTest, CurCpus) {
-  talk_base::SystemInfo info;
-  LOG(LS_INFO) << "CurCpus: " << info.GetCurCpus();
-  EXPECT_GT(info.GetCurCpus(), 0);
-  EXPECT_LE(info.GetCurCpus(), info.GetMaxCpus());
-}
-
-#ifdef CPU_X86
-
-// CPU family/model/steeping is only available on X86
-
-// Tests Intel CPU Family identification.
-TEST(SystemInfoTest, CpuFamilyNonZero) {
-  talk_base::SystemInfo info;
-  LOG(LS_INFO) << "CpuFamily: " << info.GetCpuFamily();
-  EXPECT_GT(info.GetCpuFamily(), 0);
-}
-
-// Tests Intel CPU Model identification.
-TEST(SystemInfoTest, CpuModelNonZero) {
-  talk_base::SystemInfo info;
-  LOG(LS_INFO) << "CpuModel: " << info.GetCpuModel();
-  EXPECT_GT(info.GetCpuModel(), 0);
-}
-
-// Tests Intel CPU Stepping identification.
-TEST(SystemInfoTest, CpuSteppingNonZero) {
-  talk_base::SystemInfo info;
-  LOG(LS_INFO) << "CpuStepping: " << info.GetCpuStepping();
-  EXPECT_GT(info.GetCpuStepping(), 0);
-}
-
-#endif // CPU_X86
-
-#if WIN32 && !defined(EXCLUDE_D3D9)
-TEST(SystemInfoTest, GpuInfo) {
-  talk_base::SystemInfo info;
-  talk_base::SystemInfo::GpuInfo gi;
-  EXPECT_TRUE(info.GetGpuInfo(&gi));
-  LOG(LS_INFO) << "GpuDriver: " << gi.driver;
-  EXPECT_FALSE(gi.driver.empty());
-  LOG(LS_INFO) << "GpuDriverVersion: " << gi.driver_version;
-  EXPECT_FALSE(gi.driver_version.empty());
-}
-#endif
diff --git a/third_party/libjingle/source/talk/base/task.cc b/third_party/libjingle/source/talk/base/task.cc
deleted file mode 100644
index c37797c..0000000
--- a/third_party/libjingle/source/talk/base/task.cc
+++ /dev/null
@@ -1,289 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2006, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/task.h"
-#include "talk/base/common.h"
-#include "talk/base/taskrunner.h"
-
-namespace talk_base {
-
-int32 Task::unique_id_seed_ = 0;
-
-Task::Task(TaskParent *parent)
-    : TaskParent(this, parent),
-      state_(STATE_INIT),
-      blocked_(false),
-      done_(false),
-      aborted_(false),
-      busy_(false),
-      error_(false),
-      start_time_(0),
-      timeout_time_(0),
-      timeout_seconds_(0),
-      timeout_suspended_(false)  {
-  unique_id_ = unique_id_seed_++;
-
-  // sanity check that we didn't roll-over our id seed
-  ASSERT(unique_id_ < unique_id_seed_);
-}
-
-Task::~Task() {
-  // Is this task being deleted in the correct manner?
-  ASSERT(!done_ || GetRunner()->is_ok_to_delete(this));
-  ASSERT(state_ == STATE_INIT || done_);
-  ASSERT(state_ == STATE_INIT || blocked_);
-
-  // If the task is being deleted without being done, it
-  // means that it hasn't been removed from its parent.
-  // This happens if a task is deleted outside of TaskRunner.
-  if (!done_) {
-    Stop();
-  }
-}
-
-int64 Task::CurrentTime() {
-  return GetRunner()->CurrentTime();
-}
-
-int64 Task::ElapsedTime() {
-  return CurrentTime() - start_time_;
-}
-
-void Task::Start() {
-  if (state_ != STATE_INIT)
-    return;
-  // Set the start time before starting the task.  Otherwise if the task
-  // finishes quickly and deletes the Task object, setting start_time_
-  // will crash.
-  start_time_ = CurrentTime();
-  GetRunner()->StartTask(this);
-}
-
-void Task::Step() {
-  if (done_) {
-#ifdef _DEBUG
-    // we do not know how !blocked_ happens when done_ - should be impossible.
-    // But it causes problems, so in retail build, we force blocked_, and
-    // under debug we assert.
-    ASSERT(blocked_);
-#else
-    blocked_ = true;
-#endif
-    return;
-  }
-
-  // Async Error() was called
-  if (error_) {
-    done_ = true;
-    state_ = STATE_ERROR;
-    blocked_ = true;
-//   obsolete - an errored task is not considered done now
-//   SignalDone();
-
-    Stop();
-#ifdef _DEBUG
-    // verify that stop removed this from its parent
-    ASSERT(!parent()->IsChildTask(this));
-#endif
-    return;
-  }
-
-  busy_ = true;
-  int new_state = Process(state_);
-  busy_ = false;
-
-  if (aborted_) {
-    Abort(true);  // no need to wake because we're awake
-    return;
-  }
-
-  if (new_state == STATE_BLOCKED) {
-    blocked_ = true;
-    // Let the timeout continue
-  } else {
-    state_ = new_state;
-    blocked_ = false;
-    ResetTimeout();
-  }
-
-  if (new_state == STATE_DONE) {
-    done_ = true;
-  } else if (new_state == STATE_ERROR) {
-    done_ = true;
-    error_ = true;
-  }
-
-  if (done_) {
-//  obsolete - call this yourself
-//    SignalDone();
-
-    Stop();
-#if _DEBUG
-    // verify that stop removed this from its parent
-    ASSERT(!parent()->IsChildTask(this));
-#endif
-    blocked_ = true;
-  }
-}
-
-void Task::Abort(bool nowake) {
-  // Why only check for done_ (instead of "aborted_ || done_")?
-  //
-  // If aborted_ && !done_, it means the logic for aborting still
-  // needs to be executed (because busy_ must have been true when
-  // Abort() was previously called).
-  if (done_)
-    return;
-  aborted_ = true;
-  if (!busy_) {
-    done_ = true;
-    blocked_ = true;
-    error_ = true;
-
-    // "done_" is set before calling "Stop()" to ensure that this code 
-    // doesn't execute more than once (recursively) for the same task.
-    Stop();
-#ifdef _DEBUG
-    // verify that stop removed this from its parent
-    ASSERT(!parent()->IsChildTask(this));
-#endif
-    if (!nowake) {
-      // WakeTasks to self-delete.
-      // Don't call Wake() because it is a no-op after "done_" is set.
-      // Even if Wake() did run, it clears "blocked_" which isn't desireable.
-      GetRunner()->WakeTasks();
-    }
-  }
-}
-
-void Task::Wake() {
-  if (done_)
-    return;
-  if (blocked_) {
-    blocked_ = false;
-    GetRunner()->WakeTasks();
-  }
-}
-
-void Task::Error() {
-  if (error_ || done_)
-    return;
-  error_ = true;
-  Wake();
-}
-
-std::string Task::GetStateName(int state) const {
-  switch (state) {
-    case STATE_BLOCKED: return "BLOCKED";
-    case STATE_INIT: return "INIT";
-    case STATE_START: return "START";
-    case STATE_DONE: return "DONE";
-    case STATE_ERROR: return "ERROR";
-    case STATE_RESPONSE: return "RESPONSE";
-  }
-  return "??";
-}
-
-int Task::Process(int state) {
-  int newstate = STATE_ERROR;
-
-  if (TimedOut()) {
-    ClearTimeout();
-    newstate = OnTimeout();
-    SignalTimeout();
-  } else {
-    switch (state) {
-      case STATE_INIT:
-        newstate = STATE_START;
-        break;
-      case STATE_START:
-        newstate = ProcessStart();
-        break;
-      case STATE_RESPONSE:
-        newstate = ProcessResponse();
-        break;
-      case STATE_DONE:
-      case STATE_ERROR:
-        newstate = STATE_BLOCKED;
-        break;
-    }
-  }
-
-  return newstate;
-}
-
-void Task::Stop() {
-  // No need to wake because we're either awake or in abort
-  TaskParent::OnStopped(this);
-}
-
-void Task::set_timeout_seconds(const int timeout_seconds) {
-  timeout_seconds_ = timeout_seconds;
-  ResetTimeout();
-}
-
-bool Task::TimedOut() {
-  return timeout_seconds_ &&
-    timeout_time_ &&
-    CurrentTime() >= timeout_time_;
-}
-
-void Task::ResetTimeout() {
-  int64 previous_timeout_time = timeout_time_;
-  bool timeout_allowed = (state_ != STATE_INIT)
-                      && (state_ != STATE_DONE)
-                      && (state_ != STATE_ERROR);
-  if (timeout_seconds_ && timeout_allowed && !timeout_suspended_)
-    timeout_time_ = CurrentTime() +
-                    (timeout_seconds_ * kSecToMsec * kMsecTo100ns);
-  else
-    timeout_time_ = 0;
-
-  GetRunner()->UpdateTaskTimeout(this, previous_timeout_time);
-}
-
-void Task::ClearTimeout() {
-  int64 previous_timeout_time = timeout_time_;
-  timeout_time_ = 0;
-  GetRunner()->UpdateTaskTimeout(this, previous_timeout_time);
-}
-
-void Task::SuspendTimeout() {
-  if (!timeout_suspended_) {
-    timeout_suspended_ = true;
-    ResetTimeout();
-  }
-}
-
-void Task::ResumeTimeout() {
-  if (timeout_suspended_) {
-    timeout_suspended_ = false;
-    ResetTimeout();
-  }
-}
-
-} // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/task.h b/third_party/libjingle/source/talk/base/task.h
deleted file mode 100644
index 10e6f5c..0000000
--- a/third_party/libjingle/source/talk/base/task.h
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2006, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_TASK_H__
-#define TALK_BASE_TASK_H__
-
-#include <string>
-#include "talk/base/basictypes.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/base/sigslot.h"
-#include "talk/base/taskparent.h"
-
-/////////////////////////////////////////////////////////////////////
-//
-// TASK
-//
-/////////////////////////////////////////////////////////////////////
-//
-// Task is a state machine infrastructure.  States are pushed forward by
-// pushing forwards a TaskRunner that holds on to all Tasks.  The purpose
-// of Task is threefold:
-//
-// (1) It manages ongoing work on the UI thread.  Multitasking without
-// threads, keeping it easy, keeping it real. :-)  It does this by
-// organizing a set of states for each task.  When you return from your
-// Process*() function, you return an integer for the next state.  You do
-// not go onto the next state yourself.  Every time you enter a state,
-// you check to see if you can do anything yet.  If not, you return
-// STATE_BLOCKED.  If you _could_ do anything, do not return
-// STATE_BLOCKED - even if you end up in the same state, return
-// STATE_mysamestate.  When you are done, return STATE_DONE and then the
-// task will self-delete sometime afterwards.
-//
-// (2) It helps you avoid all those reentrancy problems when you chain
-// too many triggers on one thread.  Basically if you want to tell a task
-// to process something for you, you feed your task some information and
-// then you Wake() it.  Don't tell it to process it right away.  If it
-// might be working on something as you send it information, you may want
-// to have a queue in the task.
-//
-// (3) Finally it helps manage parent tasks and children.  If a parent
-// task gets aborted, all the children tasks are too.  The nice thing
-// about this, for example, is if you have one parent task that
-// represents, say, and Xmpp connection, then you can spawn a whole bunch
-// of infinite lifetime child tasks and now worry about cleaning them up.
-//  When the parent task goes to STATE_DONE, the task engine will make
-// sure all those children are aborted and get deleted.
-//
-// Notice that Task has a few built-in states, e.g.,
-//
-// STATE_INIT - the task isn't running yet
-// STATE_START - the task is in its first state
-// STATE_RESPONSE - the task is in its second state
-// STATE_DONE - the task is done
-//
-// STATE_ERROR - indicates an error - we should audit the error code in
-// light of any usage of it to see if it should be improved.  When I
-// first put down the task stuff I didn't have a good sense of what was
-// needed for Abort and Error, and now the subclasses of Task will ground
-// the design in a stronger way.
-//
-// STATE_NEXT - the first undefined state number.  (like WM_USER) - you
-// can start defining more task states there.
-//
-// When you define more task states, just override Process(int state) and
-// add your own switch statement.  If you want to delegate to
-// Task::Process, you can effectively delegate to its switch statement.
-// No fancy method pointers or such - this is all just pretty low tech,
-// easy to debug, and fast.
-//
-// Also notice that Task has some primitive built-in timeout functionality.
-//
-// A timeout is defined as "the task stays in STATE_BLOCKED longer than
-// timeout_seconds_."
-//
-// Descendant classes can override this behavior by calling the
-// various protected methods to change the timeout behavior.  For
-// instance, a descendand might call SuspendTimeout() when it knows
-// that it isn't waiting for anything that might timeout, but isn't
-// yet in the STATE_DONE state.
-//
-
-namespace talk_base {
-
-// Executes a sequence of steps
-class Task : public TaskParent {
- public:
-  Task(TaskParent *parent);
-  virtual ~Task();
-
-  int32 unique_id() { return unique_id_; }
-
-  void Start();
-  void Step();
-  int GetState() const { return state_; }
-  bool HasError() const { return (GetState() == STATE_ERROR); }
-  bool Blocked() const { return blocked_; }
-  bool IsDone() const { return done_; }
-  int64 ElapsedTime();
-
-  // Called from outside to stop task without any more callbacks
-  void Abort(bool nowake = false);
-
-  bool TimedOut();
-
-  int64 timeout_time() const { return timeout_time_; }
-  int timeout_seconds() const { return timeout_seconds_; }
-  void set_timeout_seconds(int timeout_seconds);
-
-  sigslot::signal0<> SignalTimeout;
-
-  // Called inside the task to signal that the task may be unblocked
-  void Wake();
-
- protected:
-
-  enum {
-    STATE_BLOCKED = -1,
-    STATE_INIT = 0,
-    STATE_START = 1,
-    STATE_DONE = 2,
-    STATE_ERROR = 3,
-    STATE_RESPONSE = 4,
-    STATE_NEXT = 5,  // Subclasses which need more states start here and higher
-  };
-
-  // Called inside to advise that the task should wake and signal an error
-  void Error();
-
-  int64 CurrentTime();
-
-  virtual std::string GetStateName(int state) const;
-  virtual int Process(int state);
-  virtual void Stop();
-  virtual int ProcessStart() = 0;
-  virtual int ProcessResponse() { return STATE_DONE; }
-
-  void ResetTimeout();
-  void ClearTimeout();
-
-  void SuspendTimeout();
-  void ResumeTimeout();
-
- protected:
-  virtual int OnTimeout() {
-    // by default, we are finished after timing out
-    return STATE_DONE;
-  }
-
- private:
-  void Done();
-
-  int state_;
-  bool blocked_;
-  bool done_;
-  bool aborted_;
-  bool busy_;
-  bool error_;
-  int64 start_time_;
-  int64 timeout_time_;
-  int timeout_seconds_;
-  bool timeout_suspended_;
-  int32 unique_id_;
-  
-  static int32 unique_id_seed_;
-};
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_TASK_H__
diff --git a/third_party/libjingle/source/talk/base/task_unittest.cc b/third_party/libjingle/source/talk/base/task_unittest.cc
deleted file mode 100644
index 0c4a7a2..0000000
--- a/third_party/libjingle/source/talk/base/task_unittest.cc
+++ /dev/null
@@ -1,562 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifdef POSIX
-#include <sys/time.h>
-#endif  // POSIX
-
-// TODO: Remove this once the cause of sporadic failures in these
-// tests is tracked down.
-#include <iostream>
-
-#ifdef WIN32
-#include "talk/base/win32.h"
-#endif  // WIN32
-
-#include "talk/base/common.h"
-#include "talk/base/gunit.h"
-#include "talk/base/logging.h"
-#include "talk/base/task.h"
-#include "talk/base/taskrunner.h"
-#include "talk/base/thread.h"
-#include "talk/base/timeutils.h"
-
-namespace talk_base {
-
-static int64 GetCurrentTime() {
-  return static_cast<int64>(Time()) * 10000;
-}
-
-// feel free to change these numbers.  Note that '0' won't work, though
-#define STUCK_TASK_COUNT 5
-#define HAPPY_TASK_COUNT 20
-
-// this is a generic timeout task which, when it signals timeout, will
-// include the unique ID of the task in the signal (we don't use this
-// in production code because we haven't yet had occasion to generate
-// an array of the same types of task)
-
-class IdTimeoutTask : public Task, public sigslot::has_slots<> {
- public:
-  explicit IdTimeoutTask(TaskParent *parent) : Task(parent) {
-    SignalTimeout.connect(this, &IdTimeoutTask::OnLocalTimeout);
-  }
-
-  sigslot::signal1<const int> SignalTimeoutId;
-  sigslot::signal1<const int> SignalDoneId;
-
-  virtual int ProcessStart() {
-    return STATE_RESPONSE;
-  }
-
-  void OnLocalTimeout() {
-    SignalTimeoutId(unique_id());
-  }
-
- protected:
-  virtual void Stop() {
-    SignalDoneId(unique_id());
-    Task::Stop();
-  }
-};
-
-class StuckTask : public IdTimeoutTask {
- public:
-  explicit StuckTask(TaskParent *parent) : IdTimeoutTask(parent) {}
-  virtual int ProcessStart() {
-    return STATE_BLOCKED;
-  }
-};
-
-class HappyTask : public IdTimeoutTask {
- public:
-  explicit HappyTask(TaskParent *parent) : IdTimeoutTask(parent) {
-    time_to_perform_ = rand() % (STUCK_TASK_COUNT / 2);
-  }
-  virtual int ProcessStart() {
-    if (ElapsedTime() > (time_to_perform_ * 1000 * 10000))
-      return STATE_RESPONSE;
-    else
-      return STATE_BLOCKED;
-  }
-
- private:
-  int time_to_perform_;
-};
-
-// simple implementation of a task runner which uses Windows'
-// GetSystemTimeAsFileTime() to get the current clock ticks
-
-class MyTaskRunner : public TaskRunner {
- public:
-  virtual void WakeTasks() { RunTasks(); }
-  virtual int64 CurrentTime() {
-    return GetCurrentTime();
-  }
-
-  bool timeout_change() const {
-    return timeout_change_;
-  }
-
-  void clear_timeout_change() {
-    timeout_change_ = false;
-  }
- protected:
-  virtual void OnTimeoutChange() {
-    timeout_change_ = true;
-  }
-  bool timeout_change_;
-};
-
-//
-// this unit test is primarily concerned (for now) with the timeout
-// functionality in tasks.  It works as follows:
-//
-//   * Create a bunch of tasks, some "stuck" (ie., guaranteed to timeout)
-//     and some "happy" (will immediately finish).
-//   * Set the timeout on the "stuck" tasks to some number of seconds between
-//     1 and the number of stuck tasks
-//   * Start all the stuck & happy tasks in random order
-//   * Wait "number of stuck tasks" seconds and make sure everything timed out
-
-class TaskTest : public sigslot::has_slots<> {
- public:
-  TaskTest() {}
-
-  // no need to delete any tasks; the task runner owns them
-  ~TaskTest() {}
-
-  void Start() {
-    // create and configure tasks
-    for (int i = 0; i < STUCK_TASK_COUNT; ++i) {
-      stuck_[i].task_ = new StuckTask(&task_runner_);
-      stuck_[i].task_->SignalTimeoutId.connect(this,
-                                               &TaskTest::OnTimeoutStuck);
-      stuck_[i].timed_out_ = false;
-      stuck_[i].xlat_ = stuck_[i].task_->unique_id();
-      stuck_[i].task_->set_timeout_seconds(i + 1);
-      LOG(LS_INFO) << "Task " << stuck_[i].xlat_ << " created with timeout "
-                   << stuck_[i].task_->timeout_seconds();
-    }
-
-    for (int i = 0; i < HAPPY_TASK_COUNT; ++i) {
-      happy_[i].task_ = new HappyTask(&task_runner_);
-      happy_[i].task_->SignalTimeoutId.connect(this,
-                                               &TaskTest::OnTimeoutHappy);
-      happy_[i].task_->SignalDoneId.connect(this,
-                                            &TaskTest::OnDoneHappy);
-      happy_[i].timed_out_ = false;
-      happy_[i].xlat_ = happy_[i].task_->unique_id();
-    }
-
-    // start all the tasks in random order
-    int stuck_index = 0;
-    int happy_index = 0;
-    for (int i = 0; i < STUCK_TASK_COUNT + HAPPY_TASK_COUNT; ++i) {
-      if ((stuck_index < STUCK_TASK_COUNT) &&
-          (happy_index < HAPPY_TASK_COUNT)) {
-        if (rand() % 2 == 1) {
-          stuck_[stuck_index++].task_->Start();
-        } else {
-          happy_[happy_index++].task_->Start();
-        }
-      } else if (stuck_index < STUCK_TASK_COUNT) {
-        stuck_[stuck_index++].task_->Start();
-      } else {
-        happy_[happy_index++].task_->Start();
-      }
-    }
-
-    for (int i = 0; i < STUCK_TASK_COUNT; ++i) {
-      std::cout << "Stuck task #" << i << " timeout is " <<
-          stuck_[i].task_->timeout_seconds() << " at " <<
-          stuck_[i].task_->timeout_time() << std::endl;
-    }
-
-    // just a little self-check to make sure we started all the tasks
-    ASSERT_EQ(STUCK_TASK_COUNT, stuck_index);
-    ASSERT_EQ(HAPPY_TASK_COUNT, happy_index);
-
-    // run the unblocked tasks
-    LOG(LS_INFO) << "Running tasks";
-    task_runner_.RunTasks();
-
-    std::cout << "Start time is " << GetCurrentTime() << std::endl;
-
-    // give all the stuck tasks time to timeout
-    for (int i = 0; !task_runner_.AllChildrenDone() && i < STUCK_TASK_COUNT;
-         ++i) {
-      Thread::Current()->ProcessMessages(1000);
-      for (int j = 0; j < HAPPY_TASK_COUNT; ++j) {
-        if (happy_[j].task_) {
-          happy_[j].task_->Wake();
-        }
-      }
-      LOG(LS_INFO) << "Polling tasks";
-      task_runner_.PollTasks();
-    }
-
-    // We see occasional test failures here due to the stuck tasks not having
-    // timed-out yet, which seems like it should be impossible. To help track
-    // this down we have added logging of the timing information, which we send
-    // directly to stdout so that we get it in opt builds too.
-    std::cout << "End time is " << GetCurrentTime() << std::endl;
-  }
-
-  void OnTimeoutStuck(const int id) {
-    LOG(LS_INFO) << "Timed out task " << id;
-
-    int i;
-    for (i = 0; i < STUCK_TASK_COUNT; ++i) {
-      if (stuck_[i].xlat_ == id) {
-        stuck_[i].timed_out_ = true;
-        stuck_[i].task_ = NULL;
-        break;
-      }
-    }
-
-    // getting a bad ID here is a failure, but let's continue
-    // running to see what else might go wrong
-    EXPECT_LT(i, STUCK_TASK_COUNT);
-  }
-
-  void OnTimeoutHappy(const int id) {
-    int i;
-    for (i = 0; i < HAPPY_TASK_COUNT; ++i) {
-      if (happy_[i].xlat_ == id) {
-        happy_[i].timed_out_ = true;
-        happy_[i].task_ = NULL;
-        break;
-      }
-    }
-
-    // getting a bad ID here is a failure, but let's continue
-    // running to see what else might go wrong
-    EXPECT_LT(i, HAPPY_TASK_COUNT);
-  }
-
-  void OnDoneHappy(const int id) {
-    int i;
-    for (i = 0; i < HAPPY_TASK_COUNT; ++i) {
-      if (happy_[i].xlat_ == id) {
-        happy_[i].task_ = NULL;
-        break;
-      }
-    }
-
-    // getting a bad ID here is a failure, but let's continue
-    // running to see what else might go wrong
-    EXPECT_LT(i, HAPPY_TASK_COUNT);
-  }
-
-  void check_passed() {
-    EXPECT_TRUE(task_runner_.AllChildrenDone());
-
-    // make sure none of our happy tasks timed out
-    for (int i = 0; i < HAPPY_TASK_COUNT; ++i) {
-      EXPECT_FALSE(happy_[i].timed_out_);
-    }
-
-    // make sure all of our stuck tasks timed out
-    for (int i = 0; i < STUCK_TASK_COUNT; ++i) {
-      EXPECT_TRUE(stuck_[i].timed_out_);
-      if (!stuck_[i].timed_out_) {
-        std::cout << "Stuck task #" << i << " timeout is at "
-            << stuck_[i].task_->timeout_time() << std::endl;        
-      }
-    }
-
-    std::cout.flush();
-  }
-
- private:
-  struct TaskInfo {
-    IdTimeoutTask *task_;
-    bool timed_out_;
-    int xlat_;
-  };
-
-  MyTaskRunner task_runner_;
-  TaskInfo stuck_[STUCK_TASK_COUNT];
-  TaskInfo happy_[HAPPY_TASK_COUNT];
-};
-
-TEST(start_task_test, Timeout) {
-  TaskTest task_test;
-  task_test.Start();
-  task_test.check_passed();
-}
-
-// Test for aborting the task while it is running
-
-class AbortTask : public Task {
- public:
-  explicit AbortTask(TaskParent *parent) : Task(parent) {
-    set_timeout_seconds(1);
-  }
-
-  virtual int ProcessStart() {
-    Abort();
-    return STATE_NEXT;
-  }
- private:
-  DISALLOW_EVIL_CONSTRUCTORS(AbortTask);
-};
-
-class TaskAbortTest : public sigslot::has_slots<> {
- public:
-  TaskAbortTest() {}
-
-  // no need to delete any tasks; the task runner owns them
-  ~TaskAbortTest() {}
-
-  void Start() {
-    Task *abort_task = new AbortTask(&task_runner_);
-    abort_task->SignalTimeout.connect(this, &TaskAbortTest::OnTimeout);
-    abort_task->Start();
-
-    // run the task
-    task_runner_.RunTasks();
-  }
-
- private:
-  void OnTimeout() {
-    FAIL() << "Task timed out instead of aborting.";
-  }
-
-  MyTaskRunner task_runner_;
-  DISALLOW_EVIL_CONSTRUCTORS(TaskAbortTest);
-};
-
-TEST(start_task_test, Abort) {
-  TaskAbortTest abort_test;
-  abort_test.Start();
-}
-
-// Test for aborting a task to verify that it does the Wake operation
-// which gets it deleted.
-
-class SetBoolOnDeleteTask : public Task {
- public:
-  SetBoolOnDeleteTask(TaskParent *parent, bool *set_when_deleted)
-    : Task(parent),
-      set_when_deleted_(set_when_deleted) {
-    EXPECT_TRUE(NULL != set_when_deleted);
-    EXPECT_FALSE(*set_when_deleted);
-  }
-
-  virtual ~SetBoolOnDeleteTask() {
-    *set_when_deleted_ = true;
-  }
-
-  virtual int ProcessStart() {
-    return STATE_BLOCKED;
-  }
-
- private:
-  bool* set_when_deleted_;
-  DISALLOW_EVIL_CONSTRUCTORS(SetBoolOnDeleteTask);
-};
-
-class AbortShouldWakeTest : public sigslot::has_slots<> {
- public:
-  AbortShouldWakeTest() {}
-
-  // no need to delete any tasks; the task runner owns them
-  ~AbortShouldWakeTest() {}
-
-  void Start() {
-    bool task_deleted = false;
-    Task *task_to_abort = new SetBoolOnDeleteTask(&task_runner_, &task_deleted);
-    task_to_abort->Start();
-
-    // Task::Abort() should call TaskRunner::WakeTasks(). WakeTasks calls
-    // TaskRunner::RunTasks() immediately which should delete the task.
-    task_to_abort->Abort();
-    EXPECT_TRUE(task_deleted);
-
-    if (!task_deleted) {
-      // avoid a crash (due to referencing a local variable)
-      // if the test fails.
-      task_runner_.RunTasks();
-    }
-  }
-
- private:
-  void OnTimeout() {
-    FAIL() << "Task timed out instead of aborting.";
-  }
-
-  MyTaskRunner task_runner_;
-  DISALLOW_EVIL_CONSTRUCTORS(AbortShouldWakeTest);
-};
-
-TEST(start_task_test, AbortShouldWake) {
-  AbortShouldWakeTest abort_should_wake_test;
-  abort_should_wake_test.Start();
-}
-
-// Validate that TaskRunner's OnTimeoutChange gets called appropriately
-//  * When a task calls UpdateTaskTimeout
-//  * When the next timeout task time, times out
-class TimeoutChangeTest : public sigslot::has_slots<> {
- public:
-  TimeoutChangeTest()
-    : task_count_(ARRAY_SIZE(stuck_tasks_)) {}
-
-  // no need to delete any tasks; the task runner owns them
-  ~TimeoutChangeTest() {}
-
-  void Start() {
-    for (int i = 0; i < task_count_; ++i) {
-      stuck_tasks_[i] = new StuckTask(&task_runner_);
-      stuck_tasks_[i]->set_timeout_seconds(i + 2);
-      stuck_tasks_[i]->SignalTimeoutId.connect(this,
-                                               &TimeoutChangeTest::OnTimeoutId);
-    }
-
-    for (int i = task_count_ - 1; i >= 0; --i) {
-      stuck_tasks_[i]->Start();
-    }
-    task_runner_.clear_timeout_change();
-
-    // At this point, our timeouts are set as follows
-    // task[0] is 2 seconds, task[1] at 3 seconds, etc.
-
-    stuck_tasks_[0]->set_timeout_seconds(2);
-    // Now, task[0] is 2 seconds, task[1] at 3 seconds...
-    // so timeout change shouldn't be called.
-    EXPECT_FALSE(task_runner_.timeout_change());
-    task_runner_.clear_timeout_change();
-
-    stuck_tasks_[0]->set_timeout_seconds(1);
-    // task[0] is 1 seconds, task[1] at 3 seconds...
-    // The smallest timeout got smaller so timeout change be called.
-    EXPECT_TRUE(task_runner_.timeout_change());
-    task_runner_.clear_timeout_change();
-
-    stuck_tasks_[1]->set_timeout_seconds(2);
-    // task[0] is 1 seconds, task[1] at 2 seconds...
-    // The smallest timeout is still 1 second so no timeout change.
-    EXPECT_FALSE(task_runner_.timeout_change());
-    task_runner_.clear_timeout_change();
-
-    while (task_count_ > 0) {
-      int previous_count = task_count_;
-      task_runner_.PollTasks();
-      if (previous_count != task_count_) {
-        // We only get here when a task times out.  When that
-        // happens, the timeout change should get called because
-        // the smallest timeout is now in the past.
-        EXPECT_TRUE(task_runner_.timeout_change());
-        task_runner_.clear_timeout_change();
-      }
-      Thread::Current()->socketserver()->Wait(500, false);
-    }
-  }
-
- private:
-  void OnTimeoutId(const int id) {
-    for (int i = 0; i < ARRAY_SIZE(stuck_tasks_); ++i) {
-      if (stuck_tasks_[i] && stuck_tasks_[i]->unique_id() == id) {
-        task_count_--;
-        stuck_tasks_[i] = NULL;
-        break;
-      }
-    }
-  }
-
-  MyTaskRunner task_runner_;
-  StuckTask* (stuck_tasks_[3]);
-  int task_count_;
-  DISALLOW_EVIL_CONSTRUCTORS(TimeoutChangeTest);
-};
-
-TEST(start_task_test, TimeoutChange) {
-  TimeoutChangeTest timeout_change_test;
-  timeout_change_test.Start();
-}
-
-class DeleteTestTaskRunner : public TaskRunner {
- public:
-  DeleteTestTaskRunner() {
-  }
-  virtual void WakeTasks() { }
-  virtual int64 CurrentTime() {
-    return GetCurrentTime();
-  }
- private:
-  DISALLOW_EVIL_CONSTRUCTORS(DeleteTestTaskRunner);
-};
-
-TEST(unstarted_task_test, DeleteTask) {
-  // This test ensures that we don't
-  // crash if a task is deleted without running it.
-  DeleteTestTaskRunner task_runner;
-  HappyTask* happy_task = new HappyTask(&task_runner);
-  happy_task->Start();
-
-  // try deleting the task directly
-  HappyTask* child_happy_task = new HappyTask(happy_task);
-  delete child_happy_task;
-
-  // run the unblocked tasks
-  task_runner.RunTasks();
-}
-
-TEST(unstarted_task_test, DoNotDeleteTask1) {
-  // This test ensures that we don't
-  // crash if a task runner is deleted without
-  // running a certain task.
-  DeleteTestTaskRunner task_runner;
-  HappyTask* happy_task = new HappyTask(&task_runner);
-  happy_task->Start();
-
-  HappyTask* child_happy_task = new HappyTask(happy_task);
-  child_happy_task->Start();
-
-  // Never run the tasks
-}
-
-TEST(unstarted_task_test, DoNotDeleteTask2) {
-  // This test ensures that we don't
-  // crash if a taskrunner is delete with a
-  // task that has never been started.
-  DeleteTestTaskRunner task_runner;
-  HappyTask* happy_task = new HappyTask(&task_runner);
-  happy_task->Start();
-
-  // Do not start the task.
-  // Note: this leaks memory, so don't do this.
-  // Instead, always run your tasks or delete them.
-  new HappyTask(happy_task);
-
-  // run the unblocked tasks
-  task_runner.RunTasks();
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/taskparent.cc b/third_party/libjingle/source/talk/base/taskparent.cc
deleted file mode 100644
index f05ee82..0000000
--- a/third_party/libjingle/source/talk/base/taskparent.cc
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2006, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <algorithm>
-
-#include "talk/base/taskparent.h"
-
-#include "talk/base/task.h"
-#include "talk/base/taskrunner.h"
-
-namespace talk_base {
-
-TaskParent::TaskParent(Task* derived_instance, TaskParent *parent)
-    : parent_(parent) {
-  ASSERT(derived_instance != NULL);
-  ASSERT(parent != NULL);
-  runner_ = parent->GetRunner();
-  parent_->AddChild(derived_instance);
-  Initialize();
-}
-
-TaskParent::TaskParent(TaskRunner *derived_instance)
-    : parent_(NULL),
-      runner_(derived_instance) {
-  ASSERT(derived_instance != NULL);
-  Initialize();
-}
-
-// Does common initialization of member variables
-void TaskParent::Initialize() {
-  children_.reset(new ChildSet());
-  child_error_ = false;
-}
-
-void TaskParent::AddChild(Task *child) {
-  children_->insert(child);
-}
-
-#ifdef _DEBUG
-bool TaskParent::IsChildTask(Task *task) {
-  ASSERT(task != NULL);
-  return task->parent_ == this && children_->find(task) != children_->end();
-}
-#endif
-
-bool TaskParent::AllChildrenDone() {
-  for (ChildSet::iterator it = children_->begin();
-       it != children_->end();
-       ++it) {
-    if (!(*it)->IsDone())
-      return false;
-  }
-  return true;
-}
-
-bool TaskParent::AnyChildError() {
-  return child_error_;
-}
-
-void TaskParent::AbortAllChildren() {
-  if (children_->size() > 0) {
-#ifdef _DEBUG
-    runner_->IncrementAbortCount();
-#endif
-
-    ChildSet copy = *children_;
-    for (ChildSet::iterator it = copy.begin(); it != copy.end(); ++it) {
-      (*it)->Abort(true);  // Note we do not wake
-    }
-
-#ifdef _DEBUG
-    runner_->DecrementAbortCount();
-#endif
-  }
-}
-
-void TaskParent::OnStopped(Task *task) {
-  AbortAllChildren();
-  parent_->OnChildStopped(task);
-}
-
-void TaskParent::OnChildStopped(Task *child) {
-  if (child->HasError())
-    child_error_ = true;
-  children_->erase(child);
-}
-
-} // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/taskparent.h b/third_party/libjingle/source/talk/base/taskparent.h
deleted file mode 100644
index e2093d6..0000000
--- a/third_party/libjingle/source/talk/base/taskparent.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2006, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_TASKPARENT_H__
-#define TALK_BASE_TASKPARENT_H__
-
-#include <set>
-
-#include "talk/base/basictypes.h"
-#include "talk/base/scoped_ptr.h"
-
-namespace talk_base {
-
-class Task;
-class TaskRunner;
-
-class TaskParent {
- public:
-  TaskParent(Task *derived_instance, TaskParent *parent);
-  explicit TaskParent(TaskRunner *derived_instance);
-  virtual ~TaskParent() { }
-
-  TaskParent *GetParent() { return parent_; }
-  TaskRunner *GetRunner() { return runner_; }
-
-  bool AllChildrenDone();
-  bool AnyChildError();
-#ifdef _DEBUG
-  bool IsChildTask(Task *task);
-#endif
-
- protected:
-  void OnStopped(Task *task);
-  void AbortAllChildren();
-  TaskParent *parent() {
-    return parent_;
-  }
-
- private:
-  void Initialize();
-  void OnChildStopped(Task *child);
-  void AddChild(Task *child);
-
-  TaskParent *parent_;
-  TaskRunner *runner_;
-  bool child_error_;
-  typedef std::set<Task *> ChildSet;
-  scoped_ptr<ChildSet> children_;
-  DISALLOW_EVIL_CONSTRUCTORS(TaskParent);
-};
-
-
-} // namespace talk_base
-
-#endif  // TALK_BASE_TASKPARENT_H__
diff --git a/third_party/libjingle/source/talk/base/taskrunner.cc b/third_party/libjingle/source/talk/base/taskrunner.cc
deleted file mode 100644
index 0c0816c..0000000
--- a/third_party/libjingle/source/talk/base/taskrunner.cc
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2006, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <algorithm>
-
-#include "talk/base/taskrunner.h"
-
-#include "talk/base/common.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/base/task.h"
-#include "talk/base/logging.h"
-
-namespace talk_base {
-
-TaskRunner::TaskRunner()
-  : TaskParent(this),
-    next_timeout_task_(NULL),
-    tasks_running_(false)
-#ifdef _DEBUG
-    , abort_count_(0),
-    deleting_task_(NULL)
-#endif
-{
-}
-
-TaskRunner::~TaskRunner() {
-  // this kills and deletes children silently!
-  AbortAllChildren();
-  InternalRunTasks(true);
-}
-
-void TaskRunner::StartTask(Task * task) {
-  tasks_.push_back(task);
-
-  // the task we just started could be about to timeout --
-  // make sure our "next timeout task" is correct
-  UpdateTaskTimeout(task, 0);
-
-  WakeTasks();
-}
-
-void TaskRunner::RunTasks() {
-  InternalRunTasks(false);
-}
-
-void TaskRunner::InternalRunTasks(bool in_destructor) {
-  // This shouldn't run while an abort is happening.
-  // If that occurs, then tasks may be deleted in this method,
-  // but pointers to them will still be in the
-  // "ChildSet copy" in TaskParent::AbortAllChildren.
-  // Subsequent use of those task may cause data corruption or crashes.  
-  ASSERT(!abort_count_);
-  // Running continues until all tasks are Blocked (ok for a small # of tasks)
-  if (tasks_running_) {
-    return;  // don't reenter
-  }
-
-  tasks_running_ = true;
-
-  int64 previous_timeout_time = next_task_timeout();
-
-  int did_run = true;
-  while (did_run) {
-    did_run = false;
-    // use indexing instead of iterators because tasks_ may grow
-    for (size_t i = 0; i < tasks_.size(); ++i) {
-      while (!tasks_[i]->Blocked()) {
-        tasks_[i]->Step();
-        did_run = true;
-      }
-    }
-  }
-  // Tasks are deleted when running has paused
-  bool need_timeout_recalc = false;
-  for (size_t i = 0; i < tasks_.size(); ++i) {
-    if (tasks_[i]->IsDone()) {
-      Task* task = tasks_[i];
-      if (next_timeout_task_ &&
-          task->unique_id() == next_timeout_task_->unique_id()) {
-        next_timeout_task_ = NULL;
-        need_timeout_recalc = true;
-      }
-
-#ifdef _DEBUG
-      deleting_task_ = task;
-#endif
-      delete task;
-#ifdef _DEBUG
-      deleting_task_ = NULL;
-#endif
-      tasks_[i] = NULL;
-    }
-  }
-  // Finally, remove nulls
-  std::vector<Task *>::iterator it;
-  it = std::remove(tasks_.begin(),
-                   tasks_.end(),
-                   reinterpret_cast<Task *>(NULL));
-
-  tasks_.erase(it, tasks_.end());
-
-  if (need_timeout_recalc)
-    RecalcNextTimeout(NULL);
-
-  // Make sure that adjustments are done to account
-  // for any timeout changes (but don't call this
-  // while being destroyed since it calls a pure virtual function).
-  if (!in_destructor)
-    CheckForTimeoutChange(previous_timeout_time);
-
-  tasks_running_ = false;
-}
-
-void TaskRunner::PollTasks() {
-  // see if our "next potentially timed-out task" has indeed timed out.
-  // If it has, wake it up, then queue up the next task in line
-  // Repeat while we have new timed-out tasks.
-  // TODO: We need to guard against WakeTasks not updating
-  // next_timeout_task_. Maybe also add documentation in the header file once
-  // we understand this code better.
-  Task* old_timeout_task = NULL;
-  while (next_timeout_task_ &&
-      old_timeout_task != next_timeout_task_ &&
-      next_timeout_task_->TimedOut()) {
-    old_timeout_task = next_timeout_task_;
-    next_timeout_task_->Wake();
-    WakeTasks();
-  }
-}
-
-int64 TaskRunner::next_task_timeout() const {
-  if (next_timeout_task_) {
-    return next_timeout_task_->timeout_time();
-  }
-  return 0;
-}
-
-// this function gets called frequently -- when each task changes
-// state to something other than DONE, ERROR or BLOCKED, it calls
-// ResetTimeout(), which will call this function to make sure that
-// the next timeout-able task hasn't changed.  The logic in this function
-// prevents RecalcNextTimeout() from getting called in most cases,
-// effectively making the task scheduler O-1 instead of O-N
-
-void TaskRunner::UpdateTaskTimeout(Task* task,
-                                   int64 previous_task_timeout_time) {
-  ASSERT(task != NULL);
-  int64 previous_timeout_time = next_task_timeout();
-  bool task_is_timeout_task = next_timeout_task_ != NULL &&
-      task->unique_id() == next_timeout_task_->unique_id();
-  if (task_is_timeout_task) {
-    previous_timeout_time = previous_task_timeout_time;
-  }
-
-  // if the relevant task has a timeout, then
-  // check to see if it's closer than the current
-  // "about to timeout" task
-  if (task->timeout_time()) {
-    if (next_timeout_task_ == NULL ||
-        (task->timeout_time() <= next_timeout_task_->timeout_time())) {
-      next_timeout_task_ = task;
-    }
-  } else if (task_is_timeout_task) {
-    // otherwise, if the task doesn't have a timeout,
-    // and it used to be our "about to timeout" task,
-    // walk through all the tasks looking for the real
-    // "about to timeout" task
-    RecalcNextTimeout(task);
-  }
-
-  // Note when task_running_, then the running routine
-  // (TaskRunner::InternalRunTasks) is responsible for calling
-  // CheckForTimeoutChange.
-  if (!tasks_running_) {
-    CheckForTimeoutChange(previous_timeout_time);
-  }
-}
-
-void TaskRunner::RecalcNextTimeout(Task *exclude_task) {
-  // walk through all the tasks looking for the one
-  // which satisfies the following:
-  //   it's not finished already
-  //   we're not excluding it
-  //   it has the closest timeout time
-
-  int64 next_timeout_time = 0;
-  next_timeout_task_ = NULL;
-
-  for (size_t i = 0; i < tasks_.size(); ++i) {
-    Task *task = tasks_[i];
-    // if the task isn't complete, and it actually has a timeout time
-    if (!task->IsDone() && (task->timeout_time() > 0))
-      // if it doesn't match our "exclude" task
-      if (exclude_task == NULL ||
-          exclude_task->unique_id() != task->unique_id())
-        // if its timeout time is sooner than our current timeout time
-        if (next_timeout_time == 0 ||
-            task->timeout_time() <= next_timeout_time) {
-          // set this task as our next-to-timeout
-          next_timeout_time = task->timeout_time();
-          next_timeout_task_ = task;
-        }
-  }
-}
-
-void TaskRunner::CheckForTimeoutChange(int64 previous_timeout_time) {
-  int64 next_timeout = next_task_timeout();
-  bool timeout_change = (previous_timeout_time == 0 && next_timeout != 0) ||
-      next_timeout < previous_timeout_time ||
-      (previous_timeout_time <= CurrentTime() &&
-       previous_timeout_time != next_timeout);
-  if (timeout_change) {
-    OnTimeoutChange();
-  }
-}
-
-} // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/taskrunner.h b/third_party/libjingle/source/talk/base/taskrunner.h
deleted file mode 100644
index f34a609..0000000
--- a/third_party/libjingle/source/talk/base/taskrunner.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2006, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_TASKRUNNER_H__
-#define TALK_BASE_TASKRUNNER_H__
-
-#include <vector>
-
-#include "talk/base/basictypes.h"
-#include "talk/base/sigslot.h"
-#include "talk/base/taskparent.h"
-
-namespace talk_base {
-class Task;
-
-const int64 kSecToMsec = 1000;
-const int64 kMsecTo100ns = 10000;
-const int64 kSecTo100ns = kSecToMsec * kMsecTo100ns;
-
-class TaskRunner : public TaskParent, public sigslot::has_slots<> {
- public:
-  TaskRunner();
-  virtual ~TaskRunner();
-
-  virtual void WakeTasks() = 0;
-
-  // Returns the current time in 100ns units.  It is used for
-  // determining timeouts.  The origin is not important, only
-  // the units and that rollover while the computer is running.
-  //
-  // On Windows, GetSystemTimeAsFileTime is the typical implementation.
-  virtual int64 CurrentTime() = 0 ;
-
-  void StartTask(Task *task);
-  void RunTasks();
-  void PollTasks();
-
-  void UpdateTaskTimeout(Task *task, int64 previous_task_timeout_time);
-
-#ifdef _DEBUG
-  bool is_ok_to_delete(Task* task) {
-    return task == deleting_task_;
-  }
-
-  void IncrementAbortCount() {
-    ++abort_count_;
-  }
-
-  void DecrementAbortCount() {
-    --abort_count_;
-  }
-#endif
-
-  // Returns the next absolute time when a task times out
-  // OR "0" if there is no next timeout.
-  int64 next_task_timeout() const;
-
- protected:
-  // The primary usage of this method is to know if
-  // a callback timer needs to be set-up or adjusted.
-  // This method will be called
-  //  * when the next_task_timeout() becomes a smaller value OR
-  //  * when next_task_timeout() has changed values and the previous
-  //    value is in the past.
-  //
-  // If the next_task_timeout moves to the future, this method will *not*
-  // get called (because it subclass should check next_task_timeout()
-  // when its timer goes off up to see if it needs to set-up a new timer).
-  //
-  // Note that this maybe called conservatively.  In that it may be
-  // called when no time change has happened.
-  virtual void OnTimeoutChange() {
-    // by default, do nothing.
-  }
-
- private:
-  void InternalRunTasks(bool in_destructor);
-  void CheckForTimeoutChange(int64 previous_timeout_time);
-
-  std::vector<Task *> tasks_;
-  Task *next_timeout_task_;
-  bool tasks_running_;
-#ifdef _DEBUG
-  int abort_count_;
-  Task* deleting_task_;
-#endif
-
-  void RecalcNextTimeout(Task *exclude_task);
-};
-
-} // namespace talk_base
-
-#endif  // TASK_BASE_TASKRUNNER_H__
diff --git a/third_party/libjingle/source/talk/base/testclient.cc b/third_party/libjingle/source/talk/base/testclient.cc
deleted file mode 100644
index 8a605ce..0000000
--- a/third_party/libjingle/source/talk/base/testclient.cc
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/testclient.h"
-#include "talk/base/thread.h"
-#include "talk/base/timeutils.h"
-
-namespace talk_base {
-
-// DESIGN: Each packet received is put it into a list of packets.
-//         Callers can retrieve received packets from any thread by calling
-//         NextPacket.
-
-TestClient::TestClient(AsyncPacketSocket* socket) : socket_(socket) {
-  packets_ = new std::vector<Packet*>();
-  socket_->SignalReadPacket.connect(this, &TestClient::OnPacket);
-}
-
-TestClient::~TestClient() {
-  delete socket_;
-  for (unsigned i = 0; i < packets_->size(); i++)
-    delete (*packets_)[i];
-  delete packets_;
-}
-
-bool TestClient::CheckConnState(AsyncPacketSocket::State state) {
-  // Wait for our timeout value until the socket reaches the desired state.
-  uint32 end = TimeAfter(kTimeout);
-  while (socket_->GetState() != state && TimeUntil(end) > 0)
-    Thread::Current()->ProcessMessages(1);
-  return (socket_->GetState() == state);
-}
-
-int TestClient::Send(const char* buf, size_t size) {
-  return socket_->Send(buf, size);
-}
-
-int TestClient::SendTo(const char* buf, size_t size,
-                       const SocketAddress& dest) {
-  return socket_->SendTo(buf, size, dest);
-}
-
-TestClient::Packet* TestClient::NextPacket() {
-  // If no packets are currently available, we go into a get/dispatch loop for
-  // at most 1 second.  If, during the loop, a packet arrives, then we can stop
-  // early and return it.
-
-  // Note that the case where no packet arrives is important.  We often want to
-  // test that a packet does not arrive.
-
-  // Note also that we only try to pump our current thread's message queue.
-  // Pumping another thread's queue could lead to messages being dispatched from
-  // the wrong thread to non-thread-safe objects.
-
-  uint32 end = TimeAfter(kTimeout);
-  while (packets_->size() == 0 && TimeUntil(end) > 0)
-    Thread::Current()->ProcessMessages(1);
-
-  // Return the first packet placed in the queue.
-  Packet* packet = NULL;
-  if (packets_->size() > 0) {
-    CritScope cs(&crit_);
-    packet = packets_->front();
-    packets_->erase(packets_->begin());
-  }
-
-  return packet;
-}
-
-bool TestClient::CheckNextPacket(const char* buf, size_t size,
-                                 SocketAddress* addr) {
-  bool res = false;
-  Packet* packet = NextPacket();
-  if (packet) {
-    res = (packet->size == size && std::memcmp(packet->buf, buf, size) == 0);
-    if (addr)
-      *addr = packet->addr;
-    delete packet;
-  }
-  return res;
-}
-
-bool TestClient::CheckNoPacket() {
-  bool res;
-  Packet* packet = NextPacket();
-  res = (packet == NULL);
-  delete packet;
-  return res;
-}
-
-void TestClient::OnPacket(AsyncPacketSocket* socket, const char* buf,
-                          size_t size, const SocketAddress& remote_addr) {
-  CritScope cs(&crit_);
-  packets_->push_back(new Packet(remote_addr, buf, size));
-}
-
-TestClient::Packet::Packet(const SocketAddress& a, const char* b, size_t s)
-    : addr(a), buf(0), size(s) {
-  buf = new char[size];
-  memcpy(buf, b, size);
-}
-
-TestClient::Packet::Packet(const Packet& p)
-    : addr(p.addr), buf(0), size(p.size) {
-  buf = new char[size];
-  memcpy(buf, p.buf, size);
-}
-
-TestClient::Packet::~Packet() {
-  delete[] buf;
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/testclient.h b/third_party/libjingle/source/talk/base/testclient.h
deleted file mode 100644
index 400e58f..0000000
--- a/third_party/libjingle/source/talk/base/testclient.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_TESTCLIENT_H_
-#define TALK_BASE_TESTCLIENT_H_
-
-#include <vector>
-#include "talk/base/asyncudpsocket.h"
-#include "talk/base/criticalsection.h"
-
-namespace talk_base {
-
-// A simple client that can send TCP or UDP data and check that it receives
-// what it expects to receive. Useful for testing server functionality.
-class TestClient : public sigslot::has_slots<> {
- public:
-  // Records the contents of a packet that was received.
-  struct Packet {
-    Packet(const SocketAddress& a, const char* b, size_t s);
-    Packet(const Packet& p);
-    virtual ~Packet();
-
-    SocketAddress addr;
-    char*  buf;
-    size_t size;
-  };
-
-  // Creates a client that will send and receive with the given socket and
-  // will post itself messages with the given thread.
-  explicit TestClient(AsyncPacketSocket* socket);
-  ~TestClient();
-
-  SocketAddress address() const { return socket_->GetLocalAddress(); }
-  SocketAddress remote_address() const { return socket_->GetRemoteAddress(); }
-
-  // Checks that the socket moves to the specified connect state.
-  bool CheckConnState(AsyncPacketSocket::State state);
-
-  // Checks that the socket is connected to the remote side.
-  bool CheckConnected() {
-    return CheckConnState(AsyncPacketSocket::STATE_CONNECTED);
-  }
-
-  // Sends using the clients socket.
-  int Send(const char* buf, size_t size);
-
-  // Sends using the clients socket to the given destination.
-  int SendTo(const char* buf, size_t size, const SocketAddress& dest);
-
-  // Returns the next packet received by the client or 0 if none is received
-  // within a reasonable amount of time.  The caller must delete the packet
-  // when done with it.
-  Packet* NextPacket();
-
-  // Checks that the next packet has the given contents. Returns the remote
-  // address that the packet was sent from.
-  bool CheckNextPacket(const char* buf, size_t len, SocketAddress* addr);
-
-  // Checks that no packets have arrived or will arrive in the next second.
-  bool CheckNoPacket();
-
- private:
-  static const int kTimeout = 1000;
-  // Workaround for the fact that AsyncPacketSocket::GetConnState doesn't exist.
-  Socket::ConnState GetState();
-  // Slot for packets read on the socket.
-  void OnPacket(AsyncPacketSocket* socket, const char* buf, size_t len,
-                const SocketAddress& remote_addr);
-
-  CriticalSection crit_;
-  AsyncPacketSocket* socket_;
-  std::vector<Packet*>* packets_;
-  DISALLOW_EVIL_CONSTRUCTORS(TestClient);
-};
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_TESTCLIENT_H_
diff --git a/third_party/libjingle/source/talk/base/testclient_unittest.cc b/third_party/libjingle/source/talk/base/testclient_unittest.cc
deleted file mode 100644
index ee91067..0000000
--- a/third_party/libjingle/source/talk/base/testclient_unittest.cc
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * libjingle
- * Copyright 2006, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/gunit.h"
-#include "talk/base/host.h"
-#include "talk/base/physicalsocketserver.h"
-#include "talk/base/testclient.h"
-#include "talk/base/testechoserver.h"
-#include "talk/base/thread.h"
-
-using namespace talk_base;
-
-static const SocketAddress kLocalHostAnyAddr("127.0.0.1", 0);
-
-// Tests whether the TestClient can send UDP to itself.
-TEST(TestClientTest, TestUdp) {
-  Thread *main = Thread::Current();
-  AsyncSocket* socket = main->socketserver()->CreateAsyncSocket(SOCK_DGRAM);
-  socket->Bind(kLocalHostAnyAddr);
-
-  TestClient client(new AsyncUDPSocket(socket));
-  SocketAddress addr = client.address(), from;
-  EXPECT_EQ(3, client.SendTo("foo", 3, addr));
-  EXPECT_TRUE(client.CheckNextPacket("foo", 3, &from));
-  EXPECT_EQ(from, addr);
-  EXPECT_TRUE(client.CheckNoPacket());
-}
-
-// Tests whether the TestClient can connect to a server and exchange data.
-TEST(TestClientTest, TestTcp) {
-  Thread *main = Thread::Current();
-  TestEchoServer server(main, kLocalHostAnyAddr);
-
-  AsyncSocket* socket = main->socketserver()->CreateAsyncSocket(SOCK_STREAM);
-  AsyncTCPSocket* tcp_socket = AsyncTCPSocket::Create(
-      socket, kLocalHostAnyAddr, server.address());
-  ASSERT_TRUE(tcp_socket != NULL);
-
-  TestClient client(tcp_socket);
-  SocketAddress addr = client.address(), from;
-  EXPECT_TRUE(client.CheckConnected());
-  EXPECT_EQ(3, client.Send("foo", 3));
-  EXPECT_TRUE(client.CheckNextPacket("foo", 3, &from));
-  EXPECT_EQ(from, server.address());
-  EXPECT_TRUE(client.CheckNoPacket());
-}
diff --git a/third_party/libjingle/source/talk/base/testechoserver.h b/third_party/libjingle/source/talk/base/testechoserver.h
deleted file mode 100644
index 2c65167..0000000
--- a/third_party/libjingle/source/talk/base/testechoserver.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_TESTECHOSERVER_H_
-#define TALK_BASE_TESTECHOSERVER_H_
-
-#include <list>
-#include "talk/base/asynctcpsocket.h"
-#include "talk/base/socketaddress.h"
-#include "talk/base/sigslot.h"
-#include "talk/base/thread.h"
-
-namespace talk_base {
-
-// A test echo server, echoes back any packets sent to it.
-// Useful for unit tests.
-class TestEchoServer : public sigslot::has_slots<> {
- public:
-  TestEchoServer(Thread* thread, const SocketAddress& addr)
-      : server_socket_(thread->socketserver()->CreateAsyncSocket(SOCK_STREAM)) {
-    server_socket_->Bind(addr);
-    server_socket_->Listen(5);
-    server_socket_->SignalReadEvent.connect(this, &TestEchoServer::OnAccept);
-  }
-  ~TestEchoServer() {
-    for (ClientList::iterator it = client_sockets_.begin();
-         it != client_sockets_.end(); ++it) {
-      delete *it;
-    }
-  }
-
-  SocketAddress address() const { return server_socket_->GetLocalAddress(); }
-
- private:
-  void OnAccept(AsyncSocket* socket) {
-    AsyncSocket* raw_socket = socket->Accept(NULL);
-    if (raw_socket) {
-      AsyncTCPSocket* packet_socket = new AsyncTCPSocket(raw_socket, false);
-      packet_socket->SignalReadPacket.connect(this, &TestEchoServer::OnPacket);
-      packet_socket->SignalClose.connect(this, &TestEchoServer::OnClose);
-      client_sockets_.push_back(packet_socket);
-    }
-  }
-  void OnPacket(AsyncPacketSocket* socket, const char* buf, size_t size,
-                const SocketAddress& remote_addr) {
-    socket->Send(buf, size);
-  }
-  void OnClose(AsyncPacketSocket* socket, int err) {
-    ClientList::iterator it =
-        std::find(client_sockets_.begin(), client_sockets_.end(), socket);
-    client_sockets_.erase(it);
-    Thread::Current()->Dispose(socket);
-  }
-
-  typedef std::list<AsyncTCPSocket*> ClientList;
-  scoped_ptr<AsyncSocket> server_socket_;
-  ClientList client_sockets_;
-  DISALLOW_EVIL_CONSTRUCTORS(TestEchoServer);
-};
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_TESTECHOSERVER_H_
diff --git a/third_party/libjingle/source/talk/base/testutils.h b/third_party/libjingle/source/talk/base/testutils.h
deleted file mode 100644
index 4dc648e..0000000
--- a/third_party/libjingle/source/talk/base/testutils.h
+++ /dev/null
@@ -1,568 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_TESTUTILS_H__
-#define TALK_BASE_TESTUTILS_H__
-
-// Utilities for testing talk_base infrastructure in unittests
-
-#include <map>
-#include <vector>
-#include "talk/base/asyncsocket.h"
-#include "talk/base/common.h"
-#include "talk/base/gunit.h"
-#include "talk/base/stream.h"
-#include "talk/base/stringencode.h"
-#include "talk/base/stringutils.h"
-#include "talk/base/thread.h"
-
-namespace testing {
-
-using namespace talk_base;
-
-///////////////////////////////////////////////////////////////////////////////
-// StreamSink - Monitor asynchronously signalled events from StreamInterface
-// or AsyncSocket (which should probably be a StreamInterface.
-///////////////////////////////////////////////////////////////////////////////
-
-// Note: Any event that is an error is treaded as SSE_ERROR instead of that
-// event.
-
-enum StreamSinkEvent {
-  SSE_OPEN  = SE_OPEN,
-  SSE_READ  = SE_READ,
-  SSE_WRITE = SE_WRITE,
-  SSE_CLOSE = SE_CLOSE,
-  SSE_ERROR = 16
-};
-
-class StreamSink : public sigslot::has_slots<> {
- public:
-  void Monitor(StreamInterface* stream) {
-   stream->SignalEvent.connect(this, &StreamSink::OnEvent);
-   events_.erase(stream);
-  }
-  void Unmonitor(StreamInterface* stream) {
-   stream->SignalEvent.disconnect(this);
-   // In case you forgot to unmonitor a previous object with this address
-   events_.erase(stream);
-  }
-  bool Check(StreamInterface* stream, StreamSinkEvent event, bool reset = true) {
-    return DoCheck(stream, event, reset);
-  }
-  int Events(StreamInterface* stream, bool reset = true) {
-    return DoEvents(stream, reset);
-  }
-
-  void Monitor(AsyncSocket* socket) {
-   socket->SignalConnectEvent.connect(this, &StreamSink::OnConnectEvent);
-   socket->SignalReadEvent.connect(this, &StreamSink::OnReadEvent);
-   socket->SignalWriteEvent.connect(this, &StreamSink::OnWriteEvent);
-   socket->SignalCloseEvent.connect(this, &StreamSink::OnCloseEvent);
-   // In case you forgot to unmonitor a previous object with this address
-   events_.erase(socket);
-  }
-  void Unmonitor(AsyncSocket* socket) {
-   socket->SignalConnectEvent.disconnect(this);
-   socket->SignalReadEvent.disconnect(this);
-   socket->SignalWriteEvent.disconnect(this);
-   socket->SignalCloseEvent.disconnect(this);
-   events_.erase(socket);
-  }
-  bool Check(AsyncSocket* socket, StreamSinkEvent event, bool reset = true) {
-    return DoCheck(socket, event, reset);
-  }
-  int Events(AsyncSocket* socket, bool reset = true) {
-    return DoEvents(socket, reset);
-  }
-
- private:
-  typedef std::map<void*,int> EventMap;
-
-  void OnEvent(StreamInterface* stream, int events, int error) {
-    if (error) {
-      events = SSE_ERROR;
-    }
-    AddEvents(stream, events);
-  }
-  void OnConnectEvent(AsyncSocket* socket) {
-    AddEvents(socket, SSE_OPEN);
-  }
-  void OnReadEvent(AsyncSocket* socket) {
-    AddEvents(socket, SSE_READ);
-  }
-  void OnWriteEvent(AsyncSocket* socket) {
-    AddEvents(socket, SSE_WRITE);
-  }
-  void OnCloseEvent(AsyncSocket* socket, int error) {
-    AddEvents(socket, (0 == error) ? SSE_CLOSE : SSE_ERROR);
-  }
-
-  void AddEvents(void* obj, int events) {
-    EventMap::iterator it = events_.find(obj);
-    if (events_.end() == it) {
-      events_.insert(EventMap::value_type(obj, events));
-    } else {
-      it->second |= events;
-    }
-  }
-  bool DoCheck(void* obj, StreamSinkEvent event, bool reset) {
-    EventMap::iterator it = events_.find(obj);
-    if ((events_.end() == it) || (0 == (it->second & event))) {
-      return false;
-    }
-    if (reset) {
-      it->second &= ~event;
-    }
-    return true;
-  }
-  int DoEvents(void* obj, bool reset) {
-    EventMap::iterator it = events_.find(obj);
-    if (events_.end() == it)
-      return 0;
-    int events = it->second;
-    if (reset) {
-      it->second = 0;
-    }
-    return events;
-  }
-
-  EventMap events_;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// StreamSource - Implements stream interface and simulates asynchronous
-// events on the stream, without a network.  Also buffers written data.
-///////////////////////////////////////////////////////////////////////////////
-
-class StreamSource : public StreamInterface {
-public:
-  StreamSource() {
-    Clear();
-  }
-
-  void Clear() {
-    readable_data_.clear();
-    written_data_.clear();
-    state_ = SS_CLOSED;
-    read_block_ = 0;
-    write_block_ = SIZE_UNKNOWN;
-  }
-  void QueueString(const char* data) {
-    QueueData(data, strlen(data));
-  }
-  void QueueStringF(const char* format, ...) {
-    va_list args;
-    va_start(args, format);
-    char buffer[1024];
-    size_t len = vsprintfn(buffer, sizeof(buffer), format, args);
-    ASSERT(len < sizeof(buffer) - 1);
-    va_end(args);
-    QueueData(buffer, len);
-  }
-  void QueueData(const char* data, size_t len) {
-    readable_data_.insert(readable_data_.end(), data, data + len);
-    if ((SS_OPEN == state_) && (readable_data_.size() == len)) {
-      SignalEvent(this, SE_READ, 0);
-    }
-  }
-  std::string ReadData() {
-    std::string data;
-    // avoid accessing written_data_[0] if it is undefined
-    if (written_data_.size() > 0) {
-      data.insert(0, &written_data_[0], written_data_.size());
-    }
-    written_data_.clear();
-    return data;
-  }
-  void SetState(StreamState state) {
-    int events = 0;
-    if ((SS_OPENING == state_) && (SS_OPEN == state)) {
-      events |= SE_OPEN;
-      if (!readable_data_.empty()) {
-        events |= SE_READ;
-      }
-    } else if ((SS_CLOSED != state_) && (SS_CLOSED == state)) {
-      events |= SE_CLOSE;
-    }
-    state_ = state;
-    if (events) {
-      SignalEvent(this, events, 0);
-    }
-  }
-  // Will cause Read to block when there are pos bytes in the read queue.
-  void SetReadBlock(size_t pos) { read_block_ = pos; }
-  // Will cause Write to block when there are pos bytes in the write queue.
-  void SetWriteBlock(size_t pos) { write_block_ = pos; }
-
-  virtual StreamState GetState() const { return state_; }
-  virtual StreamResult Read(void* buffer, size_t buffer_len,
-                            size_t* read, int* error) {
-    if (SS_CLOSED == state_) {
-      if (error) *error = -1;
-      return SR_ERROR;
-    }
-    if ((SS_OPENING == state_) || (readable_data_.size() <= read_block_)) {
-      return SR_BLOCK;
-    }
-    size_t count = _min(buffer_len, readable_data_.size() - read_block_);
-    memcpy(buffer, &readable_data_[0], count);
-    size_t new_size = readable_data_.size() - count;
-    // Avoid undefined access beyond the last element of the vector.
-    // This only happens when new_size is 0.
-    if (count < readable_data_.size()) {
-      memmove(&readable_data_[0], &readable_data_[count], new_size);
-    }
-    readable_data_.resize(new_size);
-    if (read) *read = count;
-    return SR_SUCCESS;
-  }
-  virtual StreamResult Write(const void* data, size_t data_len,
-                             size_t* written, int* error) {
-    if (SS_CLOSED == state_) {
-      if (error) *error = -1;
-      return SR_ERROR;
-    }
-    if (SS_OPENING == state_) {
-      return SR_BLOCK;
-    }
-    if (SIZE_UNKNOWN != write_block_) {
-      if (written_data_.size() >= write_block_) {
-        return SR_BLOCK;
-      }
-      if (data_len > (write_block_ - written_data_.size())) {
-        data_len = write_block_ - written_data_.size();
-      }
-    }
-    if (written) *written = data_len;
-    const char* cdata = static_cast<const char*>(data);
-    written_data_.insert(written_data_.end(), cdata, cdata + data_len);
-    return SR_SUCCESS;
-  }
-  virtual void Close() { state_ = SS_CLOSED; }
-
-private:
-  typedef std::vector<char> Buffer;
-  Buffer readable_data_, written_data_;
-  StreamState state_;
-  size_t read_block_, write_block_;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// SocketTestClient
-// Creates a simulated client for testing.  Works on real and virtual networks.
-///////////////////////////////////////////////////////////////////////////////
-
-class SocketTestClient : public sigslot::has_slots<> {
-public:
-  SocketTestClient() {
-    Init(NULL);
-  }
-  SocketTestClient(AsyncSocket* socket) {
-    Init(socket);
-  }
-  SocketTestClient(const SocketAddress& address) {
-    Init(NULL);
-    socket_->Connect(address);
-  }
-
-  AsyncSocket* socket() { return socket_.get(); }
-
-  void QueueString(const char* data) {
-    QueueData(data, strlen(data));
-  }
-  void QueueStringF(const char* format, ...) {
-    va_list args;
-    va_start(args, format);
-    char buffer[1024];
-    size_t len = vsprintfn(buffer, sizeof(buffer), format, args);
-    ASSERT(len < sizeof(buffer) - 1);
-    va_end(args);
-    QueueData(buffer, len);
-  }
-  void QueueData(const char* data, size_t len) {
-    send_buffer_.insert(send_buffer_.end(), data, data + len);
-    if (Socket::CS_CONNECTED == socket_->GetState()) {
-      Flush();
-    }
-  }
-  std::string ReadData() {
-    std::string data(&recv_buffer_[0], recv_buffer_.size());
-    recv_buffer_.clear();
-    return data;
-  }
-
-  bool IsConnected() const {
-    return (Socket::CS_CONNECTED == socket_->GetState());
-  }
-  bool IsClosed() const {
-    return (Socket::CS_CLOSED == socket_->GetState());
-  }
-
-private:
-  typedef std::vector<char> Buffer;
-
-  void Init(AsyncSocket* socket) {
-    if (!socket) {
-      socket = Thread::Current()->socketserver()
-                                ->CreateAsyncSocket(SOCK_STREAM);
-    }
-    socket_.reset(socket);
-    socket_->SignalConnectEvent.connect(this,
-      &SocketTestClient::OnConnectEvent);
-    socket_->SignalReadEvent.connect(this, &SocketTestClient::OnReadEvent);
-    socket_->SignalWriteEvent.connect(this, &SocketTestClient::OnWriteEvent);
-    socket_->SignalCloseEvent.connect(this, &SocketTestClient::OnCloseEvent);
-  }
-
-  void Flush() {
-    size_t sent = 0;
-    while (sent < send_buffer_.size()) {
-      int result = socket_->Send(&send_buffer_[sent],
-                                 send_buffer_.size() - sent);
-      if (result > 0) {
-        sent += result;
-      } else {
-        break;
-      }
-    }
-    size_t new_size = send_buffer_.size() - sent;
-    memmove(&send_buffer_[0], &send_buffer_[sent], new_size);
-    send_buffer_.resize(new_size);
-  }
-
-  void OnConnectEvent(AsyncSocket* socket) {
-    if (!send_buffer_.empty()) {
-      Flush();
-    }
-  }
-  void OnReadEvent(AsyncSocket* socket) {
-    char data[64 * 1024];
-    int result = socket_->Recv(data, ARRAY_SIZE(data));
-    if (result > 0) {
-      recv_buffer_.insert(recv_buffer_.end(), data, data + result);
-    }
-  }
-  void OnWriteEvent(AsyncSocket* socket) {
-    if (!send_buffer_.empty()) {
-      Flush();
-    }
-  }
-  void OnCloseEvent(AsyncSocket* socket, int error) {
-  }
-
-  scoped_ptr<AsyncSocket> socket_;
-  Buffer send_buffer_, recv_buffer_;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// SocketTestServer
-// Creates a simulated server for testing.  Works on real and virtual networks.
-///////////////////////////////////////////////////////////////////////////////
-
-class SocketTestServer : public sigslot::has_slots<> {
- public:
-  SocketTestServer(const SocketAddress& address)
-  : socket_(Thread::Current()->socketserver()->CreateAsyncSocket(SOCK_STREAM))
-  {
-    socket_->SignalReadEvent.connect(this, &SocketTestServer::OnReadEvent);
-    socket_->Bind(address);
-    socket_->Listen(5);
-  }
-  virtual ~SocketTestServer() {
-    clear();
-  }
-
-  size_t size() const { return clients_.size(); }
-  SocketTestClient* client(size_t index) const { return clients_[index]; }
-  SocketTestClient* operator[](size_t index) const { return client(index); }
-
-  void clear() {
-    for (size_t i=0; i<clients_.size(); ++i) {
-      delete clients_[i];
-    }
-    clients_.clear();
-  }
-
- private:
-  void OnReadEvent(AsyncSocket* socket) {
-    AsyncSocket* accepted =
-      static_cast<AsyncSocket*>(socket_->Accept(NULL));
-    if (!accepted)
-      return;
-    clients_.push_back(new SocketTestClient(accepted));
-  }
-
-  scoped_ptr<AsyncSocket> socket_;
-  std::vector<SocketTestClient*> clients_;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// Generic Utilities
-///////////////////////////////////////////////////////////////////////////////
-
-inline bool ReadFile(const char* filename, std::string* contents) {
-  FILE* fp = fopen(filename, "rb");
-  if (!fp)
-    return false;
-  char buffer[1024*64];
-  size_t read;
-  contents->clear();
-  while ((read = fread(buffer, 1, sizeof(buffer), fp))) {
-    contents->append(buffer, read);
-  }
-  bool success = (0 != feof(fp));
-  fclose(fp);
-  return success;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Unittest predicates which are similar to STREQ, but for raw memory
-///////////////////////////////////////////////////////////////////////////////
-
-inline AssertionResult CmpHelperMemEq(const char* expected_expression,
-                                      const char* expected_length_expression,
-                                      const char* actual_expression,
-                                      const char* actual_length_expression,
-                                      const void* expected,
-                                      size_t expected_length,
-                                      const void* actual,
-                                      size_t actual_length)
-{
-  if ((expected_length == actual_length)
-      && (0 == memcmp(expected, actual, expected_length))) {
-    return AssertionSuccess();
-  }
-
-  Message msg;
-  msg << "Value of: " << actual_expression
-      << " [" << actual_length_expression << "]";
-  if (true) {  //!actual_value.Equals(actual_expression)) {
-    size_t buffer_size = actual_length * 2 + 1;
-    char* buffer = STACK_ARRAY(char, buffer_size);
-    hex_encode(buffer, buffer_size,
-               reinterpret_cast<const char*>(actual), actual_length);
-    msg << "\n  Actual: " << buffer << " [" << actual_length << "]";
-  }
-
-  msg << "\nExpected: " << expected_expression
-      << " [" << expected_length_expression << "]";
-  if (true) {  //!expected_value.Equals(expected_expression)) {
-    size_t buffer_size = expected_length * 2 + 1;
-    char* buffer = STACK_ARRAY(char, buffer_size);
-    hex_encode(buffer, buffer_size,
-               reinterpret_cast<const char*>(expected), expected_length);
-    msg << "\nWhich is: " << buffer << " [" << expected_length << "]";
-  }
-
-  return AssertionFailure(msg);
-}
-
-inline AssertionResult CmpHelperFileEq(const char* expected_expression,
-                                       const char* expected_length_expression,
-                                       const char* actual_filename,
-                                       const void* expected,
-                                       size_t expected_length,
-                                       const char* filename)
-{
-  std::string contents;
-  if (!ReadFile(filename, &contents)) {
-    Message msg;
-    msg << "File '" << filename << "' could not be read.";
-    return AssertionFailure(msg);
-  }
-  return CmpHelperMemEq(expected_expression, expected_length_expression,
-                        actual_filename, "",
-                        expected, expected_length,
-                        contents.c_str(), contents.size());
-}
-
-#define EXPECT_MEMEQ(expected, expected_length, actual, actual_length) \
-  EXPECT_PRED_FORMAT4(::testing::CmpHelperMemEq, expected, expected_length, \
-                      actual, actual_length)
-
-#define ASSERT_MEMEQ(expected, expected_length, actual, actual_length) \
-  ASSERT_PRED_FORMAT4(::testing::CmpHelperMemEq, expected, expected_length, \
-                      actual, actual_length)
-
-#define EXPECT_FILEEQ(expected, expected_length, filename) \
-  EXPECT_PRED_FORMAT3(::testing::CmpHelperFileEq, expected, expected_length, \
-                      filename)
-
-#define ASSERT_FILEEQ(expected, expected_length, filename) \
-  ASSERT_PRED_FORMAT3(::testing::CmpHelperFileEq, expected, expected_length, \
-                      filename)
-
-///////////////////////////////////////////////////////////////////////////////
-// Helpers for initializing constant memory with integers in a particular byte
-// order
-///////////////////////////////////////////////////////////////////////////////
-
-#define BYTE_CAST(x) static_cast<uint8>((x) & 0xFF)
-
-// Declare a N-bit integer as a little-endian sequence of bytes
-#define LE16(x) BYTE_CAST(((uint16)x) >>  0), BYTE_CAST(((uint16)x) >>  8)
-
-#define LE32(x) BYTE_CAST(((uint32)x) >>  0), BYTE_CAST(((uint32)x) >>  8), \
-                BYTE_CAST(((uint32)x) >> 16), BYTE_CAST(((uint32)x) >> 24)
-
-#define LE64(x) BYTE_CAST(((uint64)x) >>  0), BYTE_CAST(((uint64)x) >>  8), \
-                BYTE_CAST(((uint64)x) >> 16), BYTE_CAST(((uint64)x) >> 24), \
-                BYTE_CAST(((uint64)x) >> 32), BYTE_CAST(((uint64)x) >> 40), \
-                BYTE_CAST(((uint64)x) >> 48), BYTE_CAST(((uint64)x) >> 56)
-
-// Declare a N-bit integer as a big-endian (Internet) sequence of bytes
-#define BE16(x) BYTE_CAST(((uint16)x) >>  8), BYTE_CAST(((uint16)x) >>  0)
-
-#define BE32(x) BYTE_CAST(((uint32)x) >> 24), BYTE_CAST(((uint32)x) >> 16), \
-                BYTE_CAST(((uint32)x) >>  8), BYTE_CAST(((uint32)x) >>  0)
-
-#define BE64(x) BYTE_CAST(((uint64)x) >> 56), BYTE_CAST(((uint64)x) >> 48), \
-                BYTE_CAST(((uint64)x) >> 40), BYTE_CAST(((uint64)x) >> 32), \
-                BYTE_CAST(((uint64)x) >> 24), BYTE_CAST(((uint64)x) >> 16), \
-                BYTE_CAST(((uint64)x) >>  8), BYTE_CAST(((uint64)x) >>  0)
-
-// Declare a N-bit integer as a this-endian (local machine) sequence of bytes
-#ifndef BIG_ENDIAN
-#define BIG_ENDIAN 1
-#endif  // BIG_ENDIAN
-
-#if BIG_ENDIAN
-#define TE16 BE16
-#define TE32 BE32
-#define TE64 BE64
-#else  // !BIG_ENDIAN
-#define TE16 LE16
-#define TE32 LE32
-#define TE64 LE64
-#endif  // !BIG_ENDIAN
-
-///////////////////////////////////////////////////////////////////////////////
-
-}  // namespace testing
-
-#endif  // TALK_BASE_TESTUTILS_H__
diff --git a/third_party/libjingle/source/talk/base/thread.cc b/third_party/libjingle/source/talk/base/thread.cc
deleted file mode 100644
index 32c6e6f..0000000
--- a/third_party/libjingle/source/talk/base/thread.cc
+++ /dev/null
@@ -1,568 +0,0 @@
-/*
- * libjingle
- * Copyright 2004 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/thread.h"
-
-#if defined(WIN32)
-#include <comdef.h>
-#elif defined(POSIX)
-#include <time.h>
-#endif
-
-#include "talk/base/common.h"
-#include "talk/base/logging.h"
-#include "talk/base/stringutils.h"
-#include "talk/base/timeutils.h"
-
-#ifdef USE_COCOA_THREADING
-#if !defined(OSX) && !defined(IOS)
-#error USE_COCOA_THREADING is defined but not OSX nor IOS
-#endif
-#include "talk/base/maccocoathreadhelper.h"
-#include "talk/base/scoped_autorelease_pool.h"
-#endif
-
-namespace talk_base {
-
-ThreadManager g_thmgr;
-
-#ifdef POSIX
-pthread_key_t ThreadManager::key_;
-
-ThreadManager::ThreadManager() {
-  pthread_key_create(&key_, NULL);
-  main_thread_ = WrapCurrentThread();
-#ifdef USE_COCOA_THREADING
-  InitCocoaMultiThreading();
-#endif
-}
-
-ThreadManager::~ThreadManager() {
-#ifdef USE_COCOA_THREADING
-  // This is called during exit, at which point apparently no NSAutoreleasePools
-  // are available; but we might still need them to do cleanup (or we get the
-  // "no autoreleasepool in place, just leaking" warning when exiting).
-  ScopedAutoreleasePool pool;
-#endif
-  UnwrapCurrentThread();
-  // Unwrap deletes main_thread_ automatically.
-  pthread_key_delete(key_);
-}
-
-Thread *ThreadManager::CurrentThread() {
-  return static_cast<Thread *>(pthread_getspecific(key_));
-}
-
-void ThreadManager::SetCurrent(Thread *thread) {
-  pthread_setspecific(key_, thread);
-}
-#endif
-
-#ifdef WIN32
-DWORD ThreadManager::key_;
-
-ThreadManager::ThreadManager() {
-  key_ = TlsAlloc();
-  main_thread_ = WrapCurrentThread();
-}
-
-ThreadManager::~ThreadManager() {
-  UnwrapCurrentThread();
-  TlsFree(key_);
-}
-
-Thread *ThreadManager::CurrentThread() {
-  return static_cast<Thread *>(TlsGetValue(key_));
-}
-
-void ThreadManager::SetCurrent(Thread *thread) {
-  TlsSetValue(key_, thread);
-}
-#endif
-
-// static
-Thread *ThreadManager::WrapCurrentThread() {
-  Thread* result = CurrentThread();
-  if (NULL == result) {
-    result = new Thread();
-    result->WrapCurrent();
-  }
-  return result;
-}
-
-// static
-void ThreadManager::UnwrapCurrentThread() {
-  Thread* t = CurrentThread();
-  if (t && !(t->IsOwned())) {
-    t->UnwrapCurrent();
-    delete t;
-  }
-}
-
-void ThreadManager::Add(Thread *thread) {
-  CritScope cs(&crit_);
-  threads_.push_back(thread);
-}
-
-void ThreadManager::Remove(Thread *thread) {
-  CritScope cs(&crit_);
-  threads_.erase(std::remove(threads_.begin(), threads_.end(), thread),
-                 threads_.end());
-}
-
-void ThreadManager::StopAllThreads_() {
-  // TODO: In order to properly implement, Threads need to be ref-counted.
-  CritScope cs(&g_thmgr.crit_);
-  for (size_t i = 0; i < g_thmgr.threads_.size(); ++i) {
-    g_thmgr.threads_[i]->Stop();
-  }
-}
-
-struct ThreadInit {
-  Thread* thread;
-  Runnable* runnable;
-};
-
-Thread::Thread(SocketServer* ss)
-    : MessageQueue(ss),
-      priority_(PRIORITY_NORMAL),
-      started_(false),
-      has_sends_(false),
-#if defined(WIN32)
-      thread_(NULL),
-#endif
-      owned_(true),
-      delete_self_when_complete_(false) {
-  g_thmgr.Add(this);
-  SetName("Thread", this);  // default name
-}
-
-Thread::~Thread() {
-  Stop();
-  if (active_)
-    Clear(NULL);
-  g_thmgr.Remove(this);
-}
-
-bool Thread::SleepMs(int milliseconds) {
-#ifdef WIN32
-  ::Sleep(milliseconds);
-  return true;
-#else
-  // POSIX has both a usleep() and a nanosleep(), but the former is deprecated,
-  // so we use nanosleep() even though it has greater precision than necessary.
-  struct timespec ts;
-  ts.tv_sec = milliseconds / 1000;
-  ts.tv_nsec = (milliseconds % 1000) * 1000000;
-  int ret = nanosleep(&ts, NULL);
-  if (ret != 0) {
-    LOG_ERR(LS_WARNING) << "nanosleep() returning early";
-    return false;
-  }
-  return true;
-#endif
-}
-
-bool Thread::SetName(const std::string& name, const void* obj) {
-  if (started_) return false;
-  name_ = name;
-  if (obj) {
-    char buf[16];
-    sprintfn(buf, sizeof(buf), " 0x%p", obj);
-    name_ += buf;
-  }
-  return true;
-}
-
-bool Thread::SetPriority(ThreadPriority priority) {
-#if defined(WIN32)
-  if (started_) {
-    BOOL ret = FALSE;
-    if (priority == PRIORITY_NORMAL) {
-      ret = ::SetThreadPriority(thread_, THREAD_PRIORITY_NORMAL);
-    } else if (priority == PRIORITY_HIGH) {
-      ret = ::SetThreadPriority(thread_, THREAD_PRIORITY_HIGHEST);
-    } else if (priority == PRIORITY_ABOVE_NORMAL) {
-      ret = ::SetThreadPriority(thread_, THREAD_PRIORITY_ABOVE_NORMAL);
-    } else if (priority == PRIORITY_IDLE) {
-      ret = ::SetThreadPriority(thread_, THREAD_PRIORITY_IDLE);
-    }
-    if (!ret) {
-      return false;
-    }
-  }
-  priority_ = priority;
-  return true;
-#else
-  // TODO: Implement for Linux/Mac if possible.
-  if (started_) return false;
-  priority_ = priority;
-  return true;
-#endif
-}
-
-bool Thread::Start(Runnable* runnable) {
-  ASSERT(owned_);
-  if (!owned_) return false;
-  ASSERT(!started_);
-  if (started_) return false;
-
-  ThreadInit* init = new ThreadInit;
-  init->thread = this;
-  init->runnable = runnable;
-#if defined(WIN32)
-  DWORD flags = 0;
-  if (priority_ != PRIORITY_NORMAL) {
-    flags = CREATE_SUSPENDED;
-  }
-  thread_ = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)PreRun, init, flags,
-                         NULL);
-  if (thread_) {
-    started_ = true;
-    if (priority_ != PRIORITY_NORMAL) {
-      SetPriority(priority_);
-      ::ResumeThread(thread_);
-    }
-  } else {
-    return false;
-  }
-#elif defined(POSIX)
-  pthread_attr_t attr;
-  pthread_attr_init(&attr);
-  if (priority_ != PRIORITY_NORMAL) {
-    if (priority_ == PRIORITY_IDLE) {
-      // There is no POSIX-standard way to set a below-normal priority for an
-      // individual thread (only whole process), so let's not support it.
-      LOG(LS_WARNING) << "PRIORITY_IDLE not supported";
-    } else {
-      // Set real-time round-robin policy.
-      if (pthread_attr_setschedpolicy(&attr, SCHED_RR) != 0) {
-        LOG(LS_ERROR) << "pthread_attr_setschedpolicy";
-      }
-      struct sched_param param;
-      if (pthread_attr_getschedparam(&attr, &param) != 0) {
-        LOG(LS_ERROR) << "pthread_attr_getschedparam";
-      } else {
-        // The numbers here are arbitrary.
-        if (priority_ == PRIORITY_HIGH) {
-          param.sched_priority = 6;           // 6 = HIGH
-        } else {
-          ASSERT(priority_ == PRIORITY_ABOVE_NORMAL);
-          param.sched_priority = 4;           // 4 = ABOVE_NORMAL
-        }
-        if (pthread_attr_setschedparam(&attr, &param) != 0) {
-          LOG(LS_ERROR) << "pthread_attr_setschedparam";
-        }
-      }
-    }
-  }
-  int error_code = pthread_create(&thread_, &attr, PreRun, init);
-  if (0 != error_code) {
-    LOG(LS_ERROR) << "Unable to create pthread, error " << error_code;
-    return false;
-  }
-  started_ = true;
-#endif
-  return true;
-}
-
-void Thread::Join() {
-  if (started_) {
-    ASSERT(!IsCurrent());
-#if defined(WIN32)
-    WaitForSingleObject(thread_, INFINITE);
-    CloseHandle(thread_);
-    thread_ = NULL;
-#elif defined(POSIX)
-    void *pv;
-    pthread_join(thread_, &pv);
-#endif
-    started_ = false;
-  }
-}
-
-#ifdef WIN32
-// As seen on MSDN.
-// http://msdn.microsoft.com/en-us/library/xcb2z8hs(VS.71).aspx
-#define MSDEV_SET_THREAD_NAME  0x406D1388
-typedef struct tagTHREADNAME_INFO {
-  DWORD dwType;
-  LPCSTR szName;
-  DWORD dwThreadID;
-  DWORD dwFlags;
-} THREADNAME_INFO;
-
-void SetThreadName(DWORD dwThreadID, LPCSTR szThreadName) {
-  THREADNAME_INFO info;
-  info.dwType = 0x1000;
-  info.szName = szThreadName;
-  info.dwThreadID = dwThreadID;
-  info.dwFlags = 0;
-
-  __try {
-    RaiseException(MSDEV_SET_THREAD_NAME, 0, sizeof(info) / sizeof(DWORD),
-                   reinterpret_cast<DWORD*>(&info));
-  }
-  __except(EXCEPTION_CONTINUE_EXECUTION) {
-  }
-}
-#endif  // WIN32
-
-void* Thread::PreRun(void* pv) {
-  ThreadInit* init = static_cast<ThreadInit*>(pv);
-  ThreadManager::SetCurrent(init->thread);
-#if defined(WIN32)
-  SetThreadName(GetCurrentThreadId(), init->thread->name_.c_str());
-#elif defined(POSIX)
-  // TODO: See if naming exists for pthreads.
-#endif
-#ifdef USE_COCOA_THREADING
-  // Make sure the new thread has an autoreleasepool
-  ScopedAutoreleasePool pool;
-#endif
-  if (init->runnable) {
-    init->runnable->Run(init->thread);
-  } else {
-    init->thread->Run();
-  }
-  if (init->thread->delete_self_when_complete_) {
-    init->thread->started_ = false;
-    delete init->thread;
-  }
-  delete init;
-  return NULL;
-}
-
-void Thread::Run() {
-  ProcessMessages(kForever);
-}
-
-bool Thread::IsOwned() {
-  return owned_;
-}
-
-void Thread::Stop() {
-  MessageQueue::Quit();
-  Join();
-}
-
-void Thread::Send(MessageHandler *phandler, uint32 id, MessageData *pdata) {
-  if (fStop_)
-    return;
-
-  // Sent messages are sent to the MessageHandler directly, in the context
-  // of "thread", like Win32 SendMessage. If in the right context,
-  // call the handler directly.
-
-  Message msg;
-  msg.phandler = phandler;
-  msg.message_id = id;
-  msg.pdata = pdata;
-  if (IsCurrent()) {
-    phandler->OnMessage(&msg);
-    return;
-  }
-
-  AutoThread thread;
-  Thread *current_thread = Thread::Current();
-  ASSERT(current_thread != NULL);  // AutoThread ensures this
-
-  bool ready = false;
-  {
-    CritScope cs(&crit_);
-    EnsureActive();
-    _SendMessage smsg;
-    smsg.thread = current_thread;
-    smsg.msg = msg;
-    smsg.ready = &ready;
-    sendlist_.push_back(smsg);
-    has_sends_ = true;
-  }
-
-  // Wait for a reply
-
-  ss_->WakeUp();
-
-  bool waited = false;
-  while (!ready) {
-    current_thread->ReceiveSends();
-    current_thread->socketserver()->Wait(kForever, false);
-    waited = true;
-  }
-
-  // Our Wait loop above may have consumed some WakeUp events for this
-  // MessageQueue, that weren't relevant to this Send.  Losing these WakeUps can
-  // cause problems for some SocketServers.
-  //
-  // Concrete example:
-  // Win32SocketServer on thread A calls Send on thread B.  While processing the
-  // message, thread B Posts a message to A.  We consume the wakeup for that
-  // Post while waiting for the Send to complete, which means that when we exit
-  // this loop, we need to issue another WakeUp, or else the Posted message
-  // won't be processed in a timely manner.
-
-  if (waited) {
-    current_thread->socketserver()->WakeUp();
-  }
-}
-
-void Thread::ReceiveSends() {
-  // Before entering critical section, check boolean.
-
-  if (!has_sends_)
-    return;
-
-  // Receive a sent message. Cleanup scenarios:
-  // - thread sending exits: We don't allow this, since thread can exit
-  //   only via Join, so Send must complete.
-  // - thread receiving exits: Wakeup/set ready in Thread::Clear()
-  // - object target cleared: Wakeup/set ready in Thread::Clear()
-  crit_.Enter();
-  while (!sendlist_.empty()) {
-    _SendMessage smsg = sendlist_.front();
-    sendlist_.pop_front();
-    crit_.Leave();
-    smsg.msg.phandler->OnMessage(&smsg.msg);
-    crit_.Enter();
-    *smsg.ready = true;
-    smsg.thread->socketserver()->WakeUp();
-  }
-  has_sends_ = false;
-  crit_.Leave();
-}
-
-void Thread::Clear(MessageHandler *phandler, uint32 id,
-                   MessageList* removed) {
-  CritScope cs(&crit_);
-
-  // Remove messages on sendlist_ with phandler
-  // Object target cleared: remove from send list, wakeup/set ready
-  // if sender not NULL.
-
-  std::list<_SendMessage>::iterator iter = sendlist_.begin();
-  while (iter != sendlist_.end()) {
-    _SendMessage smsg = *iter;
-    if (smsg.msg.Match(phandler, id)) {
-      if (removed) {
-        removed->push_back(smsg.msg);
-      } else {
-        delete smsg.msg.pdata;
-      }
-      iter = sendlist_.erase(iter);
-      *smsg.ready = true;
-      smsg.thread->socketserver()->WakeUp();
-      continue;
-    }
-    ++iter;
-  }
-
-  MessageQueue::Clear(phandler, id, removed);
-}
-
-bool Thread::ProcessMessages(int cmsLoop) {
-  uint32 msEnd = (kForever == cmsLoop) ? 0 : TimeAfter(cmsLoop);
-  int cmsNext = cmsLoop;
-
-  while (true) {
-#ifdef USE_COCOA_THREADING
-    // see: http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSAutoreleasePool_Class/Reference/Reference.html
-    // Each thread is supposed to have an autorelease pool. Also for event loops
-    // like this, autorelease pool needs to be created and drained/released
-    // for each cycle.
-    ScopedAutoreleasePool pool;
-#endif
-    Message msg;
-    if (!Get(&msg, cmsNext))
-      return !IsQuitting();
-    Dispatch(&msg);
-
-    if (cmsLoop != kForever) {
-      cmsNext = TimeUntil(msEnd);
-      if (cmsNext < 0)
-        return true;
-    }
-  }
-}
-
-bool Thread::WrapCurrent() {
-  if (started_)
-    return false;
-#if defined(WIN32)
-  // We explicitly ask for no rights other than synchronization.
-  // This gives us the best chance of succeeding.
-  thread_ = OpenThread(SYNCHRONIZE, FALSE, GetCurrentThreadId());
-  if (!thread_) {
-    LOG_GLE(LS_ERROR) << "Unable to get handle to thread.";
-    return false;
-  }
-#elif defined(POSIX)
-  thread_ = pthread_self();
-#endif
-  owned_ = false;
-  started_ = true;
-  ThreadManager::SetCurrent(this);
-  return true;
-}
-
-void Thread::UnwrapCurrent() {
-  // Clears the platform-specific thread-specific storage.
-  ThreadManager::SetCurrent(NULL);
-#ifdef WIN32
-  if (!CloseHandle(thread_)) {
-    LOG_GLE(LS_ERROR) << "When unwrapping thread, failed to close handle.";
-  }
-#endif
-  started_ = false;
-}
-
-
-AutoThread::AutoThread(SocketServer* ss) : Thread(ss) {
-  if (!ThreadManager::CurrentThread()) {
-    ThreadManager::SetCurrent(this);
-  }
-}
-
-AutoThread::~AutoThread() {
-  if (ThreadManager::CurrentThread() == this) {
-    ThreadManager::SetCurrent(NULL);
-  }
-}
-
-#ifdef WIN32
-void ComThread::Run() {
-  HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
-  ASSERT(SUCCEEDED(hr));
-  if (SUCCEEDED(hr)) {
-    Thread::Run();
-    CoUninitialize();
-  } else {
-    LOG(LS_ERROR) << "CoInitialize failed, hr=" << hr;
-  }
-}
-#endif
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/thread.h b/third_party/libjingle/source/talk/base/thread.h
deleted file mode 100644
index 04ceeef..0000000
--- a/third_party/libjingle/source/talk/base/thread.h
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- * libjingle
- * Copyright 2004 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_THREAD_H_
-#define TALK_BASE_THREAD_H_
-
-#include <algorithm>
-#include <list>
-#include <string>
-#include <vector>
-
-#ifdef POSIX
-#include <pthread.h>
-#endif
-
-#include "talk/base/constructormagic.h"
-#include "talk/base/messagequeue.h"
-
-#ifdef WIN32
-#include "talk/base/win32.h"
-#endif
-
-namespace talk_base {
-
-class Thread;
-
-class ThreadManager {
- public:
-  ThreadManager();
-  ~ThreadManager();
-
-  static Thread *CurrentThread();
-  static void SetCurrent(Thread *thread);
-  void Add(Thread *thread);
-  void Remove(Thread *thread);
-
-  // Returns a thread object with its thread_ ivar set
-  // to whatever the OS uses to represent the thread.
-  // If there already *is* a Thread object corresponding to this thread,
-  // this method will return that.  Otherwise it creates a new Thread
-  // object whose wrapped() method will return true, and whose
-  // handle will, on Win32, be opened with only synchronization privileges -
-  // if you need more privilegs, rather than changing this method, please
-  // write additional code to adjust the privileges, or call a different
-  // factory method of your own devising, because this one gets used in
-  // unexpected contexts (like inside browser plugins) and it would be a
-  // shame to break it.  It is also conceivable on Win32 that we won't even
-  // be able to get synchronization privileges, in which case the result
-  // will have a NULL handle.
-  static Thread *WrapCurrentThread();
-  static void UnwrapCurrentThread();
-
-  static void StopAllThreads_();  // Experimental
-
- private:
-  Thread *main_thread_;
-  std::vector<Thread *> threads_;
-  CriticalSection crit_;
-
-#ifdef POSIX
-  static pthread_key_t key_;
-#endif
-
-#ifdef WIN32
-  static DWORD key_;
-#endif
-
-  DISALLOW_COPY_AND_ASSIGN(ThreadManager);
-};
-
-class Thread;
-
-struct _SendMessage {
-  _SendMessage() {}
-  Thread *thread;
-  Message msg;
-  bool *ready;
-};
-
-enum ThreadPriority {
-  PRIORITY_IDLE = -1,
-  PRIORITY_NORMAL = 0,
-  PRIORITY_ABOVE_NORMAL = 1,
-  PRIORITY_HIGH = 2,
-};
-
-class Runnable {
- public:
-  virtual ~Runnable() {}
-  virtual void Run(Thread* thread) = 0;
-
- protected:
-  Runnable() {}
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(Runnable);
-};
-
-class Thread : public MessageQueue {
- public:
-  Thread(SocketServer* ss = NULL);
-  virtual ~Thread();
-
-  static inline Thread* Current() {
-    return ThreadManager::CurrentThread();
-  }
-
-  bool IsCurrent() const {
-    return (ThreadManager::CurrentThread() == this);
-  }
-
-  // Sleeps the calling thread for the specified number of milliseconds, during
-  // which time no processing is performed. Returns false if sleeping was
-  // interrupted by a signal (POSIX only).
-  static bool SleepMs(int millis);
-
-  // Sets the thread's name, for debugging. Must be called before Start().
-  // If |obj| is non-NULL, its value is appended to |name|.
-  const std::string& name() const { return name_; }
-  bool SetName(const std::string& name, const void* obj);
-
-  // Sets the thread's priority. Must be called before Start().
-  ThreadPriority priority() const { return priority_; }
-  bool SetPriority(ThreadPriority priority);
-
-  // Starts the execution of the thread.
-  bool started() const { return started_; }
-  bool Start(Runnable* runnable = NULL);
-
-  // Used for fire-and-forget threads.  Deletes this thread object when the
-  // Run method returns.
-  void Release() {
-    delete_self_when_complete_ = true;
-  }
-
-  // Tells the thread to stop and waits until it is joined.
-  // Never call Stop on the current thread.  Instead use the inherited Quit
-  // function which will exit the base MessageQueue without terminating the
-  // underlying OS thread.
-  virtual void Stop();
-
-  // By default, Thread::Run() calls ProcessMessages(kForever).  To do other
-  // work, override Run().  To receive and dispatch messages, call
-  // ProcessMessages occasionally.
-  virtual void Run();
-
-  virtual void Send(MessageHandler *phandler, uint32 id = 0,
-      MessageData *pdata = NULL);
-
-  // From MessageQueue
-  virtual void Clear(MessageHandler *phandler, uint32 id = MQID_ANY,
-                     MessageList* removed = NULL);
-  virtual void ReceiveSends();
-
-  // ProcessMessages will process I/O and dispatch messages until:
-  //  1) cms milliseconds have elapsed (returns true)
-  //  2) Stop() is called (returns false)
-  bool ProcessMessages(int cms);
-
-  // Returns true if this is a thread that we created using the standard
-  // constructor, false if it was created by a call to
-  // ThreadManager::WrapCurrentThread().  The main thread of an application
-  // is generally not owned, since the OS representation of the thread
-  // obviously exists before we can get to it.
-  // You cannot call Start on non-owned threads.
-  bool IsOwned();
-
-#ifdef WIN32
-  HANDLE GetHandle() {
-    return thread_;
-  }
-#elif POSIX
-  pthread_t GetPThread() {
-    return thread_;
-  }
-#endif
-
-  // This method should be called when thread is created using non standard
-  // method, like derived implementation of talk_base::Thread and it can not be
-  // started by calling Start(). This will set started flag to true and
-  // owned to false. This must be called from the current thread.
-  // NOTE: These methods should be used by the derived classes only, added here
-  // only for testing.
-  bool WrapCurrent();
-  void UnwrapCurrent();
-
- protected:
-  // Blocks the calling thread until this thread has terminated.
-  void Join();
-
- private:
-  static void *PreRun(void *pv);
-
-  std::list<_SendMessage> sendlist_;
-  std::string name_;
-  ThreadPriority priority_;
-  bool started_;
-  bool has_sends_;
-
-#ifdef POSIX
-  pthread_t thread_;
-#endif
-
-#ifdef WIN32
-  HANDLE thread_;
-#endif
-
-  bool owned_;
-  bool delete_self_when_complete_;
-
-  friend class ThreadManager;
-
-  DISALLOW_COPY_AND_ASSIGN(Thread);
-};
-
-// AutoThread automatically installs itself at construction
-// uninstalls at destruction, if a Thread object is
-// _not already_ associated with the current OS thread.
-
-class AutoThread : public Thread {
- public:
-  AutoThread(SocketServer* ss = 0);
-  virtual ~AutoThread();
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(AutoThread);
-};
-
-// Win32 extension for threads that need to use COM
-#ifdef WIN32
-class ComThread : public Thread {
- public:
-  ComThread() {}
-
- protected:
-  virtual void Run();
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(ComThread);
-};
-#endif
-
-// Provides an easy way to install/uninstall a socketserver on a thread.
-class SocketServerScope {
- public:
-  explicit SocketServerScope(SocketServer* ss) {
-    old_ss_ = Thread::Current()->socketserver();
-    Thread::Current()->set_socketserver(ss);
-  }
-  ~SocketServerScope() {
-    Thread::Current()->set_socketserver(old_ss_);
-  }
-
- private:
-  SocketServer* old_ss_;
-
-  DISALLOW_IMPLICIT_CONSTRUCTORS(SocketServerScope);
-};
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_THREAD_H_
diff --git a/third_party/libjingle/source/talk/base/thread_unittest.cc b/third_party/libjingle/source/talk/base/thread_unittest.cc
deleted file mode 100644
index a70b52d..0000000
--- a/third_party/libjingle/source/talk/base/thread_unittest.cc
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/asyncudpsocket.h"
-#include "talk/base/gunit.h"
-#include "talk/base/host.h"
-#include "talk/base/physicalsocketserver.h"
-#include "talk/base/socketaddress.h"
-#include "talk/base/thread.h"
-
-#ifdef WIN32
-#include <comdef.h>  // NOLINT
-#endif
-
-using namespace talk_base;
-
-const int MAX = 65536;
-
-// Generates a sequence of numbers (collaboratively).
-class TestGenerator {
- public:
-  TestGenerator() : last(0), count(0) {}
-
-  int Next(int prev) {
-    int result = prev + last;
-    last = result;
-    count += 1;
-    return result;
-  }
-
-  int last;
-  int count;
-};
-
-struct TestMessage : public MessageData {
-  explicit TestMessage(int v) : value(v) {}
-  virtual ~TestMessage() {}
-
-  int value;
-};
-
-// Receives on a socket and sends by posting messages.
-class SocketClient : public TestGenerator, public sigslot::has_slots<> {
- public:
-  SocketClient(AsyncSocket* socket, const SocketAddress& addr,
-               Thread* post_thread, MessageHandler* phandler)
-      : socket_(AsyncUDPSocket::Create(socket, addr)),
-        post_thread_(post_thread),
-        post_handler_(phandler) {
-    socket_->SignalReadPacket.connect(this, &SocketClient::OnPacket);
-  }
-
-  ~SocketClient() {
-    delete socket_;
-  }
-
-  SocketAddress address() const { return socket_->GetLocalAddress(); }
-
-  void OnPacket(AsyncPacketSocket* socket, const char* buf, size_t size,
-                const SocketAddress& remote_addr) {
-    EXPECT_EQ(size, sizeof(uint32));
-    uint32 prev = reinterpret_cast<const uint32*>(buf)[0];
-    uint32 result = Next(prev);
-
-    //socket_->set_readable(last < MAX);
-    post_thread_->PostDelayed(200, post_handler_, 0, new TestMessage(result));
-  }
-
- private:
-  AsyncUDPSocket* socket_;
-  Thread* post_thread_;
-  MessageHandler* post_handler_;
-};
-
-// Receives messages and sends on a socket.
-class MessageClient : public MessageHandler, public TestGenerator {
- public:
-  MessageClient(Thread* pth, Socket* socket)
-      : thread_(pth), socket_(socket) {
-  }
-
-  virtual ~MessageClient() {
-    delete socket_;
-  }
-
-  virtual void OnMessage(Message *pmsg) {
-    TestMessage* msg = static_cast<TestMessage*>(pmsg->pdata);
-    int result = Next(msg->value);
-    EXPECT_GE(socket_->Send(&result, sizeof(result)), 0);
-    delete msg;
-  }
-
- private:
-  Thread* thread_;
-  Socket* socket_;
-};
-
-class CustomThread : public talk_base::Thread {
- public:
-  CustomThread() {}
-  virtual ~CustomThread() {}
-  bool Start() { return false; }
-
-  bool WrapCurrent() { return talk_base::Thread::WrapCurrent(); }
-  void UnwrapCurrent() { talk_base::Thread::UnwrapCurrent(); }
-};
-
-
-TEST(ThreadTest, Main) {
-  const SocketAddress addr("127.0.0.1", 0);
-
-  // Create the messaging client on its own thread.
-  Thread th1;
-  Socket* socket = th1.socketserver()->CreateSocket(SOCK_DGRAM);
-  MessageClient msg_client(&th1, socket);
-
-  // Create the socket client on its own thread.
-  Thread th2;
-  AsyncSocket* asocket = th2.socketserver()->CreateAsyncSocket(SOCK_DGRAM);
-  SocketClient sock_client(asocket, addr, &th1, &msg_client);
-
-  socket->Connect(sock_client.address());
-
-  th1.Start();
-  th2.Start();
-
-  // Get the messages started.
-  th1.PostDelayed(100, &msg_client, 0, new TestMessage(1));
-
-  // Give the clients a little while to run.
-  // Messages will be processed at 100, 300, 500, 700, 900.
-  Thread* th_main = Thread::Current();
-  th_main->ProcessMessages(1000);
-
-  // Stop the sending client. Give the receiver a bit longer to run, in case
-  // it is running on a machine that is under load (e.g. the build machine).
-  th1.Stop();
-  th_main->ProcessMessages(200);
-  th2.Stop();
-
-  // Make sure the results were correct
-  EXPECT_EQ(5, msg_client.count);
-  EXPECT_EQ(34, msg_client.last);
-  EXPECT_EQ(5, sock_client.count);
-  EXPECT_EQ(55, sock_client.last);
-}
-
-// Test that setting thread names doesn't cause a malfunction.
-// There's no easy way to verify the name was set properly at this time.
-TEST(ThreadTest, Names) {
-  // Default name
-  Thread *thread;
-  thread = new Thread();
-  EXPECT_TRUE(thread->Start());
-  thread->Stop();
-  delete thread;
-  thread = new Thread();
-  // Name with no object parameter
-  EXPECT_TRUE(thread->SetName("No object", NULL));
-  EXPECT_TRUE(thread->Start());
-  thread->Stop();
-  delete thread;
-  // Really long name
-  thread = new Thread();
-  EXPECT_TRUE(thread->SetName("Abcdefghijklmnopqrstuvwxyz1234567890", this));
-  EXPECT_TRUE(thread->Start());
-  thread->Stop();
-  delete thread;
-}
-
-// Test that setting thread priorities doesn't cause a malfunction.
-// There's no easy way to verify the priority was set properly at this time.
-TEST(ThreadTest, Priorities) {
-  Thread *thread;
-  thread = new Thread();
-  EXPECT_TRUE(thread->SetPriority(PRIORITY_HIGH));
-  EXPECT_TRUE(thread->Start());
-  thread->Stop();
-  delete thread;
-  thread = new Thread();
-  EXPECT_TRUE(thread->SetPriority(PRIORITY_ABOVE_NORMAL));
-  EXPECT_TRUE(thread->Start());
-  thread->Stop();
-  delete thread;
-
-  thread = new Thread();
-  EXPECT_TRUE(thread->Start());
-#ifdef WIN32
-  EXPECT_TRUE(thread->SetPriority(PRIORITY_ABOVE_NORMAL));
-#else
-  EXPECT_FALSE(thread->SetPriority(PRIORITY_ABOVE_NORMAL));
-#endif
-  thread->Stop();
-  delete thread;
-
-}
-
-TEST(ThreadTest, Wrap) {
-  Thread* current_thread = ThreadManager::CurrentThread();
-  current_thread->UnwrapCurrent();
-  CustomThread* cthread = new CustomThread();
-  EXPECT_TRUE(cthread->WrapCurrent());
-  EXPECT_TRUE(cthread->started());
-  EXPECT_FALSE(cthread->IsOwned());
-  cthread->UnwrapCurrent();
-  EXPECT_FALSE(cthread->started());
-  delete cthread;
-  current_thread->WrapCurrent();
-}
-
-
-#ifdef WIN32
-class ComThreadTest : public testing::Test, public MessageHandler {
- public:
-  ComThreadTest() : done_(false) {}
- protected:
-  virtual void OnMessage(Message* message) {
-    HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
-    // S_FALSE means the thread was already inited for a multithread apartment.
-    EXPECT_EQ(S_FALSE, hr);
-    if (SUCCEEDED(hr)) {
-      CoUninitialize();
-    }
-    done_ = true;
-  }
-  bool done_;
-};
-
-TEST_F(ComThreadTest, ComInited) {
-  Thread* thread = new ComThread();
-  EXPECT_TRUE(thread->Start());
-  thread->Post(this, 0);
-  EXPECT_TRUE_WAIT(done_, 1000);
-  delete thread;
-}
-#endif
diff --git a/third_party/libjingle/source/talk/base/time.cc b/third_party/libjingle/source/talk/base/time.cc
deleted file mode 100644
index f5fa6db..0000000
--- a/third_party/libjingle/source/talk/base/time.cc
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifdef POSIX
-#include <sys/time.h>
-#endif
-
-#ifdef WIN32
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#endif
-
-#include "talk/base/common.h"
-#include "talk/base/time.h"
-
-#define EFFICIENT_IMPLEMENTATION 1
-
-namespace talk_base {
-
-const uint32 LAST = 0xFFFFFFFF;
-const uint32 HALF = 0x80000000;
-
-#ifdef POSIX
-uint32 Time() {
-  struct timeval tv;
-  gettimeofday(&tv, 0);
-  return tv.tv_sec * 1000 + tv.tv_usec / 1000;
-}
-#endif
-
-#ifdef WIN32
-uint32 Time() {
-  return GetTickCount();
-}
-#endif
-
-uint32 StartTime() {
-  // Close to program execution time
-  static const uint32 g_start = Time();
-  return g_start;
-}
-
-// Make sure someone calls it so that it gets initialized
-static uint32 ignore = StartTime();
-
-uint32 TimeAfter(int32 elapsed) {
-  ASSERT(elapsed >= 0);
-  ASSERT(static_cast<uint32>(elapsed) < HALF);
-  return Time() + elapsed;
-}
-
-bool TimeIsBetween(uint32 earlier, uint32 middle, uint32 later) {
-  if (earlier <= later) {
-    return ((earlier <= middle) && (middle <= later));
-  } else {
-    return !((later < middle) && (middle < earlier));
-  }
-}
-
-bool TimeIsLaterOrEqual(uint32 earlier, uint32 later) {
-#if EFFICIENT_IMPLEMENTATION
-  int32 diff = later - earlier;
-  return (diff >= 0 && static_cast<uint32>(diff) < HALF);
-#else
-  const bool later_or_equal = TimeIsBetween(earlier, later, earlier + HALF);
-  return later_or_equal;
-#endif
-}
-
-bool TimeIsLater(uint32 earlier, uint32 later) {
-#if EFFICIENT_IMPLEMENTATION
-  int32 diff = later - earlier;
-  return (diff > 0 && static_cast<uint32>(diff) < HALF);
-#else
-  const bool earlier_or_equal = TimeIsBetween(later, earlier, later + HALF);
-  return !earlier_or_equal;
-#endif
-}
-
-int32 TimeDiff(uint32 later, uint32 earlier) {
-#if EFFICIENT_IMPLEMENTATION
-  return later - earlier;
-#else
-  const bool later_or_equal = TimeIsBetween(earlier, later, earlier + HALF);
-  if (later_or_equal) {
-    if (earlier <= later) {
-      return static_cast<long>(later - earlier);
-    } else {
-      return static_cast<long>(later + (LAST - earlier) + 1);
-    }
-  } else {
-    if (later <= earlier) {
-      return -static_cast<long>(earlier - later);
-    } else {
-      return -static_cast<long>(earlier + (LAST - later) + 1);
-    }
-  }
-#endif
-}
-
-} // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/time.h b/third_party/libjingle/source/talk/base/time.h
deleted file mode 100644
index 8453ef5..0000000
--- a/third_party/libjingle/source/talk/base/time.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * libjingle
- * Copyright 2005 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_TIME_H__
-#define TALK_BASE_TIME_H__
-
-#ifndef WIN32
-#include_next <time.h>
-#endif
-
-#include "talk/base/basictypes.h"
-
-namespace talk_base {
-
-static const int64 kNumMillisecsPerSec = 1000;
-static const int64 kNumMicrosecsPerSec = 1000000;
-static const int64 kNumNanosecsPerSec = 1000000000;
-
-static const int64 kNumMicrosecsPerMillisec = kNumMicrosecsPerSec /
-    kNumMillisecsPerSec;
-static const int64 kNumNanosecsPerMillisec =  kNumNanosecsPerSec /
-    kNumMillisecsPerSec;
-
-typedef uint32 TimeStamp;
-
-// Returns the current time in milliseconds.
-uint32 Time();
-
-// Approximate time when the program started.
-uint32 StartTime();
-
-// Returns a future timestamp, 'elapsed' milliseconds from now.
-uint32 TimeAfter(int32 elapsed);
-
-// Comparisons between time values, which can wrap around.
-bool TimeIsBetween(uint32 earlier, uint32 middle, uint32 later);  // Inclusive
-bool TimeIsLaterOrEqual(uint32 earlier, uint32 later);  // Inclusive
-bool TimeIsLater(uint32 earlier, uint32 later);  // Exclusive
-
-// Returns the later of two timestamps.
-inline uint32 TimeMax(uint32 ts1, uint32 ts2) {
-  return TimeIsLaterOrEqual(ts1, ts2) ? ts2 : ts1;
-}
-
-// Returns the earlier of two timestamps.
-inline uint32 TimeMin(uint32 ts1, uint32 ts2) {
-  return TimeIsLaterOrEqual(ts1, ts2) ? ts1 : ts2;
-}
-
-// Number of milliseconds that would elapse between 'earlier' and 'later'
-// timestamps.  The value is negative if 'later' occurs before 'earlier'.
-int32 TimeDiff(uint32 later, uint32 earlier);
-
-// The number of milliseconds that have elapsed since 'earlier'.
-inline int32 TimeSince(uint32 earlier) {
-  return TimeDiff(Time(), earlier);
-} 
-
-// The number of milliseconds that will elapse between now and 'later'.
-inline int32 TimeUntil(uint32 later) {
-  return TimeDiff(later, Time());
-}
-
-} // namespace talk_base
-
-#endif // TALK_BASE_TIME_H__
diff --git a/third_party/libjingle/source/talk/base/time_unittest.cc b/third_party/libjingle/source/talk/base/time_unittest.cc
deleted file mode 100644
index 52e5111..0000000
--- a/third_party/libjingle/source/talk/base/time_unittest.cc
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/common.h"
-#include "talk/base/gunit.h"
-#include "talk/base/thread.h"
-#include "talk/base/time.h"
-
-namespace talk_base {
-
-TEST(TimeTest, Comparison) {
-  // Obtain two different times, in known order
-  TimeStamp ts_earlier = Time();
-  Thread::SleepMs(100);
-  TimeStamp ts_now = Time();
-  EXPECT_NE(ts_earlier, ts_now);
-
-  // Common comparisons
-  EXPECT_TRUE( TimeIsLaterOrEqual(ts_earlier, ts_now));
-  EXPECT_TRUE( TimeIsLater(       ts_earlier, ts_now));
-  EXPECT_FALSE(TimeIsLaterOrEqual(ts_now,     ts_earlier));
-  EXPECT_FALSE(TimeIsLater(       ts_now,     ts_earlier));
-
-  // Edge cases
-  EXPECT_TRUE( TimeIsLaterOrEqual(ts_earlier, ts_earlier));
-  EXPECT_FALSE(TimeIsLater(       ts_earlier, ts_earlier));
-
-  // Obtain a third time
-  TimeStamp ts_later = TimeAfter(100);
-  EXPECT_NE(ts_now, ts_later);
-  EXPECT_TRUE( TimeIsLater(ts_now,     ts_later));
-  EXPECT_TRUE( TimeIsLater(ts_earlier, ts_later));
-
-  // Common comparisons
-  EXPECT_TRUE( TimeIsBetween(ts_earlier, ts_now,     ts_later));
-  EXPECT_FALSE(TimeIsBetween(ts_earlier, ts_later,   ts_now));
-  EXPECT_FALSE(TimeIsBetween(ts_now,     ts_earlier, ts_later));
-  EXPECT_TRUE( TimeIsBetween(ts_now,     ts_later,   ts_earlier));
-  EXPECT_TRUE( TimeIsBetween(ts_later,   ts_earlier, ts_now));
-  EXPECT_FALSE(TimeIsBetween(ts_later,   ts_now,     ts_earlier));
-
-  // Edge cases
-  EXPECT_TRUE( TimeIsBetween(ts_earlier, ts_earlier, ts_earlier));
-  EXPECT_TRUE( TimeIsBetween(ts_earlier, ts_earlier, ts_later));
-  EXPECT_TRUE( TimeIsBetween(ts_earlier, ts_later,   ts_later));
-
-  // Earlier of two times
-  EXPECT_EQ(ts_earlier, TimeMin(ts_earlier, ts_earlier));
-  EXPECT_EQ(ts_earlier, TimeMin(ts_earlier, ts_now));
-  EXPECT_EQ(ts_earlier, TimeMin(ts_earlier, ts_later));
-  EXPECT_EQ(ts_earlier, TimeMin(ts_now,     ts_earlier));
-  EXPECT_EQ(ts_earlier, TimeMin(ts_later,   ts_earlier));
-
-  // Later of two times
-  EXPECT_EQ(ts_earlier, TimeMax(ts_earlier, ts_earlier));
-  EXPECT_EQ(ts_now,     TimeMax(ts_earlier, ts_now));
-  EXPECT_EQ(ts_later,   TimeMax(ts_earlier, ts_later));
-  EXPECT_EQ(ts_now,     TimeMax(ts_now,     ts_earlier));
-  EXPECT_EQ(ts_later,   TimeMax(ts_later,   ts_earlier));
-}
-
-TEST(TimeTest, Intervals) {
-  TimeStamp ts_earlier = Time();
-  TimeStamp ts_later = TimeAfter(500);
-
-  // We can't depend on ts_later and ts_earlier to be exactly 500 apart
-  // since time elapses between the calls to Time() and TimeAfter(500)
-  EXPECT_LE(500,  TimeDiff(ts_later, ts_earlier));
-  EXPECT_GE(-500, TimeDiff(ts_earlier, ts_later));
-
-  // Time has elapsed since ts_earlier
-  EXPECT_GE(TimeSince(ts_earlier), 0);
-
-  // ts_earlier is earlier than now, so TimeUntil ts_earlier is -ve
-  EXPECT_LE(TimeUntil(ts_earlier), 0);
-
-  // ts_later likely hasn't happened yet, so TimeSince could be -ve
-  // but within 500
-  EXPECT_GE(TimeSince(ts_later), -500);
-
-  // TimeUntil ts_later is at most 500
-  EXPECT_LE(TimeUntil(ts_later), 500);
-}
-
-TEST(TimeTest, BoundaryComparison) {
-  // Obtain two different times, in known order
-  TimeStamp ts_earlier = static_cast<TimeStamp>(-50);
-  TimeStamp ts_later = ts_earlier + 100;
-  EXPECT_NE(ts_earlier, ts_later);
-
-  // Common comparisons
-  EXPECT_TRUE( TimeIsLaterOrEqual(ts_earlier, ts_later));
-  EXPECT_TRUE( TimeIsLater(       ts_earlier, ts_later));
-  EXPECT_FALSE(TimeIsLaterOrEqual(ts_later,   ts_earlier));
-  EXPECT_FALSE(TimeIsLater(       ts_later,   ts_earlier));
-
-  // Earlier of two times
-  EXPECT_EQ(ts_earlier, TimeMin(ts_earlier, ts_earlier));
-  EXPECT_EQ(ts_earlier, TimeMin(ts_earlier, ts_later));
-  EXPECT_EQ(ts_earlier, TimeMin(ts_later,   ts_earlier));
-
-  // Later of two times
-  EXPECT_EQ(ts_earlier, TimeMax(ts_earlier, ts_earlier));
-  EXPECT_EQ(ts_later,   TimeMax(ts_earlier, ts_later));
-  EXPECT_EQ(ts_later,   TimeMax(ts_later,   ts_earlier));
-
-  // Interval
-  EXPECT_EQ(100,  TimeDiff(ts_later, ts_earlier));
-  EXPECT_EQ(-100, TimeDiff(ts_earlier, ts_later));
-}
-
-} // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/timeutils.cc b/third_party/libjingle/source/talk/base/timeutils.cc
deleted file mode 100644
index 98ba0bc..0000000
--- a/third_party/libjingle/source/talk/base/timeutils.cc
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifdef POSIX
-#include <sys/time.h>
-#endif
-
-#ifdef WIN32
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#endif
-
-#include "talk/base/common.h"
-#include "talk/base/timeutils.h"
-
-#define EFFICIENT_IMPLEMENTATION 1
-
-namespace talk_base {
-
-const uint32 LAST = 0xFFFFFFFF;
-const uint32 HALF = 0x80000000;
-
-#ifdef POSIX
-uint32 Time() {
-  struct timeval tv;
-  gettimeofday(&tv, 0);
-  return tv.tv_sec * 1000 + tv.tv_usec / 1000;
-}
-#endif
-
-#ifdef WIN32
-uint32 Time() {
-  return GetTickCount();
-}
-#endif
-
-uint32 StartTime() {
-  // Close to program execution time
-  static const uint32 g_start = Time();
-  return g_start;
-}
-
-// Make sure someone calls it so that it gets initialized
-static uint32 ignore = StartTime();
-
-uint32 TimeAfter(int32 elapsed) {
-  ASSERT(elapsed >= 0);
-  ASSERT(static_cast<uint32>(elapsed) < HALF);
-  return Time() + elapsed;
-}
-
-bool TimeIsBetween(uint32 earlier, uint32 middle, uint32 later) {
-  if (earlier <= later) {
-    return ((earlier <= middle) && (middle <= later));
-  } else {
-    return !((later < middle) && (middle < earlier));
-  }
-}
-
-bool TimeIsLaterOrEqual(uint32 earlier, uint32 later) {
-#if EFFICIENT_IMPLEMENTATION
-  int32 diff = later - earlier;
-  return (diff >= 0 && static_cast<uint32>(diff) < HALF);
-#else
-  const bool later_or_equal = TimeIsBetween(earlier, later, earlier + HALF);
-  return later_or_equal;
-#endif
-}
-
-bool TimeIsLater(uint32 earlier, uint32 later) {
-#if EFFICIENT_IMPLEMENTATION
-  int32 diff = later - earlier;
-  return (diff > 0 && static_cast<uint32>(diff) < HALF);
-#else
-  const bool earlier_or_equal = TimeIsBetween(later, earlier, later + HALF);
-  return !earlier_or_equal;
-#endif
-}
-
-int32 TimeDiff(uint32 later, uint32 earlier) {
-#if EFFICIENT_IMPLEMENTATION
-  return later - earlier;
-#else
-  const bool later_or_equal = TimeIsBetween(earlier, later, earlier + HALF);
-  if (later_or_equal) {
-    if (earlier <= later) {
-      return static_cast<long>(later - earlier);
-    } else {
-      return static_cast<long>(later + (LAST - earlier) + 1);
-    }
-  } else {
-    if (later <= earlier) {
-      return -static_cast<long>(earlier - later);
-    } else {
-      return -static_cast<long>(earlier + (LAST - later) + 1);
-    }
-  }
-#endif
-}
-
-} // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/timeutils.h b/third_party/libjingle/source/talk/base/timeutils.h
deleted file mode 100644
index 713fd77..0000000
--- a/third_party/libjingle/source/talk/base/timeutils.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * libjingle
- * Copyright 2005 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_TIMEUTILS_H_
-#define TALK_BASE_TIMEUTILS_H_
-
-#ifndef WIN32
-#include <time.h>
-#endif
-
-#include "talk/base/basictypes.h"
-
-namespace talk_base {
-
-static const int64 kNumMillisecsPerSec = 1000;
-static const int64 kNumMicrosecsPerSec = 1000000;
-static const int64 kNumNanosecsPerSec = 1000000000;
-
-static const int64 kNumMicrosecsPerMillisec = kNumMicrosecsPerSec /
-    kNumMillisecsPerSec;
-static const int64 kNumNanosecsPerMillisec =  kNumNanosecsPerSec /
-    kNumMillisecsPerSec;
-
-typedef uint32 TimeStamp;
-
-// Returns the current time in milliseconds.
-uint32 Time();
-
-// Approximate time when the program started.
-uint32 StartTime();
-
-// Returns a future timestamp, 'elapsed' milliseconds from now.
-uint32 TimeAfter(int32 elapsed);
-
-// Comparisons between time values, which can wrap around.
-bool TimeIsBetween(uint32 earlier, uint32 middle, uint32 later);  // Inclusive
-bool TimeIsLaterOrEqual(uint32 earlier, uint32 later);  // Inclusive
-bool TimeIsLater(uint32 earlier, uint32 later);  // Exclusive
-
-// Returns the later of two timestamps.
-inline uint32 TimeMax(uint32 ts1, uint32 ts2) {
-  return TimeIsLaterOrEqual(ts1, ts2) ? ts2 : ts1;
-}
-
-// Returns the earlier of two timestamps.
-inline uint32 TimeMin(uint32 ts1, uint32 ts2) {
-  return TimeIsLaterOrEqual(ts1, ts2) ? ts1 : ts2;
-}
-
-// Number of milliseconds that would elapse between 'earlier' and 'later'
-// timestamps.  The value is negative if 'later' occurs before 'earlier'.
-int32 TimeDiff(uint32 later, uint32 earlier);
-
-// The number of milliseconds that have elapsed since 'earlier'.
-inline int32 TimeSince(uint32 earlier) {
-  return TimeDiff(Time(), earlier);
-} 
-
-// The number of milliseconds that will elapse between now and 'later'.
-inline int32 TimeUntil(uint32 later) {
-  return TimeDiff(later, Time());
-}
-
-} // namespace talk_base
-
-#endif // TALK_BASE_TIMEUTILS_H_
diff --git a/third_party/libjingle/source/talk/base/timeutils_unittest.cc b/third_party/libjingle/source/talk/base/timeutils_unittest.cc
deleted file mode 100644
index 9f315ee..0000000
--- a/third_party/libjingle/source/talk/base/timeutils_unittest.cc
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/common.h"
-#include "talk/base/gunit.h"
-#include "talk/base/thread.h"
-#include "talk/base/timeutils.h"
-
-namespace talk_base {
-
-TEST(TimeTest, Comparison) {
-  // Obtain two different times, in known order
-  TimeStamp ts_earlier = Time();
-  Thread::SleepMs(100);
-  TimeStamp ts_now = Time();
-  EXPECT_NE(ts_earlier, ts_now);
-
-  // Common comparisons
-  EXPECT_TRUE( TimeIsLaterOrEqual(ts_earlier, ts_now));
-  EXPECT_TRUE( TimeIsLater(       ts_earlier, ts_now));
-  EXPECT_FALSE(TimeIsLaterOrEqual(ts_now,     ts_earlier));
-  EXPECT_FALSE(TimeIsLater(       ts_now,     ts_earlier));
-
-  // Edge cases
-  EXPECT_TRUE( TimeIsLaterOrEqual(ts_earlier, ts_earlier));
-  EXPECT_FALSE(TimeIsLater(       ts_earlier, ts_earlier));
-
-  // Obtain a third time
-  TimeStamp ts_later = TimeAfter(100);
-  EXPECT_NE(ts_now, ts_later);
-  EXPECT_TRUE( TimeIsLater(ts_now,     ts_later));
-  EXPECT_TRUE( TimeIsLater(ts_earlier, ts_later));
-
-  // Common comparisons
-  EXPECT_TRUE( TimeIsBetween(ts_earlier, ts_now,     ts_later));
-  EXPECT_FALSE(TimeIsBetween(ts_earlier, ts_later,   ts_now));
-  EXPECT_FALSE(TimeIsBetween(ts_now,     ts_earlier, ts_later));
-  EXPECT_TRUE( TimeIsBetween(ts_now,     ts_later,   ts_earlier));
-  EXPECT_TRUE( TimeIsBetween(ts_later,   ts_earlier, ts_now));
-  EXPECT_FALSE(TimeIsBetween(ts_later,   ts_now,     ts_earlier));
-
-  // Edge cases
-  EXPECT_TRUE( TimeIsBetween(ts_earlier, ts_earlier, ts_earlier));
-  EXPECT_TRUE( TimeIsBetween(ts_earlier, ts_earlier, ts_later));
-  EXPECT_TRUE( TimeIsBetween(ts_earlier, ts_later,   ts_later));
-
-  // Earlier of two times
-  EXPECT_EQ(ts_earlier, TimeMin(ts_earlier, ts_earlier));
-  EXPECT_EQ(ts_earlier, TimeMin(ts_earlier, ts_now));
-  EXPECT_EQ(ts_earlier, TimeMin(ts_earlier, ts_later));
-  EXPECT_EQ(ts_earlier, TimeMin(ts_now,     ts_earlier));
-  EXPECT_EQ(ts_earlier, TimeMin(ts_later,   ts_earlier));
-
-  // Later of two times
-  EXPECT_EQ(ts_earlier, TimeMax(ts_earlier, ts_earlier));
-  EXPECT_EQ(ts_now,     TimeMax(ts_earlier, ts_now));
-  EXPECT_EQ(ts_later,   TimeMax(ts_earlier, ts_later));
-  EXPECT_EQ(ts_now,     TimeMax(ts_now,     ts_earlier));
-  EXPECT_EQ(ts_later,   TimeMax(ts_later,   ts_earlier));
-}
-
-TEST(TimeTest, Intervals) {
-  TimeStamp ts_earlier = Time();
-  TimeStamp ts_later = TimeAfter(500);
-
-  // We can't depend on ts_later and ts_earlier to be exactly 500 apart
-  // since time elapses between the calls to Time() and TimeAfter(500)
-  EXPECT_LE(500,  TimeDiff(ts_later, ts_earlier));
-  EXPECT_GE(-500, TimeDiff(ts_earlier, ts_later));
-
-  // Time has elapsed since ts_earlier
-  EXPECT_GE(TimeSince(ts_earlier), 0);
-
-  // ts_earlier is earlier than now, so TimeUntil ts_earlier is -ve
-  EXPECT_LE(TimeUntil(ts_earlier), 0);
-
-  // ts_later likely hasn't happened yet, so TimeSince could be -ve
-  // but within 500
-  EXPECT_GE(TimeSince(ts_later), -500);
-
-  // TimeUntil ts_later is at most 500
-  EXPECT_LE(TimeUntil(ts_later), 500);
-}
-
-TEST(TimeTest, BoundaryComparison) {
-  // Obtain two different times, in known order
-  TimeStamp ts_earlier = static_cast<TimeStamp>(-50);
-  TimeStamp ts_later = ts_earlier + 100;
-  EXPECT_NE(ts_earlier, ts_later);
-
-  // Common comparisons
-  EXPECT_TRUE( TimeIsLaterOrEqual(ts_earlier, ts_later));
-  EXPECT_TRUE( TimeIsLater(       ts_earlier, ts_later));
-  EXPECT_FALSE(TimeIsLaterOrEqual(ts_later,   ts_earlier));
-  EXPECT_FALSE(TimeIsLater(       ts_later,   ts_earlier));
-
-  // Earlier of two times
-  EXPECT_EQ(ts_earlier, TimeMin(ts_earlier, ts_earlier));
-  EXPECT_EQ(ts_earlier, TimeMin(ts_earlier, ts_later));
-  EXPECT_EQ(ts_earlier, TimeMin(ts_later,   ts_earlier));
-
-  // Later of two times
-  EXPECT_EQ(ts_earlier, TimeMax(ts_earlier, ts_earlier));
-  EXPECT_EQ(ts_later,   TimeMax(ts_earlier, ts_later));
-  EXPECT_EQ(ts_later,   TimeMax(ts_later,   ts_earlier));
-
-  // Interval
-  EXPECT_EQ(100,  TimeDiff(ts_later, ts_earlier));
-  EXPECT_EQ(-100, TimeDiff(ts_earlier, ts_later));
-}
-
-} // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/timing.cc b/third_party/libjingle/source/talk/base/timing.cc
deleted file mode 100644
index 5e1c6c8..0000000
--- a/third_party/libjingle/source/talk/base/timing.cc
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * libjingle
- * Copyright 2008, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/timing.h"
-
-#if defined(POSIX)
-#define _POSIX_C_SOURCE 199506L
-#endif
-
-#include <time.h>
-
-#if defined(POSIX)
-#include <errno.h>
-#include <math.h>
-#include <sys/time.h>
-#if defined(OSX)
-#include <mach/mach.h>
-#include <mach/clock.h>
-#endif
-#elif defined(WIN32)
-#include <sys/timeb.h>
-#include "talk/base/win32.h"
-#endif
-
-Timing::Timing() {
-#if defined(WIN32)
-  QueryPerformanceFrequency(&tick_hz_);
-
-  // This may fail, but we handle failure gracefully in the methods
-  // that use it (use alternative sleep method).
-  //
-  // TODO: Make it possible for user to tell if IdleWait will
-  // be done at lesser resolution because of this.
-  timer_handle_ = CreateWaitableTimer(NULL,     // Security attributes.
-                                      FALSE,    // Manual reset?
-                                      NULL);    // Timer name.
-#endif
-}
-
-Timing::~Timing() {
-#if defined(WIN32)
-  if (timer_handle_ != NULL)
-    CloseHandle(timer_handle_);
-#endif
-}
-
-double Timing::WallTimeNow() {
-#if defined(POSIX)
-  struct timeval time;
-  gettimeofday(&time, NULL);
-  // Convert from second (1.0) and microsecond (1e-6).
-  return (static_cast<double>(time.tv_sec) +
-          static_cast<double>(time.tv_usec) * 1.0e-6);
-
-#elif defined(WIN32)
-  struct _timeb time;
-  _ftime(&time);
-  // Convert from second (1.0) and milliseconds (1e-3).
-  return (static_cast<double>(time.time) +
-          static_cast<double>(time.millitm) * 1.0e-3);
-#endif
-}
-
-double Timing::TimerNow() {
-#if defined(OSX)
-  // No clock_gettime on OSX.
-  clock_serv_t clock;
-  mach_timespec_t time;
-  host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &clock);
-  clock_get_time(clock, &time);
-  return (static_cast<double>(time.tv_sec) +
-          static_cast<double>(time.tv_nsec) * 1.0e-9);
-#elif defined(POSIX)
-  struct timespec time;
-  clock_gettime(CLOCK_MONOTONIC, &time);
-  // Convert from second (1.0) and nanosecond (1e-9).
-  return (static_cast<double>(time.tv_sec) +
-          static_cast<double>(time.tv_nsec) * 1.0e-9);
-
-#elif defined(WIN32)
-  LARGE_INTEGER count;
-  QueryPerformanceCounter(&count);
-  return (static_cast<double>(count.QuadPart) /
-          static_cast<double>(tick_hz_.QuadPart));
-#endif
-}
-
-double Timing::BusyWait(double period) {
-  double start_time = TimerNow();
-  while (TimerNow() - start_time < period) {
-  }
-  return TimerNow() - start_time;
-}
-
-double Timing::IdleWait(double period) {
-  double start_time = TimerNow();
-
-#if defined(POSIX)
-  double sec_int, sec_frac = modf(period, &sec_int);
-  struct timespec ts;
-  ts.tv_sec = static_cast<time_t>(sec_int);
-  ts.tv_nsec = static_cast<long>(sec_frac * 1.0e9);  // NOLINT
-
-  // NOTE(liulk): for the NOLINT above, long is the appropriate POSIX
-  // type.
-
-  // POSIX nanosleep may be interrupted by signals.
-  while (nanosleep(&ts, &ts) == -1 && errno == EINTR) {
-  }
-
-#elif defined(WIN32)
-  if (timer_handle_ != NULL) {
-    LARGE_INTEGER due_time;
-
-    // Negative indicates relative time.  The unit is 100 nanoseconds.
-    due_time.QuadPart = -LONGLONG(period * 1.0e7);
-
-    SetWaitableTimer(timer_handle_, &due_time, 0, NULL, NULL, TRUE);
-    WaitForSingleObject(timer_handle_, INFINITE);
-  } else {
-    // Still attempts to sleep with lesser resolution.
-    // The unit is in milliseconds.
-    Sleep(DWORD(period * 1.0e3));
-  }
-#endif
-
-  return TimerNow() - start_time;
-}
diff --git a/third_party/libjingle/source/talk/base/timing.h b/third_party/libjingle/source/talk/base/timing.h
deleted file mode 100644
index f94daf0..0000000
--- a/third_party/libjingle/source/talk/base/timing.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * libjingle
- * Copyright 2008, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_MAGICFLUTE_TESTING_TIMING_H_
-#define TALK_MAGICFLUTE_TESTING_TIMING_H_
-
-#if defined(WIN32)
-#include "talk/base/win32.h"
-#endif
-
-class Timing {
- public:
-  Timing();
-  virtual ~Timing();
-
-  // WallTimeNow() returns the current wall-clock time in seconds,
-  // within 10 milliseconds resolution.
-  double WallTimeNow();
-
-  // TimerNow() is like WallTimeNow(), but is monotonically
-  // increasing.  It returns seconds in resolution of 10 microseconds
-  // or better.  Although timer and wall-clock time have the same
-  // timing unit, they do not necessarily correlate because wall-clock
-  // time may be adjusted backwards, hence not monotonic.
-  double TimerNow();
-
-  // BusyWait() exhausts CPU as long as the time elapsed is less than
-  // the specified interval in seconds.  Returns the actual waiting
-  // time based on TimerNow() measurement.
-  double BusyWait(double period);
-
-  // IdleWait() relinquishes control of CPU for specified period in
-  // seconds.  It uses highest resolution sleep mechanism as possible,
-  // but does not otherwise guarantee the accuracy.  Returns the
-  // actual waiting time based on TimerNow() measurement.
-  //
-  // This function is not re-entrant for an object.  Create a fresh
-  // Timing object for each thread.
-  double IdleWait(double period);
-
- private:
-#if defined(WIN32)
-  LARGE_INTEGER tick_hz_;
-  HANDLE timer_handle_;
-#endif
-};
-
-#endif  // TALK_MAGICFLUTE_TESTING_TIMING_H_
diff --git a/third_party/libjingle/source/talk/base/unittest_main.cc b/third_party/libjingle/source/talk/base/unittest_main.cc
deleted file mode 100644
index bca3671..0000000
--- a/third_party/libjingle/source/talk/base/unittest_main.cc
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright 2007 Google Inc. All Rights Reserved.
-
-//         juberti@google.com (Justin Uberti)
-//
-// A reuseable entry point for gunit tests.
-
-#ifdef WIN32
-#include <crtdbg.h>
-#endif
-
-#include "talk/base/flags.h"
-#include "talk/base/fileutils.h"
-#include "talk/base/gunit.h"
-#include "talk/base/logging.h"
-#include "talk/base/pathutils.h"
-
-DEFINE_bool(help, false, "prints this message");
-DEFINE_string(log, "", "logging options to use");
-#ifdef WIN32
-DEFINE_int(crt_break_alloc, -1, "memory allocation to break on");
-DEFINE_bool(default_error_handlers, false,
-            "leave the default exception/dbg handler functions in place");
-
-void TestInvalidParameterHandler(const wchar_t* expression,
-                                 const wchar_t* function,
-                                 const wchar_t* file,
-                                 unsigned int line,
-                                 uintptr_t pReserved) {
-  LOG(LS_ERROR) << "InvalidParameter Handler called.  Exiting.";
-  LOG(LS_ERROR) << expression << std::endl << function << std::endl << file
-                << std::endl << line;
-  exit(1);
-}
-void TestPureCallHandler() {
-  LOG(LS_ERROR) << "Purecall Handler called.  Exiting.";
-  exit(1);
-}
-int TestCrtReportHandler(int report_type, char* msg, int* retval) {
-    LOG(LS_ERROR) << "CrtReport Handler called...";
-    LOG(LS_ERROR) << msg;
-  if (report_type == _CRT_ASSERT) {
-    exit(1);
-  } else {
-    *retval = 0;
-    return TRUE;
-  }
-}
-#endif  // WIN32
-
-talk_base::Pathname GetTalkDirectory() {
-  // Locate talk directory.
-  talk_base::Pathname path = talk_base::Filesystem::GetCurrentDirectory();
-  std::string talk_folder_name("talk");
-  talk_folder_name += path.folder_delimiter();
-  while (path.folder_name() != talk_folder_name && !path.empty()) {
-    path.SetFolder(path.parent_folder());
-  }
-
-  // If not running inside "talk" folder, then assume running in its parent
-  // folder.
-  if (path.empty()) {
-    path = talk_base::Filesystem::GetCurrentDirectory();
-    path.AppendFolder("talk");
-    // Make sure the folder exist.
-    if (!talk_base::Filesystem::IsFolder(path)) {
-      path.clear();
-    }
-  }
-  return path;
-}
-
-int main(int argc, char** argv) {
-  testing::InitGoogleTest(&argc, argv);
-  FlagList::SetFlagsFromCommandLine(&argc, argv, false);
-  if (FLAG_help) {
-    FlagList::Print(NULL, false);
-    return 0;
-  }
-
-#ifdef WIN32
-  if (!FLAG_default_error_handlers) {
-    // Make sure any errors don't throw dialogs hanging the test run.
-    _set_invalid_parameter_handler(TestInvalidParameterHandler);
-    _set_purecall_handler(TestPureCallHandler);
-    _CrtSetReportHook2(_CRT_RPTHOOK_INSTALL, TestCrtReportHandler);
-  }
-
-#ifdef _DEBUG  // Turn on memory leak checking on Windows.
-  _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF |_CRTDBG_LEAK_CHECK_DF);
-  if (FLAG_crt_break_alloc >= 0) {
-    _crtBreakAlloc = FLAG_crt_break_alloc;
-  }
-#endif  // _DEBUG
-#endif  // WIN32
-
-  talk_base::Filesystem::SetOrganizationName("google");
-  talk_base::Filesystem::SetApplicationName("unittest");
-
-  // By default, log timestamps. Allow overrides by used of a --log flag.
-  talk_base::LogMessage::LogTimestamps();
-  if (*FLAG_log != '\0') {
-    talk_base::LogMessage::ConfigureLogging(FLAG_log, "unittest.log");
-  }
-
-  int res = RUN_ALL_TESTS();
-
-  // clean up logging so we don't appear to leak memory.
-  talk_base::LogMessage::ConfigureLogging("", "");
-
-#ifdef WIN32
-  // Unhook crt function so that we don't ever log after statics have been
-  // uninitialized.
-  if (!FLAG_default_error_handlers)
-    _CrtSetReportHook2(_CRT_RPTHOOK_REMOVE, TestCrtReportHandler);
-#endif
-
-  return res;
-}
diff --git a/third_party/libjingle/source/talk/base/unixfilesystem.cc b/third_party/libjingle/source/talk/base/unixfilesystem.cc
deleted file mode 100644
index 096c511..0000000
--- a/third_party/libjingle/source/talk/base/unixfilesystem.cc
+++ /dev/null
@@ -1,533 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2006, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/unixfilesystem.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#ifdef OSX
-#include <Carbon/Carbon.h>
-#include <IOKit/IOCFBundle.h>
-#include <sys/statvfs.h>
-#include "talk/base/macutils.h"
-#endif  // OSX
-
-#if defined(POSIX) && !defined(OSX)
-#include <sys/types.h>
-#ifdef ANDROID
-#include <sys/statfs.h>
-#else
-#include <sys/statvfs.h>
-#endif  // ANDROID
-#include <pwd.h>
-#include <stdio.h>
-#include <unistd.h>
-#endif  // POSIX && !OSX
-
-#ifdef LINUX
-#include <ctype.h>
-#include <algorithm>
-#endif
-
-#include "talk/base/fileutils.h"
-#include "talk/base/pathutils.h"
-#include "talk/base/stream.h"
-#include "talk/base/stringutils.h"
-
-namespace talk_base {
-
-#if !defined(ANDROID) && !defined(IOS)
-char* UnixFilesystem::app_temp_path_ = NULL;
-#else
-char* UnixFilesystem::provided_app_data_folder_ = NULL;
-char* UnixFilesystem::provided_app_temp_folder_ = NULL;
-
-void UnixFilesystem::SetAppDataFolder(const std::string& folder) {
-  delete [] provided_app_data_folder_;
-  provided_app_data_folder_ = CopyString(folder);
-}
-
-void UnixFilesystem::SetAppTempFolder(const std::string& folder) {
-  delete [] provided_app_temp_folder_;
-  provided_app_temp_folder_ = CopyString(folder);
-}
-#endif
-
-bool UnixFilesystem::CreateFolder(const Pathname &path) {
-  std::string pathname(path.pathname());
-  int len = pathname.length();
-  if ((len == 0) || (pathname[len - 1] != '/'))
-    return false;
-
-  struct stat st;
-  int res = ::stat(pathname.c_str(), &st);
-  if (res == 0) {
-    // Something exists at this location, check if it is a directory
-    return S_ISDIR(st.st_mode) != 0;
-  } else if (errno != ENOENT) {
-    // Unexpected error
-    return false;
-  }
-
-  // Directory doesn't exist, look up one directory level
-  do {
-    --len;
-  } while ((len > 0) && (pathname[len - 1] != '/'));
-
-  if (!CreateFolder(Pathname(pathname.substr(0, len)))) {
-    return false;
-  }
-
-  LOG(LS_INFO) << "Creating folder: " << pathname;
-  return (0 == ::mkdir(pathname.c_str(), 0755));
-}
-
-FileStream *UnixFilesystem::OpenFile(const Pathname &filename,
-                                     const std::string &mode) {
-  FileStream *fs = new FileStream();
-  if (fs && !fs->Open(filename.pathname().c_str(), mode.c_str(), NULL)) {
-    delete fs;
-    fs = NULL;
-  }
-  return fs;
-}
-
-bool UnixFilesystem::CreatePrivateFile(const Pathname &filename) {
-  int fd = open(filename.pathname().c_str(),
-                O_RDWR | O_CREAT | O_EXCL,
-                S_IRUSR | S_IWUSR);
-  if (fd < 0) {
-    LOG_ERR(LS_ERROR) << "open() failed.";
-    return false;
-  }
-  // Don't need to keep the file descriptor.
-  if (close(fd) < 0) {
-    LOG_ERR(LS_ERROR) << "close() failed.";
-    // Continue.
-  }
-  return true;
-}
-
-bool UnixFilesystem::DeleteFile(const Pathname &filename) {
-  LOG(LS_INFO) << "Deleting file:" << filename.pathname();
-
-  if (!IsFile(filename)) {
-    ASSERT(IsFile(filename));
-    return false;
-  }
-  return ::unlink(filename.pathname().c_str()) == 0;
-}
-
-bool UnixFilesystem::DeleteEmptyFolder(const Pathname &folder) {
-  LOG(LS_INFO) << "Deleting folder" << folder.pathname();
-
-  if (!IsFolder(folder)) {
-    ASSERT(IsFolder(folder));
-    return false;
-  }
-  std::string no_slash(folder.pathname(), 0, folder.pathname().length()-1);
-  return ::rmdir(no_slash.c_str()) == 0;
-}
-
-bool UnixFilesystem::GetTemporaryFolder(Pathname &pathname, bool create,
-                                        const std::string *append) {
-#ifdef OSX
-  FSRef fr;
-  if (0 != FSFindFolder(kOnAppropriateDisk, kTemporaryFolderType,
-                        kCreateFolder, &fr))
-    return false;
-  unsigned char buffer[NAME_MAX+1];
-  if (0 != FSRefMakePath(&fr, buffer, ARRAY_SIZE(buffer)))
-    return false;
-  pathname.SetPathname(reinterpret_cast<char*>(buffer), "");
-#elif defined(ANDROID) || defined(IOS)
-  ASSERT(provided_app_temp_folder_ != NULL);
-  pathname.SetPathname(provided_app_temp_folder_, "");
-#else  // !OSX && !ANDROID
-  if (const char* tmpdir = getenv("TMPDIR")) {
-    pathname.SetPathname(tmpdir, "");
-  } else if (const char* tmp = getenv("TMP")) {
-    pathname.SetPathname(tmp, "");
-  } else {
-#ifdef P_tmpdir
-    pathname.SetPathname(P_tmpdir, "");
-#else  // !P_tmpdir
-    pathname.SetPathname("/tmp/", "");
-#endif  // !P_tmpdir
-  }
-#endif  // !OSX && !ANDROID
-  if (append) {
-    ASSERT(!append->empty());
-    pathname.AppendFolder(*append);
-  }
-  return !create || CreateFolder(pathname);
-}
-
-std::string UnixFilesystem::TempFilename(const Pathname &dir,
-                                         const std::string &prefix) {
-  int len = dir.pathname().size() + prefix.size() + 2 + 6;
-  char *tempname = new char[len];
-
-  snprintf(tempname, len, "%s/%sXXXXXX", dir.pathname().c_str(),
-           prefix.c_str());
-  int fd = ::mkstemp(tempname);
-  if (fd != -1)
-    ::close(fd);
-  std::string ret(tempname);
-  delete[] tempname;
-
-  return ret;
-}
-
-bool UnixFilesystem::MoveFile(const Pathname &old_path,
-                              const Pathname &new_path) {
-  if (!IsFile(old_path)) {
-    ASSERT(IsFile(old_path));
-    return false;
-  }
-  LOG(LS_VERBOSE) << "Moving " << old_path.pathname()
-                  << " to " << new_path.pathname();
-  if (rename(old_path.pathname().c_str(), new_path.pathname().c_str()) != 0) {
-    if (errno != EXDEV)
-      return false;
-    if (!CopyFile(old_path, new_path))
-      return false;
-    if (!DeleteFile(old_path))
-      return false;
-  }
-  return true;
-}
-
-bool UnixFilesystem::MoveFolder(const Pathname &old_path,
-                                const Pathname &new_path) {
-  if (!IsFolder(old_path)) {
-    ASSERT(IsFolder(old_path));
-    return false;
-  }
-  LOG(LS_VERBOSE) << "Moving " << old_path.pathname()
-                  << " to " << new_path.pathname();
-  if (rename(old_path.pathname().c_str(), new_path.pathname().c_str()) != 0) {
-    if (errno != EXDEV)
-      return false;
-    if (!CopyFolder(old_path, new_path))
-      return false;
-    if (!DeleteFolderAndContents(old_path))
-      return false;
-  }
-  return true;
-}
-
-bool UnixFilesystem::IsFolder(const Pathname &path) {
-  struct stat st;
-  if (stat(path.pathname().c_str(), &st) < 0)
-    return false;
-  return S_ISDIR(st.st_mode);
-}
-
-bool UnixFilesystem::CopyFile(const Pathname &old_path,
-                              const Pathname &new_path) {
-  LOG(LS_VERBOSE) << "Copying " << old_path.pathname()
-                  << " to " << new_path.pathname();
-  char buf[256];
-  size_t len;
-
-  StreamInterface *source = OpenFile(old_path, "rb");
-  if (!source)
-    return false;
-
-  StreamInterface *dest = OpenFile(new_path, "wb");
-  if (!dest) {
-    delete source;
-    return false;
-  }
-
-  while (source->Read(buf, sizeof(buf), &len, NULL) == SR_SUCCESS)
-    dest->Write(buf, len, NULL, NULL);
-
-  delete source;
-  delete dest;
-  return true;
-}
-
-bool UnixFilesystem::IsTemporaryPath(const Pathname& pathname) {
-#if defined(ANDROID) || defined(IOS)
-  ASSERT(provided_app_temp_folder_ != NULL);
-#endif
-
-  const char* const kTempPrefixes[] = {
-#if defined(ANDROID) || defined(IOS)
-    provided_app_temp_folder_,
-#else
-    "/tmp/", "/var/tmp/",
-#ifdef OSX
-    "/private/tmp/", "/private/var/tmp/", "/private/var/folders/",
-#endif  // OSX
-#endif  // ANDROID || IOS
-  };
-  for (size_t i = 0; i < ARRAY_SIZE(kTempPrefixes); ++i) {
-    if (0 == strncmp(pathname.pathname().c_str(), kTempPrefixes[i],
-                     strlen(kTempPrefixes[i])))
-      return true;
-  }
-  return false;
-}
-
-bool UnixFilesystem::IsFile(const Pathname& pathname) {
-  struct stat st;
-  int res = ::stat(pathname.pathname().c_str(), &st);
-  // Treat symlinks, named pipes, etc. all as files.
-  return res == 0 && !S_ISDIR(st.st_mode);
-}
-
-bool UnixFilesystem::IsAbsent(const Pathname& pathname) {
-  struct stat st;
-  int res = ::stat(pathname.pathname().c_str(), &st);
-  // Note: we specifically maintain ENOTDIR as an error, because that implies
-  // that you could not call CreateFolder(pathname).
-  return res != 0 && ENOENT == errno;
-}
-
-bool UnixFilesystem::GetFileSize(const Pathname& pathname, size_t *size) {
-  struct stat st;
-  if (::stat(pathname.pathname().c_str(), &st) != 0)
-    return false;
-  *size = st.st_size;
-  return true;
-}
-
-bool UnixFilesystem::GetFileTime(const Pathname& path, FileTimeType which,
-                                 time_t* time) {
-  struct stat st;
-  if (::stat(path.pathname().c_str(), &st) != 0)
-    return false;
-  switch (which) {
-  case FTT_CREATED:
-    *time = st.st_ctime;
-    break;
-  case FTT_MODIFIED:
-    *time = st.st_mtime;
-    break;
-  case FTT_ACCESSED:
-    *time = st.st_atime;
-    break;
-  default:
-    return false;
-  }
-  return true;
-}
-
-bool UnixFilesystem::GetAppPathname(Pathname* path) {
-#ifdef OSX
-  ProcessSerialNumber psn = { 0, kCurrentProcess };
-  CFDictionaryRef procinfo = ProcessInformationCopyDictionary(&psn,
-      kProcessDictionaryIncludeAllInformationMask);
-  if (NULL == procinfo)
-    return false;
-  CFStringRef cfpath = (CFStringRef) CFDictionaryGetValue(procinfo,
-      kIOBundleExecutableKey);
-  std::string path8;
-  bool success = ToUtf8(cfpath, &path8);
-  CFRelease(procinfo);
-  if (success)
-    path->SetPathname(path8);
-  return success;
-#else  // OSX
-  char buffer[NAME_MAX+1];
-  size_t len = readlink("/proc/self/exe", buffer, ARRAY_SIZE(buffer) - 1);
-  if (len <= 0)
-    return false;
-  buffer[len] = '\0';
-  path->SetPathname(buffer);
-  return true;
-#endif  // OSX
-}
-
-bool UnixFilesystem::GetAppDataFolder(Pathname* path, bool per_user) {
-  ASSERT(!organization_name_.empty());
-  ASSERT(!application_name_.empty());
-
-  // First get the base directory for app data.
-#ifdef OSX
-  if (per_user) {
-    // Use ~/Library/Application Support/<orgname>/<appname>/
-    FSRef fr;
-    if (0 != FSFindFolder(kUserDomain, kApplicationSupportFolderType,
-                          kCreateFolder, &fr))
-      return false;
-    unsigned char buffer[NAME_MAX+1];
-    if (0 != FSRefMakePath(&fr, buffer, ARRAY_SIZE(buffer)))
-      return false;
-    path->SetPathname(reinterpret_cast<char*>(buffer), "");
-  } else {
-    // TODO
-    return false;
-  }
-#elif defined(ANDROID) || defined(IOS)  // && !OSX
-  ASSERT(provided_app_data_folder_ != NULL);
-  path->SetPathname(provided_app_data_folder_, "");
-#elif defined(LINUX)  // && !OSX && !defined(ANDROID) && !defined(IOS)
-  if (per_user) {
-    // We follow the recommendations in
-    // http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
-    // It specifies separate directories for data and config files, but
-    // GetAppDataFolder() does not distinguish. We just return the config dir
-    // path.
-    const char* xdg_config_home = getenv("XDG_CONFIG_HOME");
-    if (xdg_config_home) {
-      path->SetPathname(xdg_config_home, "");
-    } else {
-      // XDG says to default to $HOME/.config. We also support falling back to
-      // other synonyms for HOME if for some reason it is not defined.
-      const char* homedir;
-      if (const char* home = getenv("HOME")) {
-        homedir = home;
-      } else if (const char* dotdir = getenv("DOTDIR")) {
-        homedir = dotdir;
-      } else if (passwd* pw = getpwuid(geteuid())) {
-        homedir = pw->pw_dir;
-      } else {
-        return false;
-      }
-      path->SetPathname(homedir, "");
-      path->AppendFolder(".config");
-    }
-  } else {
-    // XDG does not define a standard directory for writable global data. Let's
-    // just use this.
-    path->SetPathname("/var/cache/", "");
-  }
-#endif  // !OSX && !defined(ANDROID) && !defined(LINUX)
-
-  // Now add on a sub-path for our app.
-#if defined(OSX) || defined(ANDROID) || defined(IOS)
-  path->AppendFolder(organization_name_);
-  path->AppendFolder(application_name_);
-#elif defined(LINUX)
-  // XDG says to use a single directory level, so we concatenate the org and app
-  // name with a hyphen. We also do the Linuxy thing and convert to all
-  // lowercase with no spaces.
-  std::string subdir(organization_name_);
-  subdir.append("-");
-  subdir.append(application_name_);
-  replace_substrs(" ", 1, "", 0, &subdir);
-  std::transform(subdir.begin(), subdir.end(), subdir.begin(), ::tolower);
-  path->AppendFolder(subdir);
-#endif
-  return CreateFolder(*path);
-}
-
-bool UnixFilesystem::GetAppTempFolder(Pathname* path) {
-#if defined(ANDROID) || defined(IOS)
-  ASSERT(provided_app_temp_folder_ != NULL);
-  path->SetPathname(provided_app_temp_folder_);
-  return true;
-#else
-  ASSERT(!application_name_.empty());
-  // TODO: Consider whether we are worried about thread safety.
-  if (app_temp_path_ != NULL && strlen(app_temp_path_) > 0) {
-    path->SetPathname(app_temp_path_);
-    return true;
-  }
-
-  // Create a random directory as /tmp/<appname>-<pid>-<timestamp>
-  char buffer[128];
-  sprintfn(buffer, ARRAY_SIZE(buffer), "-%d-%d",
-           static_cast<int>(getpid()),
-           static_cast<int>(time(0)));
-  std::string folder(application_name_);
-  folder.append(buffer);
-  if (!GetTemporaryFolder(*path, true, &folder))
-    return false;
-
-  delete [] app_temp_path_;
-  app_temp_path_ = CopyString(path->pathname());
-  // TODO: atexit(DeleteFolderAndContents(app_temp_path_));
-  return true;
-#endif
-}
-
-bool UnixFilesystem::GetDiskFreeSpace(const Pathname& path, int64 *freebytes) {
-  ASSERT(NULL != freebytes);
-  // TODO: Consider making relative paths absolute using cwd.
-  // TODO: When popping off a symlink, push back on the components of the
-  // symlink, so we don't jump out of the target disk inadvertently.
-  Pathname existing_path(path.folder(), "");
-  while (!existing_path.folder().empty() && IsAbsent(existing_path)) {
-    existing_path.SetFolder(existing_path.parent_folder());
-  }
-#ifdef ANDROID
-  struct statfs fs;
-  memset(&fs, 0, sizeof(fs));
-  if (0 != statfs(existing_path.pathname().c_str(), &fs))
-    return false;
-#else
-  struct statvfs vfs;
-  memset(&vfs, 0, sizeof(vfs));
-  if (0 != statvfs(existing_path.pathname().c_str(), &vfs))
-    return false;
-#endif  // ANDROID
-#ifdef LINUX
-  *freebytes = static_cast<int64>(vfs.f_bsize) * vfs.f_bavail;
-#elif defined(OSX)
-  *freebytes = static_cast<int64>(vfs.f_frsize) * vfs.f_bavail;
-#elif defined(ANDROID)
-  *freebytes = static_cast<int64>(fs.f_bsize) * fs.f_bavail;
-#endif
-
-  return true;
-}
-
-Pathname UnixFilesystem::GetCurrentDirectory() {
-  Pathname cwd;
-  char buffer[PATH_MAX];
-  char *path = getcwd(buffer, PATH_MAX);
-
-  if (!path) {
-    LOG_ERR(LS_ERROR) << "getcwd() failed";
-    return cwd;  // returns empty pathname
-  }
-  cwd.SetFolder(std::string(path));
-
-  return cwd;
-}
-
-char* UnixFilesystem::CopyString(const std::string& str) {
-  size_t size = str.length() + 1;
-
-  char* buf = new char[size];
-  if (!buf) {
-    return NULL;
-  }
-
-  strcpyn(buf, size, str.c_str());
-  return buf;
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/unixfilesystem.h b/third_party/libjingle/source/talk/base/unixfilesystem.h
deleted file mode 100644
index e443dc8..0000000
--- a/third_party/libjingle/source/talk/base/unixfilesystem.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2006, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _TALK_BASE_UNIXFILESYSTEM_H__
-#define _TALK_BASE_UNIXFILESYSTEM_H__
-
-#include "fileutils.h"
-
-namespace talk_base {
-
-class UnixFilesystem : public FilesystemInterface {
- public:
-
-#if defined(ANDROID) || defined(IOS)
-// Android does not have a native code API to fetch the app data or temp
-// folders. That needs to be passed into this class from Java. Similarly, iOS
-// only supports an Objective-C API for fetching the folder locations, so that
-// needs to be passed in here from Objective-C.
-
-  static void SetAppDataFolder(const std::string& folder);
-  static void SetAppTempFolder(const std::string& folder);
-#endif
-
-  // Opens a file. Returns an open StreamInterface if function succeeds. Otherwise,
-  // returns NULL.
-  virtual FileStream *OpenFile(const Pathname &filename, 
-                               const std::string &mode);
-
-  // Atomically creates an empty file accessible only to the current user if one
-  // does not already exist at the given path, otherwise fails.
-  virtual bool CreatePrivateFile(const Pathname &filename);
-
-  // This will attempt to delete the file located at filename.
-  // It will fail with VERIY if you pass it a non-existant file, or a directory.
-  virtual bool DeleteFile(const Pathname &filename);
-
-  // This will attempt to delete the folder located at 'folder'
-  // It ASSERTs and returns false if you pass it a non-existant folder or a plain file.
-  virtual bool DeleteEmptyFolder(const Pathname &folder);
-		
-  // Creates a directory. This will call itself recursively to create /foo/bar even if
-  // /foo does not exist.
-  // Returns TRUE if function succeeds
-   virtual bool CreateFolder(const Pathname &pathname);
-  
-  // This moves a file from old_path to new_path, where "file" can be a plain file
-  // or directory, which will be moved recursively.
-  // Returns true if function succeeds.
-  virtual bool MoveFile(const Pathname &old_path, const Pathname &new_path);
-  virtual bool MoveFolder(const Pathname &old_path, const Pathname &new_path);
-  
-  // This copies a file from old_path to _new_path where "file" can be a plain file
-  // or directory, which will be copied recursively.
-  // Returns true if function succeeds
-  virtual bool CopyFile(const Pathname &old_path, const Pathname &new_path);
-
-  // Returns true if a pathname is a directory
-  virtual bool IsFolder(const Pathname& pathname);
-
-  // Returns true if pathname represents a temporary location on the system.
-  virtual bool IsTemporaryPath(const Pathname& pathname);
-
-  // Returns true of pathname represents an existing file
-  virtual bool IsFile(const Pathname& pathname);
-  
-  // Returns true if pathname refers to no filesystem object, every parent
-  // directory either exists, or is also absent.
-  virtual bool IsAbsent(const Pathname& pathname);
-
-  virtual std::string TempFilename(const Pathname &dir, const std::string &prefix);
-
-  // A folder appropriate for storing temporary files (Contents are
-  // automatically deleted when the program exists)
-  virtual bool GetTemporaryFolder(Pathname &path, bool create,
-                                 const std::string *append);
-
-  virtual bool GetFileSize(const Pathname& path, size_t* size);
-  virtual bool GetFileTime(const Pathname& path, FileTimeType which,
-                           time_t* time);
-
-  // Returns the path to the running application.
-  virtual bool GetAppPathname(Pathname* path);
-
-  virtual bool GetAppDataFolder(Pathname* path, bool per_user);
-
-  // Get a temporary folder that is unique to the current user and application.
-  virtual bool GetAppTempFolder(Pathname* path);
-
-  virtual bool GetDiskFreeSpace(const Pathname& path, int64 *freebytes);
-
-  // Returns the absolute path of the current directory.
-  virtual Pathname GetCurrentDirectory();
-
- private:
-#if defined(ANDROID) || defined(IOS)
-  static char* provided_app_data_folder_;
-  static char* provided_app_temp_folder_;
-#else
-  static char* app_temp_path_;
-#endif
-
-  static char* CopyString(const std::string& str);
-};
-
-}  // namespace talk_base
-
-#endif  // _UNIXFILESYSTEM_H__
diff --git a/third_party/libjingle/source/talk/base/urlencode.cc b/third_party/libjingle/source/talk/base/urlencode.cc
deleted file mode 100644
index 6dd51e1..0000000
--- a/third_party/libjingle/source/talk/base/urlencode.cc
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * libjingle
- * Copyright 2008, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/urlencode.h"
-
-#include "talk/base/common.h"
-#include "talk/base/stringutils.h"
-
-static int HexPairValue(const char * code) {
-  int value = 0;
-  const char * pch = code;
-  for (;;) {
-    int digit = *pch++;
-    if (digit >= '0' && digit <= '9') {
-      value += digit - '0';
-    }
-    else if (digit >= 'A' && digit <= 'F') {
-      value += digit - 'A' + 10;
-    }
-    else if (digit >= 'a' && digit <= 'f') {
-      value += digit - 'a' + 10;
-    }
-    else {
-      return -1;
-    }
-    if (pch == code + 2)
-      return value;
-    value <<= 4;
-  }
-}
-
-int InternalUrlDecode(const char *source, char *dest,
-                      bool encode_space_as_plus) {
-  char * start = dest;
-
-  while (*source) {
-    switch (*source) {
-    case '+':
-      if (encode_space_as_plus) {
-        *(dest++) = ' ';
-      } else {
-        *dest++ = *source;
-      }
-      break;
-    case '%':
-      if (source[1] && source[2]) {
-        int value = HexPairValue(source + 1);
-        if (value >= 0) {
-          *(dest++) = value;
-          source += 2;
-        }
-        else {
-          *dest++ = '?';
-        }
-      }
-      else {
-        *dest++ = '?';
-      }
-      break;
-    default:
-      *dest++ = *source;
-    }
-    source++;
-  }
-
-  *dest = 0;
-  return dest - start;
-}
-
-int UrlDecode(const char *source, char *dest) {
-  return InternalUrlDecode(source, dest, true);
-}
-
-int UrlDecodeWithoutEncodingSpaceAsPlus(const char *source, char *dest) {
-  return InternalUrlDecode(source, dest, false);
-}
-
-bool IsValidUrlChar(char ch, bool unsafe_only) {
-  if (unsafe_only) {
-    return !(ch <= ' ' || strchr("\\\"^&`<>[]{}", ch));
-  } else {
-    return isalnum(ch) || strchr("-_.!~*'()", ch);
-  }
-}
-
-int InternalUrlEncode(const char *source, char *dest, unsigned int max,
-                      bool encode_space_as_plus, bool unsafe_only) {
-  static const char *digits = "0123456789ABCDEF";
-  if (max == 0) {
-    return 0;
-  }
-
-  char *start = dest;
-  while (static_cast<unsigned>(dest - start) < max && *source) {
-    unsigned char ch = static_cast<unsigned char>(*source);
-    if (*source == ' ' && encode_space_as_plus && !unsafe_only) {
-      *dest++ = '+';
-    } else if (IsValidUrlChar(ch, unsafe_only)) {
-      *dest++ = *source;
-    } else {
-      if (static_cast<unsigned>(dest - start) + 4 > max) {
-        break;
-      }
-      *dest++ = '%';
-      *dest++ = digits[(ch >> 4) & 0x0F];
-      *dest++ = digits[       ch & 0x0F];
-    }
-    source++;
-  }
-  ASSERT(static_cast<unsigned int>(dest - start) < max);
-  *dest = 0;
-
-  return dest - start;
-}
-
-int UrlEncode(const char *source, char *dest, unsigned max) {
-  return InternalUrlEncode(source, dest, max, true, false);
-}
-
-int UrlEncodeWithoutEncodingSpaceAsPlus(const char *source, char *dest,
-                                        unsigned max) {
-  return InternalUrlEncode(source, dest, max, false, false);
-}
-
-int UrlEncodeOnlyUnsafeChars(const char *source, char *dest, unsigned max) {
-  return InternalUrlEncode(source, dest, max, false, true);
-}
-
-std::string
-InternalUrlDecodeString(const std::string & encoded,
-                        bool encode_space_as_plus) {
-  size_t needed_length = encoded.length() + 1;
-  char* buf = STACK_ARRAY(char, needed_length);
-  InternalUrlDecode(encoded.c_str(), buf, encode_space_as_plus);
-  return buf;
-}
-
-std::string
-UrlDecodeString(const std::string & encoded) {
-  return InternalUrlDecodeString(encoded, true);
-}
-
-std::string
-UrlDecodeStringWithoutEncodingSpaceAsPlus(const std::string & encoded) {
-  return InternalUrlDecodeString(encoded, false);
-}
-
-std::string
-InternalUrlEncodeString(const std::string & decoded,
-                        bool encode_space_as_plus,
-                        bool unsafe_only) {
-  size_t needed_length = decoded.length() * 3 + 1;
-  char* buf = STACK_ARRAY(char, needed_length);
-  InternalUrlEncode(decoded.c_str(), buf, needed_length,
-                    encode_space_as_plus, unsafe_only);
-  return buf;
-}
-
-std::string
-UrlEncodeString(const std::string & decoded) {
-  return InternalUrlEncodeString(decoded, true, false);
-}
-
-std::string
-UrlEncodeStringWithoutEncodingSpaceAsPlus(const std::string & decoded) {
-  return InternalUrlEncodeString(decoded, false, false);
-}
-
-std::string
-UrlEncodeStringForOnlyUnsafeChars(const std::string & decoded) {
-  return InternalUrlEncodeString(decoded, false, true);
-}
diff --git a/third_party/libjingle/source/talk/base/urlencode.h b/third_party/libjingle/source/talk/base/urlencode.h
deleted file mode 100644
index 05165e8..0000000
--- a/third_party/libjingle/source/talk/base/urlencode.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * libjingle
- * Copyright 2008, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _URLENCODE_H_
-#define _URLENCODE_H_ 
-
-#include <string>
-
-// Decode all encoded characters. Also decode + as space.
-int UrlDecode(const char *source, char *dest);
-
-// Decode all encoded characters.
-int UrlDecodeWithoutEncodingSpaceAsPlus(const char *source, char *dest);
-
-// Encode all characters except alphas, numbers, and -_.!~*'()
-// Also encode space as +.
-int UrlEncode(const char *source, char *dest, unsigned max);
-
-// Encode all characters except alphas, numbers, and -_.!~*'()
-int UrlEncodeWithoutEncodingSpaceAsPlus(const char *source, char *dest,
-                                        unsigned max);
-
-// Encode only unsafe chars, including \ "^&`<>[]{}
-// Also encode space as %20, instead of +
-int UrlEncodeOnlyUnsafeChars(const char *source, char *dest, unsigned max);
-
-std::string UrlDecodeString(const std::string & encoded);
-std::string UrlDecodeStringWithoutEncodingSpaceAsPlus(
-    const std::string & encoded);
-std::string UrlEncodeString(const std::string & decoded);
-std::string UrlEncodeStringWithoutEncodingSpaceAsPlus(
-    const std::string & decoded);
-std::string UrlEncodeStringForOnlyUnsafeChars(const std::string & decoded);
-
-#endif
-
diff --git a/third_party/libjingle/source/talk/base/urlencode_unittest.cc b/third_party/libjingle/source/talk/base/urlencode_unittest.cc
deleted file mode 100644
index f71cd75..0000000
--- a/third_party/libjingle/source/talk/base/urlencode_unittest.cc
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/common.h"
-#include "talk/base/gunit.h"
-#include "talk/base/thread.h"
-#include "talk/base/urlencode.h"
-
-TEST(Urlencode, SourceTooLong) {
-  char source[] = "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"
-      "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^";
-  char dest[1];
-  ASSERT_EQ(0, UrlEncode(source, dest, ARRAY_SIZE(dest)));
-  ASSERT_EQ('\0', dest[0]);
-
-  dest[0] = 'a';
-  ASSERT_EQ(0, UrlEncode(source, dest, 0));
-  ASSERT_EQ('a', dest[0]);
-}
-
-TEST(Urlencode, OneCharacterConversion) {
-  char source[] = "^";
-  char dest[4];
-  ASSERT_EQ(3, UrlEncode(source, dest, ARRAY_SIZE(dest)));
-  ASSERT_STREQ("%5E", dest);
-}
-
-TEST(Urlencode, ShortDestinationNoEncoding) {
-  // In this case we have a destination that would not be
-  // big enough to hold an encoding but is big enough to
-  // hold the text given.
-  char source[] = "aa";
-  char dest[3];
-  ASSERT_EQ(2, UrlEncode(source, dest, ARRAY_SIZE(dest)));
-  ASSERT_STREQ("aa", dest);
-}
-
-TEST(Urlencode, ShortDestinationEncoding) {
-  // In this case we have a destination that is not
-  // big enough to hold the encoding.
-  char source[] = "&";
-  char dest[3];
-  ASSERT_EQ(0, UrlEncode(source, dest, ARRAY_SIZE(dest)));
-  ASSERT_EQ('\0', dest[0]);
-}
-
-TEST(Urlencode, Encoding1) {
-  char source[] = "A^ ";
-  char dest[8];
-  ASSERT_EQ(5, UrlEncode(source, dest, ARRAY_SIZE(dest)));
-  ASSERT_STREQ("A%5E+", dest);
-}
-
-TEST(Urlencode, Encoding2) {
-  char source[] = "A^ ";
-  char dest[8];
-  ASSERT_EQ(7, UrlEncodeWithoutEncodingSpaceAsPlus(source, dest,
-                                                   ARRAY_SIZE(dest)));
-  ASSERT_STREQ("A%5E%20", dest);
-}
-
-TEST(Urldecode, Decoding1) {
-  char source[] = "A%5E+";
-  char dest[8];
-  ASSERT_EQ(3, UrlDecode(source, dest));
-  ASSERT_STREQ("A^ ", dest);
-}
-
-TEST(Urldecode, Decoding2) {
-  char source[] = "A%5E+";
-  char dest[8];
-  ASSERT_EQ(3, UrlDecodeWithoutEncodingSpaceAsPlus(source, dest));
-  ASSERT_STREQ("A^+", dest);
-}
diff --git a/third_party/libjingle/source/talk/base/versionparsing.cc b/third_party/libjingle/source/talk/base/versionparsing.cc
deleted file mode 100644
index 03f3dec..0000000
--- a/third_party/libjingle/source/talk/base/versionparsing.cc
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/versionparsing.h"
-
-#include <cstdlib>
-
-namespace talk_base {
-
-bool ParseVersionString(const std::string& version_str,
-                        int num_expected_segments,
-                        int version[]) {
-  size_t pos = 0;
-  for (int i = 0;;) {
-    size_t dot_pos = version_str.find('.', pos);
-    size_t n;
-    if (dot_pos == std::string::npos) {
-      // npos here is a special value meaning "to the end of the string"
-      n = std::string::npos;
-    } else {
-      n = dot_pos - pos;
-    }
-
-    version[i] = atoi(version_str.substr(pos, n).c_str());
-
-    if (++i >= num_expected_segments) break;
-
-    if (dot_pos == std::string::npos) {
-      // Previous segment was not terminated by a dot, but there's supposed to
-      // be more segments, so that's an error.
-      return false;
-    }
-    pos = dot_pos + 1;
-  }
-  return true;
-}
-
-int CompareVersions(const int version1[],
-                    const int version2[],
-                    int num_segments) {
-  for (int i = 0; i < num_segments; ++i) {
-    int diff = version1[i] - version2[i];
-    if (diff != 0) {
-      return diff;
-    }
-  }
-  return 0;
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/versionparsing.h b/third_party/libjingle/source/talk/base/versionparsing.h
deleted file mode 100644
index c66ad25..0000000
--- a/third_party/libjingle/source/talk/base/versionparsing.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_VERSIONPARSING_H_
-#define TALK_BASE_VERSIONPARSING_H_
-
-#include <string>
-
-namespace talk_base {
-
-// Parses a version string into an array. "num_expected_segments" must be the
-// number of numerical segments that the version is expected to have (e.g.,
-// "1.1.2.0" has 4). "version" must be an array of that length to hold the
-// parsed numbers.
-// Returns "true" iff successful.
-bool ParseVersionString(const std::string& version_str,
-                        int num_expected_segments,
-                        int version[]);
-
-// Computes the lexicographical order of two versions. The return value
-// indicates the order in the standard way (e.g., see strcmp()).
-int CompareVersions(const int version1[],
-                    const int version2[],
-                    int num_segments);
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_VERSIONPARSING_H_
diff --git a/third_party/libjingle/source/talk/base/versionparsing_unittest.cc b/third_party/libjingle/source/talk/base/versionparsing_unittest.cc
deleted file mode 100644
index b083265..0000000
--- a/third_party/libjingle/source/talk/base/versionparsing_unittest.cc
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * libjingle
- * Copyright 2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/versionparsing.h"
-
-#include "talk/base/gunit.h"
-
-namespace talk_base {
-
-static const int kExampleSegments = 4;
-
-typedef int ExampleVersion[kExampleSegments];
-
-TEST(VersionParsing, TestGoodParse) {
-  ExampleVersion ver;
-  std::string str1("1.1.2.0");
-  static const ExampleVersion expect1 = {1, 1, 2, 0};
-  EXPECT_TRUE(ParseVersionString(str1, kExampleSegments, ver));
-  EXPECT_EQ(0, CompareVersions(ver, expect1, kExampleSegments));
-  std::string str2("2.0.0.1");
-  static const ExampleVersion expect2 = {2, 0, 0, 1};
-  EXPECT_TRUE(ParseVersionString(str2, kExampleSegments, ver));
-  EXPECT_EQ(0, CompareVersions(ver, expect2, kExampleSegments));
-}
-
-TEST(VersionParsing, TestBadParse) {
-  ExampleVersion ver;
-  std::string str1("1.1.2");
-  EXPECT_FALSE(ParseVersionString(str1, kExampleSegments, ver));
-  std::string str2("");
-  EXPECT_FALSE(ParseVersionString(str2, kExampleSegments, ver));
-  std::string str3("garbarge");
-  EXPECT_FALSE(ParseVersionString(str3, kExampleSegments, ver));
-}
-
-TEST(VersionParsing, TestCompare) {
-  static const ExampleVersion ver1 = {1, 0, 21, 0};
-  static const ExampleVersion ver2 = {1, 1, 2, 0};
-  static const ExampleVersion ver3 = {1, 1, 3, 0};
-  static const ExampleVersion ver4 = {1, 1, 3, 9861};
-
-  // Test that every combination of comparisons has the expected outcome.
-  EXPECT_EQ(0, CompareVersions(ver1, ver1, kExampleSegments));
-  EXPECT_EQ(0, CompareVersions(ver2, ver2, kExampleSegments));
-  EXPECT_EQ(0, CompareVersions(ver3, ver3, kExampleSegments));
-  EXPECT_EQ(0, CompareVersions(ver4, ver4, kExampleSegments));
-
-  EXPECT_GT(0, CompareVersions(ver1, ver2, kExampleSegments));
-  EXPECT_LT(0, CompareVersions(ver2, ver1, kExampleSegments));
-
-  EXPECT_GT(0, CompareVersions(ver1, ver3, kExampleSegments));
-  EXPECT_LT(0, CompareVersions(ver3, ver1, kExampleSegments));
-
-  EXPECT_GT(0, CompareVersions(ver1, ver4, kExampleSegments));
-  EXPECT_LT(0, CompareVersions(ver4, ver1, kExampleSegments));
-
-  EXPECT_GT(0, CompareVersions(ver2, ver3, kExampleSegments));
-  EXPECT_LT(0, CompareVersions(ver3, ver2, kExampleSegments));
-
-  EXPECT_GT(0, CompareVersions(ver2, ver4, kExampleSegments));
-  EXPECT_LT(0, CompareVersions(ver4, ver2, kExampleSegments));
-
-  EXPECT_GT(0, CompareVersions(ver3, ver4, kExampleSegments));
-  EXPECT_LT(0, CompareVersions(ver4, ver3, kExampleSegments));
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/virtualsocket_unittest.cc b/third_party/libjingle/source/talk/base/virtualsocket_unittest.cc
deleted file mode 100644
index 1c44fe7..0000000
--- a/third_party/libjingle/source/talk/base/virtualsocket_unittest.cc
+++ /dev/null
@@ -1,686 +0,0 @@
-/*
- * libjingle
- * Copyright 2006, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <time.h>
-
-#include <cmath>
-
-#include "talk/base/logging.h"
-#include "talk/base/gunit.h"
-#include "talk/base/testclient.h"
-#include "talk/base/testutils.h"
-#include "talk/base/thread.h"
-#include "talk/base/timeutils.h"
-#include "talk/base/virtualsocketserver.h"
-
-using namespace talk_base;
-
-class VirtualSocketServerTest : public testing::Test {
- public:
-  VirtualSocketServerTest() : ss_(new VirtualSocketServer(NULL)) {
-  }
-
- protected:
-  virtual void SetUp() {
-    Thread::Current()->set_socketserver(ss_);
-  }
-  virtual void TearDown() {
-    Thread::Current()->set_socketserver(NULL);
-  }
-
-  VirtualSocketServer* ss_;
-};
-
-TEST_F(VirtualSocketServerTest, basic) {
-  SocketAddress addr1(IPAddress(INADDR_ANY), 5000);
-  AsyncSocket* socket = ss_->CreateAsyncSocket(SOCK_DGRAM);
-  socket->Bind(addr1);
-  addr1 = socket->GetLocalAddress();
-
-  TestClient* client1 = new TestClient(new AsyncUDPSocket(socket));
-  AsyncSocket* socket2 = ss_->CreateAsyncSocket(SOCK_DGRAM);
-  TestClient* client2 = new TestClient(new AsyncUDPSocket(socket2));
-
-  SocketAddress addr2;
-  EXPECT_EQ(3, client2->SendTo("foo", 3, addr1));
-  EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr2));
-
-  SocketAddress addr3;
-  EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr2));
-  EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &addr3));
-  EXPECT_EQ(addr3, addr1);
-
-  for (int i = 0; i < 10; i++) {
-    client2 = new TestClient(AsyncUDPSocket::Create(ss_, SocketAddress()));
-
-    SocketAddress addr4;
-    EXPECT_EQ(3, client2->SendTo("foo", 3, addr1));
-    EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr4));
-    EXPECT_EQ(addr4.ipaddr().v4AddressAsHostOrderInteger(),
-              addr2.ipaddr().v4AddressAsHostOrderInteger() + 1);
-    EXPECT_EQ(addr4.port(), addr2.port() + 1);
-
-    SocketAddress addr5;
-    EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr4));
-    EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &addr5));
-    EXPECT_EQ(addr5, addr1);
-
-    addr2 = addr4;
-  }
-}
-
-TEST_F(VirtualSocketServerTest, connect) {
-  testing::StreamSink sink;
-  SocketAddress accept_addr;
-  const SocketAddress kEmptyAddr;
-
-  // Create client
-  AsyncSocket* client = ss_->CreateAsyncSocket(SOCK_STREAM);
-  sink.Monitor(client);
-  EXPECT_EQ(client->GetState(), AsyncSocket::CS_CLOSED);
-  EXPECT_EQ(client->GetLocalAddress(), kEmptyAddr);
-
-  // Create server
-  AsyncSocket* server = ss_->CreateAsyncSocket(SOCK_STREAM);
-  sink.Monitor(server);
-  EXPECT_NE(0, server->Listen(5));  // Bind required
-  EXPECT_EQ(0, server->Bind(kEmptyAddr));
-  EXPECT_EQ(0, server->Listen(5));
-  EXPECT_EQ(server->GetState(), AsyncSocket::CS_CONNECTING);
-
-  // No pending server connections
-  EXPECT_FALSE(sink.Check(server, testing::SSE_READ));
-  EXPECT_TRUE(NULL == server->Accept(&accept_addr));
-  EXPECT_EQ(accept_addr, kEmptyAddr);
-
-  // Attempt connect to listening socket
-  EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
-  EXPECT_NE(client->GetLocalAddress(), kEmptyAddr);  // Implicit Bind
-  EXPECT_NE(client->GetLocalAddress(), server->GetLocalAddress());
-
-  // Client is connecting
-  EXPECT_EQ(client->GetState(), AsyncSocket::CS_CONNECTING);
-  EXPECT_FALSE(sink.Check(client, testing::SSE_OPEN));
-  EXPECT_FALSE(sink.Check(client, testing::SSE_CLOSE));
-
-  ss_->ProcessMessagesUntilIdle();
-
-  // Client still connecting
-  EXPECT_EQ(client->GetState(), AsyncSocket::CS_CONNECTING);
-  EXPECT_FALSE(sink.Check(client, testing::SSE_OPEN));
-  EXPECT_FALSE(sink.Check(client, testing::SSE_CLOSE));
-
-  // Server has pending connection
-  EXPECT_TRUE(sink.Check(server, testing::SSE_READ));
-  Socket* accepted = server->Accept(&accept_addr);
-  EXPECT_TRUE(NULL != accepted);
-  EXPECT_NE(accept_addr, kEmptyAddr);
-  EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr);
-
-  EXPECT_EQ(accepted->GetState(), AsyncSocket::CS_CONNECTED);
-  EXPECT_EQ(accepted->GetLocalAddress(), server->GetLocalAddress());
-  EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
-
-  ss_->ProcessMessagesUntilIdle();
-
-  // Client has connected
-  EXPECT_EQ(client->GetState(), AsyncSocket::CS_CONNECTED);
-  EXPECT_TRUE(sink.Check(client, testing::SSE_OPEN));
-  EXPECT_FALSE(sink.Check(client, testing::SSE_CLOSE));
-  EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
-  EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
-}
-
-TEST_F(VirtualSocketServerTest, connect_to_non_listener) {
-  testing::StreamSink sink;
-  SocketAddress accept_addr;
-  const SocketAddress kEmptyAddr;
-
-  // Create client
-  AsyncSocket* client = ss_->CreateAsyncSocket(SOCK_STREAM);
-  sink.Monitor(client);
-
-  // Create server
-  AsyncSocket* server = ss_->CreateAsyncSocket(SOCK_STREAM);
-  sink.Monitor(server);
-  EXPECT_EQ(0, server->Bind(kEmptyAddr));
-
-  // Attempt connect to non-listening socket
-  EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
-
-  ss_->ProcessMessagesUntilIdle();
-
-  // No pending server connections
-  EXPECT_FALSE(sink.Check(server, testing::SSE_READ));
-  EXPECT_TRUE(NULL == server->Accept(&accept_addr));
-  EXPECT_EQ(accept_addr, kEmptyAddr);
-
-  // Connection failed
-  EXPECT_EQ(client->GetState(), AsyncSocket::CS_CLOSED);
-  EXPECT_FALSE(sink.Check(client, testing::SSE_OPEN));
-  EXPECT_TRUE(sink.Check(client, testing::SSE_ERROR));
-  EXPECT_EQ(client->GetRemoteAddress(), kEmptyAddr);
-}
-
-TEST_F(VirtualSocketServerTest, close_during_connect) {
-  testing::StreamSink sink;
-  SocketAddress accept_addr;
-  const SocketAddress kEmptyAddr;
-
-  // Create client and server
-  AsyncSocket* client = ss_->CreateAsyncSocket(SOCK_STREAM);
-  sink.Monitor(client);
-  AsyncSocket* server = ss_->CreateAsyncSocket(SOCK_STREAM);
-  sink.Monitor(server);
-
-  // Initiate connect
-  EXPECT_EQ(0, server->Bind(kEmptyAddr));
-  EXPECT_EQ(0, server->Listen(5));
-  EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
-
-  // Server close before socket enters accept queue
-  EXPECT_FALSE(sink.Check(server, testing::SSE_READ));
-  server->Close();
-
-  ss_->ProcessMessagesUntilIdle();
-
-  // Result: connection failed
-  EXPECT_EQ(client->GetState(), AsyncSocket::CS_CLOSED);
-  EXPECT_TRUE(sink.Check(client, testing::SSE_ERROR));
-
-  // New server
-  delete server;
-  server = ss_->CreateAsyncSocket(SOCK_STREAM);
-  sink.Monitor(server);
-
-  // Initiate connect
-  EXPECT_EQ(0, server->Bind(kEmptyAddr));
-  EXPECT_EQ(0, server->Listen(5));
-  EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
-
-  ss_->ProcessMessagesUntilIdle();
-
-  // Server close while socket is in accept queue
-  EXPECT_TRUE(sink.Check(server, testing::SSE_READ));
-  server->Close();
-
-  ss_->ProcessMessagesUntilIdle();
-
-  // Result: connection failed
-  EXPECT_EQ(client->GetState(), AsyncSocket::CS_CLOSED);
-  EXPECT_TRUE(sink.Check(client, testing::SSE_ERROR));
-
-  // New server
-  delete server;
-  server = ss_->CreateAsyncSocket(SOCK_STREAM);
-  sink.Monitor(server);
-
-  // Initiate connect
-  EXPECT_EQ(0, server->Bind(kEmptyAddr));
-  EXPECT_EQ(0, server->Listen(5));
-  EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
-
-  ss_->ProcessMessagesUntilIdle();
-
-  // Server accepts connection
-  EXPECT_TRUE(sink.Check(server, testing::SSE_READ));
-  AsyncSocket* accepted = server->Accept(&accept_addr);
-  ASSERT_TRUE(NULL != accepted);
-  sink.Monitor(accepted);
-
-  // Client closes before connection complets
-  EXPECT_EQ(accepted->GetState(), AsyncSocket::CS_CONNECTED);
-
-  // Connected message has not been processed yet.
-  EXPECT_EQ(client->GetState(), AsyncSocket::CS_CONNECTING);
-  client->Close();
-
-  ss_->ProcessMessagesUntilIdle();
-
-  // Result: accepted socket closes
-  EXPECT_EQ(accepted->GetState(), AsyncSocket::CS_CLOSED);
-  EXPECT_TRUE(sink.Check(accepted, testing::SSE_CLOSE));
-  EXPECT_FALSE(sink.Check(client, testing::SSE_CLOSE));
-}
-
-TEST_F(VirtualSocketServerTest, close) {
-  testing::StreamSink sink;
-  const SocketAddress kEmptyAddr;
-
-  // Create clients
-  AsyncSocket* a = ss_->CreateAsyncSocket(SOCK_STREAM);
-  sink.Monitor(a);
-  a->Bind(kEmptyAddr);
-
-  AsyncSocket* b = ss_->CreateAsyncSocket(SOCK_STREAM);
-  sink.Monitor(b);
-  b->Bind(kEmptyAddr);
-
-  EXPECT_EQ(0, a->Connect(b->GetLocalAddress()));
-  EXPECT_EQ(0, b->Connect(a->GetLocalAddress()));
-
-  ss_->ProcessMessagesUntilIdle();
-
-  EXPECT_TRUE(sink.Check(a, testing::SSE_OPEN));
-  EXPECT_EQ(a->GetState(), AsyncSocket::CS_CONNECTED);
-  EXPECT_EQ(a->GetRemoteAddress(), b->GetLocalAddress());
-
-  EXPECT_TRUE(sink.Check(b, testing::SSE_OPEN));
-  EXPECT_EQ(b->GetState(), AsyncSocket::CS_CONNECTED);
-  EXPECT_EQ(b->GetRemoteAddress(), a->GetLocalAddress());
-
-  EXPECT_EQ(1, a->Send("a", 1));
-  b->Close();
-  EXPECT_EQ(1, a->Send("b", 1));
-
-  ss_->ProcessMessagesUntilIdle();
-
-  char buffer[10];
-  EXPECT_FALSE(sink.Check(b, testing::SSE_READ));
-  EXPECT_EQ(-1, b->Recv(buffer, 10));
-
-  EXPECT_TRUE(sink.Check(a, testing::SSE_CLOSE));
-  EXPECT_EQ(a->GetState(), AsyncSocket::CS_CLOSED);
-  EXPECT_EQ(a->GetRemoteAddress(), kEmptyAddr);
-
-  EXPECT_FALSE(sink.Check(b, testing::SSE_CLOSE));  // No signal for Closer
-  EXPECT_EQ(b->GetState(), AsyncSocket::CS_CLOSED);
-  EXPECT_EQ(b->GetRemoteAddress(), kEmptyAddr);
-}
-
-TEST_F(VirtualSocketServerTest, tcp_send) {
-  testing::StreamSink sink;
-  const SocketAddress kEmptyAddr;
-
-  // Connect two sockets
-  AsyncSocket* a = ss_->CreateAsyncSocket(SOCK_STREAM);
-  sink.Monitor(a);
-  a->Bind(kEmptyAddr);
-
-  AsyncSocket* b = ss_->CreateAsyncSocket(SOCK_STREAM);
-  sink.Monitor(b);
-  b->Bind(kEmptyAddr);
-
-  EXPECT_EQ(0, a->Connect(b->GetLocalAddress()));
-  EXPECT_EQ(0, b->Connect(a->GetLocalAddress()));
-
-  ss_->ProcessMessagesUntilIdle();
-
-  const size_t kBufferSize = 2000;
-  ss_->set_send_buffer_capacity(kBufferSize);
-  ss_->set_recv_buffer_capacity(kBufferSize);
-
-  const size_t kDataSize = 5000;
-  char send_buffer[kDataSize], recv_buffer[kDataSize];
-  for (size_t i = 0; i < kDataSize; ++i) send_buffer[i] = i;
-  memset(recv_buffer, 0, sizeof(recv_buffer));
-  size_t send_pos = 0, recv_pos = 0;
-
-  // Can't send more than send buffer in one write
-  int result = a->Send(send_buffer + send_pos, kDataSize - send_pos);
-  EXPECT_EQ(static_cast<int>(kBufferSize), result);
-  send_pos += result;
-
-  ss_->ProcessMessagesUntilIdle();
-  EXPECT_FALSE(sink.Check(a, testing::SSE_WRITE));
-  EXPECT_TRUE(sink.Check(b, testing::SSE_READ));
-
-  // Receive buffer is already filled, fill send buffer again
-  result = a->Send(send_buffer + send_pos, kDataSize - send_pos);
-  EXPECT_EQ(static_cast<int>(kBufferSize), result);
-  send_pos += result;
-
-  ss_->ProcessMessagesUntilIdle();
-  EXPECT_FALSE(sink.Check(a, testing::SSE_WRITE));
-  EXPECT_FALSE(sink.Check(b, testing::SSE_READ));
-
-  // No more room in send or receive buffer
-  result = a->Send(send_buffer + send_pos, kDataSize - send_pos);
-  EXPECT_EQ(-1, result);
-  EXPECT_TRUE(a->IsBlocking());
-
-  // Read a subset of the data
-  result = b->Recv(recv_buffer + recv_pos, 500);
-  EXPECT_EQ(500, result);
-  recv_pos += result;
-
-  ss_->ProcessMessagesUntilIdle();
-  EXPECT_TRUE(sink.Check(a, testing::SSE_WRITE));
-  EXPECT_TRUE(sink.Check(b, testing::SSE_READ));
-
-  // Room for more on the sending side
-  result = a->Send(send_buffer + send_pos, kDataSize - send_pos);
-  EXPECT_EQ(500, result);
-  send_pos += result;
-
-  // Empty the recv buffer
-  while (true) {
-    result = b->Recv(recv_buffer + recv_pos, kDataSize - recv_pos);
-    if (result < 0) {
-      EXPECT_EQ(-1, result);
-      EXPECT_TRUE(b->IsBlocking());
-      break;
-    }
-    recv_pos += result;
-  }
-
-  ss_->ProcessMessagesUntilIdle();
-  EXPECT_TRUE(sink.Check(b, testing::SSE_READ));
-
-  // Continue to empty the recv buffer
-  while (true) {
-    result = b->Recv(recv_buffer + recv_pos, kDataSize - recv_pos);
-    if (result < 0) {
-      EXPECT_EQ(-1, result);
-      EXPECT_TRUE(b->IsBlocking());
-      break;
-    }
-    recv_pos += result;
-  }
-
-  // Send last of the data
-  result = a->Send(send_buffer + send_pos, kDataSize - send_pos);
-  EXPECT_EQ(500, result);
-  send_pos += result;
-
-  ss_->ProcessMessagesUntilIdle();
-  EXPECT_TRUE(sink.Check(b, testing::SSE_READ));
-
-  // Receive the last of the data
-  while (true) {
-    result = b->Recv(recv_buffer + recv_pos, kDataSize - recv_pos);
-    if (result < 0) {
-      EXPECT_EQ(-1, result);
-      EXPECT_TRUE(b->IsBlocking());
-      break;
-    }
-    recv_pos += result;
-  }
-
-  ss_->ProcessMessagesUntilIdle();
-  EXPECT_FALSE(sink.Check(b, testing::SSE_READ));
-
-  // The received data matches the sent data
-  EXPECT_EQ(kDataSize, send_pos);
-  EXPECT_EQ(kDataSize, recv_pos);
-  EXPECT_EQ(0, memcmp(recv_buffer, send_buffer, kDataSize));
-}
-
-TEST_F(VirtualSocketServerTest, CreatesStandardDistribution) {
-  const uint32 kTestMean[] = { 10, 100, 333, 1000 };
-  const double kTestDev[] = { 0.25, 0.1, 0.01 };
-  // TODO: The current code only works for 1000 data points or more.
-  const uint32 kTestSamples[] = { /*10, 100,*/ 1000 };
-  for (size_t midx = 0; midx < ARRAY_SIZE(kTestMean); ++midx) {
-    for (size_t didx = 0; didx < ARRAY_SIZE(kTestDev); ++didx) {
-      for (size_t sidx = 0; sidx < ARRAY_SIZE(kTestSamples); ++sidx) {
-        ASSERT_LT(0u, kTestSamples[sidx]);
-        const uint32 kStdDev =
-            static_cast<uint32>(kTestDev[didx] * kTestMean[midx]);
-        VirtualSocketServer::Function* f =
-            VirtualSocketServer::CreateDistribution(kTestMean[midx],
-                                                    kStdDev,
-                                                    kTestSamples[sidx]);
-        ASSERT_TRUE(NULL != f);
-        ASSERT_EQ(kTestSamples[sidx], f->size());
-        double sum = 0;
-        for (uint32 i = 0; i < f->size(); ++i) {
-          sum += (*f)[i].second;
-        }
-        const double mean = sum / f->size();
-        double sum_sq_dev = 0;
-        for (uint32 i = 0; i < f->size(); ++i) {
-          double dev = (*f)[i].second - mean;
-          sum_sq_dev += dev * dev;
-        }
-        const double stddev = std::sqrt(sum_sq_dev / f->size());
-        EXPECT_NEAR(kTestMean[midx], mean, 0.1 * kTestMean[midx])
-          << "M=" << kTestMean[midx]
-          << " SD=" << kStdDev
-          << " N=" << kTestSamples[sidx];
-        EXPECT_NEAR(kStdDev, stddev, 0.1 * kStdDev)
-          << "M=" << kTestMean[midx]
-          << " SD=" << kStdDev
-          << " N=" << kTestSamples[sidx];
-        delete f;
-      }
-    }
-  }
-}
-
-TEST_F(VirtualSocketServerTest, TcpSendsPacketsInOrder) {
-  const SocketAddress kEmptyAddr;
-
-  // Connect two sockets
-  AsyncSocket* a = ss_->CreateAsyncSocket(SOCK_STREAM);
-  AsyncSocket* b = ss_->CreateAsyncSocket(SOCK_STREAM);
-  a->Bind(kEmptyAddr);
-  b->Bind(kEmptyAddr);
-  EXPECT_EQ(0, a->Connect(b->GetLocalAddress()));
-  EXPECT_EQ(0, b->Connect(a->GetLocalAddress()));
-  ss_->ProcessMessagesUntilIdle();
-
-  // First, deliver all packets in 0 ms.
-  char buffer[2] = { 0, 0 };
-  const size_t cNumPackets = 10;
-  for (size_t i = 0; i < cNumPackets; ++i) {
-    buffer[0] = '0' + i;
-    EXPECT_EQ(1, a->Send(buffer, 1));
-  }
-
-  ss_->ProcessMessagesUntilIdle();
-
-  for (size_t i = 0; i < cNumPackets; ++i) {
-    EXPECT_EQ(1, b->Recv(buffer, sizeof(buffer)));
-    EXPECT_EQ(static_cast<char>('0' + i), buffer[0]);
-  }
-
-  // Next, deliver packets at random intervals
-  const uint32 mean = 50;
-  const uint32 stddev = 50;
-
-  ss_->set_delay_mean(mean);
-  ss_->set_delay_stddev(stddev);
-  ss_->UpdateDelayDistribution();
-
-  for (size_t i = 0; i < cNumPackets; ++i) {
-    buffer[0] = 'A' + i;
-    EXPECT_EQ(1, a->Send(buffer, 1));
-  }
-
-  ss_->ProcessMessagesUntilIdle();
-
-  for (size_t i = 0; i < cNumPackets; ++i) {
-    EXPECT_EQ(1, b->Recv(buffer, sizeof(buffer)));
-    EXPECT_EQ(static_cast<char>('A' + i), buffer[0]);
-  }
-}
-
-// Sends at a constant rate but with random packet sizes.
-struct Sender : public MessageHandler {
-  Sender(Thread* th, AsyncSocket* s, uint32 rt)
-      : thread(th), socket(new AsyncUDPSocket(s)),
-        done(false), rate(rt), count(0) {
-    last_send = Time();
-    thread->PostDelayed(NextDelay(), this, 1);
-  }
-
-  uint32 NextDelay() {
-    uint32 size = (rand() % 4096) + 1;
-    return 1000 * size / rate;
-  }
-
-  void OnMessage(Message* pmsg) {
-    ASSERT_EQ(1u, pmsg->message_id);
-
-    if (done)
-      return;
-
-    uint32 cur_time = Time();
-    uint32 delay = cur_time - last_send;
-    uint32 size = rate * delay / 1000;
-    size = std::min<uint32>(size, 4096);
-    size = std::max<uint32>(size, sizeof(uint32));
-
-    count += size;
-    memcpy(dummy, &cur_time, sizeof(cur_time));
-    socket->Send(dummy, size);
-
-    last_send = cur_time;
-    thread->PostDelayed(NextDelay(), this, 1);
-  }
-
-  Thread* thread;
-  scoped_ptr<AsyncUDPSocket> socket;
-  bool done;
-  uint32 rate;  // bytes per second
-  uint32 count;
-  uint32 last_send;
-  char dummy[4096];
-};
-
-struct Receiver : public MessageHandler, public sigslot::has_slots<> {
-  Receiver(Thread* th, AsyncSocket* s, uint32 bw)
-      : thread(th), socket(new AsyncUDPSocket(s)), bandwidth(bw), done(false),
-        count(0), sec_count(0), sum(0), sum_sq(0), samples(0) {
-    socket->SignalReadPacket.connect(this, &Receiver::OnReadPacket);
-    thread->PostDelayed(1000, this, 1);
-  }
-
-  ~Receiver() {
-    thread->Clear(this);
-  }
-
-  void OnReadPacket(AsyncPacketSocket* s, const char* data, size_t size,
-                    const SocketAddress& remote_addr) {
-    ASSERT_EQ(socket.get(), s);
-    ASSERT_GE(size, 4U);
-
-    count += size;
-    sec_count += size;
-
-    uint32 send_time = *reinterpret_cast<const uint32*>(data);
-    uint32 recv_time = Time();
-    uint32 delay = recv_time - send_time;
-    sum += delay;
-    sum_sq += delay * delay;
-    samples += 1;
-  }
-
-  void OnMessage(Message* pmsg) {
-    ASSERT_EQ(1u, pmsg->message_id);
-
-    if (done)
-      return;
-
-    // It is always possible for us to receive more than expected because
-    // packets can be further delayed in delivery.
-    if (bandwidth > 0)
-      ASSERT_TRUE(sec_count <= 5 * bandwidth / 4);
-    sec_count = 0;
-    thread->PostDelayed(1000, this, 1);
-  }
-
-  Thread* thread;
-  scoped_ptr<AsyncUDPSocket> socket;
-  uint32 bandwidth;
-  bool done;
-  uint32 count;
-  uint32 sec_count;
-  double sum;
-  double sum_sq;
-  uint32 samples;
-};
-
-TEST_F(VirtualSocketServerTest, bandwidth) {
-  AsyncSocket* send_socket = ss_->CreateAsyncSocket(SOCK_DGRAM);
-  AsyncSocket* recv_socket = ss_->CreateAsyncSocket(SOCK_DGRAM);
-  ASSERT_EQ(0, send_socket->Bind(SocketAddress(IPAddress(INADDR_ANY), 1000)));
-  ASSERT_EQ(0, recv_socket->Bind(SocketAddress(IPAddress(INADDR_ANY), 1000)));
-  ASSERT_EQ(0, send_socket->Connect(recv_socket->GetLocalAddress()));
-
-  uint32 bandwidth = 64 * 1024;
-  ss_->set_bandwidth(bandwidth);
-
-  Thread* pthMain = Thread::Current();
-  Sender sender(pthMain, send_socket, 80 * 1024);
-  Receiver receiver(pthMain, recv_socket, bandwidth);
-
-  pthMain->ProcessMessages(5000);
-  sender.done = true;
-  pthMain->ProcessMessages(5000);
-
-  ASSERT_TRUE(receiver.count >= 5 * 3 * bandwidth / 4);
-  ASSERT_TRUE(receiver.count <= 6 * bandwidth);  // queue could drain for 1 sec
-
-  ss_->set_bandwidth(0);
-}
-
-TEST_F(VirtualSocketServerTest, delay) {
-  time_t seed = ::time(NULL);
-  LOG(LS_VERBOSE) << "seed = " << seed;
-  srand(seed);
-
-  const uint32 mean = 2000;
-  const uint32 stddev = 500;
-
-  ss_->set_delay_mean(mean);
-  ss_->set_delay_stddev(stddev);
-  ss_->UpdateDelayDistribution();
-
-  AsyncSocket* send_socket = ss_->CreateAsyncSocket(SOCK_DGRAM);
-  AsyncSocket* recv_socket = ss_->CreateAsyncSocket(SOCK_DGRAM);
-  ASSERT_EQ(0, send_socket->Bind(SocketAddress(IPAddress(INADDR_ANY), 1000)));
-  ASSERT_EQ(0, recv_socket->Bind(SocketAddress(IPAddress(INADDR_ANY), 1000)));
-  ASSERT_EQ(0, send_socket->Connect(recv_socket->GetLocalAddress()));
-
-  Thread* pthMain = Thread::Current();
-  // Avg packet size is 2K, so at 200KB/s for 10s, we should see about
-  // 1000 packets, which is necessary to get a good distribution.
-  Sender sender(pthMain, send_socket, 100 * 2 * 1024);
-  Receiver receiver(pthMain, recv_socket, 0);
-
-  pthMain->ProcessMessages(10000);
-  sender.done = receiver.done = true;
-  ss_->ProcessMessagesUntilIdle();
-
-  const double sample_mean = receiver.sum / receiver.samples;
-  double num = receiver.samples * receiver.sum_sq - receiver.sum * receiver.sum;
-  double den = receiver.samples * (receiver.samples - 1);
-  const double sample_stddev = std::sqrt(num / den);
-  LOG(LS_VERBOSE) << "mean=" << sample_mean << " stddev=" << sample_stddev;
-
-  EXPECT_LE(500u, receiver.samples);
-  // We initially used a 0.1 fudge factor, but on the build machine, we
-  // have seen the value differ by as much as 0.13.
-  EXPECT_NEAR(mean, sample_mean, 0.15 * mean);
-  EXPECT_NEAR(stddev, sample_stddev, 0.15 * stddev);
-
-  ss_->set_delay_mean(0);
-  ss_->set_delay_stddev(0);
-  ss_->UpdateDelayDistribution();
-}
diff --git a/third_party/libjingle/source/talk/base/virtualsocketserver.cc b/third_party/libjingle/source/talk/base/virtualsocketserver.cc
deleted file mode 100644
index c9c9f0b..0000000
--- a/third_party/libjingle/source/talk/base/virtualsocketserver.cc
+++ /dev/null
@@ -1,982 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/virtualsocketserver.h"
-
-#include <errno.h>
-
-#include <algorithm>
-#include <cmath>
-#include <map>
-#include <vector>
-
-#include "talk/base/common.h"
-#include "talk/base/logging.h"
-#include "talk/base/physicalsocketserver.h"
-#include "talk/base/socketaddresspair.h"
-#include "talk/base/thread.h"
-#include "talk/base/timeutils.h"
-
-namespace talk_base {
-
-const uint16 kFirstEphemeralPort = 49152;
-const uint16 kLastEphemeralPort = 65535;
-const uint16 kEphemeralPortCount = kLastEphemeralPort - kFirstEphemeralPort + 1;
-const uint32 kDefaultNetworkCapacity = 64 * 1024;
-const uint32 kDefaultTcpBufferSize = 32 * 1024;
-
-const uint32 UDP_HEADER_SIZE = 28;  // IP + UDP headers
-const uint32 TCP_HEADER_SIZE = 40;  // IP + TCP headers
-const uint32 TCP_MSS = 1400;  // Maximum segment size
-
-// Note: The current algorithm doesn't work for sample sizes smaller than this.
-const int NUM_SAMPLES = 1000;
-
-enum {
-  MSG_ID_PACKET,
-  MSG_ID_CONNECT,
-  MSG_ID_DISCONNECT,
-};
-
-// Packets are passed between sockets as messages.  We copy the data just like
-// the kernel does.
-class Packet : public MessageData {
- public:
-  Packet(const char* data, size_t size, const SocketAddress& from)
-        : size_(size), consumed_(0), from_(from) {
-    ASSERT(NULL != data);
-    data_ = new char[size_];
-    std::memcpy(data_, data, size_);
-  }
-
-  virtual ~Packet() {
-    delete[] data_;
-  }
-
-  const char* data() const { return data_ + consumed_; }
-  size_t size() const { return size_ - consumed_; }
-  const SocketAddress& from() const { return from_; }
-
-  // Remove the first size bytes from the data.
-  void Consume(size_t size) {
-    ASSERT(size + consumed_ < size_);
-    consumed_ += size;
-  }
-
- private:
-  char* data_;
-  size_t size_, consumed_;
-  SocketAddress from_;
-};
-
-struct MessageAddress : public MessageData {
-  explicit MessageAddress(const SocketAddress& a) : addr(a) { }
-  SocketAddress addr;
-};
-
-// Implements the socket interface using the virtual network.  Packets are
-// passed as messages using the message queue of the socket server.
-class VirtualSocket : public AsyncSocket, public MessageHandler {
- public:
-  VirtualSocket(VirtualSocketServer* server, int type, bool async)
-      : server_(server), type_(type), async_(async), state_(CS_CLOSED),
-        listen_queue_(NULL), write_enabled_(false), network_size_(0),
-        recv_buffer_size_(0), bound_(false) {
-    ASSERT((type_ == SOCK_DGRAM) || (type_ == SOCK_STREAM));
-    ASSERT(async_ || (type_ != SOCK_STREAM));  // We only support async streams
-  }
-
-  virtual ~VirtualSocket() {
-    Close();
-
-    for (RecvBuffer::iterator it = recv_buffer_.begin();
-         it != recv_buffer_.end(); ++it) {
-      delete *it;
-    }
-  }
-
-  virtual SocketAddress GetLocalAddress() const {
-    return local_addr_;
-  }
-
-  virtual SocketAddress GetRemoteAddress() const {
-    return remote_addr_;
-  }
-
-  // Used by server sockets to set the local address without binding.
-  void SetLocalAddress(const SocketAddress& addr) {
-    local_addr_ = addr;
-  }
-
-  virtual int Bind(const SocketAddress& addr) {
-    if (!local_addr_.IsAny()) {
-      error_ = EINVAL;
-      return -1;
-    }
-    local_addr_ = addr;
-    int result = server_->Bind(this, &local_addr_);
-    if (result != 0) {
-      local_addr_.Clear();
-      error_ = EADDRINUSE;
-    } else {
-      bound_ = true;
-    }
-    return result;
-  }
-
-  virtual int Connect(const SocketAddress& addr) {
-    return InitiateConnect(addr, true);
-  }
-
-  virtual int Close() {
-    if (!local_addr_.IsAny() && bound_) {
-      // Remove from the binding table.
-      server_->Unbind(local_addr_, this);
-      bound_ = false;
-    }
-
-    if (SOCK_STREAM == type_) {
-      // Cancel pending sockets
-      if (listen_queue_) {
-        while (!listen_queue_->empty()) {
-          SocketAddress addr = listen_queue_->front();
-
-          // Disconnect listening socket.
-          server_->Disconnect(server_->LookupBinding(addr));
-          listen_queue_->pop_front();
-        }
-        delete listen_queue_;
-        listen_queue_ = NULL;
-      }
-      // Disconnect stream sockets
-      if (CS_CONNECTED == state_) {
-        // Disconnect remote socket, check if it is a child of a server socket.
-        VirtualSocket* socket =
-            server_->LookupConnection(local_addr_, remote_addr_);
-        if (!socket) {
-          // Not a server socket child, then see if it is bound.
-          // TODO: If this is indeed a server socket that has no
-          // children this will cause the server socket to be
-          // closed. This might lead to unexpected results, how to fix this?
-          socket = server_->LookupBinding(remote_addr_);
-        }
-        server_->Disconnect(socket);
-
-        // Remove mapping for both directions.
-        server_->RemoveConnection(remote_addr_, local_addr_);
-        server_->RemoveConnection(local_addr_, remote_addr_);
-      }
-      // Cancel potential connects
-      MessageList msgs;
-      if (server_->msg_queue_) {
-        server_->msg_queue_->Clear(this, MSG_ID_CONNECT, &msgs);
-      }
-      for (MessageList::iterator it = msgs.begin(); it != msgs.end(); ++it) {
-        ASSERT(NULL != it->pdata);
-        MessageAddress* data = static_cast<MessageAddress*>(it->pdata);
-
-        // Lookup remote side.
-        VirtualSocket* socket = server_->LookupConnection(local_addr_,
-                                                          data->addr);
-        if (socket) {
-          // Server socket, remote side is a socket retreived by
-          // accept. Accepted sockets are not bound so we will not
-          // find it by looking in the bindings table.
-          server_->Disconnect(socket);
-          server_->RemoveConnection(local_addr_, data->addr);
-        } else {
-          server_->Disconnect(server_->LookupBinding(data->addr));
-        }
-        delete data;
-      }
-      // Clear incoming packets and disconnect messages
-      if (server_->msg_queue_) {
-        server_->msg_queue_->Clear(this);
-      }
-    }
-
-    state_ = CS_CLOSED;
-    local_addr_.Clear();
-    remote_addr_.Clear();
-    return 0;
-  }
-
-  virtual int Send(const void *pv, size_t cb) {
-    if (CS_CONNECTED != state_) {
-      error_ = ENOTCONN;
-      return -1;
-    }
-    if (SOCK_DGRAM == type_) {
-      return SendUdp(pv, cb, remote_addr_);
-    } else {
-      return SendTcp(pv, cb);
-    }
-  }
-
-  virtual int SendTo(const void *pv, size_t cb, const SocketAddress& addr) {
-    if (SOCK_DGRAM == type_) {
-      return SendUdp(pv, cb, addr);
-    } else {
-      if (CS_CONNECTED != state_) {
-        error_ = ENOTCONN;
-        return -1;
-      }
-      return SendTcp(pv, cb);
-    }
-  }
-
-  virtual int Recv(void *pv, size_t cb) {
-    SocketAddress addr;
-    return RecvFrom(pv, cb, &addr);
-  }
-
-  virtual int RecvFrom(void *pv, size_t cb, SocketAddress *paddr) {
-    // If we don't have a packet, then either error or wait for one to arrive.
-    if (recv_buffer_.empty()) {
-      if (async_) {
-        error_ = EAGAIN;
-        return -1;
-      }
-      while (recv_buffer_.empty()) {
-        Message msg;
-        server_->msg_queue_->Get(&msg);
-        server_->msg_queue_->Dispatch(&msg);
-      }
-    }
-
-    // Return the packet at the front of the queue.
-    Packet* packet = recv_buffer_.front();
-    size_t data_read = _min(cb, packet->size());
-    std::memcpy(pv, packet->data(), data_read);
-    *paddr = packet->from();
-
-    if (data_read < packet->size()) {
-      packet->Consume(data_read);
-    } else {
-      recv_buffer_.pop_front();
-      delete packet;
-    }
-
-    if (SOCK_STREAM == type_) {
-      bool was_full = (recv_buffer_size_ == server_->recv_buffer_capacity_);
-      recv_buffer_size_ -= data_read;
-      if (was_full) {
-        VirtualSocket* sender = server_->LookupBinding(remote_addr_);
-        ASSERT(NULL != sender);
-        server_->SendTcp(sender);
-      }
-    }
-
-    return static_cast<int>(data_read);
-  }
-
-  virtual int Listen(int backlog) {
-    ASSERT(SOCK_STREAM == type_);
-    ASSERT(CS_CLOSED == state_);
-    if (local_addr_.IsAny()) {
-      error_ = EINVAL;
-      return -1;
-    }
-    ASSERT(NULL == listen_queue_);
-    listen_queue_ = new ListenQueue;
-    state_ = CS_CONNECTING;
-    return 0;
-  }
-
-  virtual VirtualSocket* Accept(SocketAddress *paddr) {
-    if (NULL == listen_queue_) {
-      error_ = EINVAL;
-      return NULL;
-    }
-    while (!listen_queue_->empty()) {
-      VirtualSocket* socket = new VirtualSocket(server_, type_, async_);
-
-      // Set the new local address to the same as this server socket.
-      socket->SetLocalAddress(local_addr_);
-      SocketAddress remote_addr(listen_queue_->front());
-      int result = socket->InitiateConnect(remote_addr, false);
-      listen_queue_->pop_front();
-      if (result != 0) {
-        delete socket;
-        continue;
-      }
-      socket->CompleteConnect(remote_addr, false);
-      if (paddr) {
-        *paddr = remote_addr;
-      }
-      return socket;
-    }
-    error_ = EWOULDBLOCK;
-    return NULL;
-  }
-
-  virtual int GetError() const {
-    return error_;
-  }
-
-  virtual void SetError(int error) {
-    error_ = error;
-  }
-
-  virtual ConnState GetState() const {
-    return state_;
-  }
-
-  virtual int GetOption(Option opt, int* value) {
-    OptionsMap::const_iterator it = options_map_.find(opt);
-    if (it == options_map_.end()) {
-      return -1;
-    }
-    *value = it->second;
-    return 0;  // 0 is success to emulate getsockopt()
-  }
-
-  virtual int SetOption(Option opt, int value) {
-    options_map_[opt] = value;
-    return 0;  // 0 is success to emulate setsockopt()
-  }
-
-  virtual int EstimateMTU(uint16* mtu) {
-    if (CS_CONNECTED != state_)
-      return ENOTCONN;
-    else
-      return 65536;
-  }
-
-  void OnMessage(Message *pmsg) {
-    if (pmsg->message_id == MSG_ID_PACKET) {
-      //ASSERT(!local_addr_.IsAny());
-      ASSERT(NULL != pmsg->pdata);
-      Packet* packet = static_cast<Packet*>(pmsg->pdata);
-
-      recv_buffer_.push_back(packet);
-
-      if (async_) {
-        SignalReadEvent(this);
-      }
-    } else if (pmsg->message_id == MSG_ID_CONNECT) {
-      ASSERT(NULL != pmsg->pdata);
-      MessageAddress* data = static_cast<MessageAddress*>(pmsg->pdata);
-      if (listen_queue_ != NULL) {
-        listen_queue_->push_back(data->addr);
-        if (async_) {
-          SignalReadEvent(this);
-        }
-      } else if ((SOCK_STREAM == type_) && (CS_CONNECTING == state_)) {
-        CompleteConnect(data->addr, true);
-      } else {
-        LOG(LS_VERBOSE) << "Socket at " << local_addr_ << " is not listening";
-        server_->Disconnect(server_->LookupBinding(data->addr));
-      }
-      delete data;
-    } else if (pmsg->message_id == MSG_ID_DISCONNECT) {
-      ASSERT(SOCK_STREAM == type_);
-      if (CS_CLOSED != state_) {
-        int error = (CS_CONNECTING == state_) ? ECONNREFUSED : 0;
-        state_ = CS_CLOSED;
-        remote_addr_.Clear();
-        if (async_) {
-          SignalCloseEvent(this, error);
-        }
-      }
-    } else {
-      ASSERT(false);
-    }
-  }
-
- private:
-  struct NetworkEntry {
-    uint32 size;
-    uint32 done_time;
-  };
-
-  typedef std::deque<SocketAddress> ListenQueue;
-  typedef std::deque<NetworkEntry> NetworkQueue;
-  typedef std::vector<char> SendBuffer;
-  typedef std::list<Packet*> RecvBuffer;
-  typedef std::map<Option, int> OptionsMap;
-
-  int InitiateConnect(const SocketAddress& addr, bool use_delay) {
-    if (!remote_addr_.IsAny()) {
-      error_ = (CS_CONNECTED == state_) ? EISCONN : EINPROGRESS;
-      return -1;
-    }
-    if (local_addr_.IsAny()) {
-      int result = Bind(SocketAddress());
-      if (result != 0) {
-        return result;
-      }
-    }
-    if (type_ == SOCK_DGRAM) {
-      remote_addr_ = addr;
-      state_ = CS_CONNECTED;
-    } else {
-      int result = server_->Connect(this, addr, use_delay);
-      if (result != 0) {
-        error_ = EHOSTUNREACH;
-        return -1;
-      }
-      state_ = CS_CONNECTING;
-    }
-    return 0;
-  }
-
-  void CompleteConnect(const SocketAddress& addr, bool notify) {
-    ASSERT(CS_CONNECTING == state_);
-    remote_addr_ = addr;
-    state_ = CS_CONNECTED;
-    server_->AddConnection(remote_addr_, local_addr_, this);
-    if (async_ && notify) {
-      SignalConnectEvent(this);
-    }
-  }
-
-  int SendUdp(const void* pv, size_t cb, const SocketAddress& addr) {
-    // If we have not been assigned a local port, then get one.
-    if (local_addr_.IsAny()) {
-      int result = server_->Bind(this, &local_addr_);
-      if (result != 0) {
-        local_addr_.Clear();
-        error_ = EADDRINUSE;
-        return result;
-      }
-    }
-
-    // Send the data in a message to the appropriate socket.
-    return server_->SendUdp(this, static_cast<const char*>(pv), cb, addr);
-  }
-
-  int SendTcp(const void* pv, size_t cb) {
-    size_t capacity = server_->send_buffer_capacity_ - send_buffer_.size();
-    if (0 == capacity) {
-      write_enabled_ = true;
-      error_ = EWOULDBLOCK;
-      return -1;
-    }
-    size_t consumed = _min(cb, capacity);
-    const char* cpv = static_cast<const char*>(pv);
-    send_buffer_.insert(send_buffer_.end(), cpv, cpv + consumed);
-    server_->SendTcp(this);
-    return consumed;
-  }
-
-  VirtualSocketServer* server_;
-  int type_;
-  bool async_;
-  ConnState state_;
-  int error_;
-  SocketAddress local_addr_;
-  SocketAddress remote_addr_;
-
-  // Pending sockets which can be Accepted
-  ListenQueue* listen_queue_;
-
-  // Data which tcp has buffered for sending
-  SendBuffer send_buffer_;
-  bool write_enabled_;
-
-  // Critical section to protect the recv_buffer and queue_
-  CriticalSection crit_;
-
-  // Network model that enforces bandwidth and capacity constraints
-  NetworkQueue network_;
-  uint32 network_size_;
-
-  // Data which has been received from the network
-  RecvBuffer recv_buffer_;
-  // The amount of data which is in flight or in recv_buffer_
-  uint32 recv_buffer_size_;
-
-  // Is this socket bound?
-  bool bound_;
-
-  // Store the options that are set
-  OptionsMap options_map_;
-
-  friend class VirtualSocketServer;
-};
-
-VirtualSocketServer::VirtualSocketServer(SocketServer* ss)
-    : server_(ss), server_owned_(false), msg_queue_(NULL), stop_on_idle_(false),
-      network_delay_(Time()), next_ip_(1), next_port_(kFirstEphemeralPort),
-      bindings_(new AddressMap()), connections_(new ConnectionMap()),
-      bandwidth_(0), network_capacity_(kDefaultNetworkCapacity),
-      send_buffer_capacity_(kDefaultTcpBufferSize),
-      recv_buffer_capacity_(kDefaultTcpBufferSize),
-      delay_mean_(0), delay_stddev_(0), delay_samples_(NUM_SAMPLES),
-      delay_dist_(NULL), drop_prob_(0.0) {
-  if (!server_) {
-    server_ = new PhysicalSocketServer();
-    server_owned_ = true;
-  }
-  UpdateDelayDistribution();
-}
-
-VirtualSocketServer::~VirtualSocketServer() {
-  delete bindings_;
-  delete connections_;
-  delete delay_dist_;
-  if (server_owned_) {
-    delete server_;
-  }
-}
-
-uint32 VirtualSocketServer::GetNextIP() {
-  return next_ip_++;
-}
-
-uint16 VirtualSocketServer::GetNextPort() {
-  uint16 port = next_port_;
-  if (next_port_ < kLastEphemeralPort) {
-    ++next_port_;
-  } else {
-    next_port_ = kFirstEphemeralPort;
-  }
-  return port;
-}
-
-Socket* VirtualSocketServer::CreateSocket(int type) {
-  return CreateSocketInternal(type);
-}
-
-AsyncSocket* VirtualSocketServer::CreateAsyncSocket(int type) {
-  return CreateSocketInternal(type);
-}
-
-VirtualSocket* VirtualSocketServer::CreateSocketInternal(int type) {
-  return new VirtualSocket(this, type, true);
-}
-
-void VirtualSocketServer::SetMessageQueue(MessageQueue* msg_queue) {
-  msg_queue_ = msg_queue;
-  if (msg_queue_) {
-    msg_queue_->SignalQueueDestroyed.connect(this,
-        &VirtualSocketServer::OnMessageQueueDestroyed);
-  }
-}
-
-bool VirtualSocketServer::Wait(int cmsWait, bool process_io) {
-  ASSERT(msg_queue_ == Thread::Current());
-  if (stop_on_idle_ && Thread::Current()->empty()) {
-    return false;
-  }
-  return socketserver()->Wait(cmsWait, process_io);
-}
-
-void VirtualSocketServer::WakeUp() {
-  socketserver()->WakeUp();
-}
-
-bool VirtualSocketServer::ProcessMessagesUntilIdle() {
-  ASSERT(msg_queue_ == Thread::Current());
-  stop_on_idle_ = true;
-  while (!msg_queue_->empty()) {
-    Message msg;
-    if (msg_queue_->Get(&msg, kForever)) {
-      msg_queue_->Dispatch(&msg);
-    }
-  }
-  stop_on_idle_ = false;
-  return !msg_queue_->IsQuitting();
-}
-
-int VirtualSocketServer::Bind(VirtualSocket* socket,
-                              const SocketAddress& addr) {
-  ASSERT(NULL != socket);
-  // Address must be completely specified at this point
-  ASSERT(!IPIsAny(addr.ipaddr()));
-  ASSERT(addr.port() != 0);
-
-  AddressMap::value_type entry(addr, socket);
-  return bindings_->insert(entry).second ? 0 : -1;
-}
-
-int VirtualSocketServer::Bind(VirtualSocket* socket, SocketAddress* addr) {
-  ASSERT(NULL != socket);
-
-  if (IPIsAny(addr->ipaddr())) {
-    // TODO: An IPv6-ish version of this?
-    addr->SetIP(IPAddress(GetNextIP()));
-  }
-
-  if (addr->port() == 0) {
-    for (int i = 0; i < kEphemeralPortCount; ++i) {
-      addr->SetPort(GetNextPort());
-      if (bindings_->find(*addr) == bindings_->end()) {
-        break;
-      }
-    }
-  }
-
-  return Bind(socket, *addr);
-}
-
-VirtualSocket* VirtualSocketServer::LookupBinding(const SocketAddress& addr) {
-  AddressMap::iterator it = bindings_->find(addr);
-  return (bindings_->end() != it) ? it->second : NULL;
-}
-
-int VirtualSocketServer::Unbind(const SocketAddress& addr,
-                                VirtualSocket* socket) {
-  ASSERT((*bindings_)[addr] == socket);
-  bindings_->erase(bindings_->find(addr));
-  return 0;
-}
-
-void VirtualSocketServer::AddConnection(const SocketAddress& local,
-                                        const SocketAddress& remote,
-                                        VirtualSocket* remote_socket) {
-  // Add this socket pair to our routing table. This will allow
-  // multiple clients to connect to the same server address.
-  SocketAddressPair address_pair(local, remote);
-  connections_->insert(std::pair<SocketAddressPair,
-                       VirtualSocket*>(address_pair, remote_socket));
-}
-
-VirtualSocket* VirtualSocketServer::LookupConnection(
-    const SocketAddress& local,
-    const SocketAddress& remote) {
-  SocketAddressPair address_pair(local, remote);
-  ConnectionMap::iterator it = connections_->find(address_pair);
-  return (connections_->end() != it) ? it->second : NULL;
-}
-
-void VirtualSocketServer::RemoveConnection(const SocketAddress& local,
-                                           const SocketAddress& remote) {
-  SocketAddressPair address_pair(local, remote);
-  connections_->erase(address_pair);
-}
-
-static double Random() {
-  return static_cast<double>(rand()) / RAND_MAX;
-}
-
-int VirtualSocketServer::Connect(VirtualSocket* socket,
-                                 const SocketAddress& remote_addr,
-                                 bool use_delay) {
-  uint32 delay = use_delay ? GetRandomTransitDelay() : 0;
-  if (VirtualSocket* remote = LookupBinding(remote_addr)) {
-    SocketAddress addr = socket->GetLocalAddress();
-    msg_queue_->PostDelayed(delay, remote, MSG_ID_CONNECT,
-                            new MessageAddress(addr));
-  } else {
-    LOG(LS_INFO) << "No one listening at " << remote_addr;
-    msg_queue_->PostDelayed(delay, socket, MSG_ID_DISCONNECT);
-  }
-  return 0;
-}
-
-bool VirtualSocketServer::Disconnect(VirtualSocket* socket) {
-  if (socket) {
-    // Remove the mapping.
-    msg_queue_->Post(socket, MSG_ID_DISCONNECT);
-    return true;
-  }
-  return false;
-}
-
-int VirtualSocketServer::SendUdp(VirtualSocket* socket,
-                                 const char* data, size_t data_size,
-                                 const SocketAddress& remote_addr) {
-  // See if we want to drop this packet.
-  if (Random() < drop_prob_) {
-    LOG(LS_VERBOSE) << "Dropping packet: bad luck";
-    return static_cast<int>(data_size);
-  }
-
-  VirtualSocket* recipient = LookupBinding(remote_addr);
-  if (!recipient) {
-    LOG(LS_VERBOSE) << "No one listening at " << remote_addr;
-    return static_cast<int>(data_size);
-  }
-
-  CritScope cs(&socket->crit_);
-
-  uint32 cur_time = Time();
-  PurgeNetworkPackets(socket, cur_time);
-
-  // Determine whether we have enough bandwidth to accept this packet.  To do
-  // this, we need to update the send queue.  Once we know it's current size,
-  // we know whether we can fit this packet.
-  //
-  // NOTE: There are better algorithms for maintaining such a queue (such as
-  // "Derivative Random Drop"); however, this algorithm is a more accurate
-  // simulation of what a normal network would do.
-
-  size_t packet_size = data_size + UDP_HEADER_SIZE;
-  if (socket->network_size_ + packet_size > network_capacity_) {
-    LOG(LS_VERBOSE) << "Dropping packet: network capacity exceeded";
-    return static_cast<int>(data_size);
-  }
-
-  AddPacketToNetwork(socket, recipient, cur_time, data, data_size,
-                     UDP_HEADER_SIZE, false);
-
-  return static_cast<int>(data_size);
-}
-
-void VirtualSocketServer::SendTcp(VirtualSocket* socket) {
-  // TCP can't send more data than will fill up the receiver's buffer.
-  // We track the data that is in the buffer plus data in flight using the
-  // recipient's recv_buffer_size_.  Anything beyond that must be stored in the
-  // sender's buffer.  We will trigger the buffered data to be sent when data
-  // is read from the recv_buffer.
-
-  // Lookup the local/remote pair in the connections table.
-  VirtualSocket* recipient = LookupConnection(socket->local_addr_,
-                                              socket->remote_addr_);
-  if (!recipient) {
-    LOG(LS_VERBOSE) << "Sending data to no one.";
-    return;
-  }
-
-  CritScope cs(&socket->crit_);
-
-  uint32 cur_time = Time();
-  PurgeNetworkPackets(socket, cur_time);
-
-  while (true) {
-    size_t available = recv_buffer_capacity_ - recipient->recv_buffer_size_;
-    size_t max_data_size = _min<size_t>(available, TCP_MSS - TCP_HEADER_SIZE);
-    size_t data_size = _min(socket->send_buffer_.size(), max_data_size);
-    if (0 == data_size)
-      break;
-
-    AddPacketToNetwork(socket, recipient, cur_time, &socket->send_buffer_[0],
-                       data_size, TCP_HEADER_SIZE, true);
-    recipient->recv_buffer_size_ += data_size;
-
-    size_t new_buffer_size = socket->send_buffer_.size() - data_size;
-    // Avoid undefined access beyond the last element of the vector.
-    // This only happens when new_buffer_size is 0.
-    if (data_size < socket->send_buffer_.size()) {
-      // memmove is required for potentially overlapping source/destination.
-      memmove(&socket->send_buffer_[0], &socket->send_buffer_[data_size],
-              new_buffer_size);
-    }
-    socket->send_buffer_.resize(new_buffer_size);
-  }
-
-  if (socket->write_enabled_
-      && (socket->send_buffer_.size() < send_buffer_capacity_)) {
-    socket->write_enabled_ = false;
-    socket->SignalWriteEvent(socket);
-  }
-}
-
-void VirtualSocketServer::AddPacketToNetwork(VirtualSocket* sender,
-                                             VirtualSocket* recipient,
-                                             uint32 cur_time,
-                                             const char* data,
-                                             size_t data_size,
-                                             size_t header_size,
-                                             bool ordered) {
-  VirtualSocket::NetworkEntry entry;
-  entry.size = data_size + header_size;
-
-  sender->network_size_ += entry.size;
-  uint32 send_delay = SendDelay(sender->network_size_);
-  entry.done_time = cur_time + send_delay;
-  sender->network_.push_back(entry);
-
-  // Find the delay for crossing the many virtual hops of the network.
-  uint32 transit_delay = GetRandomTransitDelay();
-
-  // Post the packet as a message to be delivered (on our own thread)
-  Packet* p = new Packet(data, data_size, sender->local_addr_);
-  uint32 ts = TimeAfter(send_delay + transit_delay);
-  if (ordered) {
-    // Ensure that new packets arrive after previous ones
-    // TODO: consider ordering on a per-socket basis, since this
-    // introduces artifical delay.
-    ts = TimeMax(ts, network_delay_);
-  }
-  msg_queue_->PostAt(ts, recipient, MSG_ID_PACKET, p);
-  network_delay_ = TimeMax(ts, network_delay_);
-}
-
-void VirtualSocketServer::PurgeNetworkPackets(VirtualSocket* socket,
-                                              uint32 cur_time) {
-  while (!socket->network_.empty() &&
-         (socket->network_.front().done_time <= cur_time)) {
-    ASSERT(socket->network_size_ >= socket->network_.front().size);
-    socket->network_size_ -= socket->network_.front().size;
-    socket->network_.pop_front();
-  }
-}
-
-uint32 VirtualSocketServer::SendDelay(uint32 size) {
-  if (bandwidth_ == 0)
-    return 0;
-  else
-    return 1000 * size / bandwidth_;
-}
-
-#if 0
-void PrintFunction(std::vector<std::pair<double, double> >* f) {
-  return;
-  double sum = 0;
-  for (uint32 i = 0; i < f->size(); ++i) {
-    std::cout << (*f)[i].first << '\t' << (*f)[i].second << std::endl;
-    sum += (*f)[i].second;
-  }
-  if (!f->empty()) {
-    const double mean = sum / f->size();
-    double sum_sq_dev = 0;
-    for (uint32 i = 0; i < f->size(); ++i) {
-      double dev = (*f)[i].second - mean;
-      sum_sq_dev += dev * dev;
-    }
-    std::cout << "Mean = " << mean << " StdDev = "
-              << sqrt(sum_sq_dev / f->size()) << std::endl;
-  }
-}
-#endif  // <unused>
-
-void VirtualSocketServer::UpdateDelayDistribution() {
-  Function* dist = CreateDistribution(delay_mean_, delay_stddev_,
-                                      delay_samples_);
-  // We take a lock just to make sure we don't leak memory.
-  {
-    CritScope cs(&delay_crit_);
-    delete delay_dist_;
-    delay_dist_ = dist;
-  }
-}
-
-static double PI = 4 * std::atan(1.0);
-
-static double Normal(double x, double mean, double stddev) {
-  double a = (x - mean) * (x - mean) / (2 * stddev * stddev);
-  return std::exp(-a) / (stddev * sqrt(2 * PI));
-}
-
-#if 0  // static unused gives a warning
-static double Pareto(double x, double min, double k) {
-  if (x < min)
-    return 0;
-  else
-    return k * std::pow(min, k) / std::pow(x, k+1);
-}
-#endif
-
-VirtualSocketServer::Function* VirtualSocketServer::CreateDistribution(
-    uint32 mean, uint32 stddev, uint32 samples) {
-  Function* f = new Function();
-
-  if (0 == stddev) {
-    f->push_back(Point(mean, 1.0));
-  } else {
-    double start = 0;
-    if (mean >= 4 * static_cast<double>(stddev))
-      start = mean - 4 * static_cast<double>(stddev);
-    double end = mean + 4 * static_cast<double>(stddev);
-
-    for (uint32 i = 0; i < samples; i++) {
-      double x = start + (end - start) * i / (samples - 1);
-      double y = Normal(x, mean, stddev);
-      f->push_back(Point(x, y));
-    }
-  }
-  return Resample(Invert(Accumulate(f)), 0, 1, samples);
-}
-
-uint32 VirtualSocketServer::GetRandomTransitDelay() {
-  size_t index = rand() % delay_dist_->size();
-  double delay = (*delay_dist_)[index].second;
-  //LOG_F(LS_INFO) << "random[" << index << "] = " << delay;
-  return static_cast<uint32>(delay);
-}
-
-struct FunctionDomainCmp {
-  bool operator()(const VirtualSocketServer::Point& p1,
-                   const VirtualSocketServer::Point& p2) {
-    return p1.first < p2.first;
-  }
-  bool operator()(double v1, const VirtualSocketServer::Point& p2) {
-    return v1 < p2.first;
-  }
-  bool operator()(const VirtualSocketServer::Point& p1, double v2) {
-    return p1.first < v2;
-  }
-};
-
-VirtualSocketServer::Function* VirtualSocketServer::Accumulate(Function* f) {
-  ASSERT(f->size() >= 1);
-  double v = 0;
-  for (Function::size_type i = 0; i < f->size() - 1; ++i) {
-    double dx = (*f)[i + 1].first - (*f)[i].first;
-    double avgy = ((*f)[i + 1].second + (*f)[i].second) / 2;
-    (*f)[i].second = v;
-    v = v + dx * avgy;
-  }
-  (*f)[f->size()-1].second = v;
-  return f;
-}
-
-VirtualSocketServer::Function* VirtualSocketServer::Invert(Function* f) {
-  for (Function::size_type i = 0; i < f->size(); ++i)
-    std::swap((*f)[i].first, (*f)[i].second);
-
-  std::sort(f->begin(), f->end(), FunctionDomainCmp());
-  return f;
-}
-
-VirtualSocketServer::Function* VirtualSocketServer::Resample(
-    Function* f, double x1, double x2, uint32 samples) {
-  Function* g = new Function();
-
-  for (size_t i = 0; i < samples; i++) {
-    double x = x1 + (x2 - x1) * i / (samples - 1);
-    double y = Evaluate(f, x);
-    g->push_back(Point(x, y));
-  }
-
-  delete f;
-  return g;
-}
-
-double VirtualSocketServer::Evaluate(Function* f, double x) {
-  Function::iterator iter =
-      std::lower_bound(f->begin(), f->end(), x, FunctionDomainCmp());
-  if (iter == f->begin()) {
-    return (*f)[0].second;
-  } else if (iter == f->end()) {
-    ASSERT(f->size() >= 1);
-    return (*f)[f->size() - 1].second;
-  } else if (iter->first == x) {
-    return iter->second;
-  } else {
-    double x1 = (iter - 1)->first;
-    double y1 = (iter - 1)->second;
-    double x2 = iter->first;
-    double y2 = iter->second;
-    return y1 + (y2 - y1) * (x - x1) / (x2 - x1);
-  }
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/virtualsocketserver.h b/third_party/libjingle/source/talk/base/virtualsocketserver.h
deleted file mode 100644
index 239ea9b..0000000
--- a/third_party/libjingle/source/talk/base/virtualsocketserver.h
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_VIRTUALSOCKETSERVER_H_
-#define TALK_BASE_VIRTUALSOCKETSERVER_H_
-
-#include <cassert>
-#include <deque>
-#include <map>
-
-#include "talk/base/messagequeue.h"
-#include "talk/base/socketserver.h"
-
-namespace talk_base {
-
-class VirtualSocket;
-class SocketAddressPair;
-
-// Simulates a network in the same manner as a loopback interface.  The
-// interface can create as many addresses as you want.  All of the sockets
-// created by this network will be able to communicate with one another.
-class VirtualSocketServer : public SocketServer, public sigslot::has_slots<> {
- public:
-  // TODO: Add "owned" parameter.
-  // If "owned" is set, the supplied socketserver will be deleted later.
-  explicit VirtualSocketServer(SocketServer* ss);
-  virtual ~VirtualSocketServer();
-
-  SocketServer* socketserver() { return server_; }
-
-  // Limits the network bandwidth (maximum bytes per second).  Zero means that
-  // all sends occur instantly.  Defaults to 0.
-  uint32 bandwidth() const { return bandwidth_; }
-  void set_bandwidth(uint32 bandwidth) { bandwidth_ = bandwidth; }
-
-  // Limits the amount of data which can be in flight on the network without
-  // packet loss (on a per sender basis).  Defaults to 64 KB.
-  uint32 network_capacity() const { return network_capacity_; }
-  void set_network_capacity(uint32 capacity) {
-    network_capacity_ = capacity;
-  }
-
-  // The amount of data which can be buffered by tcp on the sender's side
-  uint32 send_buffer_capacity() const { return send_buffer_capacity_; }
-  void set_send_buffer_capacity(uint32 capacity) {
-    send_buffer_capacity_ = capacity;
-  }
-
-  // The amount of data which can be buffered by tcp on the receiver's side
-  uint32 recv_buffer_capacity() const { return recv_buffer_capacity_; }
-  void set_recv_buffer_capacity(uint32 capacity) {
-    recv_buffer_capacity_ = capacity;
-  }
-
-  // Controls the (transit) delay for packets sent in the network.  This does
-  // not inclue the time required to sit in the send queue.  Both of these
-  // values are measured in milliseconds.  Defaults to no delay.
-  uint32 delay_mean() const { return delay_mean_; }
-  uint32 delay_stddev() const { return delay_stddev_; }
-  uint32 delay_samples() const { return delay_samples_; }
-  void set_delay_mean(uint32 delay_mean) { delay_mean_ = delay_mean; }
-  void set_delay_stddev(uint32 delay_stddev) {
-    delay_stddev_ = delay_stddev;
-  }
-  void set_delay_samples(uint32 delay_samples) {
-    delay_samples_ = delay_samples;
-  }
-
-  // If the (transit) delay parameters are modified, this method should be
-  // called to recompute the new distribution.
-  void UpdateDelayDistribution();
-
-  // Controls the (uniform) probability that any sent packet is dropped.  This
-  // is separate from calculations to drop based on queue size.
-  double drop_probability() { return drop_prob_; }
-  void set_drop_probability(double drop_prob) {
-    assert((0 <= drop_prob) && (drop_prob <= 1));
-    drop_prob_ = drop_prob;
-  }
-
-  // SocketFactory:
-  virtual Socket* CreateSocket(int type);
-  virtual AsyncSocket* CreateAsyncSocket(int type);
-
-  // SocketServer:
-  virtual void SetMessageQueue(MessageQueue* queue);
-  virtual bool Wait(int cms, bool process_io);
-  virtual void WakeUp();
-
-  typedef std::pair<double, double> Point;
-  typedef std::vector<Point> Function;
-
-  static Function* CreateDistribution(uint32 mean, uint32 stddev,
-                                      uint32 samples);
-
-  // Similar to Thread::ProcessMessages, but it only processes messages until
-  // there are no immediate messages or pending network traffic.  Returns false
-  // if Thread::Stop() was called.
-  bool ProcessMessagesUntilIdle();
-
- protected:
-  // Returns a new IP not used before in this network.
-  uint32 GetNextIP();
-  uint16 GetNextPort();
-
-  VirtualSocket* CreateSocketInternal(int type);
-
-  // Binds the given socket to addr, assigning and IP and Port if necessary
-  int Bind(VirtualSocket* socket, SocketAddress* addr);
-
-  // Binds the given socket to the given (fully-defined) address.
-  int Bind(VirtualSocket* socket, const SocketAddress& addr);
-
-  // Find the socket bound to the given address
-  VirtualSocket* LookupBinding(const SocketAddress& addr);
-
-  int Unbind(const SocketAddress& addr, VirtualSocket* socket);
-
-  // Adds a mapping between this socket pair and the socket.
-  void AddConnection(const SocketAddress& client,
-                     const SocketAddress& server,
-                     VirtualSocket* socket);
-
-  // Find the socket pair corresponding to this server address.
-  VirtualSocket* LookupConnection(const SocketAddress& client,
-                                  const SocketAddress& server);
-
-  void RemoveConnection(const SocketAddress& client,
-                        const SocketAddress& server);
-
-  // Connects the given socket to the socket at the given address
-  int Connect(VirtualSocket* socket, const SocketAddress& remote_addr,
-              bool use_delay);
-
-  // Sends a disconnect message to the socket at the given address
-  bool Disconnect(VirtualSocket* socket);
-
-  // Sends the given packet to the socket at the given address (if one exists).
-  int SendUdp(VirtualSocket* socket, const char* data, size_t data_size,
-              const SocketAddress& remote_addr);
-
-  // Moves as much data as possible from the sender's buffer to the network
-  void SendTcp(VirtualSocket* socket);
-
-  // Places a packet on the network.
-  void AddPacketToNetwork(VirtualSocket* socket, VirtualSocket* recipient,
-                          uint32 cur_time, const char* data, size_t data_size,
-                          size_t header_size, bool ordered);
-
-  // Removes stale packets from the network
-  void PurgeNetworkPackets(VirtualSocket* socket, uint32 cur_time);
-
-  // Computes the number of milliseconds required to send a packet of this size.
-  uint32 SendDelay(uint32 size);
-
-  // Returns a random transit delay chosen from the appropriate distribution.
-  uint32 GetRandomTransitDelay();
-
-  // Basic operations on functions.  Those that return a function also take
-  // ownership of the function given (and hence, may modify or delete it).
-  static Function* Accumulate(Function* f);
-  static Function* Invert(Function* f);
-  static Function* Resample(Function* f, double x1, double x2, uint32 samples);
-  static double Evaluate(Function* f, double x);
-
-  // NULL out our message queue if it goes away. Necessary in the case where
-  // our lifetime is greater than that of the thread we are using, since we
-  // try to send Close messages for all connected sockets when we shutdown.
-  void OnMessageQueueDestroyed() { msg_queue_ = NULL; }
-
- private:
-  friend class VirtualSocket;
-
-  typedef std::map<SocketAddress, VirtualSocket*> AddressMap;
-  typedef std::map<SocketAddressPair, VirtualSocket*> ConnectionMap;
-
-  SocketServer* server_;
-  bool server_owned_;
-  MessageQueue* msg_queue_;
-  bool stop_on_idle_;
-  uint32 network_delay_;
-  uint32 next_ip_;
-  uint16 next_port_;
-  AddressMap* bindings_;
-  ConnectionMap* connections_;
-
-  uint32 bandwidth_;
-  uint32 network_capacity_;
-  uint32 send_buffer_capacity_;
-  uint32 recv_buffer_capacity_;
-  uint32 delay_mean_;
-  uint32 delay_stddev_;
-  uint32 delay_samples_;
-  Function* delay_dist_;
-  CriticalSection delay_crit_;
-
-  double drop_prob_;
-  DISALLOW_EVIL_CONSTRUCTORS(VirtualSocketServer);
-};
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_VIRTUALSOCKETSERVER_H_
diff --git a/third_party/libjingle/source/talk/base/win32.cc b/third_party/libjingle/source/talk/base/win32.cc
deleted file mode 100644
index 3937781..0000000
--- a/third_party/libjingle/source/talk/base/win32.cc
+++ /dev/null
@@ -1,440 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/win32.h"
-
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#include <algorithm>
-
-#include "talk/base/basictypes.h"
-#include "talk/base/common.h"
-#include "talk/base/logging.h"
-
-namespace talk_base {
-
-// Helper function declarations for inet_ntop/inet_pton.
-static const char* inet_ntop_v4(const void* src, char* dst, socklen_t size);
-static const char* inet_ntop_v6(const void* src, char* dst, socklen_t size);
-static int inet_pton_v4(const char* src, void* dst);
-static int inet_pton_v6(const char* src, void* dst);
-
-// Implementation of inet_ntop (create a printable representation of an
-// ip address). XP doesn't have its own inet_ntop, and
-// WSAAddressToString requires both IPv6 to be  installed and for Winsock
-// to be initialized.
-const char* win32_inet_ntop(int af, const void *src,
-                            char* dst, socklen_t size) {
-  if (!src || !dst) {
-    return NULL;
-  }
-  switch (af) {
-    case AF_INET: {
-      return inet_ntop_v4(src, dst, size);
-    }
-    case AF_INET6: {
-      return inet_ntop_v6(src, dst, size);
-    }
-  }
-  return NULL;
-}
-
-// As above, but for inet_pton. Wraps inet_addr for v4, and implements inet_pton
-// for v6. Slightly more permissive than the RFC specified inet_pton, as it uses
-// windows' inet_addr which permits octal and hexadecimal values in v4
-// addresses, while inet_pton only allows decimal.
-// Note that our inet_ntop will output normal 'dotted' v4 addresses only.
-int win32_inet_pton(int af, const char* src, void* dst) {
-  if (!src || !dst) {
-    return 0;
-  }
-  if (af == AF_INET) {
-    return inet_pton_v4(src, dst);
-  } else if (af == AF_INET6) {
-    return inet_pton_v6(src, dst);
-  }
-  return -1;
-}
-
-// Helper function for inet_ntop for IPv4 addresses.
-// Outputs "dotted-quad" decimal notation.
-const char* inet_ntop_v4(const void* src, char* dst, socklen_t size) {
-  if (size < INET_ADDRSTRLEN) {
-    return NULL;
-  }
-  const struct in_addr* as_in_addr =
-      reinterpret_cast<const struct in_addr*>(src);
-  talk_base::sprintfn(dst, size, "%d.%d.%d.%d",
-                      as_in_addr->S_un.S_un_b.s_b1,
-                      as_in_addr->S_un.S_un_b.s_b2,
-                      as_in_addr->S_un.S_un_b.s_b3,
-                      as_in_addr->S_un.S_un_b.s_b4);
-  return dst;
-}
-
-// Helper function for inet_ntop for IPv6 addresses.
-const char* inet_ntop_v6(const void* src, char* dst, socklen_t size) {
-  if (size < INET6_ADDRSTRLEN) {
-    return NULL;
-  }
-  const uint16* as_shorts =
-      reinterpret_cast<const uint16*>(src);
-  int runpos[8];
-  int current = 1;
-  int max = 1;
-  int maxpos = -1;
-  int run_array_size = ARRAY_SIZE(runpos);
-  // Run over the address marking runs of 0s.
-  for (int i = 0; i < run_array_size; ++i) {
-    if (as_shorts[i] == 0) {
-      runpos[i] = current;
-      if (current > max) {
-        maxpos = i;
-        max = current;
-      }
-      ++current;
-    } else {
-      runpos[i] = -1;
-      current =1;
-    }
-  }
-
-  if (max > 1) {
-    int tmpmax = maxpos;
-    // Run back through, setting -1 for all but the longest run.
-    for (int i = run_array_size - 1; i >= 0; i--) {
-      if (i > tmpmax) {
-        runpos[i] = -1;
-      } else if (runpos[i] == -1) {
-        // We're less than maxpos, we hit a -1, so the 'good' run is done.
-        // Setting tmpmax -1 means all remaining positions get set to -1.
-        tmpmax = -1;
-      }
-    }
-  }
-
-  char* cursor = dst;
-  // Print IPv4 compatible and IPv4 mapped addresses using the IPv4 helper.
-  // These addresses have an initial run of either eight zero-bytes followed
-  // by 0xFFFF, or an initial run of ten zero-bytes.
-  if (runpos[0] == 1 && (maxpos == 5 ||
-                         (maxpos == 4 && as_shorts[5] == 0xFFFF))) {
-    *cursor++ = ':';
-    *cursor++ = ':';
-    if (maxpos == 4) {
-      cursor += talk_base::sprintfn(cursor, INET6_ADDRSTRLEN - 2, "ffff:");
-    }
-    const struct in_addr* as_v4 =
-        reinterpret_cast<const struct in_addr*>(&(as_shorts[6]));
-    inet_ntop_v4(as_v4, cursor, (INET6_ADDRSTRLEN - (cursor - dst)));
-  } else {
-    for (int i = 0; i < run_array_size; ++i) {
-      if (runpos[i] == -1) {
-        cursor += talk_base::sprintfn(cursor,
-                                      INET6_ADDRSTRLEN - (cursor - dst),
-                                      "%x", ntohs(as_shorts[i]));
-        if (i != 7 && runpos[i + 1] != 1) {
-          *cursor++ = ':';
-        }
-      } else if (runpos[i] == 1) {
-        // Entered the run; print the colons and skip the run.
-        *cursor++ = ':';
-        *cursor++ = ':';
-        i += (max - 1);
-      }
-    }
-  }
-  return dst;
-}
-
-// Helper function for inet_pton for IPv4 addresses.
-// Uses win32's inet_addr.
-int inet_pton_v4(const char* src, void* dst) {
-  uint32 ip = inet_addr(src);
-  if (ip == 0xFFFFFFFF && strcmp(src, "255.255.255.255") != 0) {
-    return 0;
-  }
-  struct in_addr* dst_as_in_addr = reinterpret_cast<struct in_addr*>(dst);
-  dst_as_in_addr->s_addr = ip;
-  return 1;
-}
-
-// Helper function for inet_pton for IPv6 addresses.
-int inet_pton_v6(const char* src, void* dst) {
-  // sscanf will pick any other invalid chars up, but it parses 0xnnnn as hex.
-  // Check for literal x in the input string.
-  const char* readcursor = src;
-  char c = *readcursor++;
-  while (c) {
-    if (c == 'x') {
-      return 0;
-    }
-    c = *readcursor++;
-  }
-  readcursor = src;
-
-  struct in6_addr an_addr;
-  memset(&an_addr, 0, sizeof(an_addr));
-
-  uint16* addr_cursor = reinterpret_cast<uint16*>(&an_addr.s6_addr[0]);
-  uint16* addr_end = reinterpret_cast<uint16*>(&an_addr.s6_addr[16]);
-  bool seencompressed = false;
-
-  // Addresses that start with "::" (i.e., a run of initial zeros) or
-  // "::ffff:" can potentially be IPv4 mapped or compatibility addresses.
-  // These have dotted-style IPv4 addresses on the end (e.g. "::192.168.7.1").
-  if (*readcursor == ':' && *(readcursor+1) == ':' &&
-      *(readcursor + 2) != 0) {
-    // Check for periods, which we'll take as a sign of v4 addresses.
-    const char* addrstart = readcursor + 2;
-    if (talk_base::strchr(addrstart, ".")) {
-      const char* colon = talk_base::strchr(addrstart, "::");
-      if (colon) {
-        uint16 a_short;
-        int bytesread = 0;
-        if (sscanf(addrstart, "%hx%n", &a_short, &bytesread) != 1 ||
-            a_short != 0xFFFF || bytesread != 4) {
-          // Colons + periods means has to be ::ffff:a.b.c.d. But it wasn't.
-          return 0;
-        } else {
-          an_addr.s6_addr[10] = 0xFF;
-          an_addr.s6_addr[11] = 0xFF;
-          addrstart = colon + 1;
-        }
-      }
-      struct in_addr v4;
-      if (inet_pton_v4(addrstart, &v4.s_addr)) {
-        memcpy(&an_addr.s6_addr[12], &v4, sizeof(v4));
-        memcpy(dst, &an_addr, sizeof(an_addr));
-        return 1;
-      } else {
-        // Invalid v4 address.
-        return 0;
-      }
-    }
-  }
-
-  // For addresses without a trailing IPv4 component ('normal' IPv6 addresses).
-  while (*readcursor != 0 && addr_cursor < addr_end) {
-    if (*readcursor == ':') {
-      if (*(readcursor + 1) == ':') {
-        if (seencompressed) {
-          // Can only have one compressed run of zeroes ("::") per address.
-          return 0;
-        }
-        // Hit a compressed run. Count colons to figure out how much of the
-        // address is skipped.
-        readcursor += 2;
-        const char* coloncounter = readcursor;
-        int coloncount = 0;
-        if (*coloncounter == 0) {
-          // Special case - trailing ::.
-          addr_cursor = addr_end;
-        } else {
-          while (*coloncounter) {
-            if (*coloncounter == ':') {
-              ++coloncount;
-            }
-            ++coloncounter;
-          }
-          // (coloncount + 1) is the number of shorts left in the address.
-          addr_cursor = addr_end - (coloncount + 1);
-          seencompressed = true;
-        }
-      } else {
-        ++readcursor;
-      }
-    } else {
-      uint16 word;
-      int bytesread = 0;
-      if (sscanf(readcursor, "%hx%n", &word, &bytesread) != 1) {
-        return 0;
-      } else {
-        *addr_cursor = htons(word);
-        ++addr_cursor;
-        readcursor += bytesread;
-        if (*readcursor != ':' && *readcursor != '\0') {
-          return 0;
-        }
-      }
-    }
-  }
-
-  if (*readcursor != '\0' || addr_cursor < addr_end) {
-    // Catches addresses too short or too long.
-    return 0;
-  }
-  memcpy(dst, &an_addr, sizeof(an_addr));
-  return 1;
-}
-
-//
-// Unix time is in seconds relative to 1/1/1970.  So we compute the windows
-// FILETIME of that time/date, then we add/subtract in appropriate units to
-// convert to/from unix time.
-// The units of FILETIME are 100ns intervals, so by multiplying by or dividing
-// by 10000000, we can convert to/from seconds.
-//
-// FileTime = UnixTime*10000000 + FileTime(1970)
-// UnixTime = (FileTime-FileTime(1970))/10000000
-//
-
-void FileTimeToUnixTime(const FILETIME& ft, time_t* ut) {
-  ASSERT(NULL != ut);
-
-  // FILETIME has an earlier date base than time_t (1/1/1970), so subtract off
-  // the difference.
-  SYSTEMTIME base_st;
-  memset(&base_st, 0, sizeof(base_st));
-  base_st.wDay = 1;
-  base_st.wMonth = 1;
-  base_st.wYear = 1970;
-
-  FILETIME base_ft;
-  SystemTimeToFileTime(&base_st, &base_ft);
-
-  ULARGE_INTEGER base_ul, current_ul;
-  memcpy(&base_ul, &base_ft, sizeof(FILETIME));
-  memcpy(&current_ul, &ft, sizeof(FILETIME));
-
-  // Divide by big number to convert to seconds, then subtract out the 1970
-  // base date value.
-  const ULONGLONG RATIO = 10000000;
-  *ut = static_cast<time_t>((current_ul.QuadPart - base_ul.QuadPart) / RATIO);
-}
-
-void UnixTimeToFileTime(const time_t& ut, FILETIME* ft) {
-  ASSERT(NULL != ft);
-
-  // FILETIME has an earlier date base than time_t (1/1/1970), so add in
-  // the difference.
-  SYSTEMTIME base_st;
-  memset(&base_st, 0, sizeof(base_st));
-  base_st.wDay = 1;
-  base_st.wMonth = 1;
-  base_st.wYear = 1970;
-
-  FILETIME base_ft;
-  SystemTimeToFileTime(&base_st, &base_ft);
-
-  ULARGE_INTEGER base_ul;
-  memcpy(&base_ul, &base_ft, sizeof(FILETIME));
-
-  // Multiply by big number to convert to 100ns units, then add in the 1970
-  // base date value.
-  const ULONGLONG RATIO = 10000000;
-  ULARGE_INTEGER current_ul;
-  current_ul.QuadPart = base_ul.QuadPart + static_cast<int64>(ut) * RATIO;
-  memcpy(ft, &current_ul, sizeof(FILETIME));
-}
-
-bool Utf8ToWindowsFilename(const std::string& utf8, std::wstring* filename) {
-  // TODO: Integrate into fileutils.h
-  // TODO: Handle wide and non-wide cases via TCHAR?
-  // TODO: Skip \\?\ processing if the length is not > MAX_PATH?
-  // TODO: Write unittests
-
-  // Convert to Utf16
-  int wlen = ::MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), utf8.length() + 1,
-                                   NULL, 0);
-  if (0 == wlen) {
-    return false;
-  }
-  wchar_t* wfilename = STACK_ARRAY(wchar_t, wlen);
-  if (0 == ::MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), utf8.length() + 1,
-                                 wfilename, wlen)) {
-    return false;
-  }
-  // Replace forward slashes with backslashes
-  std::replace(wfilename, wfilename + wlen, L'/', L'\\');
-  // Convert to complete filename
-  DWORD full_len = ::GetFullPathName(wfilename, 0, NULL, NULL);
-  if (0 == full_len) {
-    return false;
-  }
-  wchar_t* filepart = NULL;
-  wchar_t* full_filename = STACK_ARRAY(wchar_t, full_len + 6);
-  wchar_t* start = full_filename + 6;
-  if (0 == ::GetFullPathName(wfilename, full_len, start, &filepart)) {
-    return false;
-  }
-  // Add long-path prefix
-  const wchar_t kLongPathPrefix[] = L"\\\\?\\UNC";
-  if ((start[0] != L'\\') || (start[1] != L'\\')) {
-    // Non-unc path:     <pathname>
-    //      Becomes: \\?\<pathname>
-    start -= 4;
-    ASSERT(start >= full_filename);
-    memcpy(start, kLongPathPrefix, 4 * sizeof(wchar_t));
-  } else if (start[2] != L'?') {
-    // Unc path:       \\<server>\<pathname>
-    //  Becomes: \\?\UNC\<server>\<pathname>
-    start -= 6;
-    ASSERT(start >= full_filename);
-    memcpy(start, kLongPathPrefix, 7 * sizeof(wchar_t));
-  } else {
-    // Already in long-path form.
-  }
-  filename->assign(start);
-  return true;
-}
-
-bool GetOsVersion(int* major, int* minor, int* build) {
-  OSVERSIONINFO info = {0};
-  info.dwOSVersionInfoSize = sizeof(info);
-  if (GetVersionEx(&info)) {
-    if (major) *major = info.dwMajorVersion;
-    if (minor) *minor = info.dwMinorVersion;
-    if (build) *build = info.dwBuildNumber;
-    return true;
-  }
-  return false;
-}
-
-bool GetCurrentProcessIntegrityLevel(int* level) {
-  bool ret = false;
-  HANDLE process = ::GetCurrentProcess(), token;
-  if (OpenProcessToken(process, TOKEN_QUERY | TOKEN_QUERY_SOURCE, &token)) {
-    DWORD size;
-    if (!GetTokenInformation(token, TokenIntegrityLevel, NULL, 0, &size) &&
-        GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
-
-      char* buf = STACK_ARRAY(char, size);
-      TOKEN_MANDATORY_LABEL* til =
-          reinterpret_cast<TOKEN_MANDATORY_LABEL*>(buf);
-      if (GetTokenInformation(token, TokenIntegrityLevel, til, size, &size)) {
-
-        DWORD count = *GetSidSubAuthorityCount(til->Label.Sid);
-        *level = *GetSidSubAuthority(til->Label.Sid, count - 1);
-        ret = true;
-      }
-    }
-    CloseHandle(token);
-  }
-  return ret;
-}
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/win32.h b/third_party/libjingle/source/talk/base/win32.h
deleted file mode 100644
index 9c6ea3f..0000000
--- a/third_party/libjingle/source/talk/base/win32.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_WIN32_H_
-#define TALK_BASE_WIN32_H_
-
-#ifdef WIN32
-
-#ifndef WIN32_LEAN_AND_MEAN
-#define WIN32_LEAN_AND_MEAN
-#endif
-#include <winsock2.h>
-#include <windows.h>
-
-#ifndef SECURITY_MANDATORY_LABEL_AUTHORITY
-// Add defines that we use if we are compiling against older sdks
-#define SECURITY_MANDATORY_MEDIUM_RID               (0x00002000L)
-#define TokenIntegrityLevel static_cast<TOKEN_INFORMATION_CLASS>(0x19)
-typedef struct _TOKEN_MANDATORY_LABEL {
-    SID_AND_ATTRIBUTES Label;
-} TOKEN_MANDATORY_LABEL, *PTOKEN_MANDATORY_LABEL;
-#endif  // SECURITY_MANDATORY_LABEL_AUTHORITY
-
-#undef SetPort
-
-#include <string>
-
-#include "talk/base/stringutils.h"
-#include "talk/base/basictypes.h"
-
-namespace talk_base {
-
-const char* win32_inet_ntop(int af, const void *src, char* dst, socklen_t size);
-int win32_inet_pton(int af, const char* src, void *dst);
-
-///////////////////////////////////////////////////////////////////////////////
-
-inline std::wstring ToUtf16(const char* utf8, size_t len) {
-  int len16 = ::MultiByteToWideChar(CP_UTF8, 0, utf8, len, NULL, 0);
-  wchar_t* ws = STACK_ARRAY(wchar_t, len16);
-  ::MultiByteToWideChar(CP_UTF8, 0, utf8, len, ws, len16);
-  return std::wstring(ws, len16);
-}
-
-inline std::wstring ToUtf16(const std::string& str) {
-  return ToUtf16(str.data(), str.length());
-}
-
-inline std::string ToUtf8(const wchar_t* wide, size_t len) {
-  int len8 = ::WideCharToMultiByte(CP_UTF8, 0, wide, len, NULL, 0, NULL, NULL);
-  char* ns = STACK_ARRAY(char, len8);
-  ::WideCharToMultiByte(CP_UTF8, 0, wide, len, ns, len8, NULL, NULL);
-  return std::string(ns, len8);
-}
-
-inline std::string ToUtf8(const std::wstring& wstr) {
-  return ToUtf8(wstr.data(), wstr.length());
-}
-
-// Convert FILETIME to time_t
-void FileTimeToUnixTime(const FILETIME& ft, time_t* ut);
-
-// Convert time_t to FILETIME
-void UnixTimeToFileTime(const time_t& ut, FILETIME * ft);
-
-// Convert a Utf8 path representation to a non-length-limited Unicode pathname.
-bool Utf8ToWindowsFilename(const std::string& utf8, std::wstring* filename);
-
-// Convert a FILETIME to a UInt64
-inline uint64 ToUInt64(const FILETIME& ft) {
-  ULARGE_INTEGER r = {ft.dwLowDateTime, ft.dwHighDateTime};
-  return r.QuadPart;
-}
-
-enum WindowsMajorVersions {
-  kWindows2000 = 5,
-  kWindowsVista = 6,
-};
-bool GetOsVersion(int* major, int* minor, int* build);
-
-inline bool IsWindowsVistaOrLater() {
-  int major;
-  return (GetOsVersion(&major, NULL, NULL) && major >= kWindowsVista);
-}
-
-inline bool IsWindowsXpOrLater() {
-  int major, minor;
-  return (GetOsVersion(&major, &minor, NULL) &&
-          (major >= kWindowsVista ||
-          (major == kWindows2000 && minor >= 1)));
-}
-
-// Determine the current integrity level of the process.
-bool GetCurrentProcessIntegrityLevel(int* level);
-
-inline bool IsCurrentProcessLowIntegrity() {
-  int level;
-  return (GetCurrentProcessIntegrityLevel(&level) &&
-      level < SECURITY_MANDATORY_MEDIUM_RID);
-}
-
-bool AdjustCurrentProcessPrivilege(const TCHAR* privilege, bool to_enable);
-
-///////////////////////////////////////////////////////////////////////////////
-
-}  // namespace talk_base
-
-#endif  // WIN32
-#endif  // TALK_BASE_WIN32_H_
diff --git a/third_party/libjingle/source/talk/base/win32filesystem.cc b/third_party/libjingle/source/talk/base/win32filesystem.cc
deleted file mode 100644
index 42c0388..0000000
--- a/third_party/libjingle/source/talk/base/win32filesystem.cc
+++ /dev/null
@@ -1,477 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2006, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/win32filesystem.h"
-
-#include "talk/base/win32.h"
-#include <shellapi.h>
-#include <shlobj.h>
-#include <tchar.h>
-
-#include "talk/base/fileutils.h"
-#include "talk/base/pathutils.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/base/stream.h"
-#include "talk/base/stringutils.h"
-
-// In several places in this file, we test the integrity level of the process
-// before calling GetLongPathName. We do this because calling GetLongPathName
-// when running under protected mode IE (a low integrity process) can result in
-// a virtualized path being returned, which is wrong if you only plan to read.
-// TODO: Waiting to hear back from IE team on whether this is the
-// best approach; IEIsProtectedModeProcess is another possible solution.
-
-namespace talk_base {
-
-bool Win32Filesystem::CreateFolder(const Pathname &pathname) {
-  if (pathname.pathname().empty() || !pathname.filename().empty())
-    return false;
-
-  std::wstring path16;
-  if (!Utf8ToWindowsFilename(pathname.pathname(), &path16))
-    return false;
-
-  DWORD res = ::GetFileAttributes(path16.c_str());
-  if (res != INVALID_FILE_ATTRIBUTES) {
-    // Something exists at this location, check if it is a directory
-    return ((res & FILE_ATTRIBUTE_DIRECTORY) != 0);
-  } else if ((GetLastError() != ERROR_FILE_NOT_FOUND)
-              && (GetLastError() != ERROR_PATH_NOT_FOUND)) {
-    // Unexpected error
-    return false;
-  }
-
-  // Directory doesn't exist, look up one directory level
-  if (!pathname.parent_folder().empty()) {
-    Pathname parent(pathname);
-    parent.SetFolder(pathname.parent_folder());
-    if (!CreateFolder(parent)) {
-      return false;
-    }
-  }
-
-  return (::CreateDirectory(path16.c_str(), NULL) != 0);
-}
-
-FileStream *Win32Filesystem::OpenFile(const Pathname &filename,
-                                      const std::string &mode) {
-  FileStream *fs = new FileStream();
-  if (fs && !fs->Open(filename.pathname().c_str(), mode.c_str(), NULL)) {
-    delete fs;
-    fs = NULL;
-  }
-  return fs;
-}
-
-bool Win32Filesystem::CreatePrivateFile(const Pathname &filename) {
-  // To make the file private to the current user, we first must construct a
-  // SECURITY_DESCRIPTOR specifying an ACL. This code is mostly based upon
-  // http://msdn.microsoft.com/en-us/library/ms707085%28VS.85%29.aspx
-
-  // Get the current process token.
-  HANDLE process_token = INVALID_HANDLE_VALUE;
-  if (!::OpenProcessToken(::GetCurrentProcess(),
-                          TOKEN_QUERY,
-                          &process_token)) {
-    LOG_ERR(LS_ERROR) << "OpenProcessToken() failed";
-    return false;
-  }
-
-  // Get the size of its TOKEN_USER structure. Return value is not checked
-  // because we expect it to fail.
-  DWORD token_user_size = 0;
-  (void)::GetTokenInformation(process_token,
-                              TokenUser,
-                              NULL,
-                              0,
-                              &token_user_size);
-
-  // Get the TOKEN_USER structure.
-  scoped_array<char> token_user_bytes(new char[token_user_size]);
-  PTOKEN_USER token_user = reinterpret_cast<PTOKEN_USER>(
-      token_user_bytes.get());
-  memset(token_user, 0, token_user_size);
-  BOOL success = ::GetTokenInformation(process_token,
-                                       TokenUser,
-                                       token_user,
-                                       token_user_size,
-                                       &token_user_size);
-  // We're now done with this.
-  ::CloseHandle(process_token);
-  if (!success) {
-    LOG_ERR(LS_ERROR) << "GetTokenInformation() failed";
-    return false;
-  }
-
-  if (!IsValidSid(token_user->User.Sid)) {
-    LOG_ERR(LS_ERROR) << "Current process has invalid user SID";
-    return false;
-  }
-
-  // Compute size needed for an ACL that allows access to just this user.
-  int acl_size = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) +
-      GetLengthSid(token_user->User.Sid);
-
-  // Allocate it.
-  scoped_array<char> acl_bytes(new char[acl_size]);
-  PACL acl = reinterpret_cast<PACL>(acl_bytes.get());
-  memset(acl, 0, acl_size);
-  if (!::InitializeAcl(acl, acl_size, ACL_REVISION)) {
-    LOG_ERR(LS_ERROR) << "InitializeAcl() failed";
-    return false;
-  }
-
-  // Allow access to only the current user.
-  if (!::AddAccessAllowedAce(acl,
-                             ACL_REVISION,
-                             GENERIC_READ | GENERIC_WRITE | STANDARD_RIGHTS_ALL,
-                             token_user->User.Sid)) {
-    LOG_ERR(LS_ERROR) << "AddAccessAllowedAce() failed";
-    return false;
-  }
-
-  // Now make the security descriptor.
-  SECURITY_DESCRIPTOR security_descriptor;
-  if (!::InitializeSecurityDescriptor(&security_descriptor,
-                                      SECURITY_DESCRIPTOR_REVISION)) {
-    LOG_ERR(LS_ERROR) << "InitializeSecurityDescriptor() failed";
-    return false;
-  }
-
-  // Put the ACL in it.
-  if (!::SetSecurityDescriptorDacl(&security_descriptor,
-                                   TRUE,
-                                   acl,
-                                   FALSE)) {
-    LOG_ERR(LS_ERROR) << "SetSecurityDescriptorDacl() failed";
-    return false;
-  }
-
-  // Finally create the file.
-  SECURITY_ATTRIBUTES security_attributes;
-  security_attributes.nLength = sizeof(security_attributes);
-  security_attributes.lpSecurityDescriptor = &security_descriptor;
-  security_attributes.bInheritHandle = FALSE;
-  HANDLE handle = ::CreateFile(
-      ToUtf16(filename.pathname()).c_str(),
-      GENERIC_READ | GENERIC_WRITE,
-      FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
-      &security_attributes,
-      CREATE_NEW,
-      0,
-      NULL);
-  if (INVALID_HANDLE_VALUE == handle) {
-    LOG_ERR(LS_ERROR) << "CreateFile() failed";
-    return false;
-  }
-  if (!::CloseHandle(handle)) {
-    LOG_ERR(LS_ERROR) << "CloseFile() failed";
-    // Continue.
-  }
-  return true;
-}
-
-bool Win32Filesystem::DeleteFile(const Pathname &filename) {
-  LOG(LS_INFO) << "Deleting file " << filename.pathname();
-  if (!IsFile(filename)) {
-    ASSERT(IsFile(filename));
-    return false;
-  }
-  return ::DeleteFile(ToUtf16(filename.pathname()).c_str()) != 0;
-}
-
-bool Win32Filesystem::DeleteEmptyFolder(const Pathname &folder) {
-  LOG(LS_INFO) << "Deleting folder " << folder.pathname();
-
-  std::string no_slash(folder.pathname(), 0, folder.pathname().length()-1);
-  return ::RemoveDirectory(ToUtf16(no_slash).c_str()) != 0;
-}
-
-bool Win32Filesystem::GetTemporaryFolder(Pathname &pathname, bool create,
-                                         const std::string *append) {
-  wchar_t buffer[MAX_PATH + 1];
-  if (!::GetTempPath(ARRAY_SIZE(buffer), buffer))
-    return false;
-  if (!IsCurrentProcessLowIntegrity() &&
-      !::GetLongPathName(buffer, buffer, ARRAY_SIZE(buffer)))
-    return false;
-  size_t len = strlen(buffer);
-  if ((len > 0) && (buffer[len-1] != '\\')) {
-    len += strcpyn(buffer + len, ARRAY_SIZE(buffer) - len, L"\\");
-  }
-  if (len >= ARRAY_SIZE(buffer) - 1)
-    return false;
-  pathname.clear();
-  pathname.SetFolder(ToUtf8(buffer));
-  if (append != NULL) {
-    ASSERT(!append->empty());
-    pathname.AppendFolder(*append);
-  }
-  return !create || CreateFolder(pathname);
-}
-
-std::string Win32Filesystem::TempFilename(const Pathname &dir,
-                                          const std::string &prefix) {
-  wchar_t filename[MAX_PATH];
-  if (::GetTempFileName(ToUtf16(dir.pathname()).c_str(),
-                        ToUtf16(prefix).c_str(), 0, filename) != 0)
-    return ToUtf8(filename);
-  ASSERT(false);
-  return "";
-}
-
-bool Win32Filesystem::MoveFile(const Pathname &old_path,
-                               const Pathname &new_path) {
-  if (!IsFile(old_path)) {
-    ASSERT(IsFile(old_path));
-    return false;
-  }
-  LOG(LS_INFO) << "Moving " << old_path.pathname()
-               << " to " << new_path.pathname();
-  return ::MoveFile(ToUtf16(old_path.pathname()).c_str(),
-                    ToUtf16(new_path.pathname()).c_str()) != 0;
-}
-
-bool Win32Filesystem::MoveFolder(const Pathname &old_path,
-                                 const Pathname &new_path) {
-  if (!IsFolder(old_path)) {
-    ASSERT(IsFolder(old_path));
-    return false;
-  }
-  LOG(LS_INFO) << "Moving " << old_path.pathname()
-               << " to " << new_path.pathname();
-  if (::MoveFile(ToUtf16(old_path.pathname()).c_str(),
-               ToUtf16(new_path.pathname()).c_str()) == 0) {
-    if (::GetLastError() != ERROR_NOT_SAME_DEVICE) {
-      LOG_GLE(LS_ERROR) << "Failed to move file";
-      return false;
-    }
-    if (!CopyFolder(old_path, new_path))
-      return false;
-    if (!DeleteFolderAndContents(old_path))
-      return false;
-  }
-  return true;
-}
-
-bool Win32Filesystem::IsFolder(const Pathname &path) {
-  WIN32_FILE_ATTRIBUTE_DATA data = {0};
-  if (0 == ::GetFileAttributesEx(ToUtf16(path.pathname()).c_str(),
-                                 GetFileExInfoStandard, &data))
-    return false;
-  return (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ==
-      FILE_ATTRIBUTE_DIRECTORY;
-}
-
-bool Win32Filesystem::IsFile(const Pathname &path) {
-  WIN32_FILE_ATTRIBUTE_DATA data = {0};
-  if (0 == ::GetFileAttributesEx(ToUtf16(path.pathname()).c_str(),
-                                 GetFileExInfoStandard, &data))
-    return false;
-  return (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0;
-}
-
-bool Win32Filesystem::IsAbsent(const Pathname& path) {
-  WIN32_FILE_ATTRIBUTE_DATA data = {0};
-  if (0 != ::GetFileAttributesEx(ToUtf16(path.pathname()).c_str(),
-                                 GetFileExInfoStandard, &data))
-    return false;
-  DWORD err = ::GetLastError();
-  return (ERROR_FILE_NOT_FOUND == err || ERROR_PATH_NOT_FOUND == err);
-}
-
-bool Win32Filesystem::CopyFile(const Pathname &old_path,
-                               const Pathname &new_path) {
-  return ::CopyFile(ToUtf16(old_path.pathname()).c_str(),
-                    ToUtf16(new_path.pathname()).c_str(), TRUE) != 0;
-}
-
-bool Win32Filesystem::IsTemporaryPath(const Pathname& pathname) {
-  TCHAR buffer[MAX_PATH + 1];
-  if (!::GetTempPath(ARRAY_SIZE(buffer), buffer))
-    return false;
-  if (!IsCurrentProcessLowIntegrity() &&
-      !::GetLongPathName(buffer, buffer, ARRAY_SIZE(buffer)))
-    return false;
-  return (::strnicmp(ToUtf16(pathname.pathname()).c_str(),
-                     buffer, strlen(buffer)) == 0);
-}
-
-bool Win32Filesystem::GetFileSize(const Pathname &pathname, size_t *size) {
-  WIN32_FILE_ATTRIBUTE_DATA data = {0};
-  if (::GetFileAttributesEx(ToUtf16(pathname.pathname()).c_str(),
-                            GetFileExInfoStandard, &data) == 0)
-  return false;
-  *size = data.nFileSizeLow;
-  return true;
-}
-
-bool Win32Filesystem::GetFileTime(const Pathname& path, FileTimeType which,
-                                  time_t* time) {
-  WIN32_FILE_ATTRIBUTE_DATA data = {0};
-  if (::GetFileAttributesEx(ToUtf16(path.pathname()).c_str(),
-                            GetFileExInfoStandard, &data) == 0)
-    return false;
-  switch (which) {
-  case FTT_CREATED:
-    FileTimeToUnixTime(data.ftCreationTime, time);
-    break;
-  case FTT_MODIFIED:
-    FileTimeToUnixTime(data.ftLastWriteTime, time);
-    break;
-  case FTT_ACCESSED:
-    FileTimeToUnixTime(data.ftLastAccessTime, time);
-    break;
-  default:
-    return false;
-  }
-  return true;
-}
-
-bool Win32Filesystem::GetAppPathname(Pathname* path) {
-  TCHAR buffer[MAX_PATH + 1];
-  if (0 == ::GetModuleFileName(NULL, buffer, ARRAY_SIZE(buffer)))
-    return false;
-  path->SetPathname(ToUtf8(buffer));
-  return true;
-}
-
-bool Win32Filesystem::GetAppDataFolder(Pathname* path, bool per_user) {
-  ASSERT(!organization_name_.empty());
-  ASSERT(!application_name_.empty());
-  TCHAR buffer[MAX_PATH + 1];
-  int csidl = per_user ? CSIDL_LOCAL_APPDATA : CSIDL_COMMON_APPDATA;
-  if (!::SHGetSpecialFolderPath(NULL, buffer, csidl, TRUE))
-    return false;
-  if (!IsCurrentProcessLowIntegrity() &&
-      !::GetLongPathName(buffer, buffer, ARRAY_SIZE(buffer)))
-    return false;
-  size_t len = strcatn(buffer, ARRAY_SIZE(buffer), __T("\\"));
-  len += strcpyn(buffer + len, ARRAY_SIZE(buffer) - len,
-                 ToUtf16(organization_name_).c_str());
-  if ((len > 0) && (buffer[len-1] != __T('\\'))) {
-    len += strcpyn(buffer + len, ARRAY_SIZE(buffer) - len, __T("\\"));
-  }
-  len += strcpyn(buffer + len, ARRAY_SIZE(buffer) - len,
-                 ToUtf16(application_name_).c_str());
-  if ((len > 0) && (buffer[len-1] != __T('\\'))) {
-    len += strcpyn(buffer + len, ARRAY_SIZE(buffer) - len, __T("\\"));
-  }
-  if (len >= ARRAY_SIZE(buffer) - 1)
-    return false;
-  path->clear();
-  path->SetFolder(ToUtf8(buffer));
-  return CreateFolder(*path);
-}
-
-bool Win32Filesystem::GetAppTempFolder(Pathname* path) {
-  if (!GetAppPathname(path))
-    return false;
-  std::string filename(path->filename());
-  return GetTemporaryFolder(*path, true, &filename);
-}
-
-bool Win32Filesystem::GetDiskFreeSpace(const Pathname& path, int64 *freebytes) {
-  if (!freebytes) {
-    return false;
-  }
-  char drive[4];
-  std::wstring drive16;
-  const wchar_t* target_drive = NULL;
-  if (path.GetDrive(drive, sizeof(drive))) {
-    drive16 = ToUtf16(drive);
-    target_drive = drive16.c_str();
-  } else if (path.folder().substr(0, 2) == "\\\\") {
-    // UNC path, fail.
-    // TODO: Handle UNC paths.
-    return false;
-  } else {
-    // The path is probably relative.  GetDriveType and GetDiskFreeSpaceEx
-    // use the current drive if NULL is passed as the drive name.
-    // TODO: Add method to Pathname to determine if the path is relative.
-    // TODO: Add method to Pathname to convert a path to absolute.
-  }
-  UINT driveType = ::GetDriveType(target_drive);
-  if ( (driveType & DRIVE_REMOTE) || (driveType & DRIVE_UNKNOWN) ) {
-    LOG(LS_VERBOSE) << " remove or unknown drive " << drive;
-    return false;
-  }
-
-  int64 totalNumberOfBytes;  // receives the number of bytes on disk
-  int64 totalNumberOfFreeBytes;  // receives the free bytes on disk
-  // make sure things won't change in 64 bit machine
-  // TODO replace with compile time assert
-  ASSERT(sizeof(ULARGE_INTEGER) == sizeof(uint64));  //NOLINT
-  if (::GetDiskFreeSpaceEx(target_drive,
-                           (PULARGE_INTEGER)freebytes,
-                           (PULARGE_INTEGER)&totalNumberOfBytes,
-                           (PULARGE_INTEGER)&totalNumberOfFreeBytes)) {
-    return true;
-  } else {
-    LOG(LS_VERBOSE) << " GetDiskFreeSpaceEx returns error ";
-    return false;
-  }
-}
-
-Pathname Win32Filesystem::GetCurrentDirectory() {
-  Pathname cwd;
-  int path_len = 0;
-  scoped_array<wchar_t> path;
-  do {
-    int needed = ::GetCurrentDirectory(path_len, path.get());
-    if (needed == 0) {
-      // Error.
-      LOG_GLE(LS_ERROR) << "::GetCurrentDirectory() failed";
-      return cwd;  // returns empty pathname
-    }
-    if (needed <= path_len) {
-      // It wrote successfully.
-      break;
-    }
-    // Else need to re-alloc for "needed".
-    path.reset(new wchar_t[needed]);
-    path_len = needed;
-  } while (true);
-  cwd.SetFolder(ToUtf8(path.get()));
-  return cwd;
-}
-
-// TODO: Consider overriding DeleteFolderAndContents for speed and potentially
-// better OS integration (recycle bin?)
-/*
-  std::wstring temp_path16 = ToUtf16(temp_path.pathname());
-  temp_path16.append(1, '*');
-  temp_path16.append(1, '\0');
-
-  SHFILEOPSTRUCT file_op = { 0 };
-  file_op.wFunc = FO_DELETE;
-  file_op.pFrom = temp_path16.c_str();
-  file_op.fFlags = FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT;
-  return (0 == SHFileOperation(&file_op));
-*/
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/win32filesystem.h b/third_party/libjingle/source/talk/base/win32filesystem.h
deleted file mode 100644
index c17bdd9..0000000
--- a/third_party/libjingle/source/talk/base/win32filesystem.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2006, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _TALK_BASE_WIN32FILESYSTEM_H__
-#define _TALK_BASE_WIN32FILESYSTEM_H__
-
-#include "fileutils.h"
-
-namespace talk_base {
-
-class Win32Filesystem : public FilesystemInterface {
- public:
-  // Opens a file. Returns an open StreamInterface if function succeeds. Otherwise,
-  // returns NULL.
-  virtual FileStream *OpenFile(const Pathname &filename, 
-                               const std::string &mode);
-
-  // Atomically creates an empty file accessible only to the current user if one
-  // does not already exist at the given path, otherwise fails.
-  virtual bool CreatePrivateFile(const Pathname &filename);
-
-  // This will attempt to delete the path located at filename.
-  // If the path points to a folder, it will fail with VERIFY
-  virtual bool DeleteFile(const Pathname &filename);
-
-  // This will attempt to delete an empty folder. If the path does not point to
-  // a folder, it fails with VERIFY. If the folder is not empty, it fails normally
-  virtual bool DeleteEmptyFolder(const Pathname &folder);
-
-  // Creates a directory. This will call itself recursively to create /foo/bar even if
-  // /foo does not exist.
-  // Returns TRUE if function succeeds
-  virtual bool CreateFolder(const Pathname &pathname);
-  
-  // This moves a file from old_path to new_path. If the new path is on a 
-  // different volume than the old, it will attempt to copy and then delete
-  // the folder
-  // Returns true if the file is successfully moved
-  virtual bool MoveFile(const Pathname &old_path, const Pathname &new_path);
-  
-  // Moves a folder from old_path to new_path. If the new path is on a different
-  // volume from the old, it will attempt to Copy and then Delete the folder
-  // Returns true if the folder is successfully moved
-  virtual bool MoveFolder(const Pathname &old_path, const Pathname &new_path);
-  
-  // This copies a file from old_path to _new_path
-  // Returns true if function succeeds
-  virtual bool CopyFile(const Pathname &old_path, const Pathname &new_path);
-
-  // Returns true if a pathname is a directory
-  virtual bool IsFolder(const Pathname& pathname);
-  
-  // Returns true if a file exists at path
-  virtual bool IsFile(const Pathname &path);
-
-  // Returns true if pathname refers to no filesystem object, every parent
-  // directory either exists, or is also absent.
-  virtual bool IsAbsent(const Pathname& pathname);
-
-  // Returns true if pathname represents a temporary location on the system.
-  virtual bool IsTemporaryPath(const Pathname& pathname);
-
-  // All of the following functions set pathname and return true if successful.
-  // Returned paths always include a trailing backslash.
-  // If create is true, the path will be recursively created.
-  // If append is non-NULL, it will be appended (and possibly created).
-
-  virtual std::string TempFilename(const Pathname &dir, const std::string &prefix);
-
-  virtual bool GetFileSize(const Pathname& path, size_t* size);
-  virtual bool GetFileTime(const Pathname& path, FileTimeType which,
-                           time_t* time);
- 
-  // A folder appropriate for storing temporary files (Contents are
-  // automatically deleted when the program exists)
-  virtual bool GetTemporaryFolder(Pathname &path, bool create,
-                                 const std::string *append);
-
-  // Returns the path to the running application.
-  virtual bool GetAppPathname(Pathname* path);
-
-  virtual bool GetAppDataFolder(Pathname* path, bool per_user);
-
-  // Get a temporary folder that is unique to the current user and application.
-  virtual bool GetAppTempFolder(Pathname* path);
-
-  virtual bool GetDiskFreeSpace(const Pathname& path, int64 *freebytes);
-
-  virtual Pathname GetCurrentDirectory();
-};
-
-}  // namespace talk_base
-
-#endif  // _WIN32FILESYSTEM_H__
diff --git a/third_party/libjingle/source/talk/base/win32securityerrors.cc b/third_party/libjingle/source/talk/base/win32securityerrors.cc
deleted file mode 100644
index 50f4f66..0000000
--- a/third_party/libjingle/source/talk/base/win32securityerrors.cc
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/win32.h"
-#include "talk/base/logging.h"
-
-namespace talk_base {
-
-///////////////////////////////////////////////////////////////////////////////
-
-extern const ConstantLabel SECURITY_ERRORS[];
-
-const ConstantLabel SECURITY_ERRORS[] = {
-  KLABEL(SEC_I_COMPLETE_AND_CONTINUE),
-  KLABEL(SEC_I_COMPLETE_NEEDED),
-  KLABEL(SEC_I_CONTEXT_EXPIRED),
-  KLABEL(SEC_I_CONTINUE_NEEDED),
-  KLABEL(SEC_I_INCOMPLETE_CREDENTIALS),
-  KLABEL(SEC_I_RENEGOTIATE),
-  KLABEL(SEC_E_CERT_EXPIRED),
-  KLABEL(SEC_E_INCOMPLETE_MESSAGE),
-  KLABEL(SEC_E_INSUFFICIENT_MEMORY),
-  KLABEL(SEC_E_INTERNAL_ERROR),
-  KLABEL(SEC_E_INVALID_HANDLE),
-  KLABEL(SEC_E_INVALID_TOKEN),
-  KLABEL(SEC_E_LOGON_DENIED),
-  KLABEL(SEC_E_NO_AUTHENTICATING_AUTHORITY),
-  KLABEL(SEC_E_NO_CREDENTIALS),
-  KLABEL(SEC_E_NOT_OWNER),
-  KLABEL(SEC_E_OK),
-  KLABEL(SEC_E_SECPKG_NOT_FOUND),
-  KLABEL(SEC_E_TARGET_UNKNOWN),
-  KLABEL(SEC_E_UNKNOWN_CREDENTIALS),
-  KLABEL(SEC_E_UNSUPPORTED_FUNCTION),
-  KLABEL(SEC_E_UNTRUSTED_ROOT),
-  KLABEL(SEC_E_WRONG_PRINCIPAL),
-  LASTLABEL
-};
-
-///////////////////////////////////////////////////////////////////////////////
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/win32socketinit.cc b/third_party/libjingle/source/talk/base/win32socketinit.cc
deleted file mode 100644
index f6ac666..0000000
--- a/third_party/libjingle/source/talk/base/win32socketinit.cc
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * libjingle
- * Copyright 2009, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/win32socketinit.h"
-
-#include "talk/base/win32.h"
-
-namespace talk_base {
-
-// Please don't remove this function.
-void EnsureWinsockInit() {
-  // The default implementation uses a global initializer, so WSAStartup
-  // happens at module load time.  Thus we don't need to do anything here.
-  // The hook is provided so that a client that statically links with
-  // libjingle can override it, to provide its own initialization.
-}
-
-#ifdef WIN32
-class WinsockInitializer {
- public:
-  WinsockInitializer() {
-    WSADATA wsaData;
-    WORD wVersionRequested = MAKEWORD(1, 0);
-    err_ = WSAStartup(wVersionRequested, &wsaData);
-  }
-  ~WinsockInitializer() {
-    if (!err_)
-      WSACleanup();
-  }
-  int error() {
-    return err_;
-  }
- private:
-  int err_;
-};
-WinsockInitializer g_winsockinit;
-#endif
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/win32socketinit.h b/third_party/libjingle/source/talk/base/win32socketinit.h
deleted file mode 100644
index f56b7ff..0000000
--- a/third_party/libjingle/source/talk/base/win32socketinit.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * libjingle
- * Copyright 2009, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_WIN32SOCKETINIT_H_
-#define TALK_BASE_WIN32SOCKETINIT_H_
-
-namespace talk_base {
-
-void EnsureWinsockInit();
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_WIN32SOCKETINIT_H_
diff --git a/third_party/libjingle/source/talk/base/win32socketserver.cc b/third_party/libjingle/source/talk/base/win32socketserver.cc
deleted file mode 100644
index 0915aaf..0000000
--- a/third_party/libjingle/source/talk/base/win32socketserver.cc
+++ /dev/null
@@ -1,820 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/win32socketserver.h"
-#include "talk/base/byteorder.h"
-#include "talk/base/common.h"
-#include "talk/base/logging.h"
-#include "talk/base/winping.h"
-#include "talk/base/win32window.h"
-#include <ws2tcpip.h>  // NOLINT
-
-namespace talk_base {
-
-///////////////////////////////////////////////////////////////////////////////
-// Win32Socket
-///////////////////////////////////////////////////////////////////////////////
-
-// TODO: Move this to a common place where PhysicalSocketServer can
-// share it.
-// Standard MTUs
-static const uint16 PACKET_MAXIMUMS[] = {
-  65535,    // Theoretical maximum, Hyperchannel
-  32000,    // Nothing
-  17914,    // 16Mb IBM Token Ring
-  8166,     // IEEE 802.4
-  // 4464   // IEEE 802.5 (4Mb max)
-  4352,     // FDDI
-  // 2048,  // Wideband Network
-  2002,     // IEEE 802.5 (4Mb recommended)
-  // 1536,  // Expermental Ethernet Networks
-  // 1500,  // Ethernet, Point-to-Point (default)
-  1492,     // IEEE 802.3
-  1006,     // SLIP, ARPANET
-  // 576,   // X.25 Networks
-  // 544,   // DEC IP Portal
-  // 512,   // NETBIOS
-  508,      // IEEE 802/Source-Rt Bridge, ARCNET
-  296,      // Point-to-Point (low delay)
-  68,       // Official minimum
-  0,        // End of list marker
-};
-
-static const uint32 IP_HEADER_SIZE = 20;
-static const uint32 ICMP_HEADER_SIZE = 8;
-
-// TODO: Enable for production builds also? Use FormatMessage?
-#ifdef _DEBUG
-LPCSTR WSAErrorToString(int error, LPCSTR *description_result) {
-  LPCSTR string = "Unspecified";
-  LPCSTR description = "Unspecified description";
-  switch (error) {
-    case ERROR_SUCCESS:
-      string = "SUCCESS";
-      description = "Operation succeeded";
-      break;
-    case WSAEWOULDBLOCK:
-      string = "WSAEWOULDBLOCK";
-      description = "Using a non-blocking socket, will notify later";
-      break;
-    case WSAEACCES:
-      string = "WSAEACCES";
-      description = "Access denied, or sharing violation";
-      break;
-    case WSAEADDRNOTAVAIL:
-      string = "WSAEADDRNOTAVAIL";
-      description = "Address is not valid in this context";
-      break;
-    case WSAENETDOWN:
-      string = "WSAENETDOWN";
-      description = "Network is down";
-      break;
-    case WSAENETUNREACH:
-      string = "WSAENETUNREACH";
-      description = "Network is up, but unreachable";
-      break;
-    case WSAENETRESET:
-      string = "WSANETRESET";
-      description = "Connection has been reset due to keep-alive activity";
-      break;
-    case WSAECONNABORTED:
-      string = "WSAECONNABORTED";
-      description = "Aborted by host";
-      break;
-    case WSAECONNRESET:
-      string = "WSAECONNRESET";
-      description = "Connection reset by host";
-      break;
-    case WSAETIMEDOUT:
-      string = "WSAETIMEDOUT";
-      description = "Timed out, host failed to respond";
-      break;
-    case WSAECONNREFUSED:
-      string = "WSAECONNREFUSED";
-      description = "Host actively refused connection";
-      break;
-    case WSAEHOSTDOWN:
-      string = "WSAEHOSTDOWN";
-      description = "Host is down";
-      break;
-    case WSAEHOSTUNREACH:
-      string = "WSAEHOSTUNREACH";
-      description = "Host is unreachable";
-      break;
-    case WSAHOST_NOT_FOUND:
-      string = "WSAHOST_NOT_FOUND";
-      description = "No such host is known";
-      break;
-  }
-  if (description_result) {
-    *description_result = description;
-  }
-  return string;
-}
-
-void ReportWSAError(LPCSTR context, int error, const SocketAddress& address) {
-  LPCSTR description_string;
-  LPCSTR error_string = WSAErrorToString(error, &description_string);
-  LOG(LS_INFO) << context << " = " << error
-    << " (" << error_string << ":" << description_string << ") ["
-    << address.ToString() << "]";
-}
-#else
-void ReportWSAError(LPCSTR context, int error, const SocketAddress& address) {}
-#endif
-
-/////////////////////////////////////////////////////////////////////////////
-// Win32Socket::EventSink
-/////////////////////////////////////////////////////////////////////////////
-
-#define WM_SOCKETNOTIFY  (WM_USER + 50)
-#define WM_DNSNOTIFY     (WM_USER + 51)
-
-struct Win32Socket::DnsLookup {
-  HANDLE handle;
-  uint16 port;
-  char buffer[MAXGETHOSTSTRUCT];
-};
-
-class Win32Socket::EventSink : public Win32Window {
- public:
-  explicit EventSink(Win32Socket * parent) : parent_(parent) { }
-
-  void Dispose();
-
-  virtual bool OnMessage(UINT uMsg, WPARAM wParam, LPARAM lParam,
-                         LRESULT& result);
-  virtual void OnFinalMessage(HWND hWnd);
-
- private:
-  bool OnSocketNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& result);
-  bool OnDnsNotify(WPARAM wParam, LPARAM lParam, LRESULT& result);
-
-  Win32Socket * parent_;
-};
-
-void Win32Socket::EventSink::Dispose() {
-  parent_ = NULL;
-  if (::IsWindow(handle())) {
-    ::DestroyWindow(handle());
-  } else {
-    delete this;
-  }
-}
-
-bool Win32Socket::EventSink::OnMessage(UINT uMsg, WPARAM wParam,
-                                       LPARAM lParam, LRESULT& result) {
-  switch (uMsg) {
-  case WM_SOCKETNOTIFY:
-  case WM_TIMER:
-    return OnSocketNotify(uMsg, wParam, lParam, result);
-  case WM_DNSNOTIFY:
-    return OnDnsNotify(wParam, lParam, result);
-  }
-  return false;
-}
-
-bool Win32Socket::EventSink::OnSocketNotify(UINT uMsg, WPARAM wParam,
-                                            LPARAM lParam, LRESULT& result) {
-  result = 0;
-
-  int wsa_event = WSAGETSELECTEVENT(lParam);
-  int wsa_error = WSAGETSELECTERROR(lParam);
-
-  // Treat connect timeouts as close notifications
-  if (uMsg == WM_TIMER) {
-    wsa_event = FD_CLOSE;
-    wsa_error = WSAETIMEDOUT;
-  }
-
-  if (parent_)
-    parent_->OnSocketNotify(static_cast<SOCKET>(wParam), wsa_event, wsa_error);
-  return true;
-}
-
-bool Win32Socket::EventSink::OnDnsNotify(WPARAM wParam, LPARAM lParam,
-                                         LRESULT& result) {
-  result = 0;
-
-  int error = WSAGETASYNCERROR(lParam);
-  if (parent_)
-    parent_->OnDnsNotify(reinterpret_cast<HANDLE>(wParam), error);
-  return true;
-}
-
-void Win32Socket::EventSink::OnFinalMessage(HWND hWnd) {
-  delete this;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-// Win32Socket
-/////////////////////////////////////////////////////////////////////////////
-
-Win32Socket::Win32Socket()
-    : socket_(INVALID_SOCKET), error_(0), state_(CS_CLOSED), connect_time_(0),
-      closing_(false), close_error_(0), sink_(NULL), dns_(NULL) {
-}
-
-Win32Socket::~Win32Socket() {
-  Close();
-}
-
-bool Win32Socket::CreateT(int type) {
-  Close();
-  int proto = (SOCK_DGRAM == type) ? IPPROTO_UDP : IPPROTO_TCP;
-  socket_ = ::WSASocket(AF_INET, type, proto, NULL, NULL, 0);
-  if (socket_ == INVALID_SOCKET) {
-    UpdateLastError();
-    return false;
-  }
-  if ((SOCK_DGRAM == type) && !SetAsync(FD_READ | FD_WRITE)) {
-    return false;
-  }
-  return true;
-}
-
-int Win32Socket::Attach(SOCKET s) {
-  ASSERT(socket_ == INVALID_SOCKET);
-  if (socket_ != INVALID_SOCKET)
-    return SOCKET_ERROR;
-
-  ASSERT(s != INVALID_SOCKET);
-  if (s == INVALID_SOCKET)
-    return SOCKET_ERROR;
-
-  socket_ = s;
-  state_ = CS_CONNECTED;
-
-  if (!SetAsync(FD_READ | FD_WRITE | FD_CLOSE))
-    return SOCKET_ERROR;
-
-  return 0;
-}
-
-void Win32Socket::SetTimeout(int ms) {
-  if (sink_)
-    ::SetTimer(sink_->handle(), 1, ms, 0);
-}
-
-SocketAddress Win32Socket::GetLocalAddress() const {
-  sockaddr_in addr;
-  socklen_t addrlen = sizeof(addr);
-  int result = ::getsockname(socket_, reinterpret_cast<sockaddr*>(&addr),
-                             &addrlen);
-  SocketAddress address;
-  if (result >= 0) {
-    ASSERT(addrlen == sizeof(addr));
-    address.FromSockAddr(addr);
-  } else {
-    LOG(LS_WARNING) << "GetLocalAddress: unable to get local addr, socket="
-                    << socket_;
-  }
-  return address;
-}
-
-SocketAddress Win32Socket::GetRemoteAddress() const {
-  sockaddr_in addr;
-  socklen_t addrlen = sizeof(addr);
-  int result = ::getpeername(socket_, reinterpret_cast<sockaddr*>(&addr),
-                             &addrlen);
-  ASSERT(addrlen == sizeof(addr));
-  SocketAddress address;
-  if (result >= 0) {
-    ASSERT(addrlen == sizeof(addr));
-    address.FromSockAddr(addr);
-  } else {
-    LOG(LS_WARNING) << "GetRemoteAddress: unable to get remote addr, socket="
-                    << socket_;
-  }
-  return address;
-}
-
-int Win32Socket::Bind(const SocketAddress& addr) {
-  ASSERT(socket_ != INVALID_SOCKET);
-  if (socket_ == INVALID_SOCKET)
-    return SOCKET_ERROR;
-
-  sockaddr_in saddr;
-  addr.ToSockAddr(&saddr);
-  int err = ::bind(socket_, reinterpret_cast<sockaddr*>(&saddr), sizeof(saddr));
-  UpdateLastError();
-  return err;
-}
-
-int Win32Socket::Connect(const SocketAddress& addr) {
-  if ((socket_ == INVALID_SOCKET) && !CreateT(SOCK_STREAM))
-    return SOCKET_ERROR;
-
-  if (!sink_ && !SetAsync(FD_READ | FD_WRITE | FD_CONNECT | FD_CLOSE))
-    return SOCKET_ERROR;
-
-  // If we have an IP address, connect now.
-  if (!addr.IsUnresolved()) {
-    return DoConnect(addr);
-  }
-
-  LOG_F(LS_INFO) << "async dns lookup (" << addr.IPAsString() << ")";
-  DnsLookup * dns = new DnsLookup;
-  dns->handle = WSAAsyncGetHostByName(sink_->handle(), WM_DNSNOTIFY,
-        addr.IPAsString().c_str(), dns->buffer, sizeof(dns->buffer));
-
-  if (!dns->handle) {
-    LOG_F(LS_ERROR) << "WSAAsyncGetHostByName error: " << WSAGetLastError();
-    delete dns;
-    UpdateLastError();
-    Close();
-    return SOCKET_ERROR;
-  }
-
-  dns->port = addr.port();
-  dns_ = dns;
-  state_ = CS_CONNECTING;
-  return 0;
-}
-
-int Win32Socket::DoConnect(const SocketAddress& addr) {
-  sockaddr_in saddr;
-  addr.ToSockAddr(&saddr);
-  connect_time_ = Time();
-  int result = connect(socket_, reinterpret_cast<SOCKADDR*>(&saddr),
-                       sizeof(saddr));
-  if (result != SOCKET_ERROR) {
-    state_ = CS_CONNECTED;
-  } else {
-    int code = WSAGetLastError();
-    if (code == WSAEWOULDBLOCK) {
-      state_ = CS_CONNECTING;
-    } else {
-      ReportWSAError("WSAAsync:connect", code, addr);
-      error_ = code;
-      Close();
-      return SOCKET_ERROR;
-    }
-  }
-  addr_ = addr;
-
-  return 0;
-}
-
-int Win32Socket::GetError() const {
-  return error_;
-}
-
-void Win32Socket::SetError(int error) {
-  error_ = error;
-}
-
-Socket::ConnState Win32Socket::GetState() const {
-  return state_;
-}
-
-int Win32Socket::GetOption(Option opt, int* value) {
-  int slevel;
-  int sopt;
-  if (TranslateOption(opt, &slevel, &sopt) == -1)
-    return -1;
-
-  char* p = reinterpret_cast<char*>(value);
-  int optlen = sizeof(value);
-  return ::getsockopt(socket_, slevel, sopt, p, &optlen);
-}
-
-int Win32Socket::SetOption(Option opt, int value) {
-  int slevel;
-  int sopt;
-  if (TranslateOption(opt, &slevel, &sopt) == -1)
-    return -1;
-
-  const char* p = reinterpret_cast<const char*>(&value);
-  return ::setsockopt(socket_, slevel, sopt, p, sizeof(value));
-}
-
-int Win32Socket::Send(const void *pv, size_t cb) {
-  int sent = ::send(socket_, reinterpret_cast<const char*>(pv), cb, 0);
-  UpdateLastError();
-  return sent;
-}
-
-int Win32Socket::SendTo(const void *pv, size_t cb,
-                        const SocketAddress& addr) {
-  sockaddr_in saddr;
-  addr.ToSockAddr(&saddr);
-  int sent = ::sendto(socket_, reinterpret_cast<const char*>(pv), cb, 0,
-                      reinterpret_cast<sockaddr*>(&saddr), sizeof(saddr));
-  UpdateLastError();
-  return sent;
-}
-
-int Win32Socket::Recv(void *pv, size_t cb) {
-  int received = ::recv(socket_, static_cast<char*>(pv), cb, 0);
-  UpdateLastError();
-  if (closing_ && received <= static_cast<int>(cb))
-    PostClosed();
-  return received;
-}
-
-int Win32Socket::RecvFrom(void *pv, size_t cb,
-                          SocketAddress *paddr) {
-  sockaddr_in saddr;
-  socklen_t cbAddr = sizeof(saddr);
-  int received = ::recvfrom(socket_, static_cast<char*>(pv), cb, 0,
-                            reinterpret_cast<sockaddr*>(&saddr), &cbAddr);
-  UpdateLastError();
-  if (received != SOCKET_ERROR)
-    paddr->FromSockAddr(saddr);
-  if (closing_ && received <= static_cast<int>(cb))
-    PostClosed();
-  return received;
-}
-
-int Win32Socket::Listen(int backlog) {
-  int err = ::listen(socket_, backlog);
-  if (!SetAsync(FD_ACCEPT))
-    return SOCKET_ERROR;
-
-  UpdateLastError();
-  if (err == 0)
-    state_ = CS_CONNECTING;
-  return err;
-}
-
-Win32Socket* Win32Socket::Accept(SocketAddress *paddr) {
-  sockaddr_in saddr;
-  socklen_t cbAddr = sizeof(saddr);
-  SOCKET s = ::accept(socket_, reinterpret_cast<sockaddr*>(&saddr), &cbAddr);
-  UpdateLastError();
-  if (s == INVALID_SOCKET)
-    return NULL;
-  if (paddr)
-    paddr->FromSockAddr(saddr);
-  Win32Socket* socket = new Win32Socket;
-  if (0 == socket->Attach(s))
-    return socket;
-  delete socket;
-  return NULL;
-}
-
-int Win32Socket::Close() {
-  int err = 0;
-  if (socket_ != INVALID_SOCKET) {
-    err = ::closesocket(socket_);
-    socket_ = INVALID_SOCKET;
-    closing_ = false;
-    close_error_ = 0;
-    UpdateLastError();
-  }
-  if (dns_) {
-    WSACancelAsyncRequest(dns_->handle);
-    delete dns_;
-    dns_ = NULL;
-  }
-  if (sink_) {
-    sink_->Dispose();
-    sink_ = NULL;
-  }
-  addr_.Clear();
-  state_ = CS_CLOSED;
-  return err;
-}
-
-int Win32Socket::EstimateMTU(uint16* mtu) {
-  SocketAddress addr = GetRemoteAddress();
-  if (addr.IsAny()) {
-    error_ = ENOTCONN;
-    return -1;
-  }
-
-  WinPing ping;
-  if (!ping.IsValid()) {
-    error_ = EINVAL;  // can't think of a better error ID
-    return -1;
-  }
-
-  for (int level = 0; PACKET_MAXIMUMS[level + 1] > 0; ++level) {
-    int32 size = PACKET_MAXIMUMS[level] - IP_HEADER_SIZE - ICMP_HEADER_SIZE;
-    WinPing::PingResult result = ping.Ping(addr.ip(), size, 0, 1, false);
-    if (result == WinPing::PING_FAIL) {
-      error_ = EINVAL;  // can't think of a better error ID
-      return -1;
-    }
-    if (result != WinPing::PING_TOO_LARGE) {
-      *mtu = PACKET_MAXIMUMS[level];
-      return 0;
-    }
-  }
-
-  ASSERT(false);
-  return 0;
-}
-
-bool Win32Socket::SetAsync(int events) {
-  ASSERT(NULL == sink_);
-
-  // Create window
-  sink_ = new EventSink(this);
-  sink_->Create(NULL, L"EventSink", 0, 0, 0, 0, 10, 10);
-
-  // start the async select
-  if (WSAAsyncSelect(socket_, sink_->handle(), WM_SOCKETNOTIFY, events)
-      == SOCKET_ERROR) {
-    UpdateLastError();
-    Close();
-    return false;
-  }
-
-  return true;
-}
-
-bool Win32Socket::HandleClosed(int close_error) {
-  // WM_CLOSE will be received before all data has been read, so we need to
-  // hold on to it until the read buffer has been drained.
-  char ch;
-  closing_ = true;
-  close_error_ = close_error;
-  return (::recv(socket_, &ch, 1, MSG_PEEK) <= 0);
-}
-
-void Win32Socket::PostClosed() {
-  // If we see that the buffer is indeed drained, then send the close.
-  closing_ = false;
-  ::PostMessage(sink_->handle(), WM_SOCKETNOTIFY,
-                socket_, WSAMAKESELECTREPLY(FD_CLOSE, close_error_));
-}
-
-void Win32Socket::UpdateLastError() {
-  error_ = WSAGetLastError();
-}
-
-int Win32Socket::TranslateOption(Option opt, int* slevel, int* sopt) {
-  switch (opt) {
-    case OPT_DONTFRAGMENT:
-      *slevel = IPPROTO_IP;
-      *sopt = IP_DONTFRAGMENT;
-      break;
-    case OPT_RCVBUF:
-      *slevel = SOL_SOCKET;
-      *sopt = SO_RCVBUF;
-      break;
-    case OPT_SNDBUF:
-      *slevel = SOL_SOCKET;
-      *sopt = SO_SNDBUF;
-      break;
-    case OPT_NODELAY:
-      *slevel = IPPROTO_TCP;
-      *sopt = TCP_NODELAY;
-      break;
-    default:
-      ASSERT(false);
-      return -1;
-  }
-  return 0;
-}
-
-void Win32Socket::OnSocketNotify(SOCKET socket, int event, int error) {
-  // Ignore events if we're already closed.
-  if (socket != socket_)
-    return;
-
-  error_ = error;
-  switch (event) {
-    case FD_CONNECT:
-      if (error != ERROR_SUCCESS) {
-        ReportWSAError("WSAAsync:connect notify", error, addr_);
-#ifdef _DEBUG
-        int32 duration = TimeSince(connect_time_);
-        LOG(LS_INFO) << "WSAAsync:connect error (" << duration
-                     << " ms), faking close";
-#endif
-        state_ = CS_CLOSED;
-        // If you get an error connecting, close doesn't really do anything
-        // and it certainly doesn't send back any close notification, but
-        // we really only maintain a few states, so it is easiest to get
-        // back into a known state by pretending that a close happened, even
-        // though the connect event never did occur.
-        SignalCloseEvent(this, error);
-      } else {
-#ifdef _DEBUG
-        int32 duration = TimeSince(connect_time_);
-        LOG(LS_INFO) << "WSAAsync:connect (" << duration << " ms)";
-#endif
-        state_ = CS_CONNECTED;
-        SignalConnectEvent(this);
-      }
-      break;
-
-    case FD_ACCEPT:
-    case FD_READ:
-      if (error != ERROR_SUCCESS) {
-        ReportWSAError("WSAAsync:read notify", error, addr_);
-      } else {
-        SignalReadEvent(this);
-      }
-      break;
-
-    case FD_WRITE:
-      if (error != ERROR_SUCCESS) {
-        ReportWSAError("WSAAsync:write notify", error, addr_);
-      } else {
-        SignalWriteEvent(this);
-      }
-      break;
-
-    case FD_CLOSE:
-      if (HandleClosed(error)) {
-        ReportWSAError("WSAAsync:close notify", error, addr_);
-        state_ = CS_CLOSED;
-        SignalCloseEvent(this, error);
-      }
-      break;
-  }
-}
-
-void Win32Socket::OnDnsNotify(HANDLE task, int error) {
-  if (!dns_ || dns_->handle != task)
-    return;
-
-  uint32 ip = 0;
-  if (error == 0) {
-    hostent* pHost = reinterpret_cast<hostent*>(dns_->buffer);
-    uint32 net_ip = *reinterpret_cast<uint32*>(pHost->h_addr_list[0]);
-    ip = NetworkToHost32(net_ip);
-  }
-
-  LOG_F(LS_INFO) << "(" << SocketAddress::IPToString(ip)
-                 << ", " << error << ")";
-
-  if (error == 0) {
-    SocketAddress address(ip, dns_->port);
-    error = DoConnect(address);
-  } else {
-    Close();
-  }
-
-  if (error) {
-    error_ = error;
-    SignalCloseEvent(this, error_);
-  } else {
-    delete dns_;
-    dns_ = NULL;
-  }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Win32SocketServer
-// Provides cricket base services on top of a win32 gui thread
-///////////////////////////////////////////////////////////////////////////////
-
-static UINT s_wm_wakeup_id = 0;
-const TCHAR Win32SocketServer::kWindowName[] = L"libjingle Message Window";
-
-Win32SocketServer::Win32SocketServer(MessageQueue* message_queue)
-    : message_queue_(message_queue),
-      wnd_(this),
-      posted_(false),
-      hdlg_(NULL) {
-  if (s_wm_wakeup_id == 0)
-    s_wm_wakeup_id = RegisterWindowMessage(L"WM_WAKEUP");
-  if (!wnd_.Create(NULL, kWindowName, 0, 0, 0, 0, 0, 0)) {
-    LOG_GLE(LS_ERROR) << "Failed to create message window.";
-  }
-}
-
-Win32SocketServer::~Win32SocketServer() {
-  if (wnd_.handle() != NULL) {
-    KillTimer(wnd_.handle(), 1);
-    wnd_.Destroy();
-  }
-}
-
-Socket* Win32SocketServer::CreateSocket(int type) {
-  return CreateAsyncSocket(type);
-}
-
-AsyncSocket* Win32SocketServer::CreateAsyncSocket(int type) {
-  Win32Socket* socket = new Win32Socket;
-  if (socket->CreateT(type)) {
-    return socket;
-  }
-  delete socket;
-  return NULL;
-}
-
-void Win32SocketServer::SetMessageQueue(MessageQueue* queue) {
-  message_queue_ = queue;
-}
-
-bool Win32SocketServer::Wait(int cms, bool process_io) {
-  BOOL b;
-  if (process_io) {
-    // Spin the Win32 message pump at least once, and as long as requested.
-    // This is the Thread::ProcessMessages case.
-    uint32 start = Time();
-    do {
-      MSG msg;
-      SetTimer(wnd_.handle(), 0, cms, NULL);
-      // Get the next available message. If we have a modeless dialog, give
-      // give the message to IsDialogMessage, which will return true if it
-      // was a message for the dialog that it handled internally.
-      // Otherwise, dispatch as usual via Translate/DispatchMessage.
-      b = GetMessage(&msg, NULL, 0, 0);
-      if (b) {
-        if (!hdlg_ || !IsDialogMessage(hdlg_, &msg)) {
-          TranslateMessage(&msg);
-          DispatchMessage(&msg);
-        }
-      }
-      KillTimer(wnd_.handle(), 0);
-    } while (b && TimeSince(start) < cms);
-  } else if (cms != 0) {
-    // Sit and wait forever for a WakeUp. This is the Thread::Send case.
-    ASSERT(cms == -1);
-    MSG msg;
-    b = GetMessage(&msg, NULL, s_wm_wakeup_id, s_wm_wakeup_id);
-    {
-      CritScope scope(&cs_);
-      posted_ = false;
-    }
-  } else {
-    // No-op (cms == 0 && !process_io). This is the Pump case.
-    b = TRUE;
-  }
-  return (b != FALSE);
-}
-
-void Win32SocketServer::WakeUp() {
-  if (wnd_.handle()) {
-    // Set the "message pending" flag, if not already set.
-    {
-      CritScope scope(&cs_);
-      if (posted_)
-        return;
-      posted_ = true;
-    }
-
-    PostMessage(wnd_.handle(), s_wm_wakeup_id, 0, 0);
-  }
-}
-
-void Win32SocketServer::Pump() {
-  // Clear the "message pending" flag.
-  {
-    CritScope scope(&cs_);
-    posted_ = false;
-  }
-
-  // Dispatch all the messages that are currently in our queue. If new messages
-  // are posted during the dispatch, they will be handled in the next Pump.
-  // We use max(1, ...) to make sure we try to dispatch at least once, since
-  // this allow us to process "sent" messages, not included in the size() count.
-  Message msg;
-  for (size_t max_messages_to_process = _max<size_t>(1, message_queue_->size());
-       max_messages_to_process > 0 && message_queue_->Get(&msg, 0, false);
-       --max_messages_to_process) {
-    message_queue_->Dispatch(&msg);
-  }
-
-  // Anything remaining?
-  int delay = message_queue_->GetDelay();
-  if (delay == -1) {
-    KillTimer(wnd_.handle(), 1);
-  } else {
-    SetTimer(wnd_.handle(), 1, delay, NULL);
-  }
-}
-
-bool Win32SocketServer::MessageWindow::OnMessage(UINT wm, WPARAM wp,
-                                                 LPARAM lp, LRESULT& lr) {
-  bool handled = false;
-  if (wm == s_wm_wakeup_id || (wm == WM_TIMER && wp == 1)) {
-    ss_->Pump();
-    lr = 0;
-    handled = true;
-  }
-  return handled;
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/win32socketserver.h b/third_party/libjingle/source/talk/base/win32socketserver.h
deleted file mode 100644
index 17d3bbb..0000000
--- a/third_party/libjingle/source/talk/base/win32socketserver.h
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_WIN32SOCKETSERVER_H_
-#define TALK_BASE_WIN32SOCKETSERVER_H_
-
-#ifdef WIN32
-#include "talk/base/asyncsocket.h"
-#include "talk/base/criticalsection.h"
-#include "talk/base/messagequeue.h"
-#include "talk/base/socketserver.h"
-#include "talk/base/socketfactory.h"
-#include "talk/base/socket.h"
-#include "talk/base/thread.h"
-#include "talk/base/win32window.h"
-
-namespace talk_base {
-
-///////////////////////////////////////////////////////////////////////////////
-// Win32Socket
-///////////////////////////////////////////////////////////////////////////////
-
-class Win32Socket : public AsyncSocket {
- public:
-  Win32Socket();
-  virtual ~Win32Socket();
-
-  bool CreateT(int type);
-
-  int Attach(SOCKET s);
-  void SetTimeout(int ms);
-
-  // AsyncSocket Interface
-  virtual SocketAddress GetLocalAddress() const;
-  virtual SocketAddress GetRemoteAddress() const;
-  virtual int Bind(const SocketAddress& addr);
-  virtual int Connect(const SocketAddress& addr);
-  virtual int Send(const void *pv, size_t cb);
-  virtual int SendTo(const void *pv, size_t cb, const SocketAddress& addr);
-  virtual int Recv(void *pv, size_t cb);
-  virtual int RecvFrom(void *pv, size_t cb, SocketAddress *paddr);
-  virtual int Listen(int backlog);
-  virtual Win32Socket *Accept(SocketAddress *paddr);
-  virtual int Close();
-  virtual int GetError() const;
-  virtual void SetError(int error);
-  virtual ConnState GetState() const;
-  virtual int EstimateMTU(uint16* mtu);
-  virtual int GetOption(Option opt, int* value);
-  virtual int SetOption(Option opt, int value);
-
- private:
-  bool SetAsync(int events);
-  int DoConnect(const SocketAddress& addr);
-  bool HandleClosed(int close_error);
-  void PostClosed();
-  void UpdateLastError();
-  static int TranslateOption(Option opt, int* slevel, int* sopt);
-
-  void OnSocketNotify(SOCKET socket, int event, int error);
-  void OnDnsNotify(HANDLE task, int error);
-
-  SOCKET socket_;
-  int error_;
-  ConnState state_;
-  SocketAddress addr_;         // address that we connected to (see DoConnect)
-  uint32 connect_time_;
-  bool closing_;
-  int close_error_;
-
-  class EventSink;
-  friend class EventSink;
-  EventSink * sink_;
-
-  struct DnsLookup;
-  DnsLookup * dns_;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// Win32SocketServer
-///////////////////////////////////////////////////////////////////////////////
-
-class Win32SocketServer : public SocketServer {
- public:
-  explicit Win32SocketServer(MessageQueue* message_queue);
-  virtual ~Win32SocketServer();
-
-  void set_modeless_dialog(HWND hdlg) {
-    hdlg_ = hdlg;
-  }
-
-  // SocketServer Interface
-  virtual Socket* CreateSocket(int type);
-  virtual AsyncSocket* CreateAsyncSocket(int type);
-  virtual void SetMessageQueue(MessageQueue* queue);
-  virtual bool Wait(int cms, bool process_io);
-  virtual void WakeUp();
-
-  void Pump();
-
-  HWND handle() { return wnd_.handle(); }
-
- private:
-  class MessageWindow : public Win32Window {
-   public:
-    explicit MessageWindow(Win32SocketServer* ss) : ss_(ss) {}
-   private:
-    virtual bool OnMessage(UINT msg, WPARAM wp, LPARAM lp, LRESULT& result);
-    Win32SocketServer* ss_;
-  };
-
-  static const TCHAR kWindowName[];
-  MessageQueue *message_queue_;
-  MessageWindow wnd_;
-  CriticalSection cs_;
-  bool posted_;
-  HWND hdlg_;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// Win32Thread. Automatically pumps Windows messages.
-///////////////////////////////////////////////////////////////////////////////
-
-class Win32Thread : public Thread {
- public:
-  Win32Thread() : ss_(this), id_(0) {
-    set_socketserver(&ss_);
-  }
-  virtual ~Win32Thread() {
-    set_socketserver(NULL);
-  }
-  virtual void Run() {
-    id_ = GetCurrentThreadId();
-    Thread::Run();
-    id_ = 0;
-  }
-  virtual void Quit() {
-    PostThreadMessage(id_, WM_QUIT, 0, 0);
-  }
- private:
-  Win32SocketServer ss_;
-  DWORD id_;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-
-}  // namespace talk_base
-
-#endif  // WIN32
-
-#endif  // TALK_BASE_WIN32SOCKETSERVER_H_
diff --git a/third_party/libjingle/source/talk/base/win32window.cc b/third_party/libjingle/source/talk/base/win32window.cc
deleted file mode 100644
index 0e7761f..0000000
--- a/third_party/libjingle/source/talk/base/win32window.cc
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/common.h"
-#include "talk/base/logging.h"
-#include "talk/base/win32window.h"
-
-namespace talk_base {
-
-///////////////////////////////////////////////////////////////////////////////
-// Win32Window
-///////////////////////////////////////////////////////////////////////////////
-
-static const wchar_t kWindowBaseClassName[] = L"WindowBaseClass";
-HINSTANCE Win32Window::instance_ = GetModuleHandle(NULL);
-ATOM Win32Window::window_class_ = 0;
-
-Win32Window::Win32Window() : wnd_(NULL) {
-}
-
-Win32Window::~Win32Window() {
-  ASSERT(NULL == wnd_);
-}
-
-bool Win32Window::Create(HWND parent, const wchar_t* title, DWORD style,
-                         DWORD exstyle, int x, int y, int cx, int cy) {
-  if (wnd_) {
-    // Window already exists.
-    return false;
-  }
-
-  if (!window_class_) {
-    // Class not registered, register it.
-    WNDCLASSEX wcex;
-    memset(&wcex, 0, sizeof(wcex));
-    wcex.cbSize = sizeof(wcex);
-    wcex.hInstance = instance_;
-    wcex.lpfnWndProc = &Win32Window::WndProc;
-    wcex.lpszClassName = kWindowBaseClassName;
-    window_class_ = ::RegisterClassEx(&wcex);
-    if (!window_class_) {
-      LOG_GLE(LS_ERROR) << "RegisterClassEx failed";
-      return false;
-    }
-  }
-  wnd_ = ::CreateWindowEx(exstyle, kWindowBaseClassName, title, style,
-                          x, y, cx, cy, parent, NULL, instance_, this);
-  return (NULL != wnd_);
-}
-
-void Win32Window::Destroy() {
-  VERIFY(::DestroyWindow(wnd_) != FALSE);
-}
-
-void Win32Window::SetInstance(HINSTANCE instance) {
-  instance_ = instance;
-}
-
-void Win32Window::Shutdown() {
-  if (window_class_) {
-    ::UnregisterClass(MAKEINTATOM(window_class_), instance_);
-    window_class_ = 0;
-  }
-}
-
-bool Win32Window::OnMessage(UINT uMsg, WPARAM wParam, LPARAM lParam,
-                            LRESULT& result) {
-  switch (uMsg) {
-  case WM_CLOSE:
-    if (!OnClose()) {
-      result = 0;
-      return true;
-    }
-    break;
-  }
-  return false;
-}
-
-LRESULT Win32Window::WndProc(HWND hwnd, UINT uMsg,
-                             WPARAM wParam, LPARAM lParam) {
-  Win32Window* that = reinterpret_cast<Win32Window*>(
-      ::GetWindowLongPtr(hwnd, GWL_USERDATA));
-  if (!that && (WM_CREATE == uMsg)) {
-    CREATESTRUCT* cs = reinterpret_cast<CREATESTRUCT*>(lParam);
-    that = static_cast<Win32Window*>(cs->lpCreateParams);
-    that->wnd_ = hwnd;
-    ::SetWindowLongPtr(hwnd, GWL_USERDATA, reinterpret_cast<LONG_PTR>(that));
-  }
-  if (that) {
-    LRESULT result;
-    bool handled = that->OnMessage(uMsg, wParam, lParam, result);
-    if (WM_DESTROY == uMsg) {
-      for (HWND child = ::GetWindow(hwnd, GW_CHILD); child;
-           child = ::GetWindow(child, GW_HWNDNEXT)) {
-        LOG(LS_INFO) << "Child window: " << static_cast<void*>(child);
-      }
-    }
-    if (WM_NCDESTROY == uMsg) {
-      ::SetWindowLongPtr(hwnd, GWL_USERDATA, NULL);
-      that->wnd_ = NULL;
-      that->OnDestroyed();
-    }
-    if (handled) {
-      return result;
-    }
-  }
-  return ::DefWindowProc(hwnd, uMsg, wParam, lParam);
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/win32window.h b/third_party/libjingle/source/talk/base/win32window.h
deleted file mode 100644
index 66a56ce..0000000
--- a/third_party/libjingle/source/talk/base/win32window.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_WIN32WINDOW_H_
-#define TALK_BASE_WIN32WINDOW_H_
-
-#ifdef WIN32
-
-#include "talk/base/win32.h"
-
-namespace talk_base {
-
-///////////////////////////////////////////////////////////////////////////////
-// Win32Window
-///////////////////////////////////////////////////////////////////////////////
-
-class Win32Window {
- public:
-  Win32Window();
-  virtual ~Win32Window();
-
-  HWND handle() const { return wnd_; }
-
-  bool Create(HWND parent, const wchar_t* title, DWORD style, DWORD exstyle,
-              int x, int y, int cx, int cy);
-  void Destroy();
-
-  // Call this first if you are running inside a DLL.
-  static void SetInstance(HINSTANCE instance);
-  // Call this when your DLL unloads.
-  static void Shutdown();
-
- protected:
-  virtual bool OnMessage(UINT uMsg, WPARAM wParam, LPARAM lParam,
-                         LRESULT& result);
-
-  virtual bool OnClose() { return true; }
-  virtual void OnDestroyed() { }
-
- private:
-  static LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam,
-                                  LPARAM lParam);
-
-  HWND wnd_;
-  static HINSTANCE instance_;
-  static ATOM window_class_;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-
-}  // namespace talk_base
-
-#endif  // WIN32
-
-#endif  // TALK_BASE_WIN32WINDOW_H_
diff --git a/third_party/libjingle/source/talk/base/window.h b/third_party/libjingle/source/talk/base/window.h
deleted file mode 100644
index aa1f4c1..0000000
--- a/third_party/libjingle/source/talk/base/window.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_WINDOW_H_
-#define TALK_BASE_WINDOW_H_
-
-namespace talk_base {
-
-// Used for identifying a window handle.
-typedef unsigned int WindowId;
-
-const WindowId kInvalidWindowId = 0;
-const WindowId kDesktopWindowId = 0xFFFFFFFF;
-
-// Window event types.
-enum WindowEvent {
-  WE_RESIZE = 0,
-  WE_CLOSE = 1,
-  WE_MINIMIZE = 2,
-  WE_RESTORE = 3,
-};
-
-}  // namespace talk_base
-
-#endif // TALK_BASE_WINDOW_H_
diff --git a/third_party/libjingle/source/talk/base/winfirewall.cc b/third_party/libjingle/source/talk/base/winfirewall.cc
deleted file mode 100644
index e87ee5a..0000000
--- a/third_party/libjingle/source/talk/base/winfirewall.cc
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/winfirewall.h"
-
-#include "talk/base/win32.h"
-
-#include <comdef.h>
-#include <netfw.h>
-
-#define RELEASE(lpUnk) do { \
-  if ((lpUnk) != NULL) { \
-    (lpUnk)->Release(); \
-    (lpUnk) = NULL; \
-  } \
-} while (0)
-
-namespace talk_base {
-
-//////////////////////////////////////////////////////////////////////
-// WinFirewall
-//////////////////////////////////////////////////////////////////////
-
-WinFirewall::WinFirewall() : mgr_(NULL), policy_(NULL), profile_(NULL) {
-}
-
-WinFirewall::~WinFirewall() {
-  Shutdown();
-}
-
-bool WinFirewall::Initialize(HRESULT* result) {
-  if (mgr_) {
-    if (result) {
-      *result = S_OK;
-    }
-    return true;
-  }
-
-  HRESULT hr = CoCreateInstance(__uuidof(NetFwMgr),
-                                0, CLSCTX_INPROC_SERVER,
-                                __uuidof(INetFwMgr),
-                                reinterpret_cast<void **>(&mgr_));
-  if (SUCCEEDED(hr) && (mgr_ != NULL))
-    hr = mgr_->get_LocalPolicy(&policy_);
-  if (SUCCEEDED(hr) && (policy_ != NULL))
-    hr = policy_->get_CurrentProfile(&profile_);
-
-  if (result)
-    *result = hr;
-  return SUCCEEDED(hr) && (profile_ != NULL);
-}
-
-void WinFirewall::Shutdown() {
-  RELEASE(profile_);
-  RELEASE(policy_);
-  RELEASE(mgr_);
-}
-
-bool WinFirewall::Enabled() const {
-  if (!profile_)
-    return false;
-
-  VARIANT_BOOL fwEnabled = VARIANT_FALSE;
-  profile_->get_FirewallEnabled(&fwEnabled);
-  return (fwEnabled != VARIANT_FALSE);
-}
-
-bool WinFirewall::QueryAuthorized(const char* filename, bool* authorized)
-    const {
-  return QueryAuthorizedW(ToUtf16(filename).c_str(), authorized);
-}
-
-bool WinFirewall::QueryAuthorizedW(const wchar_t* filename, bool* authorized)
-    const {
-  *authorized = false;
-  bool success = false;
-
-  if (!profile_)
-    return false;
-
-  _bstr_t bfilename = filename;
-
-  INetFwAuthorizedApplications* apps = NULL;
-  HRESULT hr = profile_->get_AuthorizedApplications(&apps);
-  if (SUCCEEDED(hr) && (apps != NULL)) {
-    INetFwAuthorizedApplication* app = NULL;
-    hr = apps->Item(bfilename, &app);
-    if (SUCCEEDED(hr) && (app != NULL)) {
-      VARIANT_BOOL fwEnabled = VARIANT_FALSE;
-      hr = app->get_Enabled(&fwEnabled);
-      app->Release();
-
-      if (SUCCEEDED(hr)) {
-        success = true;
-        *authorized = (fwEnabled != VARIANT_FALSE);
-      }
-    } else if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) {
-      // No entry in list of authorized apps
-      success = true;
-    } else {
-      // Unexpected error
-    }
-    apps->Release();
-  }
-
-  return success;
-}
-
-bool WinFirewall::AddApplication(const char* filename,
-                                 const char* friendly_name,
-                                 bool authorized,
-                                 HRESULT* result) {
-  return AddApplicationW(ToUtf16(filename).c_str(),
-      ToUtf16(friendly_name).c_str(), authorized, result);
-}
-
-bool WinFirewall::AddApplicationW(const wchar_t* filename,
-                                  const wchar_t* friendly_name,
-                                  bool authorized,
-                                  HRESULT* result) {
-  INetFwAuthorizedApplications* apps = NULL;
-  HRESULT hr = profile_->get_AuthorizedApplications(&apps);
-  if (SUCCEEDED(hr) && (apps != NULL)) {
-    INetFwAuthorizedApplication* app = NULL;
-    hr = CoCreateInstance(__uuidof(NetFwAuthorizedApplication),
-                          0, CLSCTX_INPROC_SERVER,
-                          __uuidof(INetFwAuthorizedApplication),
-                          reinterpret_cast<void **>(&app));
-    if (SUCCEEDED(hr) && (app != NULL)) {
-      _bstr_t bstr = filename;
-      hr = app->put_ProcessImageFileName(bstr);
-      bstr = friendly_name;
-      if (SUCCEEDED(hr))
-        hr = app->put_Name(bstr);
-      if (SUCCEEDED(hr))
-        hr = app->put_Enabled(authorized ? VARIANT_TRUE : VARIANT_FALSE);
-      if (SUCCEEDED(hr))
-        hr = apps->Add(app);
-      app->Release();
-    }
-    apps->Release();
-  }
-  if (result)
-    *result = hr;
-  return SUCCEEDED(hr);
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/winfirewall.h b/third_party/libjingle/source/talk/base/winfirewall.h
deleted file mode 100644
index 11d687e..0000000
--- a/third_party/libjingle/source/talk/base/winfirewall.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_WINFIREWALL_H_
-#define TALK_BASE_WINFIREWALL_H_
-
-#ifndef _HRESULT_DEFINED
-#define _HRESULT_DEFINED
-typedef long HRESULT;  // Can't forward declare typedef, but don't need all win
-#endif // !_HRESULT_DEFINED
-
-struct INetFwMgr;
-struct INetFwPolicy;
-struct INetFwProfile;
-
-namespace talk_base {
-
-//////////////////////////////////////////////////////////////////////
-// WinFirewall
-//////////////////////////////////////////////////////////////////////
-
-class WinFirewall {
- public:
-  WinFirewall();
-  ~WinFirewall();
-
-  bool Initialize(HRESULT* result);
-  void Shutdown();
-
-  bool Enabled() const;
-  bool QueryAuthorized(const char* filename, bool* authorized) const;
-  bool QueryAuthorizedW(const wchar_t* filename, bool* authorized) const;
-
-  bool AddApplication(const char* filename, const char* friendly_name,
-                      bool authorized, HRESULT* result);
-  bool AddApplicationW(const wchar_t* filename, const wchar_t* friendly_name,
-                       bool authorized, HRESULT* result);
-
- private:
-  INetFwMgr* mgr_;
-  INetFwPolicy* policy_;
-  INetFwProfile* profile_;
-};
-
-//////////////////////////////////////////////////////////////////////
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_WINFIREWALL_H_
diff --git a/third_party/libjingle/source/talk/base/winping.cc b/third_party/libjingle/source/talk/base/winping.cc
deleted file mode 100644
index a16ac78..0000000
--- a/third_party/libjingle/source/talk/base/winping.cc
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/byteorder.h"
-#include "talk/base/common.h"
-#include "talk/base/socketaddress.h"
-#include "talk/base/winping.h"
-#include "talk/base/logging.h"
-#include <cassert>
-
-namespace talk_base {
-
-//////////////////////////////////////////////////////////////////////
-// Found in IPExport.h
-//////////////////////////////////////////////////////////////////////
-
-typedef struct icmp_echo_reply {
-    ULONG   Address;            // Replying address
-    ULONG   Status;             // Reply IP_STATUS
-    ULONG   RoundTripTime;      // RTT in milliseconds
-    USHORT  DataSize;           // Reply data size in bytes
-    USHORT  Reserved;           // Reserved for system use
-    PVOID   Data;               // Pointer to the reply data
-    struct ip_option_information Options; // Reply options
-} ICMP_ECHO_REPLY, * PICMP_ECHO_REPLY;
-
-//
-// IP_STATUS codes returned from IP APIs
-//
-
-#define IP_STATUS_BASE              11000
-
-#define IP_SUCCESS                  0
-#define IP_BUF_TOO_SMALL            (IP_STATUS_BASE + 1)
-#define IP_DEST_NET_UNREACHABLE     (IP_STATUS_BASE + 2)
-#define IP_DEST_HOST_UNREACHABLE    (IP_STATUS_BASE + 3)
-#define IP_DEST_PROT_UNREACHABLE    (IP_STATUS_BASE + 4)
-#define IP_DEST_PORT_UNREACHABLE    (IP_STATUS_BASE + 5)
-#define IP_NO_RESOURCES             (IP_STATUS_BASE + 6)
-#define IP_BAD_OPTION               (IP_STATUS_BASE + 7)
-#define IP_HW_ERROR                 (IP_STATUS_BASE + 8)
-#define IP_PACKET_TOO_BIG           (IP_STATUS_BASE + 9)
-#define IP_REQ_TIMED_OUT            (IP_STATUS_BASE + 10)
-#define IP_BAD_REQ                  (IP_STATUS_BASE + 11)
-#define IP_BAD_ROUTE                (IP_STATUS_BASE + 12)
-#define IP_TTL_EXPIRED_TRANSIT      (IP_STATUS_BASE + 13)
-#define IP_TTL_EXPIRED_REASSEM      (IP_STATUS_BASE + 14)
-#define IP_PARAM_PROBLEM            (IP_STATUS_BASE + 15)
-#define IP_SOURCE_QUENCH            (IP_STATUS_BASE + 16)
-#define IP_OPTION_TOO_BIG           (IP_STATUS_BASE + 17)
-#define IP_BAD_DESTINATION          (IP_STATUS_BASE + 18)
-
-#define IP_ADDR_DELETED             (IP_STATUS_BASE + 19)
-#define IP_SPEC_MTU_CHANGE          (IP_STATUS_BASE + 20)
-#define IP_MTU_CHANGE               (IP_STATUS_BASE + 21)
-#define IP_UNLOAD                   (IP_STATUS_BASE + 22)
-#define IP_ADDR_ADDED               (IP_STATUS_BASE + 23)
-#define IP_MEDIA_CONNECT            (IP_STATUS_BASE + 24)
-#define IP_MEDIA_DISCONNECT         (IP_STATUS_BASE + 25)
-#define IP_BIND_ADAPTER             (IP_STATUS_BASE + 26)
-#define IP_UNBIND_ADAPTER           (IP_STATUS_BASE + 27)
-#define IP_DEVICE_DOES_NOT_EXIST    (IP_STATUS_BASE + 28)
-#define IP_DUPLICATE_ADDRESS        (IP_STATUS_BASE + 29)
-#define IP_INTERFACE_METRIC_CHANGE  (IP_STATUS_BASE + 30)
-#define IP_RECONFIG_SECFLTR         (IP_STATUS_BASE + 31)
-#define IP_NEGOTIATING_IPSEC        (IP_STATUS_BASE + 32)
-#define IP_INTERFACE_WOL_CAPABILITY_CHANGE  (IP_STATUS_BASE + 33)
-#define IP_DUPLICATE_IPADD          (IP_STATUS_BASE + 34)
-
-#define IP_GENERAL_FAILURE          (IP_STATUS_BASE + 50)
-#define MAX_IP_STATUS               IP_GENERAL_FAILURE
-#define IP_PENDING                  (IP_STATUS_BASE + 255)
-
-//
-// Values used in the IP header Flags field.
-//
-#define IP_FLAG_DF      0x2         // Don't fragment this packet.
-
-//
-// Supported IP Option Types.
-//
-// These types define the options which may be used in the OptionsData field
-// of the ip_option_information structure.  See RFC 791 for a complete
-// description of each.
-//
-#define IP_OPT_EOL      0          // End of list option
-#define IP_OPT_NOP      1          // No operation
-#define IP_OPT_SECURITY 0x82       // Security option
-#define IP_OPT_LSRR     0x83       // Loose source route
-#define IP_OPT_SSRR     0x89       // Strict source route
-#define IP_OPT_RR       0x7        // Record route
-#define IP_OPT_TS       0x44       // Timestamp
-#define IP_OPT_SID      0x88       // Stream ID (obsolete)
-#define IP_OPT_ROUTER_ALERT 0x94  // Router Alert Option
-
-#define MAX_OPT_SIZE    40         // Maximum length of IP options in bytes
-
-//////////////////////////////////////////////////////////////////////
-// Global Constants and Types
-//////////////////////////////////////////////////////////////////////
-
-const char * const ICMP_DLL_NAME = "icmp.dll";
-const char * const ICMP_CREATE_FUNC = "IcmpCreateFile";
-const char * const ICMP_CLOSE_FUNC = "IcmpCloseHandle";
-const char * const ICMP_SEND_FUNC = "IcmpSendEcho";
-
-inline uint32 ReplySize(uint32 data_size) {
-  // A ping error message is 8 bytes long, so make sure we allow for at least
-  // 8 bytes of reply data.
-  return sizeof(ICMP_ECHO_REPLY) + talk_base::_max<uint32>(8, data_size);
-}
-
-//////////////////////////////////////////////////////////////////////
-// WinPing
-//////////////////////////////////////////////////////////////////////
-
-WinPing::WinPing()
-    : dll_(0), hping_(INVALID_HANDLE_VALUE), create_(0), close_(0), send_(0),
-      data_(0), dlen_(0), reply_(0), rlen_(0), valid_(false) {
-
-  dll_ = LoadLibraryA(ICMP_DLL_NAME);
-  if (!dll_) {
-    LOG(LERROR) << "LoadLibrary: " << GetLastError();
-    return;
-  }
-
-  create_ = (PIcmpCreateFile) GetProcAddress(dll_, ICMP_CREATE_FUNC);
-  close_ = (PIcmpCloseHandle) GetProcAddress(dll_, ICMP_CLOSE_FUNC);
-  send_ = (PIcmpSendEcho) GetProcAddress(dll_, ICMP_SEND_FUNC);
-  if (!create_ || !close_ || !send_) {
-    LOG(LERROR) << "GetProcAddress(ICMP_*): " << GetLastError();
-    return;
-  }
-
-  hping_ = create_();
-  if (hping_ == INVALID_HANDLE_VALUE) {
-    LOG(LERROR) << "IcmpCreateFile: " << GetLastError();
-    return;
-  }
-
-  dlen_ = 0;
-  rlen_ = ReplySize(dlen_);
-  data_ = new char[dlen_];
-  reply_ = new char[rlen_];
-
-  valid_ = true;
-}
-
-WinPing::~WinPing() {
-  if (dll_)
-    FreeLibrary(dll_);
-
-  if ((hping_ != INVALID_HANDLE_VALUE) && close_) {
-    if (!close_(hping_))
-      LOG(WARNING) << "IcmpCloseHandle: " << GetLastError();
-  }
-
-  delete[] data_;
-  delete[] reply_;
-}
-
-WinPing::PingResult WinPing::Ping(
-    uint32 ip, uint32 data_size, uint32 timeout, uint8 ttl,
-    bool allow_fragments) {
-
-  assert(IsValid());
-
-  IP_OPTION_INFORMATION ipopt;
-  memset(&ipopt, 0, sizeof(ipopt));
-  if (!allow_fragments)
-    ipopt.Flags |= IP_FLAG_DF;
-  ipopt.Ttl = ttl;
-
-  uint32 reply_size = ReplySize(data_size);
-
-  if (data_size > dlen_) {
-    delete [] data_;
-    dlen_ = data_size;
-    data_ = new char[dlen_];
-    memset(data_, 'z', dlen_);
-  }
-
-  if (reply_size > rlen_) {
-    delete [] reply_;
-    rlen_ = reply_size;
-    reply_ = new char[rlen_];
-  }
-
-  DWORD result = send_(hping_, talk_base::HostToNetwork32(ip),
-                       data_, uint16(data_size), &ipopt,
-                       reply_, reply_size, timeout);
-  if (result == 0) {
-    long error = GetLastError();
-    if (error == IP_PACKET_TOO_BIG)
-      return PING_TOO_LARGE;
-    if (error == IP_REQ_TIMED_OUT)
-      return PING_TIMEOUT;
-    LOG(LERROR) << "IcmpSendEcho(" << talk_base::SocketAddress::IPToString(ip)
-                << ", " << data_size << "): " << error;
-    return PING_FAIL;
-  }
-
-  return PING_SUCCESS;
-}
-
-//////////////////////////////////////////////////////////////////////
-// Microsoft Documenation
-//////////////////////////////////////////////////////////////////////
-//
-// Routine Name:
-//
-//     IcmpCreateFile
-//
-// Routine Description:
-//
-//     Opens a handle on which ICMP Echo Requests can be issued.
-//
-// Arguments:
-//
-//     None.
-//
-// Return Value:
-//
-//     An open file handle or INVALID_HANDLE_VALUE. Extended error information
-//     is available by calling GetLastError().
-//
-//////////////////////////////////////////////////////////////////////
-//
-// Routine Name:
-//
-//     IcmpCloseHandle
-//
-// Routine Description:
-//
-//     Closes a handle opened by ICMPOpenFile.
-//
-// Arguments:
-//
-//     IcmpHandle  - The handle to close.
-//
-// Return Value:
-//
-//     TRUE if the handle was closed successfully, otherwise FALSE. Extended
-//     error information is available by calling GetLastError().
-//
-//////////////////////////////////////////////////////////////////////
-//
-// Routine Name:
-//
-//     IcmpSendEcho
-//
-// Routine Description:
-//
-//     Sends an ICMP Echo request and returns any replies. The
-//     call returns when the timeout has expired or the reply buffer
-//     is filled.
-//
-// Arguments:
-//
-//     IcmpHandle           - An open handle returned by ICMPCreateFile.
-//
-//     DestinationAddress   - The destination of the echo request.
-//
-//     RequestData          - A buffer containing the data to send in the
-//                            request.
-//
-//     RequestSize          - The number of bytes in the request data buffer.
-//
-//     RequestOptions       - Pointer to the IP header options for the request.
-//                            May be NULL.
-//
-//     ReplyBuffer          - A buffer to hold any replies to the request.
-//                            On return, the buffer will contain an array of
-//                            ICMP_ECHO_REPLY structures followed by the
-//                            options and data for the replies. The buffer
-//                            should be large enough to hold at least one
-//                            ICMP_ECHO_REPLY structure plus
-//                            MAX(RequestSize, 8) bytes of data since an ICMP
-//                            error message contains 8 bytes of data.
-//
-//     ReplySize            - The size in bytes of the reply buffer.
-//
-//     Timeout              - The time in milliseconds to wait for replies.
-//
-// Return Value:
-//
-//     Returns the number of ICMP_ECHO_REPLY structures stored in ReplyBuffer.
-//     The status of each reply is contained in the structure. If the return
-//     value is zero, extended error information is available via
-//     GetLastError().
-//
-//////////////////////////////////////////////////////////////////////
-
-} // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/winping.h b/third_party/libjingle/source/talk/base/winping.h
deleted file mode 100644
index 35d36e3..0000000
--- a/third_party/libjingle/source/talk/base/winping.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_WINPING_H__
-#define TALK_BASE_WINPING_H__
-
-#ifdef WIN32
-
-#include "talk/base/win32.h"
-#include "talk/base/basictypes.h"
-
-namespace talk_base {
-
-// This class wraps a Win32 API for doing ICMP pinging.  This API, unlike the
-// the normal socket APIs (as implemented on Win9x), will return an error if
-// an ICMP packet with the dont-fragment bit set is too large.  This means this
-// class can be used to detect the MTU to a given address.
-
-typedef struct ip_option_information {
-    UCHAR   Ttl;                // Time To Live
-    UCHAR   Tos;                // Type Of Service
-    UCHAR   Flags;              // IP header flags
-    UCHAR   OptionsSize;        // Size in bytes of options data
-    PUCHAR  OptionsData;        // Pointer to options data
-} IP_OPTION_INFORMATION, * PIP_OPTION_INFORMATION;
-
-typedef HANDLE (WINAPI *PIcmpCreateFile)();
-
-typedef BOOL (WINAPI *PIcmpCloseHandle)(HANDLE icmp_handle);
-
-typedef DWORD (WINAPI *PIcmpSendEcho)(
-    HANDLE                   IcmpHandle,
-    ULONG                    DestinationAddress,
-    LPVOID                   RequestData,
-    WORD                     RequestSize,
-    PIP_OPTION_INFORMATION   RequestOptions,
-    LPVOID                   ReplyBuffer,
-    DWORD                    ReplySize,
-    DWORD                    Timeout);
-
-class WinPing {
-public:
-    WinPing();
-    ~WinPing();
-
-    // Determines whether the class was initialized correctly.
-    bool IsValid() { return valid_; }
-
-    // Attempts to send a ping with the given parameters.
-    enum PingResult { PING_FAIL, PING_TOO_LARGE, PING_TIMEOUT, PING_SUCCESS };
-    PingResult Ping(
-        uint32 ip, uint32 data_size, uint32 timeout_millis, uint8 ttl,
-        bool allow_fragments);
-
-private:
-    HMODULE dll_;
-    HANDLE hping_;
-    PIcmpCreateFile create_;
-    PIcmpCloseHandle close_;
-    PIcmpSendEcho send_;
-    char* data_;
-    uint32 dlen_;
-    char* reply_;
-    uint32 rlen_;
-    bool valid_;
-};
-
-} // namespace talk_base
-
-#endif // WIN32
-
-#endif // TALK_BASE_WINPING_H__
-
diff --git a/third_party/libjingle/source/talk/base/worker.cc b/third_party/libjingle/source/talk/base/worker.cc
deleted file mode 100644
index 28fcc9f..0000000
--- a/third_party/libjingle/source/talk/base/worker.cc
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/worker.h"
-
-#include "talk/base/common.h"
-#include "talk/base/logging.h"
-#include "talk/base/thread.h"
-
-namespace talk_base {
-
-enum {
-  MSG_HAVEWORK = 0,
-};
-
-Worker::Worker() : worker_thread_(NULL) {}
-
-Worker::~Worker() {
-  // We need to already be stopped before being destroyed. We cannot call
-  // StopWork() from here because the subclass's data has already been
-  // destructed, so OnStop() cannot be called.
-  ASSERT(!worker_thread_);
-}
-
-bool Worker::StartWork() {
-  talk_base::Thread *me = talk_base::Thread::Current();
-  if (worker_thread_) {
-    if (worker_thread_ == me) {
-      // Already working on this thread, so nothing to do.
-      return true;
-    } else {
-      LOG(LS_ERROR) << "Automatically switching threads is not supported";
-      ASSERT(false);
-      return false;
-    }
-  }
-  worker_thread_ = me;
-  OnStart();
-  return true;
-}
-
-bool Worker::StopWork() {
-  if (!worker_thread_) {
-    // Already not working, so nothing to do.
-    return true;
-  } else if (worker_thread_ != talk_base::Thread::Current()) {
-    LOG(LS_ERROR) << "Stopping from a different thread is not supported";
-    ASSERT(false);
-    return false;
-  }
-  OnStop();
-  worker_thread_->Clear(this, MSG_HAVEWORK);
-  worker_thread_ = NULL;
-  return true;
-}
-
-void Worker::HaveWork() {
-  ASSERT(worker_thread_ != NULL);
-  worker_thread_->Post(this, MSG_HAVEWORK);
-}
-
-void Worker::OnMessage(talk_base::Message *msg) {
-  ASSERT(msg->message_id == MSG_HAVEWORK);
-  ASSERT(worker_thread_ == talk_base::Thread::Current());
-  OnHaveWork();
-}
-
-}  // namespace talk_base
diff --git a/third_party/libjingle/source/talk/base/worker.h b/third_party/libjingle/source/talk/base/worker.h
deleted file mode 100644
index 582fe1b..0000000
--- a/third_party/libjingle/source/talk/base/worker.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_BASE_WORKER_H_
-#define TALK_BASE_WORKER_H_
-
-#include "talk/base/constructormagic.h"
-#include "talk/base/messagehandler.h"
-
-namespace talk_base {
-
-class Thread;
-
-// A worker is an object that performs some specific long-lived task in an
-// event-driven manner.
-// The only method that should be considered thread-safe is HaveWork(), which
-// allows you to signal the availability of work from any thread. All other
-// methods are thread-hostile. Specifically:
-// StartWork()/StopWork() should not be called concurrently with themselves or
-// each other, and it is an error to call them while the worker is running on
-// a different thread.
-// The destructor may not be called if the worker is currently running
-// (regardless of the thread), but you can call StopWork() in a subclass's
-// destructor.
-class Worker : private MessageHandler {
- public:
-  Worker();
-
-  // Destroys this Worker, but it must have already been stopped via StopWork().
-  virtual ~Worker();
-
-  // Attaches the worker to the current thread and begins processing work if not
-  // already doing so.
-  bool StartWork();
-  // Stops processing work if currently doing so and detaches from the current
-  // thread.
-  bool StopWork();
-
- protected:
-  // Signal that work is available to be done. May only be called within the
-  // lifetime of a OnStart()/OnStop() pair.
-  void HaveWork();
-
-  // These must be implemented by a subclass.
-  // Called on the worker thread to start working.
-  virtual void OnStart() = 0;
-  // Called on the worker thread when work has been signalled via HaveWork().
-  virtual void OnHaveWork() = 0;
-  // Called on the worker thread to stop working. Upon return, any pending
-  // OnHaveWork() calls are cancelled.
-  virtual void OnStop() = 0;
-
- private:
-  // Inherited from MessageHandler.
-  virtual void OnMessage(Message *msg);
-
-  // The thread that is currently doing the work.
-  Thread *worker_thread_;
-
-  DISALLOW_COPY_AND_ASSIGN(Worker);
-};
-
-}  // namespace talk_base
-
-#endif  // TALK_BASE_WORKER_H_
diff --git a/third_party/libjingle/source/talk/examples/call/call_main.cc b/third_party/libjingle/source/talk/examples/call/call_main.cc
deleted file mode 100644
index 077869c..0000000
--- a/third_party/libjingle/source/talk/examples/call/call_main.cc
+++ /dev/null
@@ -1,410 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <cstdio>
-#include <cstring>
-#include <time.h>
-#include <iomanip>
-#include <iostream>
-#include <vector>
-
-#include "talk/base/flags.h"
-#include "talk/base/logging.h"
-#ifdef OSX
-#include "talk/base/macsocketserver.h"
-#endif
-#include "talk/base/pathutils.h"
-#include "talk/base/stream.h"
-#include "talk/base/ssladapter.h"
-#include "talk/base/win32socketserver.h"
-#include "talk/examples/login/xmppthread.h"
-#include "talk/examples/login/xmppauth.h"
-#include "talk/examples/login/xmpppump.h"
-#include "talk/examples/call/callclient.h"
-#include "talk/examples/call/console.h"
-#include "talk/examples/call/mediaenginefactory.h"
-#include "talk/p2p/base/constants.h"
-#ifdef ANDROID
-#include "talk/session/phone/androidmediaengine.h"
-#endif
-#include "talk/session/phone/mediasessionclient.h"
-#include "talk/session/phone/srtpfilter.h"
-#include "talk/xmpp/xmppclientsettings.h"
-
-class DebugLog : public sigslot::has_slots<> {
- public:
-  DebugLog() :
-    debug_input_buf_(NULL), debug_input_len_(0), debug_input_alloc_(0),
-    debug_output_buf_(NULL), debug_output_len_(0), debug_output_alloc_(0),
-    censor_password_(false)
-      {}
-  char * debug_input_buf_;
-  int debug_input_len_;
-  int debug_input_alloc_;
-  char * debug_output_buf_;
-  int debug_output_len_;
-  int debug_output_alloc_;
-  bool censor_password_;
-
-  void Input(const char * data, int len) {
-    if (debug_input_len_ + len > debug_input_alloc_) {
-      char * old_buf = debug_input_buf_;
-      debug_input_alloc_ = 4096;
-      while (debug_input_alloc_ < debug_input_len_ + len) {
-        debug_input_alloc_ *= 2;
-      }
-      debug_input_buf_ = new char[debug_input_alloc_];
-      memcpy(debug_input_buf_, old_buf, debug_input_len_);
-      delete[] old_buf;
-    }
-    memcpy(debug_input_buf_ + debug_input_len_, data, len);
-    debug_input_len_ += len;
-    DebugPrint(debug_input_buf_, &debug_input_len_, false);
-  }
-
-  void Output(const char * data, int len) {
-    if (debug_output_len_ + len > debug_output_alloc_) {
-      char * old_buf = debug_output_buf_;
-      debug_output_alloc_ = 4096;
-      while (debug_output_alloc_ < debug_output_len_ + len) {
-        debug_output_alloc_ *= 2;
-      }
-      debug_output_buf_ = new char[debug_output_alloc_];
-      memcpy(debug_output_buf_, old_buf, debug_output_len_);
-      delete[] old_buf;
-    }
-    memcpy(debug_output_buf_ + debug_output_len_, data, len);
-    debug_output_len_ += len;
-    DebugPrint(debug_output_buf_, &debug_output_len_, true);
-  }
-
-  static bool IsAuthTag(const char * str, size_t len) {
-    if (str[0] == '<' && str[1] == 'a' &&
-                         str[2] == 'u' &&
-                         str[3] == 't' &&
-                         str[4] == 'h' &&
-                         str[5] <= ' ') {
-      std::string tag(str, len);
-
-      if (tag.find("mechanism") != std::string::npos)
-        return true;
-    }
-    return false;
-  }
-
-  void DebugPrint(char * buf, int * plen, bool output) {
-    int len = *plen;
-    if (len > 0) {
-      time_t tim = time(NULL);
-      struct tm * now = localtime(&tim);
-      char *time_string = asctime(now);
-      if (time_string) {
-        size_t time_len = strlen(time_string);
-        if (time_len > 0) {
-          time_string[time_len-1] = 0;    // trim off terminating \n
-        }
-      }
-      LOG(INFO) << (output ? "SEND >>>>>>>>>>>>>>>>" : "RECV <<<<<<<<<<<<<<<<")
-                << " : " << time_string;
-
-      bool indent;
-      int start = 0, nest = 3;
-      for (int i = 0; i < len; i += 1) {
-        if (buf[i] == '>') {
-          if ((i > 0) && (buf[i-1] == '/')) {
-            indent = false;
-          } else if ((start + 1 < len) && (buf[start + 1] == '/')) {
-            indent = false;
-            nest -= 2;
-          } else {
-            indent = true;
-          }
-
-          // Output a tag
-          LOG(INFO) << std::setw(nest) << " "
-                    << std::string(buf + start, i + 1 - start);
-
-          if (indent)
-            nest += 2;
-
-          // Note if it's a PLAIN auth tag
-          if (IsAuthTag(buf + start, i + 1 - start)) {
-            censor_password_ = true;
-          }
-
-          // incr
-          start = i + 1;
-        }
-
-        if (buf[i] == '<' && start < i) {
-          if (censor_password_) {
-            LOG(INFO) << std::setw(nest) << " " << "## TEXT REMOVED ##";
-            censor_password_ = false;
-          } else {
-            LOG(INFO) << std::setw(nest) << " "
-                      << std::string(buf + start, i - start);
-          }
-          start = i;
-        }
-      }
-      len = len - start;
-      memcpy(buf, buf + start, len);
-      *plen = len;
-    }
-  }
-};
-
-static DebugLog debug_log_;
-static const int DEFAULT_PORT = 5222;
-
-#ifdef ANDROID
-static std::vector<cricket::AudioCodec> codecs;
-static const cricket::AudioCodec ISAC(103, "ISAC", 40000, 16000, 1, 0);
-
-cricket::MediaEngine *AndroidMediaEngineFactory() {
-    cricket::FakeMediaEngine *engine = new cricket::FakeMediaEngine();
-
-    codecs.push_back(ISAC);
-    engine->SetAudioCodecs(codecs);
-    return engine;
-}
-#endif
-
-// TODO: Move this into Console.
-void Print(const char* chars) {
-  printf("%s", chars);
-  fflush(stdout);
-}
-
-int main(int argc, char **argv) {
-  // This app has three threads. The main thread will run the XMPP client,
-  // which will print to the screen in its own thread. A second thread
-  // will get input from the console, parse it, and pass the appropriate
-  // message back to the XMPP client's thread. A third thread is used
-  // by MediaSessionClient as its worker thread.
-
-  // define options
-  DEFINE_bool(a, false, "Turn on auto accept.");
-  DEFINE_bool(d, false, "Turn on debugging.");
-  DEFINE_string(protocol, "hybrid",
-      "Initial signaling protocol to use: jingle, gingle, or hybrid.");
-  DEFINE_string(secure, "enable",
-      "Disable or enable encryption: disable, enable, require.");
-  DEFINE_string(tls, "enable",
-      "Disable or enable tls: disable, enable, require.");
-  DEFINE_bool(allowplain, false, "Allow plain authentication");
-  DEFINE_bool(testserver, false, "Use test server");
-  DEFINE_int(portallocator, 0, "Filter out unwanted connection types.");
-  DEFINE_string(filterhost, NULL, "Filter out the host from all candidates.");
-  DEFINE_string(pmuc, "groupchat.google.com", "The persistant muc domain.");
-  DEFINE_string(s, "talk.google.com", "The connection server to use.");
-  DEFINE_string(voiceinput, NULL, "RTP dump file for voice input.");
-  DEFINE_string(voiceoutput, NULL, "RTP dump file for voice output.");
-  DEFINE_string(videoinput, NULL, "RTP dump file for video input.");
-  DEFINE_string(videooutput, NULL, "RTP dump file for video output.");
-  DEFINE_bool(render, true, "Renders the video.");
-  DEFINE_bool(debugsrtp, false, "Enable debugging for srtp.");
-  DEFINE_bool(help, false, "Prints this message");
-
-  // parse options
-  FlagList::SetFlagsFromCommandLine(&argc, argv, true);
-  if (FLAG_help) {
-    FlagList::Print(NULL, false);
-    return 0;
-  }
-
-  bool auto_accept = FLAG_a;
-  bool debug = FLAG_d;
-  std::string protocol = FLAG_protocol;
-  bool test_server = FLAG_testserver;
-  bool allow_plain = FLAG_allowplain;
-  std::string tls = FLAG_tls;
-  int32 portallocator_flags = FLAG_portallocator;
-  std::string pmuc_domain = FLAG_pmuc;
-  std::string server = FLAG_s;
-  std::string secure = FLAG_secure;
-  bool debugsrtp = FLAG_debugsrtp;
-  bool render = FLAG_render;
-
-  if (debugsrtp) {
-    cricket::EnableSrtpDebugging();
-  }
-
-  cricket::SignalingProtocol initial_protocol = cricket::PROTOCOL_HYBRID;
-  if (protocol == "jingle") {
-    initial_protocol = cricket::PROTOCOL_JINGLE;
-  } else if (protocol == "gingle") {
-    initial_protocol = cricket::PROTOCOL_GINGLE;
-  } else if (protocol == "hybrid") {
-    initial_protocol = cricket::PROTOCOL_HYBRID;
-  } else {
-    Print("Invalid protocol.  Must be jingle, gingle, or hybrid.\n");
-    return 1;
-  }
-
-  cricket::SecureMediaPolicy secure_policy = cricket::SEC_ENABLED;
-  if (secure == "disable") {
-    secure_policy = cricket::SEC_DISABLED;
-  } else if (secure == "enable") {
-    secure_policy = cricket::SEC_ENABLED;
-  } else if (secure == "require") {
-    secure_policy = cricket::SEC_REQUIRED;
-  } else {
-    Print("Invalid encryption.  Must be enable, disable, or require.\n");
-    return 1;
-  }
-
-  // parse username and password, if present
-  buzz::Jid jid;
-  std::string username;
-  talk_base::InsecureCryptStringImpl pass;
-  if (argc > 1) {
-    username = argv[1];
-    if (argc > 2) {
-      pass.password() = argv[2];
-    }
-  }
-
-  if (debug)
-    talk_base::LogMessage::LogToDebug(talk_base::LS_VERBOSE);
-
-  if (username.empty()) {
-    Print("JID: ");
-    std::cin >> username;
-  }
-  if (username.find('@') == std::string::npos) {
-    username.append("@localhost");
-  }
-  jid = buzz::Jid(username);
-  if (!jid.IsValid() || jid.node() == "") {
-    Print("Invalid JID. JIDs should be in the form user@domain\n");
-    return 1;
-  }
-  if (pass.password().empty() && !test_server) {
-    Console::SetEcho(false);
-    Print("Password: ");
-    std::cin >> pass.password();
-    Console::SetEcho(true);
-    Print("\n");
-  }
-
-  buzz::XmppClientSettings xcs;
-  xcs.set_user(jid.node());
-  xcs.set_resource("call");
-  xcs.set_host(jid.domain());
-  xcs.set_allow_plain(allow_plain);
-
-  if(tls == "disable") {
-    xcs.set_use_tls(buzz::TLS_DISABLED);
-  } else if (tls == "enable") {
-    xcs.set_use_tls(buzz::TLS_ENABLED);
-  } else if (tls == "require") {
-    xcs.set_use_tls(buzz::TLS_REQUIRED);
-  } else {
-    Print("Invalid TLS option, must be enable, disable, or require.\n");
-    return 1;
-  }
-
-  if (test_server) {
-    pass.password() = jid.node();
-    xcs.set_allow_plain(true);
-    xcs.set_use_tls(buzz::TLS_DISABLED);
-    xcs.set_test_server_domain("google.com");
-  }
-  xcs.set_pass(talk_base::CryptString(pass));
-
-  std::string host;
-  int port;
-
-  int colon = server.find(':');
-  if (colon == -1) {
-    host = server;
-    port = DEFAULT_PORT;
-  } else {
-    host = server.substr(0, colon);
-    port = atoi(server.substr(colon + 1).c_str());
-  }
-
-  xcs.set_server(talk_base::SocketAddress(host, port));
-  Print(("Logging in to " + server + " as " + jid.Str() + "\n").c_str());
-
-  talk_base::InitializeSSL();
-
-#ifdef ANDROID
-  InitAndroidMediaEngineFactory(AndroidMediaEngineFactory);
-#endif
-
-#if WIN32
-  // Need to pump messages on our main thread on Windows.
-  talk_base::Win32Thread w32_thread;
-  talk_base::ThreadManager::SetCurrent(&w32_thread);
-#endif
-  talk_base::Thread* main_thread = talk_base::Thread::Current();
-#ifdef OSX
-  talk_base::MacCarbonAppSocketServer ss;
-  talk_base::SocketServerScope ss_scope(&ss);
-#endif
-
-  XmppPump pump;
-  CallClient *client = new CallClient(pump.client());
-
-  if (FLAG_voiceinput || FLAG_voiceoutput ||
-      FLAG_videoinput || FLAG_videooutput) {
-    // If any dump file is specified, we use a FileMediaEngine.
-    cricket::MediaEngineInterface* engine =
-        MediaEngineFactory::CreateFileMediaEngine(
-            FLAG_voiceinput, FLAG_voiceoutput,
-            FLAG_videoinput, FLAG_videooutput);
-    client->SetMediaEngine(engine);
-  }
-
-  Console *console = new Console(main_thread, client);
-  client->SetConsole(console);
-  client->SetAutoAccept(auto_accept);
-  client->SetPmucDomain(pmuc_domain);
-  client->SetPortAllocatorFlags(portallocator_flags);
-  client->SetAllowLocalIps(true);
-  client->SetInitialProtocol(initial_protocol);
-  client->SetSecurePolicy(secure_policy);
-  client->SetRender(render);
-  console->Start();
-
-  if (debug) {
-    pump.client()->SignalLogInput.connect(&debug_log_, &DebugLog::Input);
-    pump.client()->SignalLogOutput.connect(&debug_log_, &DebugLog::Output);
-  }
-
-  pump.DoLogin(xcs, new XmppSocket(buzz::TLS_REQUIRED), NULL);
-  main_thread->Run();
-  pump.DoDisconnect();
-
-  console->Stop();
-  delete console;
-  delete client;
-
-  return 0;
-}
diff --git a/third_party/libjingle/source/talk/examples/call/callclient.cc b/third_party/libjingle/source/talk/examples/call/callclient.cc
deleted file mode 100644
index b427783..0000000
--- a/third_party/libjingle/source/talk/examples/call/callclient.cc
+++ /dev/null
@@ -1,1220 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/examples/call/callclient.h"
-
-#include <string>
-
-#include "talk/base/helpers.h"
-#include "talk/base/logging.h"
-#include "talk/base/network.h"
-#include "talk/base/socketaddress.h"
-#include "talk/base/stringencode.h"
-#include "talk/base/stringutils.h"
-#include "talk/base/thread.h"
-#include "talk/examples/call/console.h"
-#include "talk/examples/call/presencepushtask.h"
-#include "talk/examples/call/presenceouttask.h"
-#include "talk/examples/call/mucinviterecvtask.h"
-#include "talk/examples/call/mucinvitesendtask.h"
-#include "talk/examples/call/friendinvitesendtask.h"
-#include "talk/examples/call/muc.h"
-#include "talk/examples/call/voicemailjidrequester.h"
-#include "talk/p2p/base/sessionmanager.h"
-#include "talk/p2p/client/basicportallocator.h"
-#include "talk/p2p/client/sessionmanagertask.h"
-#include "talk/session/phone/devicemanager.h"
-#include "talk/session/phone/mediacommon.h"
-#include "talk/session/phone/mediaengine.h"
-#include "talk/session/phone/mediamessages.h"
-#include "talk/session/phone/mediasessionclient.h"
-#include "talk/session/phone/videorendererfactory.h"
-#include "talk/xmpp/constants.h"
-#include "talk/xmpp/hangoutpubsubclient.h"
-#include "talk/xmpp/mucroomconfigtask.h"
-#include "talk/xmpp/mucroomlookuptask.h"
-
-namespace {
-
-const char* DescribeStatus(buzz::Status::Show show, const std::string& desc) {
-  switch (show) {
-  case buzz::Status::SHOW_XA:      return desc.c_str();
-  case buzz::Status::SHOW_ONLINE:  return "online";
-  case buzz::Status::SHOW_AWAY:    return "away";
-  case buzz::Status::SHOW_DND:     return "do not disturb";
-  case buzz::Status::SHOW_CHAT:    return "ready to chat";
-  default:                         return "offline";
-  }
-}
-
-std::string GetWord(const std::vector<std::string>& words,
-                    size_t index, const std::string& def) {
-  if (words.size() > index) {
-    return words[index];
-  } else {
-    return def;
-  }
-}
-
-int GetInt(const std::vector<std::string>& words, size_t index, int def) {
-  int val;
-  if (words.size() > index && talk_base::FromString(words[index], &val)) {
-    return val;
-  } else {
-    return def;
-  }
-}
-
-
-}  // namespace
-
-const char* CALL_COMMANDS =
-"Available commands:\n"
-"\n"
-"  hangup     Ends the call.\n"
-"  mute       Stops sending voice.\n"
-"  unmute     Re-starts sending voice.\n"
-"  dtmf       Sends a DTMF tone.\n"
-"  quit       Quits the application.\n"
-"";
-
-// TODO: Make present and record really work.
-const char* HANGOUT_COMMANDS =
-"Available MUC commands:\n"
-"\n"
-"  present    Starts presenting (just signalling; not actually presenting.)\n"
-"  unpresent  Stops presenting (just signalling; not actually presenting.)\n"
-"  record     Starts recording (just signalling; not actually recording.)\n"
-"  unrecord   Stops recording (just signalling; not actually recording.)\n"
-"  rmute [nick] Remote mute another participant.\n"
-"  block [nick] Block another participant.\n"
-"  quit       Quits the application.\n"
-"";
-
-const char* RECEIVE_COMMANDS =
-"Available commands:\n"
-"\n"
-"  accept [bw] Accepts the incoming call and switches to it.\n"
-"  reject  Rejects the incoming call and stays with the current call.\n"
-"  quit    Quits the application.\n"
-"";
-
-const char* CONSOLE_COMMANDS =
-"Available commands:\n"
-"\n"
-"  roster              Prints the online friends from your roster.\n"
-"  friend user         Request to add a user to your roster.\n"
-"  call [jid] [bw]     Initiates a call to the user[/room] with the\n"
-"                      given JID and with optional bandwidth.\n"
-"  vcall [jid] [bw]    Initiates a video call to the user[/room] with\n"
-"                      the given JID and with optional bandwidth.\n"
-"  voicemail [jid]     Leave a voicemail for the user with the given JID.\n"
-"  join [room_jid]     Joins a multi-user-chat with room JID.\n"
-"  ljoin [room_name]   Joins a MUC by looking up JID from room name.\n"
-"  invite user [room]  Invites a friend to a multi-user-chat.\n"
-"  leave [room]        Leaves a multi-user-chat.\n"
-"  nick [nick]         Sets the nick.\n"
-"  getdevs             Prints the available media devices.\n"
-"  quit                Quits the application.\n"
-"";
-
-void CallClient::ParseLine(const std::string& line) {
-  std::vector<std::string> words;
-  int start = -1;
-  int state = 0;
-  for (int index = 0; index <= static_cast<int>(line.size()); ++index) {
-    if (state == 0) {
-      if (!isspace(line[index])) {
-        start = index;
-        state = 1;
-      }
-    } else {
-      ASSERT(state == 1);
-      ASSERT(start >= 0);
-      if (isspace(line[index])) {
-        std::string word(line, start, index - start);
-        words.push_back(word);
-        start = -1;
-        state = 0;
-      }
-    }
-  }
-
-  // Global commands
-  const std::string& command = GetWord(words, 0, "");
-  if (command == "quit") {
-    Quit();
-  } else if (call_ && incoming_call_) {
-    if (command == "accept") {
-      cricket::CallOptions options;
-      options.video_bandwidth = GetInt(words, 1, cricket::kAutoBandwidth);
-      options.has_video = true;
-      Accept(options);
-    } else if (command == "reject") {
-      Reject();
-    } else {
-      console_->PrintLine(RECEIVE_COMMANDS);
-    }
-  } else if (call_) {
-    if (command == "hangup") {
-      call_->Terminate();
-    } else if (command == "mute") {
-      call_->Mute(true);
-      if (InMuc()) {
-        hangout_pubsub_client_->PublishAudioMuteState(true);
-      }
-    } else if (command == "unmute") {
-      call_->Mute(false);
-      if (InMuc()) {
-        hangout_pubsub_client_->PublishAudioMuteState(false);
-      }
-    } else if (command == "present") {
-      if (InMuc()) {
-        hangout_pubsub_client_->PublishPresenterState(true);
-      }
-    } else if (command == "unpresent") {
-      if (InMuc()) {
-        hangout_pubsub_client_->PublishPresenterState(false);
-      }
-    } else if (command == "record") {
-      if (InMuc()) {
-        hangout_pubsub_client_->PublishRecordingState(true);
-      }
-    } else if (command == "unrecord") {
-      if (InMuc()) {
-        hangout_pubsub_client_->PublishRecordingState(false);
-      }
-    } else if ((command == "rmute") && (words.size() == 2)) {
-      if (InMuc()) {
-        const std::string& nick = words[1];
-        hangout_pubsub_client_->RemoteMute(nick);
-      }
-    } else if ((command == "block") && (words.size() == 2)) {
-      if (InMuc()) {
-        const std::string& nick = words[1];
-        hangout_pubsub_client_->BlockMedia(nick);
-      }
-    } else if ((command == "dtmf") && (words.size() == 2)) {
-      int ev = std::string("0123456789*#").find(words[1][0]);
-      call_->PressDTMF(ev);
-    } else {
-      console_->PrintLine(CALL_COMMANDS);
-      if (InMuc()) {
-        console_->PrintLine(HANGOUT_COMMANDS);
-      }
-    }
-  } else {
-    if (command == "roster") {
-      PrintRoster();
-    } else if (command == "send") {
-      buzz::Jid jid(words[1]);
-      if (jid.IsValid()) {
-        last_sent_to_ = words[1];
-        SendChat(words[1], words[2]);
-      } else if (!last_sent_to_.empty()) {
-        SendChat(last_sent_to_, words[1]);
-      } else {
-        console_->PrintLine(
-            "Invalid JID. JIDs should be in the form user@domain");
-      }
-    } else if ((words.size() == 2) && (command == "friend")) {
-      InviteFriend(words[1]);
-    } else if (command == "call") {
-      std::string to = GetWord(words, 1, "");
-      MakeCallTo(to, cricket::CallOptions());
-    } else if (command == "vcall") {
-      std::string to = GetWord(words, 1, "");
-      int bandwidth = GetInt(words, 2, cricket::kAutoBandwidth);
-      cricket::CallOptions options;
-      options.has_video = true;
-      options.video_bandwidth = bandwidth;
-      MakeCallTo(to, options);
-    } else if (command == "join") {
-      JoinMuc(GetWord(words, 1, ""));
-    } else if (command == "ljoin") {
-      LookupAndJoinMuc(GetWord(words, 1, ""));
-    } else if ((words.size() >= 2) && (command == "invite")) {
-      InviteToMuc(words[1], GetWord(words, 2, ""));
-    } else if (command == "leave") {
-      LeaveMuc(GetWord(words, 1, ""));
-    } else if (command == "nick") {
-      SetNick(GetWord(words, 1, ""));
-    } else if (command == "getdevs") {
-      GetDevices();
-    } else if ((words.size() == 2) && (command == "setvol")) {
-      SetVolume(words[1]);
-    } else if (command == "voicemail") {
-      CallVoicemail((words.size() >= 2) ? words[1] : "");
-    } else {
-      console_->PrintLine(CONSOLE_COMMANDS);
-    }
-  }
-}
-
-CallClient::CallClient(buzz::XmppClient* xmpp_client)
-    : xmpp_client_(xmpp_client),
-      worker_thread_(NULL),
-      media_engine_(NULL),
-      media_client_(NULL),
-      call_(NULL),
-      hangout_pubsub_client_(NULL),
-      incoming_call_(false),
-      auto_accept_(false),
-      pmuc_domain_("groupchat.google.com"),
-      render_(true),
-      local_renderer_(NULL),
-      remote_renderer_(NULL),
-      static_views_accumulated_count_(0),
-      roster_(new RosterMap),
-      portallocator_flags_(0),
-      allow_local_ips_(false),
-      initial_protocol_(cricket::PROTOCOL_HYBRID),
-      secure_policy_(cricket::SEC_DISABLED) {
-  xmpp_client_->SignalStateChange.connect(this, &CallClient::OnStateChange);
-}
-
-CallClient::~CallClient() {
-  delete media_client_;
-  delete roster_;
-  delete worker_thread_;
-}
-
-const std::string CallClient::strerror(buzz::XmppEngine::Error err) {
-  switch (err) {
-    case  buzz::XmppEngine::ERROR_NONE:
-      return "";
-    case  buzz::XmppEngine::ERROR_XML:
-      return "Malformed XML or encoding error";
-    case  buzz::XmppEngine::ERROR_STREAM:
-      return "XMPP stream error";
-    case  buzz::XmppEngine::ERROR_VERSION:
-      return "XMPP version error";
-    case  buzz::XmppEngine::ERROR_UNAUTHORIZED:
-      return "User is not authorized (Check your username and password)";
-    case  buzz::XmppEngine::ERROR_TLS:
-      return "TLS could not be negotiated";
-    case  buzz::XmppEngine::ERROR_AUTH:
-      return "Authentication could not be negotiated";
-    case  buzz::XmppEngine::ERROR_BIND:
-      return "Resource or session binding could not be negotiated";
-    case  buzz::XmppEngine::ERROR_CONNECTION_CLOSED:
-      return "Connection closed by output handler.";
-    case  buzz::XmppEngine::ERROR_DOCUMENT_CLOSED:
-      return "Closed by </stream:stream>";
-    case  buzz::XmppEngine::ERROR_SOCKET:
-      return "Socket error";
-    default:
-      return "Unknown error";
-  }
-}
-
-void CallClient::OnCallDestroy(cricket::Call* call) {
-  if (call == call_) {
-    if (remote_renderer_) {
-      delete remote_renderer_;
-      remote_renderer_ = NULL;
-    }
-    if (local_renderer_) {
-      delete local_renderer_;
-      local_renderer_ = NULL;
-    }
-    RemoveAllStaticRenderedViews();
-    console_->PrintLine("call destroyed");
-    call_ = NULL;
-    session_ = NULL;
-    delete hangout_pubsub_client_;
-    hangout_pubsub_client_ = NULL;
-  }
-}
-
-void CallClient::OnStateChange(buzz::XmppEngine::State state) {
-  switch (state) {
-  case buzz::XmppEngine::STATE_START:
-    console_->PrintLine("connecting...");
-    break;
-
-  case buzz::XmppEngine::STATE_OPENING:
-    console_->PrintLine("logging in...");
-    break;
-
-  case buzz::XmppEngine::STATE_OPEN:
-    console_->PrintLine("logged in...");
-    InitMedia();
-    InitPresence();
-    break;
-
-  case buzz::XmppEngine::STATE_CLOSED:
-    buzz::XmppEngine::Error error = xmpp_client_->GetError(NULL);
-    console_->PrintLine("logged out... %s", strerror(error).c_str());
-    Quit();
-  }
-}
-
-void CallClient::InitMedia() {
-  std::string client_unique = xmpp_client_->jid().Str();
-  talk_base::InitRandom(client_unique.c_str(), client_unique.size());
-
-  worker_thread_ = new talk_base::Thread();
-  // The worker thread must be started here since initialization of
-  // the ChannelManager will generate messages that need to be
-  // dispatched by it.
-  worker_thread_->Start();
-
-  // TODO: It looks like we are leaking many objects. E.g.
-  // |network_manager_| is never deleted.
-
-  network_manager_ = new talk_base::BasicNetworkManager();
-
-  // TODO: Decide if the relay address should be specified here.
-  talk_base::SocketAddress stun_addr("stun.l.google.com", 19302);
-  port_allocator_ =  new cricket::BasicPortAllocator(
-      network_manager_, stun_addr, talk_base::SocketAddress(),
-      talk_base::SocketAddress(), talk_base::SocketAddress());
-
-  if (portallocator_flags_ != 0) {
-    port_allocator_->set_flags(portallocator_flags_);
-  }
-  session_manager_ = new cricket::SessionManager(
-      port_allocator_, worker_thread_);
-  session_manager_->SignalRequestSignaling.connect(
-      this, &CallClient::OnRequestSignaling);
-  session_manager_->SignalSessionCreate.connect(
-      this, &CallClient::OnSessionCreate);
-  session_manager_->OnSignalingReady();
-
-  session_manager_task_ =
-      new cricket::SessionManagerTask(xmpp_client_, session_manager_);
-  session_manager_task_->EnableOutgoingMessages();
-  session_manager_task_->Start();
-
-  if (!media_engine_) {
-    media_engine_ = cricket::MediaEngineFactory::Create();
-  }
-
-  media_client_ = new cricket::MediaSessionClient(
-      xmpp_client_->jid(),
-      session_manager_,
-      media_engine_,
-      cricket::DeviceManagerFactory::Create());
-  media_client_->SignalCallCreate.connect(this, &CallClient::OnCallCreate);
-  media_client_->SignalCallDestroy.connect(this, &CallClient::OnCallDestroy);
-  media_client_->SignalDevicesChange.connect(this,
-                                             &CallClient::OnDevicesChange);
-  media_client_->set_secure(secure_policy_);
-}
-
-void CallClient::OnRequestSignaling() {
-  session_manager_->OnSignalingReady();
-}
-
-void CallClient::OnSessionCreate(cricket::Session* session, bool initiate) {
-  session->set_allow_local_ips(allow_local_ips_);
-  session->set_current_protocol(initial_protocol_);
-}
-
-void CallClient::OnCallCreate(cricket::Call* call) {
-  call->SignalSessionState.connect(this, &CallClient::OnSessionState);
-  call->SignalMediaSourcesUpdate.connect(
-      this, &CallClient::OnMediaSourcesUpdate);
-}
-
-void CallClient::OnSessionState(cricket::Call* call,
-                                cricket::Session* session,
-                                cricket::Session::State state) {
-  if (state == cricket::Session::STATE_RECEIVEDINITIATE) {
-    buzz::Jid jid(session->remote_name());
-    console_->PrintLine("Incoming call from '%s'", jid.Str().c_str());
-    call_ = call;
-    session_ = session;
-    incoming_call_ = true;
-    if (call->video() && render_) {
-      local_renderer_ =
-          cricket::VideoRendererFactory::CreateGuiVideoRenderer(160, 100);
-      remote_renderer_ =
-          cricket::VideoRendererFactory::CreateGuiVideoRenderer(160, 100);
-    }
-    cricket::CallOptions options;
-    if (auto_accept_) {
-      options.has_video = true;
-      Accept(options);
-    }
-  } else if (state == cricket::Session::STATE_SENTINITIATE) {
-    if (call->video() && render_) {
-      local_renderer_ =
-          cricket::VideoRendererFactory::CreateGuiVideoRenderer(160, 100);
-      remote_renderer_ =
-          cricket::VideoRendererFactory::CreateGuiVideoRenderer(160, 100);
-    }
-    console_->PrintLine("calling...");
-  } else if (state == cricket::Session::STATE_RECEIVEDACCEPT) {
-    console_->PrintLine("call answered");
-  } else if (state == cricket::Session::STATE_RECEIVEDREJECT) {
-    console_->PrintLine("call not answered");
-  } else if (state == cricket::Session::STATE_INPROGRESS) {
-    console_->PrintLine("call in progress");
-    call->SignalSpeakerMonitor.connect(this, &CallClient::OnSpeakerChanged);
-    call->StartSpeakerMonitor(session);
-  } else if (state == cricket::Session::STATE_RECEIVEDTERMINATE) {
-    console_->PrintLine("other side hung up");
-  }
-}
-
-void CallClient::OnSpeakerChanged(cricket::Call* call,
-                                  cricket::Session* session,
-                                  const cricket::NamedSource& speaker) {
-  if (speaker.ssrc == 0) {
-    console_->PrintLine("Session %s has no current speaker.",
-                        session->id().c_str());
-  } else if (speaker.nick.empty()) {
-    console_->PrintLine("Session %s speaker change to unknown (%u).",
-                        session->id().c_str(), speaker.ssrc);
-  } else {
-    console_->PrintLine("Session %s speaker changed to %s (%u).",
-                        session->id().c_str(), speaker.nick.c_str(),
-                        speaker.ssrc);
-  }
-}
-
-void CallClient::InitPresence() {
-  presence_push_ = new buzz::PresencePushTask(xmpp_client_, this);
-  presence_push_->SignalStatusUpdate.connect(
-    this, &CallClient::OnStatusUpdate);
-  presence_push_->SignalMucJoined.connect(this, &CallClient::OnMucJoined);
-  presence_push_->SignalMucLeft.connect(this, &CallClient::OnMucLeft);
-  presence_push_->SignalMucStatusUpdate.connect(
-    this, &CallClient::OnMucStatusUpdate);
-  presence_push_->Start();
-
-  presence_out_ = new buzz::PresenceOutTask(xmpp_client_);
-  RefreshStatus();
-  presence_out_->Start();
-
-  muc_invite_recv_ = new buzz::MucInviteRecvTask(xmpp_client_);
-  muc_invite_recv_->SignalInviteReceived.connect(this,
-      &CallClient::OnMucInviteReceived);
-  muc_invite_recv_->Start();
-
-  muc_invite_send_ = new buzz::MucInviteSendTask(xmpp_client_);
-  muc_invite_send_->Start();
-
-  friend_invite_send_ = new buzz::FriendInviteSendTask(xmpp_client_);
-  friend_invite_send_->Start();
-}
-
-void CallClient::RefreshStatus() {
-  int media_caps = media_client_->GetCapabilities();
-  my_status_.set_jid(xmpp_client_->jid());
-  my_status_.set_available(true);
-  my_status_.set_show(buzz::Status::SHOW_ONLINE);
-  my_status_.set_priority(0);
-  my_status_.set_know_capabilities(true);
-  my_status_.set_pmuc_capability(true);
-  my_status_.set_voice_capability(
-      (media_caps & cricket::AUDIO_RECV) != 0);
-  my_status_.set_video_capability(
-      (media_caps & cricket::VIDEO_RECV) != 0);
-  my_status_.set_camera_capability(
-      (media_caps & cricket::VIDEO_SEND) != 0);
-  my_status_.set_is_google_client(true);
-  my_status_.set_version("1.0.0.67");
-  presence_out_->Send(my_status_);
-}
-
-void CallClient::OnStatusUpdate(const buzz::Status& status) {
-  RosterItem item;
-  item.jid = status.jid();
-  item.show = status.show();
-  item.status = status.status();
-
-  std::string key = item.jid.Str();
-
-  if (status.available() && status.voice_capability()) {
-     console_->PrintLine("Adding to roster: %s", key.c_str());
-    (*roster_)[key] = item;
-    // TODO: Make some of these constants.
-  } else {
-    console_->PrintLine("Removing from roster: %s", key.c_str());
-    RosterMap::iterator iter = roster_->find(key);
-    if (iter != roster_->end())
-      roster_->erase(iter);
-  }
-}
-
-void CallClient::PrintRoster() {
-  console_->PrintLine("Roster contains %d callable", roster_->size());
-  RosterMap::iterator iter = roster_->begin();
-  while (iter != roster_->end()) {
-    console_->PrintLine("%s - %s",
-                        iter->second.jid.BareJid().Str().c_str(),
-                        DescribeStatus(iter->second.show, iter->second.status));
-    iter++;
-  }
-}
-
-void CallClient::SendChat(const std::string& to, const std::string msg) {
-  buzz::XmlElement* stanza = new buzz::XmlElement(buzz::QN_MESSAGE);
-  stanza->AddAttr(buzz::QN_TO, to);
-  stanza->AddAttr(buzz::QN_ID, talk_base::CreateRandomString(16));
-  stanza->AddAttr(buzz::QN_TYPE, "chat");
-  buzz::XmlElement* body = new buzz::XmlElement(buzz::QN_BODY);
-  body->SetBodyText(msg);
-  stanza->AddElement(body);
-
-  xmpp_client_->SendStanza(stanza);
-  delete stanza;
-}
-
-void CallClient::InviteFriend(const std::string& name) {
-  buzz::Jid jid(name);
-  if (!jid.IsValid() || jid.node() == "") {
-    console_->PrintLine("Invalid JID. JIDs should be in the form user@domain.");
-    return;
-  }
-  // Note: for some reason the Buzz backend does not forward our presence
-  // subscription requests to the end user when that user is another call
-  // client as opposed to a Smurf user. Thus, in that scenario, you must
-  // run the friend command as the other user too to create the linkage
-  // (and you won't be notified to do so).
-  friend_invite_send_->Send(jid);
-  console_->PrintLine("Requesting to befriend %s.", name.c_str());
-}
-
-void CallClient::MakeCallTo(const std::string& name,
-                            const cricket::CallOptions& given_options) {
-  // Copy so we can change .is_muc.
-  cricket::CallOptions options = given_options;
-
-  bool found = false;
-  options.is_muc = false;
-  buzz::Jid callto_jid(name);
-  buzz::Jid found_jid;
-  if (name.length() == 0 && mucs_.size() > 0) {
-    // if no name, and in a MUC, establish audio with the MUC
-    found_jid = mucs_.begin()->first;
-    found = true;
-    options.is_muc = true;
-  } else if (name[0] == '+') {
-    // if the first character is a +, assume it's a phone number
-    found_jid = callto_jid;
-    found = true;
-  } else if (callto_jid.resource() == "voicemail") {
-    // if the resource is /voicemail, allow that
-    found_jid = callto_jid;
-    found = true;
-  } else {
-    // otherwise, it's a friend
-    for (RosterMap::iterator iter = roster_->begin();
-         iter != roster_->end(); ++iter) {
-      if (iter->second.jid.BareEquals(callto_jid)) {
-        found = true;
-        found_jid = iter->second.jid;
-        break;
-      }
-    }
-
-    if (!found) {
-      if (mucs_.count(callto_jid) == 1 &&
-          mucs_[callto_jid]->state() == buzz::Muc::MUC_JOINED) {
-        found = true;
-        found_jid = callto_jid;
-        options.is_muc = true;
-      }
-    }
-  }
-
-  if (found) {
-    console_->PrintLine("Found %s '%s'",
-                        options.is_muc ? "room" : "online friend",
-                        found_jid.Str().c_str());
-    PlaceCall(found_jid, options);
-  } else {
-    console_->PrintLine("Could not find online friend '%s'", name.c_str());
-  }
-}
-
-void CallClient::PlaceCall(const buzz::Jid& jid,
-                           const cricket::CallOptions& options) {
-  if (!call_) {
-    call_ = media_client_->CreateCall();
-    session_ = call_->InitiateSession(jid, options);
-  }
-  media_client_->SetFocus(call_);
-  if (call_->video() && render_) {
-    if (!options.is_muc) {
-      call_->SetLocalRenderer(local_renderer_);
-      call_->SetVideoRenderer(session_, 0, remote_renderer_);
-    }
-  }
-  if (options.is_muc) {
-    const std::string& nick = mucs_[jid]->local_jid().resource();
-    hangout_pubsub_client_ =
-        new buzz::HangoutPubSubClient(xmpp_client_, jid, nick);
-    hangout_pubsub_client_->SignalPresenterStateChange.connect(
-        this, &CallClient::OnPresenterStateChange);
-    hangout_pubsub_client_->SignalAudioMuteStateChange.connect(
-        this, &CallClient::OnAudioMuteStateChange);
-    hangout_pubsub_client_->SignalRecordingStateChange.connect(
-        this, &CallClient::OnRecordingStateChange);
-    hangout_pubsub_client_->SignalRemoteMute.connect(
-        this, &CallClient::OnRemoteMuted);
-    hangout_pubsub_client_->SignalMediaBlock.connect(
-        this, &CallClient::OnMediaBlocked);
-    hangout_pubsub_client_->SignalRequestError.connect(
-        this, &CallClient::OnHangoutRequestError);
-    hangout_pubsub_client_->SignalPublishAudioMuteError.connect(
-        this, &CallClient::OnHangoutPublishAudioMuteError);
-    hangout_pubsub_client_->SignalPublishPresenterError.connect(
-        this, &CallClient::OnHangoutPublishPresenterError);
-    hangout_pubsub_client_->SignalPublishRecordingError.connect(
-        this, &CallClient::OnHangoutPublishRecordingError);
-    hangout_pubsub_client_->SignalRemoteMuteError.connect(
-        this, &CallClient::OnHangoutRemoteMuteError);
-    hangout_pubsub_client_->RequestAll();
-  }
-}
-
-void CallClient::OnPresenterStateChange(
-    const std::string& nick, bool was_presenting, bool is_presenting) {
-  if (!was_presenting && is_presenting) {
-    console_->PrintLine("%s now presenting.", nick.c_str());
-  } else if (was_presenting && !is_presenting) {
-    console_->PrintLine("%s no longer presenting.", nick.c_str());
-  }
-}
-
-void CallClient::OnAudioMuteStateChange(
-    const std::string& nick, bool was_muted, bool is_muted) {
-  if (!was_muted && is_muted) {
-    console_->PrintLine("%s now muted.", nick.c_str());
-  } else if (was_muted && !is_muted) {
-    console_->PrintLine("%s no longer muted.", nick.c_str());
-  }
-}
-
-void CallClient::OnRecordingStateChange(
-    const std::string& nick, bool was_recording, bool is_recording) {
-  if (!was_recording && is_recording) {
-    console_->PrintLine("%s now recording.", nick.c_str());
-  } else if (was_recording && !is_recording) {
-    console_->PrintLine("%s no longer recording.", nick.c_str());
-  }
-}
-
-void CallClient::OnRemoteMuted(const std::string& mutee_nick,
-                               const std::string& muter_nick,
-                               bool should_mute_locally) {
-  if (should_mute_locally) {
-    call_->Mute(true);
-    console_->PrintLine("Remote muted by %s.", muter_nick.c_str());
-  } else {
-    console_->PrintLine("%s remote muted by %s.",
-                        mutee_nick.c_str(), muter_nick.c_str());
-  }
-}
-
-void CallClient::OnMediaBlocked(const std::string& blockee_nick,
-                                const std::string& blocker_nick) {
-  console_->PrintLine("%s blocked by %s.",
-                      blockee_nick.c_str(), blocker_nick.c_str());
-}
-
-void CallClient::OnHangoutRequestError(const std::string& node,
-                                       const buzz::XmlElement* stanza) {
-  console_->PrintLine("Failed request pub sub items for node %s.",
-                      node.c_str());
-}
-
-void CallClient::OnHangoutPublishAudioMuteError(
-    const std::string& task_id, const buzz::XmlElement* stanza) {
-  console_->PrintLine("Failed to publish audio mute state.");
-}
-
-void CallClient::OnHangoutPublishPresenterError(
-    const std::string& task_id, const buzz::XmlElement* stanza) {
-  console_->PrintLine("Failed to publish presenting state.");
-}
-
-void CallClient::OnHangoutPublishRecordingError(
-    const std::string& task_id, const buzz::XmlElement* stanza) {
-  console_->PrintLine("Failed to publish recording state.");
-}
-
-void CallClient::OnHangoutRemoteMuteError(const std::string& task_id,
-                                          const std::string& mutee_nick,
-                                          const buzz::XmlElement* stanza) {
-  console_->PrintLine("Failed to remote mute.");
-}
-
-void CallClient::CallVoicemail(const std::string& name) {
-  buzz::Jid jid(name);
-  if (!jid.IsValid() || jid.node() == "") {
-    console_->PrintLine("Invalid JID. JIDs should be in the form user@domain.");
-    return;
-  }
-  buzz::VoicemailJidRequester *request =
-      new buzz::VoicemailJidRequester(xmpp_client_, jid, my_status_.jid());
-  request->SignalGotVoicemailJid.connect(this,
-                                         &CallClient::OnFoundVoicemailJid);
-  request->SignalVoicemailJidError.connect(this,
-                                           &CallClient::OnVoicemailJidError);
-  request->Start();
-}
-
-void CallClient::OnFoundVoicemailJid(const buzz::Jid& to,
-                                     const buzz::Jid& voicemail) {
-  console_->PrintLine("Calling %s's voicemail.", to.Str().c_str());
-  PlaceCall(voicemail, cricket::CallOptions());
-}
-
-void CallClient::OnVoicemailJidError(const buzz::Jid& to) {
-  console_->PrintLine("Unable to voicemail %s.", to.Str().c_str());
-}
-
-void CallClient::Accept(const cricket::CallOptions& options) {
-  ASSERT(call_ && incoming_call_);
-  ASSERT(call_->sessions().size() == 1);
-  call_->AcceptSession(call_->sessions()[0], options);
-  media_client_->SetFocus(call_);
-  if (call_->video() && render_) {
-    call_->SetLocalRenderer(local_renderer_);
-    // The client never does an accept for multiway, so this must be 1:1,
-    // so there's no SSRC.
-    call_->SetVideoRenderer(session_, 0, remote_renderer_);
-  }
-  incoming_call_ = false;
-}
-
-void CallClient::Reject() {
-  ASSERT(call_ && incoming_call_);
-  call_->RejectSession(call_->sessions()[0]);
-  incoming_call_ = false;
-}
-
-void CallClient::Quit() {
-  talk_base::Thread::Current()->Quit();
-}
-
-void CallClient::SetNick(const std::string& muc_nick) {
-  my_status_.set_nick(muc_nick);
-
-  // TODO: We might want to re-send presence, but right
-  // now, it appears to be ignored by the MUC.
-  //
-  // presence_out_->Send(my_status_); for (MucMap::const_iterator itr
-  // = mucs_.begin(); itr != mucs_.end(); ++itr) {
-  // presence_out_->SendDirected(itr->second->local_jid(),
-  // my_status_); }
-
-  console_->PrintLine("Nick set to '%s'.", muc_nick.c_str());
-}
-
-void CallClient::LookupAndJoinMuc(const std::string& room_name) {
-  // The room_name can't be empty for lookup task.
-  if (room_name.empty()) {
-    console_->PrintLine("Please provide a room name or room jid.");
-    return;
-  }
-
-  std::string room = room_name;
-  std::string domain =  xmpp_client_->jid().domain();
-  if (room_name.find("@") != std::string::npos) {
-    // Assume the room_name is a fully qualified room name.
-    // We'll find the room name string and domain name string from it.
-    room = room_name.substr(0, room_name.find("@"));
-    domain = room_name.substr(room_name.find("@") + 1);
-  }
-
-  buzz::MucRoomLookupTask* lookup_query_task = new buzz::MucRoomLookupTask(
-      xmpp_client_, buzz::Jid(buzz::STR_GOOGLE_MUC_LOOKUP_JID), room, domain);
-  lookup_query_task->SignalResult.connect(this,
-      &CallClient::OnRoomLookupResponse);
-  lookup_query_task->SignalError.connect(this,
-      &CallClient::OnRoomLookupError);
-  lookup_query_task->Start();
-}
-
-void CallClient::JoinMuc(const std::string& room_jid_str) {
-  if (room_jid_str.empty()) {
-    buzz::Jid room_jid = GenerateRandomMucJid();
-    console_->PrintLine("Generated a random room jid: %s",
-                        room_jid.Str().c_str());
-    JoinMuc(room_jid);
-  } else {
-    JoinMuc(buzz::Jid(room_jid_str));
-  }
-}
-
-void CallClient::JoinMuc(const buzz::Jid& room_jid) {
-  if (!room_jid.IsValid()) {
-    console_->PrintLine("Unable to make valid muc endpoint for %s",
-                        room_jid.Str().c_str());
-    return;
-  }
-
-  std::string room_nick = room_jid.resource();
-  if (room_nick.empty()) {
-    room_nick = (xmpp_client_->jid().node()
-                 + "_" + xmpp_client_->jid().resource());
-  }
-
-  MucMap::iterator elem = mucs_.find(room_jid);
-  if (elem != mucs_.end()) {
-    console_->PrintLine("This MUC already exists.");
-    return;
-  }
-
-  buzz::Muc* muc = new buzz::Muc(room_jid.BareJid(), room_nick);
-  mucs_[muc->jid()] = muc;
-  presence_out_->SendDirected(muc->local_jid(), my_status_);
-}
-
-void CallClient::OnRoomLookupResponse(buzz::MucRoomLookupTask* task,
-                                      const buzz::MucRoomInfo& room) {
-  // The server requires the room be "configured" before being used.
-  // We only need to configure it if we create it, but rooms are
-  // auto-created at lookup, so there's currently no way to know if we
-  // created it.  So, we configure it every time, just in case.
-  // Luckily, it appears to be safe to configure a room that's already
-  // configured.  Our current flow is:
-  // 1. Lookup/auto-create
-  // 2. Configure
-  // 3. Join
-  // TODO: In the future, once the server supports it, we
-  // should:
-  // 1. Lookup
-  // 2. Create and Configure if necessary
-  // 3. Join
-  std::vector<std::string> room_features;
-  room_features.push_back(buzz::STR_MUC_ROOM_FEATURE_ENTERPRISE);
-  buzz::MucRoomConfigTask* room_config_task = new buzz::MucRoomConfigTask(
-      xmpp_client_, room.jid, room.full_name(), room_features);
-  room_config_task->SignalResult.connect(this,
-      &CallClient::OnRoomConfigResult);
-  room_config_task->SignalError.connect(this,
-      &CallClient::OnRoomConfigError);
-  room_config_task->Start();
-}
-
-void CallClient::OnRoomLookupError(buzz::IqTask* task,
-                                   const buzz::XmlElement* stanza) {
-  if (stanza == NULL) {
-    console_->PrintLine("Room lookup failed.");
-  } else {
-    console_->PrintLine("Room lookup error: ", stanza->Str().c_str());
-  }
-}
-
-void CallClient::OnRoomConfigResult(buzz::MucRoomConfigTask* task) {
-  JoinMuc(task->room_jid());
-}
-
-void CallClient::OnRoomConfigError(buzz::IqTask* task,
-                                   const buzz::XmlElement* stanza) {
-  console_->PrintLine("Room config failed.");
-  // We join the muc anyway, because if the room is already
-  // configured, the configure will fail, but we still want to join.
-  // Idealy, we'd know why the room config failed and only do this on
-  // "already configured" errors.  But right now all we get back is
-  // "not-allowed".
-  buzz::MucRoomConfigTask* config_task =
-      static_cast<buzz::MucRoomConfigTask*>(task);
-  JoinMuc(config_task->room_jid());
-}
-
-void CallClient::OnMucInviteReceived(const buzz::Jid& inviter,
-    const buzz::Jid& room,
-    const std::vector<buzz::AvailableMediaEntry>& avail) {
-
-  console_->PrintLine("Invited to join %s by %s.", room.Str().c_str(),
-      inviter.Str().c_str());
-  console_->PrintLine("Available media:");
-  if (avail.size() > 0) {
-    for (std::vector<buzz::AvailableMediaEntry>::const_iterator i =
-            avail.begin();
-        i != avail.end();
-        ++i) {
-      console_->PrintLine("  %s, %s",
-                          buzz::AvailableMediaEntry::TypeAsString(i->type),
-                          buzz::AvailableMediaEntry::StatusAsString(i->status));
-    }
-  } else {
-    console_->PrintLine("  None");
-  }
-  // We automatically join the room.
-  JoinMuc(room);
-}
-
-void CallClient::OnMucJoined(const buzz::Jid& endpoint) {
-  MucMap::iterator elem = mucs_.find(endpoint);
-  ASSERT(elem != mucs_.end() &&
-         elem->second->state() == buzz::Muc::MUC_JOINING);
-
-  buzz::Muc* muc = elem->second;
-  muc->set_state(buzz::Muc::MUC_JOINED);
-  console_->PrintLine("Joined \"%s\"", muc->jid().Str().c_str());
-}
-
-void CallClient::OnMucStatusUpdate(const buzz::Jid& jid,
-    const buzz::MucStatus& status) {
-
-  // Look up this muc.
-  MucMap::iterator elem = mucs_.find(jid);
-  ASSERT(elem != mucs_.end());
-
-  buzz::Muc* muc = elem->second;
-
-  if (status.jid().IsBare() || status.jid() == muc->local_jid()) {
-    // We are only interested in status about other users.
-    return;
-  }
-
-  if (!status.available()) {
-    // Remove them from the room.
-    muc->members().erase(status.jid().resource());
-  }
-}
-
-bool CallClient::InMuc() {
-  const buzz::Jid* muc_jid = FirstMucJid();
-  if (!muc_jid) return false;
-  return muc_jid->IsValid();
-}
-
-const buzz::Jid* CallClient::FirstMucJid() {
-  if (mucs_.empty()) return NULL;
-  return &(mucs_.begin()->first);
-}
-
-void CallClient::LeaveMuc(const std::string& room) {
-  buzz::Jid room_jid;
-  const buzz::Jid* muc_jid = FirstMucJid();
-  if (room.length() > 0) {
-    room_jid = buzz::Jid(room);
-  } else if (mucs_.size() > 0) {
-    // leave the first MUC if no JID specified
-    if (muc_jid) {
-      room_jid = *(muc_jid);
-    }
-  }
-
-  if (!room_jid.IsValid()) {
-    console_->PrintLine("Invalid MUC JID.");
-    return;
-  }
-
-  MucMap::iterator elem = mucs_.find(room_jid);
-  if (elem == mucs_.end()) {
-    console_->PrintLine("No such MUC.");
-    return;
-  }
-
-  buzz::Muc* muc = elem->second;
-  muc->set_state(buzz::Muc::MUC_LEAVING);
-
-  buzz::Status status;
-  status.set_jid(my_status_.jid());
-  status.set_available(false);
-  status.set_priority(0);
-  presence_out_->SendDirected(muc->local_jid(), status);
-}
-
-void CallClient::OnMucLeft(const buzz::Jid& endpoint, int error) {
-  // We could be kicked from a room from any state.  We would hope this
-  // happens While in the MUC_LEAVING state
-  MucMap::iterator elem = mucs_.find(endpoint);
-  if (elem == mucs_.end())
-    return;
-
-  buzz::Muc* muc = elem->second;
-  if (muc->state() == buzz::Muc::MUC_JOINING) {
-    console_->PrintLine("Failed to join \"%s\", code=%d",
-                        muc->jid().Str().c_str(), error);
-  } else if (muc->state() == buzz::Muc::MUC_JOINED) {
-    console_->PrintLine("Kicked from \"%s\"",
-                        muc->jid().Str().c_str());
-  }
-
-  delete muc;
-  mucs_.erase(elem);
-}
-
-void CallClient::InviteToMuc(const std::string& given_user,
-                             const std::string& room) {
-  std::string user = given_user;
-
-  // First find the room.
-  const buzz::Muc* found_muc;
-  if (room.length() == 0) {
-    if (mucs_.size() == 0) {
-      console_->PrintLine("Not in a room yet; can't invite.");
-      return;
-    }
-    // Invite to the first muc
-    found_muc = mucs_.begin()->second;
-  } else {
-    MucMap::iterator elem = mucs_.find(buzz::Jid(room));
-    if (elem == mucs_.end()) {
-      console_->PrintLine("Not in room %s.", room.c_str());
-      return;
-    }
-    found_muc = elem->second;
-  }
-
-  buzz::Jid invite_to = found_muc->jid();
-
-  // Now find the user. We invite all of their resources.
-  bool found_user = false;
-  buzz::Jid user_jid(user);
-  for (RosterMap::iterator iter = roster_->begin();
-       iter != roster_->end(); ++iter) {
-    if (iter->second.jid.BareEquals(user_jid)) {
-      buzz::Jid invitee = iter->second.jid;
-      muc_invite_send_->Send(invite_to, invitee);
-      found_user = true;
-    }
-  }
-  if (!found_user) {
-    buzz::Jid invitee = user_jid;
-    muc_invite_send_->Send(invite_to, invitee);
-  }
-}
-
-void CallClient::GetDevices() {
-  std::vector<std::string> names;
-  media_client_->GetAudioInputDevices(&names);
-  console_->PrintLine("Audio input devices:");
-  PrintDevices(names);
-  media_client_->GetAudioOutputDevices(&names);
-  console_->PrintLine("Audio output devices:");
-  PrintDevices(names);
-  media_client_->GetVideoCaptureDevices(&names);
-  console_->PrintLine("Video capture devices:");
-  PrintDevices(names);
-}
-
-void CallClient::PrintDevices(const std::vector<std::string>& names) {
-  for (size_t i = 0; i < names.size(); ++i) {
-    console_->PrintLine("%d: %s", static_cast<int>(i), names[i].c_str());
-  }
-}
-
-void CallClient::OnDevicesChange() {
-  console_->PrintLine("Devices changed.");
-  RefreshStatus();
-}
-
-void CallClient::SetVolume(const std::string& level) {
-  media_client_->SetOutputVolume(strtol(level.c_str(), NULL, 10));
-}
-
-void CallClient::OnMediaSourcesUpdate(cricket::Call* call,
-                                      cricket::Session* session,
-                                      const cricket::MediaSources& sources) {
-  for (cricket::NamedSources::const_iterator it = sources.video().begin();
-       it != sources.video().end(); ++it) {
-    if (it->removed) {
-      RemoveStaticRenderedView(it->ssrc);
-    } else {
-      if (render_) {
-        // TODO: Make dimensions and positions more configurable.
-        int offset = (50 * static_views_accumulated_count_) % 300;
-        AddStaticRenderedView(session, it->ssrc, 640, 400, 30,
-                              offset, offset);
-      }
-    }
-  }
-
-  SendViewRequest(session);
-}
-
-// TODO: Would these methods to add and remove views make
-// more sense in call.cc?  Would other clients use them?
-void CallClient::AddStaticRenderedView(
-    cricket::Session* session,
-    uint32 ssrc, int width, int height, int framerate,
-    int x_offset, int y_offset) {
-  StaticRenderedView rendered_view(
-      cricket::StaticVideoView(ssrc, width, height, framerate),
-      cricket::VideoRendererFactory::CreateGuiVideoRenderer(
-          x_offset, y_offset));
-  rendered_view.renderer->SetSize(width, height, 0);
-  call_->SetVideoRenderer(session, ssrc, rendered_view.renderer);
-  static_rendered_views_.push_back(rendered_view);
-  ++static_views_accumulated_count_;
-  console_->PrintLine("Added renderer for ssrc %d", ssrc);
-}
-
-bool CallClient::RemoveStaticRenderedView(uint32 ssrc) {
-  for (StaticRenderedViews::iterator it = static_rendered_views_.begin();
-       it != static_rendered_views_.end(); ++it) {
-    if (it->view.ssrc == ssrc) {
-      delete it->renderer;
-      static_rendered_views_.erase(it);
-      console_->PrintLine("Removed renderer for ssrc %d", ssrc);
-      return true;
-    }
-  }
-  return false;
-}
-
-void CallClient::RemoveAllStaticRenderedViews() {
-  for (StaticRenderedViews::iterator it = static_rendered_views_.begin();
-       it != static_rendered_views_.end(); ++it) {
-    delete it->renderer;
-  }
-  static_rendered_views_.clear();
-}
-
-void CallClient::SendViewRequest(cricket::Session* session) {
-  cricket::ViewRequest request;
-  for (StaticRenderedViews::iterator it = static_rendered_views_.begin();
-       it != static_rendered_views_.end(); ++it) {
-    request.static_video_views.push_back(it->view);
-  }
-  call_->SendViewRequest(session, request);
-}
-
-buzz::Jid CallClient::GenerateRandomMucJid() {
-  // Generate a GUID of the form XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX,
-  // for an eventual JID of private-chat-<GUID>@groupchat.google.com.
-  char guid[37], guid_room[256];
-  for (size_t i = 0; i < ARRAY_SIZE(guid) - 1;) {
-    if (i == 8 || i == 13 || i == 18 || i == 23) {
-      guid[i++] = '-';
-    } else {
-      sprintf(guid + i, "%04x", rand());
-      i += 4;
-    }
-  }
-
-  talk_base::sprintfn(guid_room,
-                      ARRAY_SIZE(guid_room),
-                      "private-chat-%s@%s",
-                      guid,
-                      pmuc_domain_.c_str());
-  return buzz::Jid(guid_room);
-}
diff --git a/third_party/libjingle/source/talk/examples/call/callclient.h b/third_party/libjingle/source/talk/examples/call/callclient.h
deleted file mode 100644
index 3ba9994..0000000
--- a/third_party/libjingle/source/talk/examples/call/callclient.h
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_EXAMPLES_CALL_CALLCLIENT_H_
-#define TALK_EXAMPLES_CALL_CALLCLIENT_H_
-
-#include <map>
-#include <string>
-#include <vector>
-
-#include "talk/p2p/base/session.h"
-#include "talk/session/phone/mediachannel.h"
-#include "talk/session/phone/mediamessages.h"
-#include "talk/session/phone/mediasessionclient.h"
-#include "talk/xmpp/hangoutpubsubclient.h"
-#include "talk/xmpp/xmppclient.h"
-#include "talk/examples/call/status.h"
-#include "talk/examples/call/console.h"
-
-namespace buzz {
-class PresencePushTask;
-class PresenceOutTask;
-class MucInviteRecvTask;
-class MucInviteSendTask;
-class FriendInviteSendTask;
-class VoicemailJidRequester;
-class DiscoInfoQueryTask;
-class Muc;
-class Status;
-class IqTask;
-class MucRoomConfigTask;
-class MucRoomLookupTask;
-class MucStatus;
-class XmlElement;
-class HangoutPubSubClient;
-struct AvailableMediaEntry;
-struct MucRoomInfo;
-}
-
-namespace talk_base {
-class Thread;
-class NetworkManager;
-}
-
-namespace cricket {
-class PortAllocator;
-class MediaEngineInterface;
-class MediaSessionClient;
-class Receiver;
-class Call;
-class SessionManagerTask;
-struct CallOptions;
-struct NamedSource;
-}
-
-struct RosterItem {
-  buzz::Jid jid;
-  buzz::Status::Show show;
-  std::string status;
-};
-
-struct StaticRenderedView {
-  StaticRenderedView(const cricket::StaticVideoView& view,
-                     cricket::VideoRenderer* renderer) :
-      view(view),
-      renderer(renderer) {
-  }
-
-  cricket::StaticVideoView view;
-  cricket::VideoRenderer* renderer;
-};
-
-typedef std::vector<StaticRenderedView> StaticRenderedViews;
-
-class CallClient: public sigslot::has_slots<> {
- public:
-  explicit CallClient(buzz::XmppClient* xmpp_client);
-  ~CallClient();
-
-  cricket::MediaSessionClient* media_client() const { return media_client_; }
-  void SetMediaEngine(cricket::MediaEngineInterface* media_engine) {
-    media_engine_ = media_engine;
-  }
-  void SetAutoAccept(bool auto_accept) {
-    auto_accept_ = auto_accept;
-  }
-  void SetPmucDomain(const std::string &pmuc_domain) {
-    pmuc_domain_ = pmuc_domain;
-  }
-  void SetRender(bool render) {
-    render_ = render;
-  }
-  void SetConsole(Console *console) {
-    console_ = console;
-  }
-
-  void ParseLine(const std::string &str);
-
-  void SendChat(const std::string& to, const std::string msg);
-  void InviteFriend(const std::string& user);
-  void JoinMuc(const buzz::Jid& room_jid);
-  void JoinMuc(const std::string& room_jid_str);
-  void LookupAndJoinMuc(const std::string& room_name);
-  void InviteToMuc(const std::string& user, const std::string& room);
-  bool InMuc();
-  const buzz::Jid* FirstMucJid();
-  void LeaveMuc(const std::string& room);
-  void SetNick(const std::string& muc_nick);
-  void SetPortAllocatorFlags(uint32 flags) { portallocator_flags_ = flags; }
-  void SetAllowLocalIps(bool allow_local_ips) {
-    allow_local_ips_ = allow_local_ips;
-  }
-
-  void SetInitialProtocol(cricket::SignalingProtocol initial_protocol) {
-    initial_protocol_ = initial_protocol;
-  }
-
-  void SetSecurePolicy(cricket::SecureMediaPolicy secure_policy) {
-    secure_policy_ = secure_policy;
-  }
-
-
-  typedef std::map<buzz::Jid, buzz::Muc*> MucMap;
-
-  const MucMap& mucs() const {
-    return mucs_;
-  }
-
- private:
-  void AddStream(uint32 audio_src_id, uint32 video_src_id);
-  void RemoveStream(uint32 audio_src_id, uint32 video_src_id);
-  void OnStateChange(buzz::XmppEngine::State state);
-
-  void InitMedia();
-  void InitPresence();
-  void RefreshStatus();
-  void OnRequestSignaling();
-  void OnSessionCreate(cricket::Session* session, bool initiate);
-  void OnCallCreate(cricket::Call* call);
-  void OnCallDestroy(cricket::Call* call);
-  void OnSessionState(cricket::Call* call,
-                      cricket::Session* session,
-                      cricket::Session::State state);
-  void OnStatusUpdate(const buzz::Status& status);
-  void OnMucInviteReceived(const buzz::Jid& inviter, const buzz::Jid& room,
-      const std::vector<buzz::AvailableMediaEntry>& avail);
-  void OnMucJoined(const buzz::Jid& endpoint);
-  void OnMucStatusUpdate(const buzz::Jid& jid, const buzz::MucStatus& status);
-  void OnMucLeft(const buzz::Jid& endpoint, int error);
-  void OnPresenterStateChange(const std::string& nick,
-                              bool was_presenting, bool is_presenting);
-  void OnAudioMuteStateChange(const std::string& nick,
-                              bool was_muted, bool is_muted);
-  void OnRecordingStateChange(const std::string& nick,
-                              bool was_recording, bool is_recording);
-  void OnRemoteMuted(const std::string& mutee_nick,
-                     const std::string& muter_nick,
-                     bool should_mute_locally);
-  void OnMediaBlocked(const std::string& blockee_nick,
-                      const std::string& blocker_nick);
-  void OnHangoutRequestError(const std::string& node,
-                             const buzz::XmlElement* stanza);
-  void OnHangoutPublishAudioMuteError(const std::string& task_id,
-                                      const buzz::XmlElement* stanza);
-  void OnHangoutPublishPresenterError(const std::string& task_id,
-                                      const buzz::XmlElement* stanza);
-  void OnHangoutPublishRecordingError(const std::string& task_id,
-                                      const buzz::XmlElement* stanza);
-  void OnHangoutRemoteMuteError(const std::string& task_id,
-                                const std::string& mutee_nick,
-                                const buzz::XmlElement* stanza);
-  void OnDevicesChange();
-  void OnFoundVoicemailJid(const buzz::Jid& to, const buzz::Jid& voicemail);
-  void OnVoicemailJidError(const buzz::Jid& to);
-  void OnMediaSourcesUpdate(cricket::Call* call,
-                            cricket::Session* session,
-                            const cricket::MediaSources& sources);
-  void OnSpeakerChanged(cricket::Call* call,
-                        cricket::Session* session,
-                        const cricket::NamedSource& speaker_source);
-  void OnRoomLookupResponse(buzz::MucRoomLookupTask* task,
-                            const buzz::MucRoomInfo& room_info);
-  void OnRoomLookupError(buzz::IqTask* task,
-                         const buzz::XmlElement* stanza);
-  void OnRoomConfigResult(buzz::MucRoomConfigTask* task);
-  void OnRoomConfigError(buzz::IqTask* task,
-                         const buzz::XmlElement* stanza);
-  buzz::Jid GenerateRandomMucJid();
-
-  void AddStaticRenderedView(
-      cricket::Session* session,
-      uint32 ssrc, int width, int height, int framerate,
-      int x_offset, int y_offset);
-  bool RemoveStaticRenderedView(uint32 ssrc);
-  void RemoveAllStaticRenderedViews();
-  void SendViewRequest(cricket::Session* session);
-
-
-  static const std::string strerror(buzz::XmppEngine::Error err);
-
-  void PrintRoster();
-  void MakeCallTo(const std::string& name, const cricket::CallOptions& options);
-  void PlaceCall(const buzz::Jid& jid, const cricket::CallOptions& options);
-  void CallVoicemail(const std::string& name);
-  void Accept(const cricket::CallOptions& options);
-  void Reject();
-  void Quit();
-
-  void GetDevices();
-  void PrintDevices(const std::vector<std::string>& names);
-
-  void SetVolume(const std::string& level);
-
-  typedef std::map<std::string, RosterItem> RosterMap;
-
-  Console *console_;
-  buzz::XmppClient* xmpp_client_;
-  talk_base::Thread* worker_thread_;
-  talk_base::NetworkManager* network_manager_;
-  cricket::PortAllocator* port_allocator_;
-  cricket::SessionManager* session_manager_;
-  cricket::SessionManagerTask* session_manager_task_;
-  cricket::MediaEngineInterface* media_engine_;
-  cricket::MediaSessionClient* media_client_;
-  MucMap mucs_;
-
-  cricket::Call* call_;
-  cricket::Session *session_;
-  buzz::HangoutPubSubClient* hangout_pubsub_client_;
-  bool incoming_call_;
-  bool auto_accept_;
-  std::string pmuc_domain_;
-  bool render_;
-  cricket::VideoRenderer* local_renderer_;
-  cricket::VideoRenderer* remote_renderer_;
-  StaticRenderedViews static_rendered_views_;
-  uint32 static_views_accumulated_count_;
-
-  buzz::Status my_status_;
-  buzz::PresencePushTask* presence_push_;
-  buzz::PresenceOutTask* presence_out_;
-  buzz::MucInviteRecvTask* muc_invite_recv_;
-  buzz::MucInviteSendTask* muc_invite_send_;
-  buzz::FriendInviteSendTask* friend_invite_send_;
-  RosterMap* roster_;
-  uint32 portallocator_flags_;
-
-  bool allow_local_ips_;
-  cricket::SignalingProtocol initial_protocol_;
-  cricket::SecureMediaPolicy secure_policy_;
-  std::string last_sent_to_;
-};
-
-#endif  // TALK_EXAMPLES_CALL_CALLCLIENT_H_
diff --git a/third_party/libjingle/source/talk/examples/call/console.cc b/third_party/libjingle/source/talk/examples/call/console.cc
deleted file mode 100644
index 7949c15..0000000
--- a/third_party/libjingle/source/talk/examples/call/console.cc
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#define _CRT_SECURE_NO_DEPRECATE 1
-
-#ifdef POSIX
-#include <signal.h>
-#include <termios.h>
-#include <unistd.h>
-#endif  // POSIX
-#include <cassert>
-#include "talk/base/logging.h"
-#include "talk/base/messagequeue.h"
-#include "talk/base/stringutils.h"
-#include "talk/examples/call/console.h"
-#include "talk/examples/call/callclient.h"
-
-#ifdef POSIX
-static void DoNothing(int unused) {}
-#endif
-
-Console::Console(talk_base::Thread *thread, CallClient *client) :
-  client_(client),
-  client_thread_(thread),
-  console_thread_(new talk_base::Thread()) {}
-
-Console::~Console() {
-  Stop();
-}
-
-void Console::Start() {
-  if (!console_thread_.get()) {
-    // stdin was closed in Stop(), so we can't restart.
-    LOG(LS_ERROR) << "Cannot re-start";
-    return;
-  }
-  if (console_thread_->started()) {
-    LOG(LS_WARNING) << "Already started";
-    return;
-  }
-  console_thread_->Start();
-  console_thread_->Post(this, MSG_START);
-}
-
-void Console::Stop() {
-  if (console_thread_.get() && console_thread_->started()) {
-#ifdef WIN32
-    CloseHandle(GetStdHandle(STD_INPUT_HANDLE));
-#else
-    close(fileno(stdin));
-    // This forces the read() in fgets() to return with errno = EINTR. fgets()
-    // will retry the read() and fail, thus returning.
-    pthread_kill(console_thread_->GetPThread(), SIGUSR1);
-#endif
-    console_thread_->Stop();
-    console_thread_.reset();
-  }
-}
-
-void Console::SetEcho(bool on) {
-#ifdef WIN32
-  HANDLE hIn = GetStdHandle(STD_INPUT_HANDLE);
-  if ((hIn == INVALID_HANDLE_VALUE) || (hIn == NULL))
-    return;
-
-  DWORD mode;
-  if (!GetConsoleMode(hIn, &mode))
-    return;
-
-  if (on) {
-    mode = mode | ENABLE_ECHO_INPUT;
-  } else {
-    mode = mode & ~ENABLE_ECHO_INPUT;
-  }
-
-  SetConsoleMode(hIn, mode);
-#else
-  const int fd = fileno(stdin);
-  if (fd == -1)
-   return;
-
-  struct termios tcflags;
-  if (tcgetattr(fd, &tcflags) == -1)
-    return;
-
-  if (on) {
-    tcflags.c_lflag |= ECHO;
-  } else {
-    tcflags.c_lflag &= ~ECHO;
-  }
-
-  tcsetattr(fd, TCSANOW, &tcflags);
-#endif
-}
-
-void Console::PrintLine(const char* format, ...) {
-  va_list ap;
-  va_start(ap, format);
-
-  char buf[4096];
-  int size = vsnprintf(buf, sizeof(buf), format, ap);
-  assert(size >= 0);
-  assert(size < static_cast<int>(sizeof(buf)));
-  buf[size] = '\0';
-  printf("%s\n", buf);
-  fflush(stdout);
-
-  va_end(ap);
-}
-
-void Console::RunConsole() {
-  char input_buffer[128];
-  while (fgets(input_buffer, sizeof(input_buffer), stdin) != NULL) {
-    client_thread_->Post(this, MSG_INPUT,
-        new talk_base::TypedMessageData<std::string>(input_buffer));
-  }
-}
-
-void Console::OnMessage(talk_base::Message *msg) {
-  switch (msg->message_id) {
-    case MSG_START:
-#ifdef POSIX
-      // Install a no-op signal so that we can abort RunConsole() by raising
-      // SIGUSR1.
-      struct sigaction act;
-      act.sa_handler = &DoNothing;
-      sigemptyset(&act.sa_mask);
-      act.sa_flags = 0;
-      if (sigaction(SIGUSR1, &act, NULL) < 0) {
-        LOG(LS_WARNING) << "Can't install signal";
-      }
-#endif
-      RunConsole();
-      break;
-    case MSG_INPUT:
-      talk_base::TypedMessageData<std::string> *data =
-          static_cast<talk_base::TypedMessageData<std::string>*>(msg->pdata);
-      client_->ParseLine(data->data());
-      break;
-  }
-}
diff --git a/third_party/libjingle/source/talk/examples/call/console.h b/third_party/libjingle/source/talk/examples/call/console.h
deleted file mode 100644
index 4a90a7f..0000000
--- a/third_party/libjingle/source/talk/examples/call/console.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_EXAMPLES_CALL_CONSOLE_H_
-#define TALK_EXAMPLES_CALL_CONSOLE_H_
-
-#include <cstdio>
-
-#include "talk/base/thread.h"
-#include "talk/base/messagequeue.h"
-#include "talk/base/scoped_ptr.h"
-
-class CallClient;
-
-class Console : public talk_base::MessageHandler {
- public:
-  Console(talk_base::Thread *thread, CallClient *client);
-  ~Console();
-
-  // Starts reading lines from the console and giving them to the CallClient.
-  void Start();
-  // Stops reading lines. Cannot be restarted.
-  void Stop();
-
-  virtual void OnMessage(talk_base::Message *msg);
-
-  void PrintLine(const char* format, ...);
-
-  static void SetEcho(bool on);
-
- private:
-  enum {
-    MSG_START,
-    MSG_INPUT,
-  };
-
-  void RunConsole();
-  void ParseLine(std::string &str);
-
-  CallClient *client_;
-  talk_base::Thread *client_thread_;
-  talk_base::scoped_ptr<talk_base::Thread> console_thread_;
-};
-
-#endif // TALK_EXAMPLES_CALL_CONSOLE_H_
diff --git a/third_party/libjingle/source/talk/examples/call/discoitemsquerytask.cc b/third_party/libjingle/source/talk/examples/call/discoitemsquerytask.cc
deleted file mode 100644
index 6bbfb1d..0000000
--- a/third_party/libjingle/source/talk/examples/call/discoitemsquerytask.cc
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/examples/call/discoitemsquerytask.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/xmpp/constants.h"
-
-
-namespace buzz {
-
-namespace {
-const int kDiscoItemsTimeout = 60;
-} // namespace
-
-DiscoItemsQueryTask::DiscoItemsQueryTask(XmppTaskParentInterface* parent,
-                                         const std::string& node,
-                                         const Jid& to)
-    : XmppTask(parent, XmppEngine::HL_SINGLE), node_(node) {
-  set_timeout_seconds(kDiscoItemsTimeout);
-  to_ = to;
-}
-
-int DiscoItemsQueryTask::ProcessStart() {
-  talk_base::scoped_ptr<XmlElement> get(MakeIq(STR_GET, to_, task_id()));
-
-  XmlElement* element = new XmlElement(QN_DISCO_ITEMS_QUERY, true);
-  element->AddAttr(QN_NODE, node_);
-
-  get->AddElement(element);
-
-  if (SendStanza(get.get()) != XMPP_RETURN_OK) {
-    SignalDiscoItemsError(to_, NULL);
-    return STATE_ERROR;
-  }
-
-  return STATE_RESPONSE;
-}
-
-int DiscoItemsQueryTask::ProcessResponse() {
-  const XmlElement* stanza = NextStanza();
-  if (stanza == NULL)
-    return STATE_BLOCKED;
-
-  bool success = false;
-  if (stanza->Attr(QN_TYPE) != STR_ERROR) {
-    const XmlElement* query = stanza->FirstNamed(QN_DISCO_ITEMS_QUERY);
-    if (query) {
-      SignalGotDiscoItems(to_, query);
-      success = true;
-    }
-  }
-
-  if (!success) {
-    SignalDiscoItemsError(to_, stanza->FirstNamed(QN_ERROR));
-  }
-
-  return STATE_DONE;
-}
-
-int DiscoItemsQueryTask::OnTimeout() {
-  SignalDiscoItemsError(to_, NULL);
-  return XmppTask::OnTimeout();
-}
-
-bool DiscoItemsQueryTask::HandleStanza(const XmlElement* stanza) {
-  if (!MatchResponseIq(stanza, to_, task_id()))
-    return false;
-  QueueStanza(stanza);
-  return true;
-
-}
-
-}
diff --git a/third_party/libjingle/source/talk/examples/call/discoitemsquerytask.h b/third_party/libjingle/source/talk/examples/call/discoitemsquerytask.h
deleted file mode 100644
index 27912bc..0000000
--- a/third_party/libjingle/source/talk/examples/call/discoitemsquerytask.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// Fires a disco items query, such as the following example:
-// 
-//      <iq type='get'
-//          from='foo@gmail.com/asdf'
-//          to='bar@google.com'
-//          id='1234'>
-//          <query xmlns=' http://jabber.org/protocol/disco#items'
-//                 node='blah '/>
-//      </iq>
-//
-// Sample response:
-//
-//      <iq type='result'
-//          from=' hendriks@google.com'
-//          to='rsturgell@google.com/asdf'
-//          id='1234'>
-//          <query xmlns=' http://jabber.org/protocol/disco#items '
-//                 node='blah'>
-//                 <item something='somethingelse'/>
-//          </query>
-//      </iq>
-
-
-#ifndef _DISCOITEMSQUERYTASK_H_
-#define _DISCOITEMSQUERYTASK_H_
-
-#include "talk/xmpp/xmpptask.h"
-
-namespace buzz {
-
-class DiscoItemsQueryTask : public XmppTask {
- public:
-  // TODO: Currently, this only supports one query stanza - we may eventually
-  // need it to support multiple
-  DiscoItemsQueryTask(XmppTaskParentInterface* parent,
-                      const std::string& node, const Jid& to);
-
-  virtual int ProcessStart();
-  virtual int ProcessResponse();
-
-  // On success, fires a signal with the jid we sent the query to and the inner
-  // XmlElement
-  sigslot::signal2<Jid, const XmlElement*> SignalGotDiscoItems;
-
-  // The XmlElement here is the error element under the error response.  If the
-  // request just timed out then this will be NULL
-  sigslot::signal2<Jid, const XmlElement*> SignalDiscoItemsError;
-
- protected:
-  virtual bool HandleStanza(const XmlElement* stanza);
-  virtual int OnTimeout();
-  
- private:
-  // The jid we're querying
-  Jid to_;
-  // The name of the node
-  const std::string node_;
-};
-
-}
-
-#endif
diff --git a/third_party/libjingle/source/talk/examples/call/friendinvitesendtask.cc b/third_party/libjingle/source/talk/examples/call/friendinvitesendtask.cc
deleted file mode 100644
index cdb0b2c..0000000
--- a/third_party/libjingle/source/talk/examples/call/friendinvitesendtask.cc
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/xmpp/constants.h"
-#include "talk/examples/call/friendinvitesendtask.h"
-
-namespace buzz {
-
-XmppReturnStatus
-FriendInviteSendTask::Send(const Jid& user) {
-  if (GetState() != STATE_INIT && GetState() != STATE_START)
-    return XMPP_RETURN_BADSTATE;
-
-  // Need to first add to roster, then subscribe to presence.
-  XmlElement* iq = new XmlElement(QN_IQ);
-  iq->AddAttr(QN_TYPE, STR_SET);
-  XmlElement* query = new XmlElement(QN_ROSTER_QUERY);
-  XmlElement* item = new XmlElement(QN_ROSTER_ITEM);
-  item->AddAttr(QN_JID, user.Str());
-  item->AddAttr(QN_NAME, user.node());
-  query->AddElement(item);
-  iq->AddElement(query);
-  QueueStanza(iq);
-
-  // Subscribe to presence
-  XmlElement* presence = new XmlElement(QN_PRESENCE);
-  presence->AddAttr(QN_TO, user.Str());
-  presence->AddAttr(QN_TYPE, STR_SUBSCRIBE);
-  XmlElement* invitation = new XmlElement(QN_INVITATION);
-  invitation->AddAttr(QN_INVITE_MESSAGE,
-      "I've been using Google Talk and thought you might like to try it out. "
-      "We can use it to call each other for free over the internet. Here's an "
-      "invitation to download Google Talk. Give it a try!");
-  presence->AddElement(invitation);
-  QueueStanza(presence);
-
-  return XMPP_RETURN_OK;
-}
-
-int
-FriendInviteSendTask::ProcessStart() {
-  const XmlElement* stanza = NextStanza();
-  if (stanza == NULL)
-    return STATE_BLOCKED;
-
-  if (SendStanza(stanza) != XMPP_RETURN_OK)
-    return STATE_ERROR;
-
-  return STATE_START;
-}
-
-}
diff --git a/third_party/libjingle/source/talk/examples/call/friendinvitesendtask.h b/third_party/libjingle/source/talk/examples/call/friendinvitesendtask.h
deleted file mode 100644
index 625f077..0000000
--- a/third_party/libjingle/source/talk/examples/call/friendinvitesendtask.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _FRIENDINVITESENDTASK_H_
-#define _FRIENDINVITESENDTASK_H_
-
-#include "talk/xmpp/xmppengine.h"
-#include "talk/xmpp/xmpptask.h"
-
-namespace buzz {
-
-class FriendInviteSendTask : public XmppTask {
-public:
-  explicit FriendInviteSendTask(XmppTaskParentInterface* parent)
-    : XmppTask(parent) {}
-  virtual ~FriendInviteSendTask() {}
-
-  XmppReturnStatus Send(const Jid& user);
-
-  virtual int ProcessStart();
-};
-
-}
-
-#endif
diff --git a/third_party/libjingle/source/talk/examples/call/mediaenginefactory.cc b/third_party/libjingle/source/talk/examples/call/mediaenginefactory.cc
deleted file mode 100644
index 7bd39c9..0000000
--- a/third_party/libjingle/source/talk/examples/call/mediaenginefactory.cc
+++ /dev/null
@@ -1,82 +0,0 @@
-//
-// libjingle
-// Copyright 2004--2007, Google Inc.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-//  1. Redistributions of source code must retain the above copyright notice,
-//     this list of conditions and the following disclaimer.
-//  2. Redistributions in binary form must reproduce the above copyright notice,
-//     this list of conditions and the following disclaimer in the documentation
-//     and/or other materials provided with the distribution.
-//  3. The name of the author may not be used to endorse or promote products
-//     derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-
-#include "talk/examples/call/mediaenginefactory.h"
-
-#include "talk/base/stringutils.h"
-#include "talk/session/phone/mediaengine.h"
-#include "talk/session/phone/fakemediaengine.h"
-#include "talk/session/phone/filemediaengine.h"
-
-std::vector<cricket::AudioCodec> RequiredAudioCodecs() {
-  std::vector<cricket::AudioCodec> audio_codecs;
-  audio_codecs.push_back(
-      cricket::AudioCodec(9, "G722", 16000, 0, 1, 0));
-  audio_codecs.push_back(
-      cricket::AudioCodec(0, "PCMU", 8000, 0, 1, 0));
-  audio_codecs.push_back(
-      cricket::AudioCodec(13, "CN", 8000, 0, 1, 0));
-  audio_codecs.push_back(
-      cricket::AudioCodec(105, "CN", 16000, 0, 1, 0));
-  return audio_codecs;
-}
-
-std::vector<cricket::VideoCodec> RequiredVideoCodecs() {
-  std::vector<cricket::VideoCodec> video_codecs;
-  video_codecs.push_back(
-      cricket::VideoCodec(97, "H264", 320, 240, 30, 0));
-  video_codecs.push_back(
-      cricket::VideoCodec(99, "H264-SVC", 640, 360, 30, 0));
-  return video_codecs;
-}
-
-cricket::MediaEngineInterface* MediaEngineFactory::CreateFileMediaEngine(
-    const char* voice_in, const char* voice_out,
-    const char* video_in, const char* video_out) {
-
-  cricket::FileMediaEngine* file_media_engine = new cricket::FileMediaEngine;
-  // Set the RTP dump file names.
-  if (voice_in) {
-    file_media_engine->set_voice_input_filename(voice_in);
-  }
-  if (voice_out) {
-    file_media_engine->set_voice_output_filename(voice_out);
-  }
-  if (video_in) {
-    file_media_engine->set_video_input_filename(video_in);
-  }
-  if (video_out) {
-    file_media_engine->set_video_output_filename(video_out);
-  }
-
-  // Set voice and video codecs. TODO: The codecs actually depend on
-  // the the input voice and video streams.
-  file_media_engine->set_voice_codecs(RequiredAudioCodecs());
-  file_media_engine->set_video_codecs(RequiredVideoCodecs());
-
-  return file_media_engine;
-}
diff --git a/third_party/libjingle/source/talk/examples/call/mediaenginefactory.h b/third_party/libjingle/source/talk/examples/call/mediaenginefactory.h
deleted file mode 100644
index f7ba68e..0000000
--- a/third_party/libjingle/source/talk/examples/call/mediaenginefactory.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * libjingle
- * Copyright 2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_EXAMPLES_CALL_MEDIAENGINEFACTORY_H_
-#define TALK_EXAMPLES_CALL_MEDIAENGINEFACTORY_H_
-
-#include "talk/session/phone/mediaengine.h"
-
-class MediaEngineFactory {
- public:
-  static cricket::MediaEngineInterface* CreateFileMediaEngine(
-      const char* voice_in, const char* voice_out,
-      const char* video_in, const char* video_out);
-};
-
-#endif  // TALK_EXAMPLES_CALL_MEDIAENGINEFACTORY_H_
diff --git a/third_party/libjingle/source/talk/examples/call/muc.h b/third_party/libjingle/source/talk/examples/call/muc.h
deleted file mode 100644
index 2f6df2e..0000000
--- a/third_party/libjingle/source/talk/examples/call/muc.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _MUC_H_
-#define _MUC_H_
-
-#include <map>
-#include "talk/xmpp/jid.h"
-#include "talk/examples/call/status.h"
-
-namespace buzz {
-
-class Muc {
- public:
-   Muc(const Jid& jid, const std::string& nick) : state_(MUC_JOINING),
-       jid_(jid), local_jid_(Jid(jid.Str() + "/" + nick)) {}
-  ~Muc() {};
-
-  enum State { MUC_JOINING, MUC_JOINED, MUC_LEAVING };
-  State state() const { return state_; }
-  void set_state(State state) { state_ = state; }
-  const Jid & jid() const { return jid_; }
-  const Jid & local_jid() const { return local_jid_; }
-
-  typedef std::map<std::string, MucStatus> MemberMap;
-
-  // All the intelligence about how to manage the members is in
-  // CallClient, so we completely expose the map.
-  MemberMap& members() {
-    return members_;
-  }
-
-private:
-  State state_;
-  Jid jid_;
-  Jid local_jid_;
-  MemberMap members_;
-};
-
-}
-
-#endif
diff --git a/third_party/libjingle/source/talk/examples/call/mucinviterecvtask.cc b/third_party/libjingle/source/talk/examples/call/mucinviterecvtask.cc
deleted file mode 100644
index 061db74..0000000
--- a/third_party/libjingle/source/talk/examples/call/mucinviterecvtask.cc
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/xmpp/constants.h"
-#include "talk/examples/call/mucinviterecvtask.h"
-
-namespace buzz {
-
-const char* types[] = {
-  "unknown",
-  "audio",
-  "video",
-};
-
-const char* statuses[] = {
-  "unknown",
-  "sendrecv",
-  "sendonly",
-  "recvonly",
-  "inactive",
-};
-
-const char*
-AvailableMediaEntry::TypeAsString(type_t type) {
-  // The values of the constants have been chosen such that this is correct.
-  return types[type];
-}
-
-const char*
-AvailableMediaEntry::StatusAsString(status_t status) {
-  // The values of the constants have been chosen such that this is correct.
-  return statuses[status];
-}
-
-int bodytext_to_array_pos(const XmlElement* elem, const char* array[],
-    int len, int defval = -1) {
-  if (elem) {
-    const std::string& body(elem->BodyText());
-    for (int i = 0; i < len; ++i) {
-      if (body == array[i]) {
-        // Found it.
-        return i;
-      }
-    }
-  }
-  // If we get here, it's not any value in the array.
-  return defval;
-}
-
-bool
-MucInviteRecvTask::HandleStanza(const XmlElement* stanza) {
-  // Figuring out that we want to handle this is a lot of the work of
-  // actually handling it, so we handle it right here instead of queueing it.
-  const XmlElement* xstanza;
-  const XmlElement* invite;
-  if (stanza->Name() != QN_MESSAGE) return false;
-  xstanza = stanza->FirstNamed(QN_MUC_USER_X);
-  if (!xstanza) return false;
-  invite = xstanza->FirstNamed(QN_MUC_USER_INVITE);
-  if (!invite) return false;
-  // Else it's an invite and we definitely want to handle it. Parse the
-  // available-media, if any.
-  std::vector<AvailableMediaEntry> v;
-  const XmlElement* avail =
-    invite->FirstNamed(QN_GOOGLE_MUC_USER_AVAILABLE_MEDIA);
-  if (avail) {
-    for (const XmlElement* entry = avail->FirstNamed(QN_GOOGLE_MUC_USER_ENTRY);
-        entry;
-        entry = entry->NextNamed(QN_GOOGLE_MUC_USER_ENTRY)) {
-      AvailableMediaEntry tmp;
-      // In the interest of debugging, we accept as much valid-looking data
-      // as we can.
-      tmp.label = atoi(entry->Attr(QN_LABEL).c_str());
-      tmp.type = static_cast<AvailableMediaEntry::type_t>(
-          bodytext_to_array_pos(
-              entry->FirstNamed(QN_GOOGLE_MUC_USER_TYPE),
-              types,
-              sizeof(types)/sizeof(const char*),
-              AvailableMediaEntry::TYPE_UNKNOWN));
-      tmp.status = static_cast<AvailableMediaEntry::status_t>(
-          bodytext_to_array_pos(
-              entry->FirstNamed(QN_GOOGLE_MUC_USER_STATUS),
-              statuses,
-              sizeof(statuses)/sizeof(const char*),
-              AvailableMediaEntry::STATUS_UNKNOWN));
-      v.push_back(tmp);
-    }
-  }
-  SignalInviteReceived(Jid(invite->Attr(QN_FROM)), Jid(stanza->Attr(QN_FROM)),
-      v);
-  return true;
-}
-
-int
-MucInviteRecvTask::ProcessStart() {
-  // We never queue anything so we are always blocked.
-  return STATE_BLOCKED;
-}
-
-}
diff --git a/third_party/libjingle/source/talk/examples/call/mucinviterecvtask.h b/third_party/libjingle/source/talk/examples/call/mucinviterecvtask.h
deleted file mode 100644
index 24f05e0..0000000
--- a/third_party/libjingle/source/talk/examples/call/mucinviterecvtask.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _MUCINVITERECVTASK_H_
-#define _MUCINVITERECVTASK_H_
-
-#include <vector>
-
-#include "talk/base/sigslot.h"
-#include "talk/xmpp/xmppengine.h"
-#include "talk/xmpp/xmpptask.h"
-
-namespace buzz {
-
-struct AvailableMediaEntry {
-  enum type_t {
-    // SIP defines other media types, but these are the only ones we use in
-    // multiway jingle.
-    // These numbers are important; see .cc file
-    TYPE_UNKNOWN = 0, // indicates invalid string
-    TYPE_AUDIO = 1,
-    TYPE_VIDEO = 2,
-  };
-
-  enum status_t {
-    // These numbers are important; see .cc file
-    STATUS_UNKNOWN = 0, // indicates invalid string
-    STATUS_SENDRECV = 1,
-    STATUS_SENDONLY = 2,
-    STATUS_RECVONLY = 3,
-    STATUS_INACTIVE = 4,
-  };
-
-  uint32 label;
-  type_t type;
-  status_t status;
-
-  static const char* TypeAsString(type_t type);
-  static const char* StatusAsString(status_t status);
-};
-
-class MucInviteRecvTask : public XmppTask {
- public:
-  explicit MucInviteRecvTask(XmppTaskParentInterface* parent)
-      : XmppTask(parent, XmppEngine::HL_TYPE) {}
-  virtual int ProcessStart();
-
-  // First arg is inviter's JID; second is MUC's JID.
-  sigslot::signal3<const Jid&, const Jid&, const std::vector<AvailableMediaEntry>& > SignalInviteReceived;
-
- protected:
-  virtual bool HandleStanza(const XmlElement* stanza);
-
-};
-
-}
-
-#endif
diff --git a/third_party/libjingle/source/talk/examples/call/mucinvitesendtask.cc b/third_party/libjingle/source/talk/examples/call/mucinvitesendtask.cc
deleted file mode 100644
index d648fef..0000000
--- a/third_party/libjingle/source/talk/examples/call/mucinvitesendtask.cc
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/examples/call/mucinvitesendtask.h"
-#include "talk/xmpp/constants.h"
-#include "talk/xmpp/xmppclient.h"
-
-namespace buzz {
-
-XmppReturnStatus
-MucInviteSendTask::Send(const Jid& to, const Jid& invitee) {
-  if (GetState() != STATE_INIT && GetState() != STATE_START)
-    return XMPP_RETURN_BADSTATE;
-
-  XmlElement* message = new XmlElement(QN_MESSAGE);
-  message->AddAttr(QN_TO, to.Str());
-  XmlElement* xstanza = new XmlElement(QN_MUC_USER_X);
-  XmlElement* invite = new XmlElement(QN_MUC_USER_INVITE);
-  invite->AddAttr(QN_TO, invitee.Str());
-  xstanza->AddElement(invite);
-  message->AddElement(xstanza);
-
-  QueueStanza(message);
-  return XMPP_RETURN_OK;
-}
-
-int
-MucInviteSendTask::ProcessStart() {
-  const XmlElement* stanza = NextStanza();
-  if (stanza == NULL)
-    return STATE_BLOCKED;
-
-  if (SendStanza(stanza) != XMPP_RETURN_OK)
-    return STATE_ERROR;
-
-  return STATE_START;
-}
-
-}
diff --git a/third_party/libjingle/source/talk/examples/call/mucinvitesendtask.h b/third_party/libjingle/source/talk/examples/call/mucinvitesendtask.h
deleted file mode 100644
index 2429b31..0000000
--- a/third_party/libjingle/source/talk/examples/call/mucinvitesendtask.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _MUCINVITESENDTASK_H_
-#define _MUCINVITESENDTASK_H_
-
-#include "talk/xmpp/xmppengine.h"
-#include "talk/xmpp/xmpptask.h"
-#include "talk/examples/call/muc.h"
-
-namespace buzz {
-
-class MucInviteSendTask : public XmppTask {
-public:
-  explicit MucInviteSendTask(XmppTaskParentInterface* parent)
-      : XmppTask(parent) {}
-  virtual ~MucInviteSendTask() {}
-
-  XmppReturnStatus Send(const Jid& to, const Jid& invitee);
-
-  virtual int ProcessStart();
-};
-
-}
-
-#endif
diff --git a/third_party/libjingle/source/talk/examples/call/presenceouttask.cc b/third_party/libjingle/source/talk/examples/call/presenceouttask.cc
deleted file mode 100644
index bdb2712..0000000
--- a/third_party/libjingle/source/talk/examples/call/presenceouttask.cc
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <time.h>
-#include <sstream>
-#include "talk/base/stringencode.h"
-#include "talk/examples/call/presenceouttask.h"
-#include "talk/xmpp/constants.h"
-#include "talk/xmpp/xmppclient.h"
-
-namespace buzz {
-
-XmppReturnStatus
-PresenceOutTask::Send(const Status & s) {
-  if (GetState() != STATE_INIT && GetState() != STATE_START)
-    return XMPP_RETURN_BADSTATE;
-
-  XmlElement * presence = TranslateStatus(s);
-  QueueStanza(presence);
-  delete presence;
-  return XMPP_RETURN_OK;
-}
-
-XmppReturnStatus
-PresenceOutTask::SendDirected(const Jid & j, const Status & s) {
-  if (GetState() != STATE_INIT && GetState() != STATE_START)
-    return XMPP_RETURN_BADSTATE;
-
-  XmlElement * presence = TranslateStatus(s);
-  presence->AddAttr(QN_TO, j.Str());
-  QueueStanza(presence);
-  delete presence;
-  return XMPP_RETURN_OK;
-}
-
-XmppReturnStatus PresenceOutTask::SendProbe(const Jid & jid) {
-  if (GetState() != STATE_INIT && GetState() != STATE_START)
-    return XMPP_RETURN_BADSTATE;
-
-  XmlElement * presence = new XmlElement(QN_PRESENCE);
-  presence->AddAttr(QN_TO, jid.Str());
-  presence->AddAttr(QN_TYPE, "probe");
-
-  QueueStanza(presence);
-  delete presence;
-  return XMPP_RETURN_OK;
-}
-
-int
-PresenceOutTask::ProcessStart() {
-  const XmlElement * stanza = NextStanza();
-  if (stanza == NULL)
-    return STATE_BLOCKED;
-
-  if (SendStanza(stanza) != XMPP_RETURN_OK)
-    return STATE_ERROR;
-
-  return STATE_START;
-}
-
-XmlElement *
-PresenceOutTask::TranslateStatus(const Status & s) {
-  XmlElement * result = new XmlElement(QN_PRESENCE);
-  if (!s.available()) {
-    result->AddAttr(QN_TYPE, STR_UNAVAILABLE);
-  }
-  else {
-    if (s.show() != Status::SHOW_ONLINE && s.show() != Status::SHOW_OFFLINE) {
-      result->AddElement(new XmlElement(QN_SHOW));
-      switch (s.show()) {
-        default:
-          result->AddText(STR_SHOW_AWAY, 1);
-          break;
-        case Status::SHOW_XA:
-          result->AddText(STR_SHOW_XA, 1);
-          break;
-        case Status::SHOW_DND:
-          result->AddText(STR_SHOW_DND, 1);
-          break;
-        case Status::SHOW_CHAT:
-          result->AddText(STR_SHOW_CHAT, 1);
-          break;
-      }
-    }
-
-    result->AddElement(new XmlElement(QN_STATUS));
-    result->AddText(s.status(), 1);
-
-    if (!s.nick().empty()) {
-      result->AddElement(new XmlElement(QN_NICKNAME));
-      result->AddText(s.nick(), 1);
-    }
-
-    std::string pri;
-    talk_base::ToString(s.priority(), &pri);
-
-    result->AddElement(new XmlElement(QN_PRIORITY));
-    result->AddText(pri, 1);
-
-    if (s.know_capabilities() && s.is_google_client()) {
-      result->AddElement(new XmlElement(QN_CAPS_C, true));
-      result->AddAttr(QN_NODE, GOOGLE_CLIENT_NODE, 1);
-      result->AddAttr(QN_VER, s.version(), 1);
-
-      std::string caps;
-      caps.append(s.voice_capability() ? "voice-v1" : "");
-      caps.append(s.pmuc_capability() ? " pmuc-v1" : "");
-      caps.append(s.video_capability() ? " video-v1" : "");
-      caps.append(s.camera_capability() ? " camera-v1" : "");
-
-      result->AddAttr(QN_EXT, caps, 1);
-    }
-
-    // Put the delay mark on the presence according to JEP-0091
-    {
-      result->AddElement(new XmlElement(kQnDelayX, true));
-
-      // This here is why we *love* the C runtime
-      time_t current_time_seconds;
-      time(&current_time_seconds);
-      struct tm* current_time = gmtime(&current_time_seconds);
-      char output[256];
-      strftime(output, ARRAY_SIZE(output), "%Y%m%dT%H:%M:%S", current_time);
-      result->AddAttr(kQnStamp, output, 1);
-    }
-  }
-
-  return result;
-}
-
-
-}
diff --git a/third_party/libjingle/source/talk/examples/call/presenceouttask.h b/third_party/libjingle/source/talk/examples/call/presenceouttask.h
deleted file mode 100644
index 5735ce2..0000000
--- a/third_party/libjingle/source/talk/examples/call/presenceouttask.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _PRESENCEOUTTASK_H_
-#define _PRESENCEOUTTASK_H_
-
-#include "talk/xmpp/xmppengine.h"
-#include "talk/xmpp/xmpptask.h"
-#include "talk/examples/call/status.h"
-
-namespace buzz {
-
-class PresenceOutTask : public XmppTask {
-public:
-  explicit PresenceOutTask(XmppTaskParentInterface* parent)
-      : XmppTask(parent) {}
-  virtual ~PresenceOutTask() {}
-
-  XmppReturnStatus Send(const Status & s);
-  XmppReturnStatus SendDirected(const Jid & j, const Status & s);
-  XmppReturnStatus SendProbe(const Jid& jid);
-
-  virtual int ProcessStart();
-private:
-  XmlElement * TranslateStatus(const Status & s);
-};
-
-}
-
-#endif
diff --git a/third_party/libjingle/source/talk/examples/call/presencepushtask.cc b/third_party/libjingle/source/talk/examples/call/presencepushtask.cc
deleted file mode 100644
index fba3322..0000000
--- a/third_party/libjingle/source/talk/examples/call/presencepushtask.cc
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/examples/call/presencepushtask.h"
-
-#include "talk/base/stringencode.h"
-#include "talk/examples/call/muc.h"
-#include "talk/xmpp/constants.h"
-
-
-
-namespace buzz {
-
-// string helper functions -----------------------------------------------------
-
-static bool
-IsXmlSpace(int ch) {
-  return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t';
-}
-
-static bool ListContainsToken(const std::string & list,
-                              const std::string & token) {
-  size_t i = list.find(token);
-  if (i == std::string::npos || token.empty())
-    return false;
-  bool boundary_before = (i == 0 || IsXmlSpace(list[i - 1]));
-  bool boundary_after = (i == list.length() - token.length() ||
-                         IsXmlSpace(list[i + token.length()]));
-  return boundary_before && boundary_after;
-}
-
-
-bool PresencePushTask::HandleStanza(const XmlElement * stanza) {
-  if (stanza->Name() != QN_PRESENCE)
-    return false;
-  QueueStanza(stanza);
-  return true;
-}
-
-static bool IsUtf8FirstByte(int c) {
-  return (((c)&0x80)==0) || // is single byte
-    ((unsigned char)((c)-0xc0)<0x3e); // or is lead byte
-}
-
-int PresencePushTask::ProcessStart() {
-  const XmlElement * stanza = NextStanza();
-  if (stanza == NULL)
-    return STATE_BLOCKED;
-
-  Jid from(stanza->Attr(QN_FROM));
-  std::map<Jid, buzz::Muc*>::const_iterator elem =
-      client_->mucs().find(from.BareJid());
-  if (elem == client_->mucs().end()) {
-    HandlePresence(from, stanza);
-  } else {
-    HandleMucPresence(elem->second, from, stanza);
-  }
-
-  return STATE_START;
-}
-
-void PresencePushTask::HandlePresence(const Jid& from,
-                                      const XmlElement* stanza) {
-  if (stanza->Attr(QN_TYPE) == STR_ERROR)
-    return;
-
-  Status s;
-  FillStatus(from, stanza, &s);
-  SignalStatusUpdate(s);
-}
-
-void PresencePushTask::HandleMucPresence(buzz::Muc* muc,
-                                         const Jid& from,
-                                         const XmlElement* stanza) {
-  if (from == muc->local_jid()) {
-    if (!stanza->HasAttr(QN_TYPE)) {
-      // We joined the MUC.
-      const XmlElement* elem = stanza->FirstNamed(QN_MUC_USER_X);
-      // Status code=110 or 100 is not guaranteed to be present, so we
-      // only check the item element and Muc join status.
-      if (elem) {
-        if (elem->FirstNamed(QN_MUC_USER_ITEM) &&
-            muc->state() == buzz::Muc::MUC_JOINING) {
-          SignalMucJoined(muc->jid());
-        }
-      }
-    } else {
-      // We've been kicked. Bye.
-      int error = 0;
-      if (stanza->Attr(QN_TYPE) == STR_ERROR) {
-        const XmlElement* elem = stanza->FirstNamed(QN_ERROR);
-        if (elem && elem->HasAttr(QN_CODE)) {
-          error = atoi(elem->Attr(QN_CODE).c_str());
-        }
-      }
-      SignalMucLeft(muc->jid(), error);
-    }
-  } else {
-    MucStatus s;
-    FillMucStatus(from, stanza, &s);
-    SignalMucStatusUpdate(muc->jid(), s);
-  }
-}
-
-void PresencePushTask::FillStatus(const Jid& from, const XmlElement* stanza,
-                                  Status* s) {
-  s->set_jid(from);
-  if (stanza->Attr(QN_TYPE) == STR_UNAVAILABLE) {
-    s->set_available(false);
-  } else {
-    s->set_available(true);
-    const XmlElement * status = stanza->FirstNamed(QN_STATUS);
-    if (status != NULL) {
-      s->set_status(status->BodyText());
-
-      // Truncate status messages longer than 300 bytes
-      if (s->status().length() > 300) {
-        size_t len = 300;
-
-        // Be careful not to split legal utf-8 chars in half
-        while (!IsUtf8FirstByte(s->status()[len]) && len > 0) {
-          len -= 1;
-        }
-        std::string truncated(s->status(), 0, len);
-        s->set_status(truncated);
-      }
-    }
-
-    const XmlElement * priority = stanza->FirstNamed(QN_PRIORITY);
-    if (priority != NULL) {
-      int pri;
-      if (talk_base::FromString(priority->BodyText(), &pri)) {
-        s->set_priority(pri);
-      }
-    }
-
-    const XmlElement * show = stanza->FirstNamed(QN_SHOW);
-    if (show == NULL || show->FirstChild() == NULL) {
-      s->set_show(Status::SHOW_ONLINE);
-    }
-    else {
-      if (show->BodyText() == "away") {
-        s->set_show(Status::SHOW_AWAY);
-      }
-      else if (show->BodyText() == "xa") {
-        s->set_show(Status::SHOW_XA);
-      }
-      else if (show->BodyText() == "dnd") {
-        s->set_show(Status::SHOW_DND);
-      }
-      else if (show->BodyText() == "chat") {
-        s->set_show(Status::SHOW_CHAT);
-      }
-      else {
-        s->set_show(Status::SHOW_ONLINE);
-      }
-    }
-
-    const XmlElement * caps = stanza->FirstNamed(QN_CAPS_C);
-    if (caps != NULL) {
-      std::string node = caps->Attr(QN_NODE);
-      std::string ver = caps->Attr(QN_VER);
-      std::string exts = caps->Attr(QN_EXT);
-
-      s->set_know_capabilities(true);
-
-      if (node == GOOGLE_CLIENT_NODE) {
-        s->set_is_google_client(true);
-        s->set_version(ver);
-      }
-
-      if (ListContainsToken(exts, "voice-v1")) {
-        s->set_voice_capability(true);
-      }
-      if (ListContainsToken(exts, "video-v1")) {
-        s->set_video_capability(true);
-      }
-    }
-
-    const XmlElement* delay = stanza->FirstNamed(kQnDelayX);
-    if (delay != NULL) {
-      // Ideally we would parse this according to the Psuedo ISO-8601 rules
-      // that are laid out in JEP-0082:
-      // http://www.jabber.org/jeps/jep-0082.html
-      std::string stamp = delay->Attr(kQnStamp);
-      s->set_sent_time(stamp);
-    }
-
-    const XmlElement* nick = stanza->FirstNamed(QN_NICKNAME);
-    if (nick) {
-      s->set_nick(nick->BodyText());
-    }
-  }
-}
-
-void PresencePushTask::FillMucStatus(const Jid& from, const XmlElement* stanza,
-                                     MucStatus* s) {
-  FillStatus(from, stanza, s);
-}
-
-}
diff --git a/third_party/libjingle/source/talk/examples/call/presencepushtask.h b/third_party/libjingle/source/talk/examples/call/presencepushtask.h
deleted file mode 100644
index dccc827..0000000
--- a/third_party/libjingle/source/talk/examples/call/presencepushtask.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _PRESENCEPUSHTASK_H_
-#define _PRESENCEPUSHTASK_H_
-
-#include <vector>
-
-#include "talk/xmpp/xmppengine.h"
-#include "talk/xmpp/xmpptask.h"
-#include "talk/base/sigslot.h"
-#include "talk/examples/call/status.h"
-#include "talk/examples/call/callclient.h"
-
-namespace buzz {
-
-class PresencePushTask : public XmppTask {
- public:
-  PresencePushTask(XmppTaskParentInterface* parent, CallClient* client)
-    : XmppTask(parent, XmppEngine::HL_TYPE),
-      client_(client) {}
-  virtual int ProcessStart();
-
-  sigslot::signal1<const Status&> SignalStatusUpdate;
-  sigslot::signal1<const Jid&> SignalMucJoined;
-  sigslot::signal2<const Jid&, int> SignalMucLeft;
-  sigslot::signal2<const Jid&, const MucStatus&> SignalMucStatusUpdate;
-
- protected:
-  virtual bool HandleStanza(const XmlElement * stanza);
-  void HandlePresence(const Jid& from, const XmlElement * stanza);
-  void HandleMucPresence(buzz::Muc* muc,
-                         const Jid& from, const XmlElement * stanza);
-  static void FillStatus(const Jid& from, const XmlElement * stanza,
-                         Status* status);
-  static void FillMucStatus(const Jid& from, const XmlElement * stanza,
-                            MucStatus* status);
-
- private:
-  CallClient* client_;
-};
-
-
-}
-
-#endif
diff --git a/third_party/libjingle/source/talk/examples/call/status.h b/third_party/libjingle/source/talk/examples/call/status.h
deleted file mode 100644
index c3778e5..0000000
--- a/third_party/libjingle/source/talk/examples/call/status.h
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _STATUS_H_
-#define _STATUS_H_
-
-#include "talk/xmpp/jid.h"
-#include "talk/xmpp/constants.h"
-
-#define GOOGLE_CLIENT_NODE "http://www.google.com/xmpp/client/caps"
-
-namespace buzz {
-
-class Status {
-public:
-  Status() :
-    pri_(0),
-    show_(SHOW_NONE),
-    available_(false),
-    e_code_(0),
-    feedback_probation_(false),
-    know_capabilities_(false),
-    voice_capability_(false),
-    pmuc_capability_(false),
-    video_capability_(false),
-    camera_capability_(false),
-    is_google_client_(false) {}
-
-  ~Status() {}
-
-  // These are arranged in "priority order", i.e., if we see
-  // two statuses at the same priority but with different Shows,
-  // we will show the one with the highest show in the following
-  // order.
-  enum Show {
-    SHOW_NONE     = 0,
-    SHOW_OFFLINE  = 1,
-    SHOW_XA       = 2,
-    SHOW_AWAY     = 3,
-    SHOW_DND      = 4,
-    SHOW_ONLINE   = 5,
-    SHOW_CHAT     = 6,
-  };
-
-  const Jid & jid() const { return jid_; }
-  int priority() const { return pri_; }
-  Show show() const { return show_; }
-  const std::string & status() const { return status_; }
-  const std::string & nick() const { return nick_; }
-  bool available() const { return available_ ; }
-  int error_code() const { return e_code_; }
-  const std::string & error_string() const { return e_str_; }
-  bool know_capabilities() const { return know_capabilities_; }
-  bool voice_capability() const { return voice_capability_; }
-  bool pmuc_capability() const { return pmuc_capability_; }
-  bool video_capability() const { return video_capability_; }
-  bool camera_capability() const { return camera_capability_; }
-  bool is_google_client() const { return is_google_client_; }
-  const std::string & version() const { return version_; }
-  bool feedback_probation() const { return feedback_probation_; }
-  const std::string& sent_time() const { return sent_time_; }
-
-  void set_jid(const Jid & jid) { jid_ = jid; }
-  void set_priority(int pri) { pri_ = pri; }
-  void set_show(Show show) { show_ = show; }
-  void set_status(const std::string & status) { status_ = status; }
-  void set_nick(const std::string & nick) { nick_ = nick; }
-  void set_available(bool a) { available_ = a; }
-  void set_error(int e_code, const std::string e_str)
-      { e_code_ = e_code; e_str_ = e_str; }
-  void set_know_capabilities(bool f) { know_capabilities_ = f; }
-  void set_voice_capability(bool f) { voice_capability_ = f; }
-  void set_pmuc_capability(bool f) { pmuc_capability_ = f; }
-  void set_video_capability(bool f) { video_capability_ = f; }
-  void set_camera_capability(bool f) { camera_capability_ = f; }
-  void set_is_google_client(bool f) { is_google_client_ = f; }
-  void set_version(const std::string & v) { version_ = v; }
-  void set_feedback_probation(bool f) { feedback_probation_ = f; }
-  void set_sent_time(const std::string& time) { sent_time_ = time; }
-
-  void UpdateWith(const Status & new_value) {
-    if (!new_value.know_capabilities()) {
-       bool k = know_capabilities();
-       bool i = is_google_client();
-       bool p = voice_capability();
-       std::string v = version();
-
-       *this = new_value;
-
-       set_know_capabilities(k);
-       set_is_google_client(i);
-       set_voice_capability(p);
-       set_version(v);
-    }
-    else {
-      *this = new_value;
-    }
-  }
-
-  bool HasQuietStatus() const {
-    if (status_.empty())
-      return false;
-    return !(QuietStatus().empty());
-  }
-
-  // Knowledge of other clients' silly automatic status strings -
-  // Don't show these.
-  std::string QuietStatus() const {
-    if (jid_.resource().find("Psi") != std::string::npos) {
-      if (status_ == "Online" ||
-          status_.find("Auto Status") != std::string::npos)
-        return STR_EMPTY;
-    }
-    if (jid_.resource().find("Gaim") != std::string::npos) {
-      if (status_ == "Sorry, I ran out for a bit!")
-        return STR_EMPTY;
-    }
-    return TrimStatus(status_);
-  }
-
-  std::string ExplicitStatus() const {
-    std::string result = QuietStatus();
-    if (result.empty()) {
-      result = ShowStatus();
-    }
-    return result;
-  }
-
-  std::string ShowStatus() const {
-    std::string result;
-    if (!available()) {
-      result = "Offline";
-    }
-    else {
-      switch (show()) {
-        case SHOW_AWAY:
-        case SHOW_XA:
-          result = "Idle";
-          break;
-        case SHOW_DND:
-          result = "Busy";
-          break;
-        case SHOW_CHAT:
-          result = "Chatty";
-          break;
-        default:
-          result = "Available";
-          break;
-      }
-    }
-    return result;
-  }
-
-  static std::string TrimStatus(const std::string & st) {
-    std::string s(st);
-    int j = 0;
-    bool collapsing = true;
-    for (unsigned int i = 0; i < s.length(); i+= 1) {
-      if (s[i] <= ' ' && s[i] >= 0) {
-        if (collapsing) {
-          continue;
-        }
-        else {
-          s[j] = ' ';
-          j += 1;
-          collapsing = true;
-        }
-      }
-      else {
-        s[j] = s[i];
-        j += 1;
-        collapsing = false;
-      }
-    }
-    if (collapsing && j > 0) {
-      j -= 1;
-    }
-    s.erase(j, s.length());
-    return s;
-  }
-
-private:
-  Jid jid_;
-  int pri_;
-  Show show_;
-  std::string status_;
-  std::string nick_;
-  bool available_;
-  int e_code_;
-  std::string e_str_;
-  bool feedback_probation_;
-
-  // capabilities (valid only if know_capabilities_
-  bool know_capabilities_;
-  bool voice_capability_;
-  bool pmuc_capability_;
-  bool video_capability_;
-  bool camera_capability_;
-  bool is_google_client_;
-  std::string version_;
-
-  std::string sent_time_; // from the jabber:x:delay element
-};
-
-class MucStatus : public Status {
-};
-
-}
-
-
-#endif
diff --git a/third_party/libjingle/source/talk/examples/call/voicemailjidrequester.cc b/third_party/libjingle/source/talk/examples/call/voicemailjidrequester.cc
deleted file mode 100644
index 7287700..0000000
--- a/third_party/libjingle/source/talk/examples/call/voicemailjidrequester.cc
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/scoped_ptr.h"
-#include "talk/examples/call/discoitemsquerytask.h"
-#include "talk/examples/call/voicemailjidrequester.h"
-#include "talk/xmpp/constants.h"
-#include "talk/xmpp/xmpptask.h"
-
-namespace buzz {
-
-VoicemailJidRequester::VoicemailJidRequester(XmppTaskParentInterface* parent,
-                                             const Jid& their_jid,
-                                             const Jid& my_jid) :
-    XmppTaskBase(parent),
-    their_jid_(their_jid),
-    my_jid_(my_jid),
-    done_with_query_(false) {
-}
-
-int VoicemailJidRequester::ProcessStart() {
-  // Start first query to node='voicemail'
-  DiscoItemsQueryTask* disco_items_task = new DiscoItemsQueryTask(this,
-      STR_VOICEMAIL, their_jid_.BareJid());
-  disco_items_task->SignalGotDiscoItems.connect(this,
-      &VoicemailJidRequester::OnFirstVoicemailJidSuccess);
-  disco_items_task->SignalDiscoItemsError.connect(this,
-      &VoicemailJidRequester::OnFirstVoicemailJidError);
-  disco_items_task->Start();
-  return STATE_BLOCKED;
-}
-
-void VoicemailJidRequester::OnFirstVoicemailJidError(buzz::Jid jid,
-    const XmlElement* xml_element) {
-  // First query gave us an error - try second query to node='outgoingvoicemail'
-  // and send it to your own jid
-  StartSecondQuery();
-}
-
-void VoicemailJidRequester::OnFirstVoicemailJidSuccess(buzz::Jid jid,
-    const XmlElement* xml_element) {
-  // Process the XML and fire the appropriate signals.  If the xml was valid,
-  // then we're done with queries.  If it wasn't valid, then start the second
-  // query.
-  bool valid_xml = ProcessVoicemailXml(xml_element);
-  if (valid_xml) {
-    done_with_query_ = true;
-    Wake();
-  } else {
-    StartSecondQuery();
-  }
-}
-
-void VoicemailJidRequester::OnSecondVoicemailJidError(buzz::Jid jid,
-    const XmlElement* xml_element) {
-  SignalVoicemailJidError(their_jid_);
-  done_with_query_ = true;
-  Wake();
-}
-
-void VoicemailJidRequester::OnSecondVoicemailJidSuccess(buzz::Jid jid,
-    const XmlElement* xml_element) {
-  // Whether this is good xml or bad, we're still done with the query
-  bool valid_xml = ProcessVoicemailXml(xml_element);
-  if (!valid_xml) {
-    SignalVoicemailJidError(their_jid_);
-  }
-  done_with_query_ = true;
-  Wake();
-}
-
-
-void VoicemailJidRequester::StartSecondQuery() {
-  // Send a query to your own jid to get the voicemail jid
-  DiscoItemsQueryTask* disco_items_task = new DiscoItemsQueryTask(this,
-      STR_OUTGOINGVOICEMAIL, my_jid_.BareJid());
-  disco_items_task->SignalGotDiscoItems.connect(this,
-      &VoicemailJidRequester::OnSecondVoicemailJidSuccess);
-  disco_items_task->SignalDiscoItemsError.connect(this,
-      &VoicemailJidRequester::OnSecondVoicemailJidError);
-  disco_items_task->Start();
-}
-
-int VoicemailJidRequester::Process(int state) {
-  if (done_with_query_) {
-    return STATE_DONE;
-  } else {
-    return talk_base::Task::Process(state);
-  }
-}
-
-bool VoicemailJidRequester::ProcessVoicemailXml(const XmlElement* xml_element) {
-  if (!xml_element) {
-    return false;
-  }
-  const std::string& node_name = xml_element->Attr(QN_NODE);
-  // Verify that it's one of the two nodes - we don't really care which one
-  if (node_name != "voicemail" &&
-      node_name != "outgoingvoicemail") {
-    return false;
-  }
-
-  const XmlElement* item = xml_element->FirstNamed(QN_DISCO_ITEM);
-  if (item) {
-    const std::string& jid_str = item->Attr(QN_JID);
-    buzz::Jid voicemail_jid(jid_str);
-    SignalGotVoicemailJid(their_jid_, voicemail_jid);
-    return true;
-  }
-  return false;
-}
-}
diff --git a/third_party/libjingle/source/talk/examples/call/voicemailjidrequester.h b/third_party/libjingle/source/talk/examples/call/voicemailjidrequester.h
deleted file mode 100644
index 686f763..0000000
--- a/third_party/libjingle/source/talk/examples/call/voicemailjidrequester.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// VoicemailJidRequester wraps the requesting of voicemail jids for a user.
-//
-// To request a voicemail jid, we first set off a query to the user's bare jid
-// that looks like this:
-//
-//      <iq type='get'
-//          from='foo@gmail.com/asdf'
-//          to='bar@google.com'
-//          id='1234'>
-//          <query xmlns=' http://jabber.org/protocol/disco#items'
-//                 node='voicemail '/>
-//      </iq>
-//
-// If foo@gmail.com's server supports voicemail, it'll return this, and forward
-// the jid up to phoneapp.  We do not do the second query.
-//
-//      <iq type='result'
-//          from='foo@google.com'
-//          to='bar@google.com/asdf'
-//          id='1234'>
-//          <query xmlns=' http://jabber.org/protocol/disco#items '
-//                 node=' voicemail '>
-//                 <item jid='bar@google.com/voicemail '/>
-//          </query>
-//      </iq>
-//
-// If we get an error, we spin off a new request:
-//
-//      <iq type='get'
-//          from='foo@google.com/asdf'
-//          to='foo@google.com'
-//          id='1234'>
-//          <query xmlns=' http://jabber.org/protocol/disco#items'
-//                 node='outgoingvoicemail '/>
-//      </iq>
-//
-// If both of these return errors, we then forward the request to phoneapp.
-
-#ifndef TALK_EXAMPLES_CALL_VOICEMAILJIDREQUESTER_H_
-#define TALK_EXAMPLES_CALL_VOICEMAILJIDREQUESTER_H_
-
-#include "talk/xmpp/xmpptask.h"
-
-namespace buzz {
-
-class Task;
-
-class VoicemailJidRequester : public sigslot::has_slots<>,
-                              public XmppTaskBase {
- public:
-  VoicemailJidRequester(XmppTaskParentInterface* parent,
-                        const Jid& their_jid, const Jid& my_jid);
-
-  // Provides the target jid and the voicemail to reach it
-  sigslot::signal2<const Jid&, const Jid&> SignalGotVoicemailJid;
-  sigslot::signal1<const Jid&> SignalVoicemailJidError;
-
-  virtual int ProcessStart();
- protected:
-
-  virtual int Process(int state);
-
- private:
-  // The first query (to node='voicemail' has returned an error) - we now spin
-  // off a request to node='outgoingvoicemail')
-  void OnFirstVoicemailJidError(buzz::Jid jid, const XmlElement* xml_element);
-
-  // The first query (to node='voicemail' has returned a successfully)
-  void OnFirstVoicemailJidSuccess(buzz::Jid jid, const XmlElement* xml_element);
-
-  // The second query (to node='outgoingvoicemail') has returned an error -
-  // nothing we can do now, just fire our error signal
-  void OnSecondVoicemailJidError(buzz::Jid jid, const XmlElement* xml_element);
-
-  // The second query (to node='outgoingvoicemail') has returned a successfully
-  void OnSecondVoicemailJidSuccess(buzz::Jid jid,
-                                   const XmlElement* xml_element);
-
-  // Parse the xml, fire SignalGotVoicemail jid if it was valid (and had a jid)
-  // and return true if it was a valid xml.
-  bool ProcessVoicemailXml(const XmlElement* xml_element);
-
-  // Send a query to your own jid to get the voicemail jid.  This is used after
-  // the first query fails.
-  void StartSecondQuery();
-
-  Jid their_jid_;
-
-  // Your own jid (not the other user's)
-  Jid my_jid_;
-
-  // A flag indicating whether or not we're done with the query so that we can
-  // set the state correctly in Process(int state)
-  bool done_with_query_;
-};
-}
-
-#endif  // TALK_EXAMPLES_CALL_VOICEMAILJIDREQUESTER_H_
diff --git a/third_party/libjingle/source/talk/examples/login/login_main.cc b/third_party/libjingle/source/talk/examples/login/login_main.cc
deleted file mode 100644
index 9cd00b9..0000000
--- a/third_party/libjingle/source/talk/examples/login/login_main.cc
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <cstdio>
-#include <iostream>
-
-#include "talk/base/thread.h"
-#include "talk/xmpp/xmppclientsettings.h"
-#include "talk/examples/login/xmppthread.h"
-#include "talk/xmpp/xmppengine.h"
-
-int main(int argc, char **argv) {
-  std::cout << "Auth Cookie: ";
-  std::string auth_cookie;
-  std::getline(std::cin, auth_cookie);
-
-  std::cout << "User Name: ";
-  std::string username;
-  std::getline(std::cin, username);
-
-  // Start xmpp on a different thread
-  XmppThread thread;
-  thread.Start();
-
-  buzz::XmppClientSettings xcs;
-  xcs.set_user(username.c_str());
-  xcs.set_host("gmail.com");
-  xcs.set_use_tls(buzz::TLS_DISABLED);
-  xcs.set_auth_cookie(auth_cookie.c_str());
-  xcs.set_server(talk_base::SocketAddress("talk.google.com", 5222));
-  thread.Login(xcs);
-
-  // Use main thread for console input
-  std::string line;
-  while (std::getline(std::cin, line)) {
-    if (line == "quit")
-      break;
-  }
-  return 0;
-}
-
diff --git a/third_party/libjingle/source/talk/examples/login/xmppauth.cc b/third_party/libjingle/source/talk/examples/login/xmppauth.cc
deleted file mode 100644
index 7773e00..0000000
--- a/third_party/libjingle/source/talk/examples/login/xmppauth.cc
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/examples/login/xmppauth.h"
-
-#include <algorithm>
-
-#include "talk/xmpp/saslcookiemechanism.h"
-#include "talk/xmpp/saslplainmechanism.h"
-
-XmppAuth::XmppAuth() : done_(false) {
-}
-
-XmppAuth::~XmppAuth() {
-}
-
-void XmppAuth::StartPreXmppAuth(const buzz::Jid & jid,
-                                const talk_base::SocketAddress & server,
-                                const talk_base::CryptString & pass,
-                                const std::string & auth_cookie) {
-  jid_ = jid;
-  passwd_ = pass;
-  auth_cookie_ = auth_cookie;
-  done_ = true;
-
-  SignalAuthDone();
-}
-
-std::string XmppAuth::ChooseBestSaslMechanism(
-    const std::vector<std::string> & mechanisms,
-    bool encrypted) {
-  std::vector<std::string>::const_iterator it;
-
-  // A token is the weakest auth - 15s, service-limited, so prefer it.
-  it = std::find(mechanisms.begin(), mechanisms.end(), "X-GOOGLE-TOKEN");
-  if (it != mechanisms.end() && !auth_cookie_.empty())
-    return "X-GOOGLE-TOKEN";
-
-  // A cookie is the next weakest - 14 days.
-  it = std::find(mechanisms.begin(), mechanisms.end(), "X-GOOGLE-COOKIE");
-  if (it != mechanisms.end() && !auth_cookie_.empty())
-    return "X-GOOGLE-COOKIE";
-
-  // As a last resort, use plain authentication.
-  it = std::find(mechanisms.begin(), mechanisms.end(), "PLAIN");
-  if (it != mechanisms.end())
-    return "PLAIN";
-
-  // No good mechanism found
- return "";
-}
-
-buzz::SaslMechanism* XmppAuth::CreateSaslMechanism(
-    const std::string & mechanism) {
-  if (mechanism == "X-GOOGLE-TOKEN") {
-    return new buzz::SaslCookieMechanism(mechanism, jid_.Str(), auth_cookie_);
-  //} else if (mechanism == "X-GOOGLE-COOKIE") {
-  //  return new buzz::SaslCookieMechanism(mechanism, jid.Str(), sid_);
-  } else if (mechanism == "PLAIN") {
-    return new buzz::SaslPlainMechanism(jid_, passwd_);
-  } else {
-    return NULL;
-  }
-}
diff --git a/third_party/libjingle/source/talk/examples/login/xmppauth.h b/third_party/libjingle/source/talk/examples/login/xmppauth.h
deleted file mode 100644
index 18672b8..0000000
--- a/third_party/libjingle/source/talk/examples/login/xmppauth.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _XMPPAUTH_H_
-#define _XMPPAUTH_H_
-
-#include <vector>
-
-#include "talk/base/cryptstring.h"
-#include "talk/base/sigslot.h"
-#include "talk/xmpp/jid.h"
-#include "talk/xmpp/saslhandler.h"
-#include "talk/xmpp/prexmppauth.h"
-
-class XmppAuth: public buzz::PreXmppAuth {
-public:
-  XmppAuth();
-  virtual ~XmppAuth();
-
-  virtual void StartPreXmppAuth(const buzz::Jid & jid,
-                                const talk_base::SocketAddress & server,
-                                const talk_base::CryptString & pass,
-                                const std::string & auth_cookie);
-
-  virtual bool IsAuthDone() const { return done_; }
-  virtual bool IsAuthorized() const { return true; }
-  virtual bool HadError() const { return false; }
-  virtual int  GetError() const { return 0; }
-  virtual buzz::CaptchaChallenge GetCaptchaChallenge() const {
-      return buzz::CaptchaChallenge();
-  }
-  virtual std::string GetAuthCookie() const { return auth_cookie_; }
-
-  virtual std::string ChooseBestSaslMechanism(
-      const std::vector<std::string> & mechanisms,
-      bool encrypted);
-
-  virtual buzz::SaslMechanism * CreateSaslMechanism(
-      const std::string & mechanism);
-
-private:
-  buzz::Jid jid_;
-  talk_base::CryptString passwd_;
-  std::string auth_cookie_;
-  bool done_;
-};
-
-#endif
diff --git a/third_party/libjingle/source/talk/examples/login/xmpppump.cc b/third_party/libjingle/source/talk/examples/login/xmpppump.cc
deleted file mode 100644
index de4057b..0000000
--- a/third_party/libjingle/source/talk/examples/login/xmpppump.cc
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/examples/login/xmpppump.h"
-#include "talk/examples/login/xmppauth.h"
-
-XmppPump::XmppPump(XmppPumpNotify * notify) {
-  state_ = buzz::XmppEngine::STATE_NONE;
-  notify_ = notify;
-  client_ = new buzz::XmppClient(this);  // NOTE: deleted by TaskRunner
-}
-
-void XmppPump::DoLogin(const buzz::XmppClientSettings & xcs,
-                       buzz::AsyncSocket* socket,
-                       buzz::PreXmppAuth* auth) {
-  OnStateChange(buzz::XmppEngine::STATE_START);
-  if (!AllChildrenDone()) {
-    client_->SignalStateChange.connect(this, &XmppPump::OnStateChange);
-    client_->Connect(xcs, "", socket, auth);
-    client_->Start();
-  }
-}
-
-void XmppPump::DoDisconnect() {
-  if (!AllChildrenDone())
-    client_->Disconnect();
-  OnStateChange(buzz::XmppEngine::STATE_CLOSED);
-}
-
-void XmppPump::OnStateChange(buzz::XmppEngine::State state) {
-  if (state_ == state)
-    return;
-  state_ = state;
-  if (notify_ != NULL)
-    notify_->OnStateChange(state);
-}
-
-void XmppPump::WakeTasks() {
-  talk_base::Thread::Current()->Post(this);
-}
-
-int64 XmppPump::CurrentTime() {
-  return (int64)talk_base::Time();
-}
-
-void XmppPump::OnMessage(talk_base::Message *pmsg) {
-  RunTasks();
-}
-
-buzz::XmppReturnStatus XmppPump::SendStanza(const buzz::XmlElement *stanza) {
-  if (!AllChildrenDone())
-    return client_->SendStanza(stanza);
-  return buzz::XMPP_RETURN_BADSTATE;
-}
diff --git a/third_party/libjingle/source/talk/examples/login/xmpppump.h b/third_party/libjingle/source/talk/examples/login/xmpppump.h
deleted file mode 100644
index 6f705ec..0000000
--- a/third_party/libjingle/source/talk/examples/login/xmpppump.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _XMPPPUMP_H_
-#define _XMPPPUMP_H_
-
-#include "talk/base/messagequeue.h"
-#include "talk/base/taskrunner.h"
-#include "talk/base/thread.h"
-#include "talk/base/timeutils.h"
-#include "talk/xmpp/xmppclient.h"
-#include "talk/xmpp/xmppengine.h"
-#include "talk/xmpp/xmpptask.h"
-
-// Simple xmpp pump
-
-class XmppPumpNotify {
-public:
-  virtual ~XmppPumpNotify() {}
-  virtual void OnStateChange(buzz::XmppEngine::State state) = 0;
-};
-
-class XmppPump : public talk_base::MessageHandler, public talk_base::TaskRunner {
-public:
-  XmppPump(XmppPumpNotify * notify = NULL);
-
-  buzz::XmppClient *client() { return client_; }
-
-  void DoLogin(const buzz::XmppClientSettings & xcs,
-               buzz::AsyncSocket* socket,
-               buzz::PreXmppAuth* auth);
-  void DoDisconnect();
-
-  void OnStateChange(buzz::XmppEngine::State state);
-
-  void WakeTasks();
-
-  int64 CurrentTime();
-
-  void OnMessage(talk_base::Message *pmsg);
-
-  buzz::XmppReturnStatus SendStanza(const buzz::XmlElement *stanza);
-
-private:
-  buzz::XmppClient *client_;
-  buzz::XmppEngine::State state_;
-  XmppPumpNotify *notify_;
-};
-
-#endif // _XMPPPUMP_H_
diff --git a/third_party/libjingle/source/talk/examples/login/xmppsocket.cc b/third_party/libjingle/source/talk/examples/login/xmppsocket.cc
deleted file mode 100644
index cbd4661..0000000
--- a/third_party/libjingle/source/talk/examples/login/xmppsocket.cc
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <errno.h>
-#include "talk/base/basicdefs.h"
-#include "talk/base/logging.h"
-#include "talk/base/thread.h"
-#ifdef FEATURE_ENABLE_SSL
-#include "talk/base/ssladapter.h"
-#endif
-#include "xmppsocket.h"
-
-#ifdef USE_SSLSTREAM
-#include "talk/base/socketstream.h"
-#ifdef FEATURE_ENABLE_SSL
-#include "talk/base/sslstreamadapter.h"
-#endif  // FEATURE_ENABLE_SSL
-#endif  // USE_SSLSTREAM
-
-XmppSocket::XmppSocket(buzz::TlsOptions tls) : tls_(tls) {
-  talk_base::Thread* pth = talk_base::Thread::Current();
-  talk_base::AsyncSocket* socket =
-    pth->socketserver()->CreateAsyncSocket(SOCK_STREAM);
-#ifndef USE_SSLSTREAM
-#ifdef FEATURE_ENABLE_SSL
-  if (tls_ != buzz::TLS_DISABLED) {
-    socket = talk_base::SSLAdapter::Create(socket);
-  }
-#endif  // FEATURE_ENABLE_SSL
-  cricket_socket_ = socket;
-  cricket_socket_->SignalReadEvent.connect(this, &XmppSocket::OnReadEvent);
-  cricket_socket_->SignalWriteEvent.connect(this, &XmppSocket::OnWriteEvent);
-  cricket_socket_->SignalConnectEvent.connect(this,
-                                              &XmppSocket::OnConnectEvent);
-  cricket_socket_->SignalCloseEvent.connect(this, &XmppSocket::OnCloseEvent);
-#else  // USE_SSLSTREAM
-  cricket_socket_ = socket;
-  stream_ = new talk_base::SocketStream(cricket_socket_);
-#ifdef FEATURE_ENABLE_SSL
-  if (tls_ != buzz::TLS_DISABLED)
-    stream_ = talk_base::SSLStreamAdapter::Create(stream_);
-#endif  // FEATURE_ENABLE_SSL
-  stream_->SignalEvent.connect(this, &XmppSocket::OnEvent);
-#endif  // USE_SSLSTREAM
-
-  state_ = buzz::AsyncSocket::STATE_CLOSED;
-}
-
-XmppSocket::~XmppSocket() {
-  Close();
-#ifndef USE_SSLSTREAM
-  delete cricket_socket_;
-#else  // USE_SSLSTREAM
-  delete stream_;
-#endif  // USE_SSLSTREAM
-}
-
-#ifndef USE_SSLSTREAM
-void XmppSocket::OnReadEvent(talk_base::AsyncSocket * socket) {
-  SignalRead();
-}
-
-void XmppSocket::OnWriteEvent(talk_base::AsyncSocket * socket) {
-  // Write bytes if there are any
-  while (buffer_.Length() != 0) {
-    int written = cricket_socket_->Send(buffer_.Data(), buffer_.Length());
-    if (written > 0) {
-      buffer_.Shift(written);
-      continue;
-    }
-    if (!cricket_socket_->IsBlocking())
-      LOG(LS_ERROR) << "Send error: " << cricket_socket_->GetError();
-    return;
-  }
-}
-
-void XmppSocket::OnConnectEvent(talk_base::AsyncSocket * socket) {
-#if defined(FEATURE_ENABLE_SSL)
-  if (state_ == buzz::AsyncSocket::STATE_TLS_CONNECTING) {
-    state_ = buzz::AsyncSocket::STATE_TLS_OPEN;
-    SignalSSLConnected();
-    OnWriteEvent(cricket_socket_);
-    return;
-  }
-#endif  // !defined(FEATURE_ENABLE_SSL)
-  state_ = buzz::AsyncSocket::STATE_OPEN;
-  SignalConnected();
-}
-
-void XmppSocket::OnCloseEvent(talk_base::AsyncSocket * socket, int error) {
-  SignalCloseEvent(error);
-}
-
-#else  // USE_SSLSTREAM
-
-void XmppSocket::OnEvent(talk_base::StreamInterface* stream,
-                         int events, int err) {
-  if ((events & talk_base::SE_OPEN)) {
-#if defined(FEATURE_ENABLE_SSL)
-    if (state_ == buzz::AsyncSocket::STATE_TLS_CONNECTING) {
-      state_ = buzz::AsyncSocket::STATE_TLS_OPEN;
-      SignalSSLConnected();
-      events |= talk_base::SE_WRITE;
-    } else
-#endif
-    {
-      state_ = buzz::AsyncSocket::STATE_OPEN;
-      SignalConnected();
-    }
-  }
-  if ((events & talk_base::SE_READ))
-    SignalRead();
-  if ((events & talk_base::SE_WRITE)) {
-    // Write bytes if there are any
-    while (buffer_.Length() != 0) {
-      talk_base::StreamResult result;
-      size_t written;
-      int error;
-      result = stream_->Write(buffer_.Data(), buffer_.Length(),
-                              &written, &error);
-      if (result == talk_base::SR_ERROR) {
-        LOG(LS_ERROR) << "Send error: " << error;
-        return;
-      }
-      if (result == talk_base::SR_BLOCK)
-        return;
-      ASSERT(result == talk_base::SR_SUCCESS);
-      ASSERT(written > 0);
-      buffer_.Shift(written);
-    }
-  }
-  if ((events & talk_base::SE_CLOSE))
-    SignalCloseEvent(err);
-}
-#endif  // USE_SSLSTREAM
-
-buzz::AsyncSocket::State XmppSocket::state() {
-  return state_;
-}
-
-buzz::AsyncSocket::Error XmppSocket::error() {
-  return buzz::AsyncSocket::ERROR_NONE;
-}
-
-int XmppSocket::GetError() {
-  return 0;
-}
-
-bool XmppSocket::Connect(const talk_base::SocketAddress& addr) {
-  if (cricket_socket_->Connect(addr) < 0) {
-    return cricket_socket_->IsBlocking();
-  }
-  return true;
-}
-
-bool XmppSocket::Read(char * data, size_t len, size_t* len_read) {
-#ifndef USE_SSLSTREAM
-  int read = cricket_socket_->Recv(data, len);
-  if (read > 0) {
-    *len_read = (size_t)read;
-    return true;
-  }
-#else  // USE_SSLSTREAM
-  talk_base::StreamResult result = stream_->Read(data, len, len_read, NULL);
-  if (result == talk_base::SR_SUCCESS)
-    return true;
-#endif  // USE_SSLSTREAM
-  return false;
-}
-
-bool XmppSocket::Write(const char * data, size_t len) {
-  buffer_.WriteBytes(data, len);
-#ifndef USE_SSLSTREAM
-  OnWriteEvent(cricket_socket_);
-#else  // USE_SSLSTREAM
-  OnEvent(stream_, talk_base::SE_WRITE, 0);
-#endif  // USE_SSLSTREAM
-  return true;
-}
-
-bool XmppSocket::Close() {
-  if (state_ != buzz::AsyncSocket::STATE_OPEN)
-    return false;
-#ifndef USE_SSLSTREAM
-  if (cricket_socket_->Close() == 0) {
-    state_ = buzz::AsyncSocket::STATE_CLOSED;
-    SignalClosed();
-    return true;
-  }
-  return false;
-#else  // USE_SSLSTREAM
-  state_ = buzz::AsyncSocket::STATE_CLOSED;
-  stream_->Close();
-  SignalClosed();
-  return true;
-#endif  // USE_SSLSTREAM
-}
-
-bool XmppSocket::StartTls(const std::string & domainname) {
-#if defined(FEATURE_ENABLE_SSL)
-  if (tls_ == buzz::TLS_DISABLED)
-    return false;
-#ifndef USE_SSLSTREAM
-  talk_base::SSLAdapter* ssl_adapter =
-    static_cast<talk_base::SSLAdapter *>(cricket_socket_);
-  if (ssl_adapter->StartSSL(domainname.c_str(), false) != 0)
-    return false;
-#else  // USE_SSLSTREAM
-  talk_base::SSLStreamAdapter* ssl_stream =
-    static_cast<talk_base::SSLStreamAdapter *>(stream_);
-  if (ssl_stream->StartSSLWithServer(domainname.c_str()) != 0)
-    return false;
-#endif  // USE_SSLSTREAM
-  state_ = buzz::AsyncSocket::STATE_TLS_CONNECTING;
-  return true;
-#else  // !defined(FEATURE_ENABLE_SSL)
-  return false;
-#endif  // !defined(FEATURE_ENABLE_SSL)
-}
diff --git a/third_party/libjingle/source/talk/examples/login/xmppsocket.h b/third_party/libjingle/source/talk/examples/login/xmppsocket.h
deleted file mode 100644
index ed9f6e1..0000000
--- a/third_party/libjingle/source/talk/examples/login/xmppsocket.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _XMPPSOCKET_H_
-#define _XMPPSOCKET_H_
-
-#include "talk/base/asyncsocket.h"
-#include "talk/base/bytebuffer.h"
-#include "talk/base/sigslot.h"
-#include "talk/xmpp/asyncsocket.h"
-#include "talk/xmpp/xmppengine.h"
-
-// The below define selects the SSLStreamAdapter implementation for
-// SSL, as opposed to the SSLAdapter socket adapter.
-// #define USE_SSLSTREAM 
-
-namespace talk_base {
-  class StreamInterface;
-};
-extern talk_base::AsyncSocket* cricket_socket_;
-
-class XmppSocket : public buzz::AsyncSocket, public sigslot::has_slots<> {
-public:
-  XmppSocket(buzz::TlsOptions tls);
-  ~XmppSocket();
-
-  virtual buzz::AsyncSocket::State state();
-  virtual buzz::AsyncSocket::Error error();
-  virtual int GetError();
-
-  virtual bool Connect(const talk_base::SocketAddress& addr);
-  virtual bool Read(char * data, size_t len, size_t* len_read);
-  virtual bool Write(const char * data, size_t len);
-  virtual bool Close();
-  virtual bool StartTls(const std::string & domainname);
-
-  sigslot::signal1<int> SignalCloseEvent;
-
-private:
-#ifndef USE_SSLSTREAM
-  void OnReadEvent(talk_base::AsyncSocket * socket);
-  void OnWriteEvent(talk_base::AsyncSocket * socket);
-  void OnConnectEvent(talk_base::AsyncSocket * socket);
-  void OnCloseEvent(talk_base::AsyncSocket * socket, int error);
-#else  // USE_SSLSTREAM
-  void OnEvent(talk_base::StreamInterface* stream, int events, int err);
-#endif  // USE_SSLSTREAM
-
-  talk_base::AsyncSocket * cricket_socket_;
-#ifdef USE_SSLSTREAM
-  talk_base::StreamInterface *stream_;
-#endif  // USE_SSLSTREAM
-  buzz::AsyncSocket::State state_;
-  talk_base::ByteBuffer buffer_;
-  buzz::TlsOptions tls_;
-};
-
-#endif // _XMPPSOCKET_H_
diff --git a/third_party/libjingle/source/talk/examples/login/xmppthread.cc b/third_party/libjingle/source/talk/examples/login/xmppthread.cc
deleted file mode 100644
index 5345643..0000000
--- a/third_party/libjingle/source/talk/examples/login/xmppthread.cc
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/examples/login/xmppthread.h"
-
-#include "talk/xmpp/xmppclientsettings.h"
-#include "talk/examples/login/xmppauth.h"
-
-namespace {
-
-const uint32 MSG_LOGIN = 1;
-const uint32 MSG_DISCONNECT = 2;
-
-struct LoginData: public talk_base::MessageData {
-  LoginData(const buzz::XmppClientSettings& s) : xcs(s) {}
-  virtual ~LoginData() {}
-
-  buzz::XmppClientSettings xcs;
-};
-
-} // namespace
-
-XmppThread::XmppThread() {
-  pump_ = new XmppPump(this);
-}
-
-XmppThread::~XmppThread() {
-  delete pump_;
-}
-
-void XmppThread::ProcessMessages(int cms) {
-  talk_base::Thread::ProcessMessages(cms);
-}
-
-void XmppThread::Login(const buzz::XmppClientSettings& xcs) {
-  Post(this, MSG_LOGIN, new LoginData(xcs));
-}
-
-void XmppThread::Disconnect() {
-  Post(this, MSG_DISCONNECT);
-}
-
-void XmppThread::OnStateChange(buzz::XmppEngine::State state) {
-}
-
-void XmppThread::OnMessage(talk_base::Message* pmsg) {
-  if (pmsg->message_id == MSG_LOGIN) {
-    ASSERT(pmsg->pdata != NULL);
-    LoginData* data = reinterpret_cast<LoginData*>(pmsg->pdata);
-    pump_->DoLogin(data->xcs, new XmppSocket(buzz::TLS_DISABLED),
-        new XmppAuth());
-    delete data;
-  } else if (pmsg->message_id == MSG_DISCONNECT) {
-    pump_->DoDisconnect();
-  } else {
-    ASSERT(false);
-  }
-}
diff --git a/third_party/libjingle/source/talk/examples/login/xmppthread.h b/third_party/libjingle/source/talk/examples/login/xmppthread.h
deleted file mode 100644
index efaa67a..0000000
--- a/third_party/libjingle/source/talk/examples/login/xmppthread.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_EXAMPLES_LOGIN_XMPPTHREAD_H_
-#define TALK_EXAMPLES_LOGIN_XMPPTHREAD_H_
-
-#include "talk/base/thread.h"
-#include "talk/examples/login/xmpppump.h"
-#include "talk/examples/login/xmppsocket.h"
-#include "talk/xmpp/xmppclientsettings.h"
-#include "talk/xmpp/xmppengine.h"
-
-
-class XmppThread:
-    public talk_base::Thread, XmppPumpNotify, talk_base::MessageHandler {
-public:
-  XmppThread();
-  ~XmppThread();
-
-  buzz::XmppClient* client() { return pump_->client(); }
-
-  void ProcessMessages(int cms);
-
-  void Login(const buzz::XmppClientSettings & xcs);
-  void Disconnect();
-
-private:
-  XmppPump* pump_;
-
-  void OnStateChange(buzz::XmppEngine::State state);
-  void OnMessage(talk_base::Message* pmsg);
-};
-
-#endif  // TALK_EXAMPLES_LOGIN_XMPPTHREAD_H_
diff --git a/third_party/libjingle/source/talk/libjingle.scons b/third_party/libjingle/source/talk/libjingle.scons
deleted file mode 100644
index 0ec1f59..0000000
--- a/third_party/libjingle/source/talk/libjingle.scons
+++ /dev/null
@@ -1,659 +0,0 @@
-import talk
-Import("env")
-
-talk.Library(env, name = "expat",
-             cppdefines = [
-               "XML_STATIC",
-             ],
-             srcs = [
-               "third_party/expat-2.0.1/lib/xmlparse.c",
-               "third_party/expat-2.0.1/lib/xmlrole.c",
-               "third_party/expat-2.0.1/lib/xmltok.c",
-             ],
-             includedirs = [
-               "third_party/expat-2.0.1/lib",
-             ],
-             win_cppdefines = [
-               "COMPILED_FROM_DSP",
-             ],
-             posix_cppdefines = [
-               "HAVE_EXPAT_CONFIG_H",
-             ],
-)
-talk.Library(env, name = "gunit",
-             srcs = [
-               "third_party/gtest/src/gtest-all.cc",
-             ],
-             includedirs = [
-               "third_party/gtest/include",
-               "third_party/expat-2.0.1/lib",
-               "third_party/srtp",
-               "third_party/gtest",
-             ],
-             cppdefines = [
-               "LIBJINGLE_UNITTEST",
-               "EXPAT_RELATIVE_PATH",
-               "SRTP_RELATIVE_PATH",
-             ],
-)
-talk.Library(env, name = "srtp",
-             srcs = [
-               "third_party/srtp/crypto/cipher/aes.c",
-               "third_party/srtp/crypto/cipher/aes_cbc.c",
-               "third_party/srtp/crypto/cipher/aes_icm.c",
-               "third_party/srtp/crypto/cipher/cipher.c",
-               "third_party/srtp/crypto/cipher/null_cipher.c",
-               "third_party/srtp/crypto/hash/auth.c",
-               "third_party/srtp/crypto/hash/hmac.c",
-               "third_party/srtp/crypto/hash/null_auth.c",
-               "third_party/srtp/crypto/hash/sha1.c",
-               "third_party/srtp/crypto/replay/rdb.c",
-               "third_party/srtp/crypto/replay/rdbx.c",
-               "third_party/srtp/crypto/replay/ut_sim.c",
-               "third_party/srtp/crypto/math/datatypes.c",
-               "third_party/srtp/crypto/math/stat.c",
-               "third_party/srtp/crypto/kernel/alloc.c",
-               "third_party/srtp/crypto/kernel/crypto_kernel.c",
-               "third_party/srtp/crypto/kernel/err.c",
-               "third_party/srtp/crypto/kernel/key.c",
-               "third_party/srtp/crypto/rng/ctr_prng.c",
-               "third_party/srtp/crypto/rng/rand_source.c",
-               "third_party/srtp/srtp/ekt.c",
-               "third_party/srtp/srtp/srtp.c",
-             ],
-             includedirs = [
-               "third_party/srtp/include",
-               "third_party/srtp/crypto/include",
-             ],
-             win_ccflags = [
-               "/wd4701",
-               "/wd4702",
-             ],
-)
-talk.Library(env, name = "jingle",
-             lin_srcs = [
-               "base/latebindingsymboltable.cc",
-               "base/linux.cc",
-               "session/phone/libudevsymboltable.cc",
-               "session/phone/linuxdevicemanager.cc",
-               "session/phone/v4llookup.cc",
-               "sound/alsasoundsystem.cc",
-               "sound/alsasymboltable.cc",
-               "sound/linuxsoundsystem.cc",
-               "sound/pulseaudiosoundsystem.cc",
-               "sound/pulseaudiosymboltable.cc",
-             ],
-             dependent_target_settings = {
-               'lin_libs': [
-                 "dl",
-                 "pthread",
-                 "rt",
-               ],
-               'mac_libs': [
-                 "-lcrypto",
-                 "-lssl",
-               ],
-             },
-             mac_srcs = [
-               "base/macasyncsocket.cc",
-               "base/macconversion.cc",
-               "base/macsocketserver.cc",
-               "base/macutils.cc",
-               "session/phone/carbonvideorenderer.cc",
-               "session/phone/macdevicemanager.cc",
-               "session/phone/macdevicemanagermm.mm",
-             ],
-             posix_srcs = [
-               "base/unixfilesystem.cc",
-               "base/opensslidentity.cc",
-               "base/opensslstreamadapter.cc",
-               "base/sslidentity.cc",
-               "base/sslstreamadapter.cc",
-             ],
-             linphone_srcs = [
-               "session/phone/linphonemediaengine.cc",
-             ],
-             cppdefines = [
-               "FEATURE_ENABLE_VOICEMAIL",
-               "EXPAT_RELATIVE_PATH",
-               "SRTP_RELATIVE_PATH",
-               "XML_STATIC",
-             ],
-             srcs = [
-               "base/asyncfile.cc",
-               "base/asynchttprequest.cc",
-               "base/asyncsocket.cc",
-               "base/asynctcpsocket.cc",
-               "base/asyncudpsocket.cc",
-               "base/autodetectproxy.cc",
-               "base/bandwidthsmoother.cc",
-               "base/base64.cc",
-               "base/basicpacketsocketfactory.cc",
-               "base/bytebuffer.cc",
-               "base/checks.cc",
-               "base/common.cc",
-               "base/cpuid.cc",
-               "base/cpumonitor.cc",
-               "base/diskcache.cc",
-               "base/event.cc",
-               "base/filelock.cc",
-               "base/fileutils.cc",
-               "base/firewallsocketserver.cc",
-               "base/flags.cc",
-               "base/helpers.cc",
-               "base/host.cc",
-               "base/httpbase.cc",
-               "base/httpclient.cc",
-               "base/httpcommon.cc",
-               "base/httprequest.cc",
-               "base/httpserver.cc",
-               "base/ipaddress.cc",
-               "base/logging.cc",
-               "base/md5c.c",
-               "base/messagehandler.cc",
-               "base/messagequeue.cc",
-               "base/multipart.cc",
-               "base/natserver.cc",
-               "base/natsocketfactory.cc",
-               "base/nattypes.cc",
-               "base/nethelpers.cc",
-               "base/network.cc",
-               "base/openssladapter.cc",
-               "base/optionsfile.cc",
-               "base/pathutils.cc",
-               "base/physicalsocketserver.cc",
-               "base/proxydetect.cc",
-               "base/proxyinfo.cc",
-               "base/proxyserver.cc",
-               "base/ratetracker.cc",
-               "base/sharedexclusivelock.cc",
-               "base/signalthread.cc",
-               "base/socketadapters.cc",
-               "base/socketaddress.cc",
-               "base/socketaddresspair.cc",
-               "base/socketpool.cc",
-               "base/socketstream.cc",
-               "base/ssladapter.cc",
-               "base/sslsocketfactory.cc",
-               "base/stream.cc",
-               "base/stringdigest.cc",
-               "base/stringencode.cc",
-               "base/stringutils.cc",
-               "base/systeminfo.cc",
-               "base/task.cc",
-               "base/taskparent.cc",
-               "base/taskrunner.cc",
-               "base/testclient.cc",
-               "base/thread.cc",
-               "base/timeutils.cc",
-               "base/timing.cc",
-               "base/urlencode.cc",
-               "base/versionparsing.cc",
-               "base/virtualsocketserver.cc",
-               "base/worker.cc",
-               "p2p/base/constants.cc",
-               "p2p/base/p2ptransport.cc",
-               "p2p/base/p2ptransportchannel.cc",
-               "p2p/base/parsing.cc",
-               "p2p/base/port.cc",
-               "p2p/base/pseudotcp.cc",
-               "p2p/base/relayport.cc",
-               "p2p/base/relayserver.cc",
-               "p2p/base/rawtransport.cc",
-               "p2p/base/rawtransportchannel.cc",
-               "p2p/base/session.cc",
-               "p2p/base/sessiondescription.cc",
-               "p2p/base/sessionmanager.cc",
-               "p2p/base/sessionmessages.cc",
-               "p2p/base/stun.cc",
-               "p2p/base/stunport.cc",
-               "p2p/base/stunrequest.cc",
-               "p2p/base/stunserver.cc",
-               "p2p/base/tcpport.cc",
-               "p2p/base/transport.cc",
-               "p2p/base/transportchannel.cc",
-               "p2p/base/transportchannelproxy.cc",
-               "p2p/base/udpport.cc",
-               "p2p/client/basicportallocator.cc",
-               "p2p/client/httpportallocator.cc",
-               "p2p/client/socketmonitor.cc",
-               "session/tunnel/pseudotcpchannel.cc",
-               "session/tunnel/tunnelsessionclient.cc",
-               "session/tunnel/securetunnelsessionclient.cc",
-               "session/phone/audiomonitor.cc",
-               "session/phone/call.cc",
-               "session/phone/channel.cc",
-               "session/phone/channelmanager.cc",
-               "session/phone/codec.cc",
-               "session/phone/currentspeakermonitor.cc",
-               "session/phone/devicemanager.cc",
-               "session/phone/dummydevicemanager.cc",
-               "session/phone/filemediaengine.cc",
-               "session/phone/filevideocapturer.cc",
-               "session/phone/mediaengine.cc",
-               "session/phone/mediamessages.cc",
-               "session/phone/mediamonitor.cc",
-               "session/phone/mediarecorder.cc",
-               "session/phone/mediasession.cc",
-               "session/phone/mediasessionclient.cc",
-               "session/phone/rtpdump.cc",
-               "session/phone/rtputils.cc",
-               "session/phone/rtcpmuxfilter.cc",
-               "session/phone/soundclip.cc",
-               "session/phone/srtpfilter.cc",
-               "session/phone/ssrcmuxfilter.cc",
-               "session/phone/videocapturer.cc",
-               "session/phone/videocommon.cc",
-               "session/phone/videoframe.cc",
-               "sound/nullsoundsystem.cc",
-               "sound/nullsoundsystemfactory.cc",
-               "sound/platformsoundsystem.cc",
-               "sound/platformsoundsystemfactory.cc",
-               "sound/soundsysteminterface.cc",
-               "sound/soundsystemproxy.cc",
-               "xmllite/qname.cc",
-               "xmllite/xmlbuilder.cc",
-               "xmllite/xmlconstants.cc",
-               "xmllite/xmlelement.cc",
-               "xmllite/xmlnsstack.cc",
-               "xmllite/xmlparser.cc",
-               "xmllite/xmlprinter.cc",
-               "xmpp/constants.cc",
-               "xmpp/hangoutpubsubclient.cc",
-               "xmpp/iqtask.cc",
-               "xmpp/jid.cc",
-               "xmpp/mucroomconfigtask.cc",
-               "xmpp/mucroomlookuptask.cc",
-               "xmpp/pubsubclient.cc",
-               "xmpp/pubsubtasks.cc",
-               "xmpp/ratelimitmanager.cc",
-               "xmpp/receivetask.cc",
-               "xmpp/saslmechanism.cc",
-               "xmpp/xmppclient.cc",
-               "xmpp/xmppengineimpl.cc",
-               "xmpp/xmppengineimpl_iq.cc",
-               "xmpp/xmpplogintask.cc",
-               "xmpp/xmppstanzaparser.cc",
-               "xmpp/xmpptask.cc",
-             ],
-             includedirs = [
-               "third_party/libudev",
-               "third_party/expat-2.0.1/lib",
-               "third_party/srtp/include",
-               "third_party/srtp/crypto/include",
-               "third_party/openssl/include",
-             ],
-             win_srcs = [
-               "base/schanneladapter.cc",
-               "base/win32.cc",
-               "base/win32filesystem.cc",
-               "base/win32securityerrors.cc",
-               "base/win32socketserver.cc",
-               "base/win32socketinit.cc",
-               "base/win32window.cc",
-               "base/winfirewall.cc",
-               "base/winping.cc",
-               "session/phone/win32devicemanager.cc",
-               "session/phone/gdivideorenderer.cc",
-             ],
-             mac_ccflags = [
-               "-Wno-deprecated-declarations",
-             ],
-             extra_srcs = [
-               "base/json.cc",
-             ],
-)
-talk.Library(env, name = "xmpphelp",
-             libs = [
-               "jingle",
-             ],
-             srcs = [
-               "examples/login/xmppauth.cc",
-               "examples/login/xmpppump.cc",
-               "examples/login/xmppsocket.cc",
-             ],
-)
-talk.Library(env, name = "videorenderer",
-             lin_srcs = [
-               "session/phone/gtkvideorenderer.cc",
-             ],
-             lin_packages = [
-               "gtk+-2.0",
-             ],
-)
-talk.Library(env, name = "unittest_main",
-             libs = [
-               "gunit",
-             ],
-             srcs = [
-               "base/unittest_main.cc",
-             ],
-             includedirs = [
-               "third_party/gtest/include",
-               "third_party/expat-2.0.1/lib",
-               "third_party/srtp",
-               "third_party/gtest",
-             ],
-             cppdefines = [
-               "LIBJINGLE_UNITTEST",
-               "EXPAT_RELATIVE_PATH",
-               "SRTP_RELATIVE_PATH",
-             ],
-)
-talk.App(env, name = "login",
-         libs = [
-           "jingle",
-           "expat",
-           "xmpphelp",
-         ],
-         srcs = [
-           "examples/login/xmppthread.cc",
-           "examples/login/login_main.cc",
-         ],
-         posix_libs = [
-           "crypto",
-           "ssl",
-         ],
-         lin_libs = [
-           "videorenderer",
-         ],
-)
-talk.App(env, name = "call",
-         mac_frameworks = [
-           "AudioToolbox",
-           "AudioUnit",
-           "Cocoa",
-           "CoreAudio",
-           "CoreFoundation",
-           "IOKit",
-           "QTKit",
-           "QuickTime",
-         ],
-         win_libs = [
-           "d3d9.lib",
-           "gdi32.lib",
-           "powrprof.lib",
-           "strmiids.lib",
-           "winmm.lib",
-         ],
-         posix_libs = [
-           "crypto",
-           "ssl",
-         ],
-         cppdefines = [
-           "FEATURE_ENABLE_VOICEMAIL",
-         ],
-         lin_libs = [
-           "videorenderer",
-         ],
-         srcs = [
-           "examples/call/call_main.cc",
-           "examples/call/callclient.cc",
-           "examples/call/console.cc",
-           "examples/call/discoitemsquerytask.cc",
-           "examples/call/friendinvitesendtask.cc",
-           "examples/call/mediaenginefactory.cc",
-           "examples/call/mucinviterecvtask.cc",
-           "examples/call/mucinvitesendtask.cc",
-           "examples/call/presenceouttask.cc",
-           "examples/call/presencepushtask.cc",
-           "examples/call/voicemailjidrequester.cc",
-         ],
-         libs = [
-           "jingle",
-           "expat",
-           "srtp",
-           "xmpphelp",
-         ],
-)
-talk.App(env, name = "relayserver",
-         libs = [
-           "jingle",
-         ],
-         srcs = [
-           "p2p/base/relayserver_main.cc",
-         ],
-)
-talk.App(env, name = "stunserver",
-         libs = [
-           "jingle",
-         ],
-         srcs = [
-           "p2p/base/stunserver_main.cc",
-         ],
-)
-talk.Unittest(env, name = "base",
-              libs = [
-                "jingle",
-              ],
-              srcs = [
-                "base/asynchttprequest_unittest.cc",
-                "base/atomicops_unittest.cc",
-                "base/autodetectproxy_unittest.cc",
-                "base/bandwidthsmoother_unittest.cc",
-                "base/buffer_unittest.cc",
-                "base/bytebuffer_unittest.cc",
-                "base/cpuid_unittest.cc",
-                "base/cpumonitor_unittest.cc",
-                "base/event_unittest.cc",
-                "base/filelock_unittest.cc",
-                "base/fileutils_unittest.cc",
-                "base/helpers_unittest.cc",
-                "base/host_unittest.cc",
-                "base/httpbase_unittest.cc",
-                "base/httpcommon_unittest.cc",
-                "base/httpserver_unittest.cc",
-                "base/ipaddress_unittest.cc",
-                "base/logging_unittest.cc",
-                "base/messagequeue_unittest.cc",
-                "base/multipart_unittest.cc",
-                "base/nat_unittest.cc",
-                "base/network_unittest.cc",
-                "base/optionsfile_unittest.cc",
-                "base/pathutils_unittest.cc",
-                "base/proxy_unittest.cc",
-                "base/proxydetect_unittest.cc",
-                "base/ratetracker_unittest.cc",
-                "base/referencecountedsingletonfactory_unittest.cc",
-                "base/rollingaccumulator_unittest.cc",
-                "base/sharedexclusivelock_unittest.cc",
-                "base/signalthread_unittest.cc",
-                "base/socket_unittest.cc",
-                "base/socketaddress_unittest.cc",
-                "base/stream_unittest.cc",
-                "base/stringencode_unittest.cc",
-                "base/stringutils_unittest.cc",
-                "base/systeminfo_unittest.cc",
-                "base/task_unittest.cc",
-                "base/testclient_unittest.cc",
-                "base/thread_unittest.cc",
-                "base/timeutils_unittest.cc",
-                "base/urlencode_unittest.cc",
-                "base/versionparsing_unittest.cc",
-                "base/virtualsocket_unittest.cc",
-              ],
-              includedirs = [
-                "third_party/gtest/include",
-                "third_party/expat-2.0.1/lib",
-                "third_party/srtp",
-                "third_party/gtest",
-              ],
-              posix_srcs = [
-                "base/sslidentity_unittest.cc",
-                "base/sslstreamadapter_unittest.cc",
-              ],
-              cppdefines = [
-                "LIBJINGLE_UNITTEST",
-                "EXPAT_RELATIVE_PATH",
-                "SRTP_RELATIVE_PATH",
-              ],
-)
-talk.Unittest(env, name = "p2p",
-              mac_FRAMEWORKS = [
-                "Foundation",
-                "IOKit",
-                "QTKit",
-              ],
-              mac_libs = [
-                "crypto",
-                "ssl",
-              ],
-              cppdefines = [
-                "LIBJINGLE_UNITTEST",
-                "EXPAT_RELATIVE_PATH",
-                "SRTP_RELATIVE_PATH",
-              ],
-              srcs = [
-                "p2p/base/p2ptransportchannel_unittest.cc",
-                "p2p/base/port_unittest.cc",
-                "p2p/base/pseudotcp_unittest.cc",
-                "p2p/base/relayport_unittest.cc",
-                "p2p/base/relayserver_unittest.cc",
-                "p2p/base/session_unittest.cc",
-                "p2p/base/stun_unittest.cc",
-                "p2p/base/stunport_unittest.cc",
-                "p2p/base/stunrequest_unittest.cc",
-                "p2p/base/stunserver_unittest.cc",
-                "p2p/base/transport_unittest.cc",
-                "p2p/client/portallocator_unittest.cc",
-              ],
-              includedirs = [
-                "third_party/gtest/include",
-                "third_party/expat-2.0.1/lib",
-                "third_party/srtp",
-                "third_party/gtest",
-              ],
-              libs = [
-                "jingle",
-                "expat",
-              ],
-)
-talk.Unittest(env, name = "media",
-              libs = [
-                "jingle",
-                "expat",
-                "srtp",
-              ],
-              srcs = [
-                "session/phone/channel_unittest.cc",
-                "session/phone/channelmanager_unittest.cc",
-                "session/phone/codec_unittest.cc",
-                "session/phone/currentspeakermonitor_unittest.cc",
-                "session/phone/devicemanager_unittest.cc",
-                "session/phone/dummydevicemanager_unittest.cc",
-                "session/phone/filemediaengine_unittest.cc",
-                "session/phone/filevideocapturer_unittest.cc",
-                "session/phone/mediarecorder_unittest.cc",
-                "session/phone/mediamessages_unittest.cc",
-                "session/phone/mediasession_unittest.cc",
-                "session/phone/mediasessionclient_unittest.cc",
-                "session/phone/rtcpmuxfilter_unittest.cc",
-                "session/phone/rtpdump_unittest.cc",
-                "session/phone/rtputils_unittest.cc",
-                "session/phone/srtpfilter_unittest.cc",
-                "session/phone/ssrcmuxfilter_unittest.cc",
-                "session/phone/testutils.cc",
-                "session/phone/videocapturer_unittest.cc",
-                "session/phone/videocommon_unittest.cc",
-              ],
-              includedirs = [
-                "third_party/gtest/include",
-                "third_party/expat-2.0.1/lib",
-                "third_party/srtp",
-                "third_party/gtest",
-              ],
-              cppdefines = [
-                "LIBJINGLE_UNITTEST",
-                "EXPAT_RELATIVE_PATH",
-                "SRTP_RELATIVE_PATH",
-              ],
-              win_libs = [
-                "winmm.lib",
-                "strmiids",
-              ],
-)
-talk.Unittest(env, name = "sound",
-              libs = [
-                "jingle",
-              ],
-              srcs = [
-                "sound/automaticallychosensoundsystem_unittest.cc",
-              ],
-              mac_libs = [
-                "crypto",
-                "ssl",
-              ],
-              includedirs = [
-                "third_party/gtest/include",
-                "third_party/expat-2.0.1/lib",
-                "third_party/srtp",
-                "third_party/gtest",
-              ],
-              cppdefines = [
-                "LIBJINGLE_UNITTEST",
-                "EXPAT_RELATIVE_PATH",
-                "SRTP_RELATIVE_PATH",
-              ],
-)
-talk.Unittest(env, name = "xmllite",
-              libs = [
-                "jingle",
-                "expat",
-              ],
-              srcs = [
-                "xmllite/qname_unittest.cc",
-                "xmllite/xmlbuilder_unittest.cc",
-                "xmllite/xmlelement_unittest.cc",
-                "xmllite/xmlnsstack_unittest.cc",
-                "xmllite/xmlparser_unittest.cc",
-                "xmllite/xmlprinter_unittest.cc",
-              ],
-              mac_libs = [
-                "crypto",
-                "ssl",
-              ],
-              includedirs = [
-                "third_party/gtest/include",
-                "third_party/expat-2.0.1/lib",
-                "third_party/srtp",
-                "third_party/gtest",
-              ],
-              cppdefines = [
-                "LIBJINGLE_UNITTEST",
-                "EXPAT_RELATIVE_PATH",
-                "SRTP_RELATIVE_PATH",
-              ],
-)
-talk.Unittest(env, name = "xmpp",
-              libs = [
-                "jingle",
-                "expat",
-              ],
-              srcs = [
-                "xmpp/hangoutpubsubclient_unittest.cc",
-                "xmpp/jid_unittest.cc",
-                "xmpp/mucroomconfigtask_unittest.cc",
-                "xmpp/mucroomlookuptask_unittest.cc",
-                "xmpp/pubsubclient_unittest.cc",
-                "xmpp/pubsubtasks_unittest.cc",
-                "xmpp/util_unittest.cc",
-                "xmpp/xmppengine_unittest.cc",
-                "xmpp/xmpplogintask_unittest.cc",
-                "xmpp/xmppstanzaparser_unittest.cc",
-              ],
-              mac_libs = [
-                "crypto",
-                "ssl",
-              ],
-              includedirs = [
-                "third_party/gtest/include",
-                "third_party/expat-2.0.1/lib",
-                "third_party/srtp",
-                "third_party/gtest",
-              ],
-              cppdefines = [
-                "LIBJINGLE_UNITTEST",
-                "EXPAT_RELATIVE_PATH",
-                "SRTP_RELATIVE_PATH",
-              ],
-)
diff --git a/third_party/libjingle/source/talk/main.scons b/third_party/libjingle/source/talk/main.scons
deleted file mode 100644
index 8e4d7fa..0000000
--- a/third_party/libjingle/source/talk/main.scons
+++ /dev/null
@@ -1,587 +0,0 @@
-# -*- Python -*-
-#
-# All the helper functions are defined in:
-#  - site_scons/talk.py
-# Use 'import talk' in any .scons file to get access to it.
-# Add any new helper functions to it; unittest are available
-# in talk_unittest.py.
-#
-# Each 'component' that is built is defined in a .scons file.
-# See talk.Components(...) for further info on file naming convention.
-#
-# To add a new platform clone and modify the root_env object. Remember to add
-# the new environment object to the envs list otherwise it will not be included
-# in the build.
-#
-#
-#
-import talk
-import os
-import platform
-
-#-------------------------------------------------------------------------------
-# The build files/directories to 'build'.
-# If the name is the name of a directory then that directory shall contain a
-# .scons file with the same name as the directory itself:
-#  Ex: The directory session/phone contains a file called phone.scons
-# This list must be in order of library dependencies. e.g., if
-# session/phone/phone.scons defines a target that links to a library target
-# defined in sound/sound.scons, then 'sound' must come first.
-# When no particular order is imposed by library dependencies, try to keep in
-# mostly alphabetical order.
-#
-components = talk.Components("libjingle.scons")
-
-#-------------------------------------------------------------------------------
-# Build environments
-#
-
-# The list of build environments.
-envs = []
-
-# The root of all builds.
-root_env = Environment(
-  tools = [
-    'component_bits',
-    'component_setup',
-    'replace_strings',
-    'talk_noops',
-    #'talk_utils',
-  ],
-  BUILD_SCONSCRIPTS = components,
-  DESTINATION_ROOT = '$MAIN_DIR/build',
-  CPPPATH = [
-    '$OBJ_ROOT',     # generated headers are relative to here
-    '$MAIN_DIR/..',  # TODO: how can we use GOOGLECLIENT instead?
-  ],
-  CPPDEFINES = [
-    # Temp flag while porting to hammer.
-    'HAMMER_TIME=1',
-    'LOGGING=1',
-
-    # Feature selection
-    'FEATURE_ENABLE_SSL',
-    'FEATURE_ENABLE_VOICEMAIL',
-    'FEATURE_ENABLE_PSTN',
-    'HAVE_SRTP',
-  ],
-  # Ensure the os environment is captured for any scripts we call out to
-  ENV = os.environ,
-)
-
-# This is where we set common environments
-#
-# Detect if building on 64-bit or 32-bit platform.
-DeclareBit('build_platform_64bit', 'Platform of the build machine is 64-bit')
-if platform.architecture()[0] == "64bit":
-  root_env.SetBits('build_platform_64bit')
-
-# This bit denotes that an env is for 64-bit builds. When set, all build
-# artifacts will be 64-bit. When unset, all build artifacts will be 32-bit.
-DeclareBit('host_platform_64bit', 'Platform of the host machine (where artifacts will execute) is 64-bit')
-
-def CrossBuilding(env):
-  return env.Bit('host_platform_64bit') != env.Bit('build_platform_64bit')
-root_env.AddMethod(CrossBuilding)
-
-DeclareBit('use_static_openssl', 'Build OpenSSL as a static library')
-
-DeclareBit('have_dbus_glib',
-           'Whether the build system has the dbus-glib-1 package')
-DeclareBit('have_libpulse',
-           'Whether the build system has the libpulse package')
-
-
-# List all the locales we localize to.
-root_env.AppendUnique(locales = [
-    'ar', 'bg', 'bn', 'ca', 'cs', 'da', 'de', 'el', 'en', 'en-GB', 'es',
-    'es-419', 'et', 'fa', 'fi', 'fil', 'fr', 'gu', 'hi', 'hr', 'hu', 'id',
-    'is', 'it', 'iw', 'ja', 'kn', 'ko', 'lt', 'lv', 'ml', 'mr', 'ms', 'nl',
-    'no', 'or', 'pl', 'pt-BR', 'pt-PT', 'ro', 'ru', 'sk', 'sl', 'sr', 'sv',
-    'ta', 'te', 'th', 'tl', 'tr', 'uk', 'ur', 'vi', 'zh-CN', 'zh-TW'])
-
-#-------------------------------------------------------------------------------
-# W I N D O W S
-#
-win_env = root_env.Clone(
-  tools = [
-    'atlmfc_vc80',
-    #'code_signing',
-    'component_targets_msvs',
-    'directx_9_0_c',
-    #'grid_builder',
-    'midl',
-    'target_platform_windows'
-  ],
-  # Don't use default vc80 midl.exe.  It doesn't understand vista_sdk idl files.
-  MIDL = '$PLATFORM_SDK_VISTA_6_0_DIR/Bin/midl.exe ',
-  WIX_DIR = '$GOOGLECLIENT/third_party/wix/v3_0_2925/files',
-  # Flags for debug and optimization are added to CCFLAGS instead
-  CCPDBFLAGS = '',
-  CCFLAGS_DEBUG = '',
-  CCFLAGS_OPTIMIZED = '',
-  # We force a x86 target even when building on x64 Windows platforms.
-  TARGET_ARCH = 'x86',
-)
-
-win_env.Append(
-  COMPONENT_LIBRARY_PUBLISH = True,  # Put dlls in output dir too
-  CCFLAGS = [
-    '/Fd${TARGET}.pdb', # pdb per object allows --jobs=
-    '/WX',          # warnings are errors
-    '/Zc:forScope', # handle 'for (int i = 0 ...)' right
-    '/EHs-c-',      # disable C++ EH
-    '/GR-',         # disable RTTI
-    '/Gy',          # enable function level linking
-    '/wd4996',      # ignore POSIX deprecated warnings
-
-    # promote certain level 4 warnings
-    '/w14701',     # potentially uninitialized var
-    '/w14702',     # unreachable code
-    '/w14706',     # assignment within a conditional
-    '/w14709',     # comma operator within array index
-    '/w14063',     # case 'identifier' is not a valid value for switch of enum
-    '/w14064',     # switch of incomplete enum 'enumeration'
-    '/w14057',     # 'identifier1' indirection to slightly different base
-                   #   types from 'identifier2'
-    '/w14263',     # member function does not override any base class virtual
-                   #   member function
-    '/w14266',     # no override available for virtual memberfunction from base
-                   #  'type'; function is hidden
-    '/w14296',     # expression is always false
-    '/w14355',     # 'this' : used in base member initializer list
-  ],
-  CPPDEFINES = [
-    '_ATL_CSTRING_EXPLICIT_CONSTRUCTORS',
-    # TODO: encapsulate all string operations that are not based
-    # on std::string/std::wstring and make sure we use the safest versions
-    # available on all platforms.
-    '_CRT_SECURE_NO_WARNINGS',
-    '_SCL_SECURE_NO_WARNINGS',
-    '_USE_32BIT_TIME_T',
-    '_UNICODE',
-    'UNICODE',
-    '_HAS_EXCEPTIONS=0',
-    'WIN32',
-    # TODO: remove this from logging.cc and enable here instead.
-    #'WIN32_LEAN_AND_MEAN',
-
-    'WINVER=0x0500',
-    '_WIN32_WINNT=0x0501',
-    '_WIN32_IE=0x0501',
-    # The Vista platform SDK 6.0 needs at least
-    # this NTDDI version or else the headers
-    # that LMI includes from it won't compile.
-    'NTDDI_VERSION=NTDDI_WINXP',
-
-    # npapi.h requires the following:
-    '_WINDOWS',
-  ],
-  CPPPATH = [
-    '$THIRD_PARTY/wtl_71/include',
-    '$PLATFORM_SDK_VISTA_6_0_DIR/Include',
-  ],
-  LIBPATH = [
-    '$PLATFORM_SDK_VISTA_6_0_DIR/Lib'
-  ],
-  LINKFLAGS = [
-    '-manifest' # TODO: Why do we need this?
-  ],
-  MIDLFLAGS = [
-    '/win32',
-    '/I$PLATFORM_SDK_VISTA_6_0_DIR/include'
-  ]
-)
-
-# TODO: Figure out what this does; found it in
-# omaha/main.scons. This fixes the problem with redefinition
-# of OS_WINDOWS symbol.
-win_env.FilterOut(CPPDEFINES = ['OS_WINDOWS=OS_WINDOWS'])
-
-# Set up digital signing
-DeclareBit('test_signing', 'Sign binaries with the test certificate')
-win_env.SetBitFromOption('test_signing', False)
-if win_env.Bit('test_signing'):
-   win_env.Replace(
-     CERTIFICATE_PATH = win_env.File(
-         '$GOOGLECLIENT/tools/test_key/testkey.pfx').abspath,
-     CERTIFICATE_PASSWORD = 'test',
-   )
-AddTargetGroup('signed_binaries', 'digitally signed binaries can be built')
-
-win_dbg_env = win_env.Clone(
-  BUILD_TYPE = 'dbg',
-  BUILD_TYPE_DESCRIPTION = 'Windows debug build',
-  BUILD_GROUPS = ['default', 'all'],
-  tools = ['target_debug'],
-)
-
-win_dbg_env.Prepend(
-  CCFLAGS = [
-      '/ZI',     # enable debugging
-      '/Od',     # disable optimizations
-      '/MTd',    # link with LIBCMTD.LIB debug lib
-      '/RTC1',   # enable runtime checks
-  ],
-)
-
-envs.append(win_dbg_env)
-
-win_coverage_env = win_dbg_env.Clone(
-  tools = ['code_coverage'],
-  BUILD_TYPE = 'coverage',
-  BUILD_TYPE_DESCRIPTION = 'Windows code coverage build',
-  BUILD_GROUPS = ['all'],
-)
-
-win_coverage_env.Append(
-  CPPDEFINES = [
-    'COVERAGE_ENABLED',
-  ],
-)
-
-envs.append(win_coverage_env)
-
-win_opt_env = win_env.Clone(
-  BUILD_TYPE = 'opt',
-  BUILD_TYPE_DESCRIPTION = 'Windows opt build',
-  BUILD_GROUPS = ['all'],
-  tools = ['target_optimized'],
-)
-
-win_opt_env.Prepend(
-  CCFLAGS=[
-      '/Zi',     # enable debugging
-      '/O1',     # optimize for size
-      '/MT',     # link with LIBCMT.LIB (multi-threaded, static linked crt)
-      '/GS',     # enable security checks
-  ],
-  LINKFLAGS = [
-    '/safeseh',  # protect against attacks against exception handlers
-    '/opt:ref',  # Remove unused references (functions/data).
-  ],
-)
-
-envs.append(win_opt_env)
-
-#-------------------------------------------------------------------------------
-# P O S I X
-#
-posix_env = root_env.Clone()
-posix_env.Append(
-  CPPDEFINES = [
-    'HASHNAMESPACE=__gnu_cxx',
-    'HASH_NAMESPACE=__gnu_cxx',
-    'POSIX',
-    'DISABLE_DYNAMIC_CAST',
-    'HAVE_OPENSSL_SSL_H=1',
-    # The POSIX standard says we have to define this.
-    '_REENTRANT',
-  ],
-  CCFLAGS = [
-    '-Wall',
-    '-Werror',
-    '-Wno-switch',
-    '-fno-exceptions',
-    # Needed for a clean ABI and for link-time dead-code removal to work
-    # properly.
-    '-fvisibility=hidden',
-    # Generate debugging info in the DWARF2 format.
-    '-gdwarf-2',
-    # Generate maximal debugging information. (It is stripped from what we ship
-    # to users, so we want it for both dbg and opt.)
-    # Note that hammer automatically supplies "-g" for mac/linux dbg, so that
-    # flag must be filtered out of linux_dbg and mac_dbg envs below.
-    '-g3',
-  ],
-  CXXFLAGS = [
-    '-Wno-non-virtual-dtor',
-    '-Wno-ctor-dtor-privacy',
-    '-fno-rtti',
-  ],
-)
-
-#-------------------------------------------------------------------------------
-# M A C OSX
-#
-mac_env = posix_env.Clone(
-  tools = [
-    'target_platform_mac',
-    #'talk_mac',
-    #'fill_plist',
-  ],
-)
-mac_env.Append(
-  CPPDEFINES = [
-    'OSX',
-  ],
-  CCFLAGS = [
-    '-m32',
-    '-arch', 'i386',
-    '-isysroot', '/Developer/SDKs/MacOSX10.5.sdk',
-    '-fasm-blocks',
-  ],
-  LINKFLAGS = [
-    '-Wl,-search_paths_first',
-    # This flag makes all members of a static library be included in the
-    # final exe - that increases the size of the exe, but without it
-    # Obj-C categories aren't properly included in the exe.
-    # TODO: consider only defining for libs that actually have objc.
-    '-ObjC',
-    '-arch', 'i386',
-    '-mmacosx-version-min=10.5',
-    '-isysroot', '/Developer/SDKs/MacOSX10.5.sdk',
-    '-m32',
-    '-dead_strip',
-  ],
-  FRAMEWORKS = [
-    'CoreServices',
-    'Carbon',
-    'Security',
-    'SystemConfiguration',
-    'OpenGL',
-    'CoreAudio',
-    'Quartz',
-    'QuickTime',
-    'Cocoa',
-    'QTKit',
-  ]
-)
-
-mac_dbg_env = mac_env.Clone(
-  BUILD_TYPE = 'dbg',
-  BUILD_TYPE_DESCRIPTION = 'Mac debug build',
-  BUILD_GROUPS = ['default', 'all'],
-  tools = ['target_debug'],
-)
-mac_dbg_env.Append(
-  CCFLAGS = [
-    '-O0',
-  ],
-  CPPDEFINES = [
-    'DEBUG=1',
-  ],
-)
-# Remove -g set by hammer, which is not what we want (we have set -g3 above).
-mac_dbg_env.FilterOut(CCFLAGS = ['-g'])
-envs.append(mac_dbg_env)
-
-mac_opt_env = mac_env.Clone(
-  BUILD_TYPE = 'opt',
-  BUILD_TYPE_DESCRIPTION = 'Mac opt build',
-  BUILD_GROUPS = ['all'],
-  tools = ['target_optimized'],
-)
-mac_opt_env.Append(
-  CCFLAGS = [
-    # TODO: Figure out how mk can compile without
-    # this flag, then remove.  Confirmed asserts are preprocessed
-    # out.  Maybe it's a different version of gcc?
-    '-Wno-unused-variable',
-  ],
-  # Hammer automatically specifies -Os for mac opt.
-)
-envs.append(mac_opt_env)
-
-#-------------------------------------------------------------------------------
-# L I N U X
-#
-linux_common_env = posix_env.Clone(
-  tools = [
-    'target_platform_linux',
-    'talk_linux',
-  ],
-)
-
-linux_common_env.Append(
-  CPPDEFINES = [
-    'LINUX',
-  ],
-  CCFLAGS = [
-    # Needed for link-time dead-code removal to work properly.
-    '-ffunction-sections',
-    '-fdata-sections',
-  ],
-  LINKFLAGS = [
-    # Enable dead-code removal.
-    '-Wl,--gc-sections',
-    # Elide dependencies on shared libraries that we're not actually using.
-    '-Wl,--as-needed',
-    '-Wl,--start-group',
-  ],
-  _LIBFLAGS = ['-Wl,--end-group'],
-)
-
-# Remove default rpath set by Hammer. Hammer sets it to LIB_DIR, which is wrong.
-# The rpath is the _run-time_ library search path for the resulting binary, i.e.
-# the one used by ld.so at load time. Setting it equal to the path to build
-# output on the build machine is nonsense.
-linux_common_env.Replace(
-  RPATH = [],
-)
-
-# Enable the optional DBus-GLib code if the build machine has the required
-# dependency.
-linux_common_env.EnableFeatureWherePackagePresent('have_dbus_glib',
-                                                  'HAVE_DBUS_GLIB',
-                                                  'dbus-glib-1')
-
-def linux_common_include_x86_32(env):
-  """Include x86-32 settings into an env based on linux_common."""
-  env.Append(
-    CCFLAGS = [
-      '-m32',
-    ],
-    LINKFLAGS = [
-      '-m32',
-    ],
-  )
-
-def linux_common_include_x86_64(env):
-  """Include x86-64 settings into an env based on linux_common."""
-  env.Append(
-    CCFLAGS = [
-      '-m64',
-      '-fPIC',
-    ],
-    LINKFLAGS = [
-      '-m64',
-    ],
-  )
-  env.SetBits('host_platform_64bit')
-
-#-------------------------------------------------------------------------------
-# L I N U X -- T R A D I T I O N A L -- X 8 6
-#
-# Settings that are specific to our desktop Linux x86 targets.
-linux_x86_32_env = linux_common_env.Clone()
-linux_common_include_x86_32(linux_x86_32_env)
-
-linux_x86_64_env = linux_common_env.Clone()
-linux_common_include_x86_64(linux_x86_64_env)
-
-def gen_linux_x86(base_env, type_suffix, desc_suffix):
-  linux_env = base_env.Clone()
-  # OpenSSL has infamously poor ABI stability, so that building against one
-  # version and running against a different one often will not work. Since our
-  # non-ChromeOS Linux builds are used on many different distros and distro
-  # versions, this means we can't safely dynamically link to OpenSSL because the
-  # product would end up being broken on any computer with a different version
-  # installed. So instead we build it ourself and statically link to it.
-  linux_env.SetBits('use_static_openssl')
-  # Enable the optional PulseAudio code if the build machine has the required
-  # dependency. (Not doing this for linux_common_env because we don't want
-  # PulseAudio used on ChromeOS.)
-  linux_env.EnableFeatureWherePackagePresent('have_libpulse',
-                                             'HAVE_LIBPULSE',
-                                             'libpulse')
-
-  groups = ['all']
-  if not linux_env.CrossBuilding():
-    groups = groups + ['all-native']
-    # The native-arch dbg build is the default.
-    dbg_groups = groups + ['default']
-    native_desc = ', native '
-    # No suffix for native modes.
-    type_suffix = ''
-  else:
-    groups = groups + ['all-cross']
-    dbg_groups = groups
-    native_desc = ', cross-built for '
-
-  linux_dbg_env = linux_env.Clone(
-    BUILD_TYPE = 'dbg' + type_suffix,
-    BUILD_TYPE_DESCRIPTION = 'Linux debug build%s%s' % (native_desc,
-        desc_suffix),
-    BUILD_GROUPS = dbg_groups,
-    tools = ['target_debug'],
-  )
-  # Remove -g set by hammer, which is not what we want (we have set -g3 above).
-  linux_dbg_env.FilterOut(CCFLAGS = ['-g'])
-  envs.append(linux_dbg_env)
-
-  linux_opt_env = linux_env.Clone(
-    BUILD_TYPE = 'opt' + type_suffix,
-    BUILD_TYPE_DESCRIPTION = 'Linux optimized build%s%s' % (native_desc,
-        desc_suffix),
-    BUILD_GROUPS = groups,
-    tools = ['target_optimized'],
-  )
-  # Remove -O2 set by hammer, which is not what we want.
-  linux_opt_env.FilterOut(CCFLAGS = ['-O2'])
-  linux_opt_env.Append(CCFLAGS = ['-Os'])
-  envs.append(linux_opt_env)
-
-gen_linux_x86(linux_x86_32_env, '32', '32-bit')
-gen_linux_x86(linux_x86_64_env, '64', '64-bit')
-
-
-
-# TODO(): Clone linux envs for 64bit.  See 'variant' documentation.
-
-# Create a group for installers
-AddTargetGroup('all_installers', 'installers that can be built')
-
-# Parse child .scons files
-BuildEnvironments(envs)
-
-# Explicitly set which targets to build when not stated on commandline
-Default(None)
-# Build the following, which excludes unit test output (ie running them)
-# To run unittests, specify the test to run, or run_all_tests.  See -h option.
-Default(['all_libraries', 'all_programs', 'all_test_programs'])
-
-# .sln creation code lifted from googleclient/bar/main.scons.  Must be after
-# the call to BuildEnvironments for all_foo aliases to be defined.
-# Run 'hammer --mode=all --vsproj' to generate
-DeclareBit('vsproj', 'Generate Visual Studio projects and solution files.')
-win_env.SetBitFromOption('vsproj', False)
-
-if win_env.Bit('vsproj'):
-  vs_env = win_env.Clone()
-  vs_env.Append(
-    COMPONENT_VS_SOURCE_SUFFIXES = [
-      '.def',
-      '.grd',
-      '.html',
-      '.idl',
-      '.mk',
-      '.txt',
-      '.py',
-      '.scons',
-      '.wxs.template',
-    ]
-  )
-
-  # Source project
-  p = vs_env.ComponentVSDirProject(
-    'flute_source',
-    ['$MAIN_DIR',
-    ],
-    COMPONENT_VS_SOURCE_FOLDERS = [
-      # Files are assigned to first matching folder. Folder names of None
-      # are filters.
-      (None, '$DESTINATION_ROOT'),
-      ('flute', '$MAIN_DIR'),
-      ('google3', '$GOOGLE3'),
-      ('third_party', '$THIRD_PARTY'),
-    ],
-    # Force source project to main dir, so that Visual Studio can find the
-    # source files corresponding to build errors.
-    COMPONENT_VS_PROJECT_DIR = '$MAIN_DIR',
-  )
-  vs_env.AlwaysBuild(p)
-
-  # Solution and target projects
-  s = vs_env.ComponentVSSolution(
-    # 'libjingle',  # Please uncomment this line if you build VS proj files.
-    ['all_libraries', 'all_programs', 'all_test_programs'],
-    projects = [p],
-  )
-
-  print '***Unfortunately the vsproj creator isn\'t smart enough to '
-  print '***automatically get the correct output locations.  It is very easy'
-  print '***though to change it in the properties pane to the following'
-  print '***$(SolutionDir)/build/<foo>/staging/<bar>.exe'
-  Default(None)
-  Default([s])
diff --git a/third_party/libjingle/source/talk/p2p/base/candidate.h b/third_party/libjingle/source/talk/p2p/base/candidate.h
deleted file mode 100644
index e347ec5..0000000
--- a/third_party/libjingle/source/talk/p2p/base/candidate.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_P2P_BASE_CANDIDATE_H_
-#define TALK_P2P_BASE_CANDIDATE_H_
-
-#include <string>
-#include <sstream>
-#include "talk/base/socketaddress.h"
-
-namespace cricket {
-
-// Candidate for ICE based connection discovery.
-
-class Candidate {
- public:
-  Candidate() : preference_(0), generation_(0) {}
-  Candidate(const std::string& name, const std::string& protocol,
-            const talk_base::SocketAddress& address, float preference,
-            const std::string& username, const std::string& password,
-            const std::string& type, const std::string& network_name,
-            uint32 generation)
-      : name_(name), protocol_(protocol), address_(address),
-        preference_(preference), username_(username), password_(password),
-        type_(type), network_name_(network_name), generation_(generation) {}
-
-  const std::string & name() const { return name_; }
-  void set_name(const std::string & name) { name_ = name; }
-
-  const std::string & protocol() const { return protocol_; }
-  void set_protocol(const std::string & protocol) { protocol_ = protocol; }
-
-  const talk_base::SocketAddress & address() const { return address_; }
-  void set_address(const talk_base::SocketAddress & address) {
-    address_ = address;
-  }
-
-  float preference() const { return preference_; }
-  void set_preference(const float preference) { preference_ = preference; }
-  const std::string preference_str() const {
-    std::ostringstream ost;
-    ost << preference_;
-    return ost.str();
-  }
-  void set_preference_str(const std::string & preference) {
-    std::istringstream ist(preference);
-    ist >> preference_;
-  }
-
-  const std::string & username() const { return username_; }
-  void set_username(const std::string & username) { username_ = username; }
-
-  const std::string & password() const { return password_; }
-  void set_password(const std::string & password) { password_ = password; }
-
-  const std::string & type() const { return type_; }
-  void set_type(const std::string & type) { type_ = type; }
-
-  const std::string & network_name() const { return network_name_; }
-  void set_network_name(const std::string & network_name) {
-    network_name_ = network_name;
-  }
-
-  // Candidates in a new generation replace those in the old generation.
-  uint32 generation() const { return generation_; }
-  void set_generation(uint32 generation) { generation_ = generation; }
-  const std::string generation_str() const {
-    std::ostringstream ost;
-    ost << generation_;
-    return ost.str();
-  }
-  void set_generation_str(const std::string& str) {
-    std::istringstream ist(str);
-    ist >> generation_;
-  }
-
-  // Determines whether this candidate is equivalent to the given one.
-  bool IsEquivalent(const Candidate& c) const {
-    // We ignore the network name, since that is just debug information, and
-    // the preference, since that should be the same if the rest is (and it's
-    // a float so equality checking is always worrisome).
-    return (name_ == c.name_) &&
-           (protocol_ == c.protocol_) &&
-           (address_ == c.address_) &&
-           (username_ == c.username_) &&
-           (password_ == c.password_) &&
-           (type_ == c.type_) &&
-           (generation_ == c.generation_);
-  }
-
-  std::string ToString() const {
-    std::ostringstream ost;
-    ost << "Cand[" << name_ << ":" << type_ << ":" << protocol_ << ":"
-        << network_name_ << ":" << address_.ToString() << ":"
-        << username_ << ":" << password_ << "]";
-    return ost.str();
-  }
-
- private:
-  std::string name_;
-  std::string protocol_;
-  talk_base::SocketAddress address_;
-  float preference_;
-  std::string username_;
-  std::string password_;
-  std::string type_;
-  std::string network_name_;
-  uint32 generation_;
-};
-
-}  // namespace cricket
-
-#endif  // TALK_P2P_BASE_CANDIDATE_H_
diff --git a/third_party/libjingle/source/talk/p2p/base/common.h b/third_party/libjingle/source/talk/p2p/base/common.h
deleted file mode 100644
index 5a38180..0000000
--- a/third_party/libjingle/source/talk/p2p/base/common.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_P2P_BASE_COMMON_H_
-#define TALK_P2P_BASE_COMMON_H_
-
-#include "talk/base/logging.h"
-
-// Common log description format for jingle messages
-#define LOG_J(sev, obj) LOG(sev) << "Jingle:" << obj->ToString() << ": "
-#define LOG_JV(sev, obj) LOG_V(sev) << "Jingle:" << obj->ToString() << ": "
-
-#endif  // TALK_P2P_BASE_COMMON_H_
diff --git a/third_party/libjingle/source/talk/p2p/base/constants.cc b/third_party/libjingle/source/talk/p2p/base/constants.cc
deleted file mode 100644
index 4d65f5b..0000000
--- a/third_party/libjingle/source/talk/p2p/base/constants.cc
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/p2p/base/constants.h"
-
-#include <string>
-
-#include "talk/xmllite/qname.h"
-
-namespace cricket {
-
-const char NS_EMPTY[] = "";
-const char NS_JINGLE[] = "urn:xmpp:jingle:1";
-const char NS_JINGLE_DRAFT[] = "google:jingle";
-const char NS_GINGLE[] = "http://www.google.com/session";
-
-// actions (aka <session> or <jingle>)
-const buzz::StaticQName QN_ACTION = { NS_EMPTY, "action" };
-const char LN_INITIATOR[] = "initiator";
-const buzz::StaticQName QN_INITIATOR = { NS_EMPTY, LN_INITIATOR };
-const buzz::StaticQName QN_CREATOR = { NS_EMPTY, "creator" };
-
-const buzz::StaticQName QN_JINGLE = { NS_JINGLE, "jingle" };
-const buzz::StaticQName QN_JINGLE_CONTENT = { NS_JINGLE, "content" };
-const buzz::StaticQName QN_JINGLE_CONTENT_NAME = { NS_EMPTY, "name" };
-const buzz::StaticQName QN_JINGLE_CONTENT_MEDIA = { NS_EMPTY, "media" };
-const buzz::StaticQName QN_JINGLE_REASON = { NS_JINGLE, "reason" };
-const char JINGLE_CONTENT_MEDIA_AUDIO[] = "audio";
-const char JINGLE_CONTENT_MEDIA_VIDEO[] = "video";
-const char JINGLE_ACTION_SESSION_INITIATE[] = "session-initiate";
-const char JINGLE_ACTION_SESSION_INFO[] = "session-info";
-const char JINGLE_ACTION_SESSION_ACCEPT[] = "session-accept";
-const char JINGLE_ACTION_SESSION_TERMINATE[] = "session-terminate";
-const char JINGLE_ACTION_TRANSPORT_INFO[] = "transport-info";
-const char JINGLE_ACTION_TRANSPORT_ACCEPT[] = "transport-accept";
-const char JINGLE_ACTION_DESCRIPTION_INFO[] = "description-info";
-
-const buzz::StaticQName QN_GINGLE_SESSION = { NS_GINGLE, "session" };
-const char GINGLE_ACTION_INITIATE[] = "initiate";
-const char GINGLE_ACTION_INFO[] = "info";
-const char GINGLE_ACTION_ACCEPT[] = "accept";
-const char GINGLE_ACTION_REJECT[] = "reject";
-const char GINGLE_ACTION_TERMINATE[] = "terminate";
-const char GINGLE_ACTION_CANDIDATES[] = "candidates";
-const char GINGLE_ACTION_UPDATE[] = "update";
-
-const char LN_ERROR[] = "error";
-const buzz::StaticQName QN_GINGLE_REDIRECT = { NS_GINGLE, "redirect" };
-const char STR_REDIRECT_PREFIX[] = "xmpp:";
-
-// Session Contents (aka Gingle <session><description>
-//                   or Jingle <content><description>)
-const char LN_DESCRIPTION[] = "description";
-const char LN_PAYLOADTYPE[] = "payload-type";
-const buzz::StaticQName QN_ID = { NS_EMPTY, "id" };
-const buzz::StaticQName QN_SID = { NS_EMPTY, "sid" };
-const buzz::StaticQName QN_NAME = { NS_EMPTY, "name" };
-const buzz::StaticQName QN_CLOCKRATE = { NS_EMPTY, "clockrate" };
-const buzz::StaticQName QN_BITRATE = { NS_EMPTY, "bitrate" };
-const buzz::StaticQName QN_CHANNELS = { NS_EMPTY, "channels" };
-const buzz::StaticQName QN_WIDTH = { NS_EMPTY, "width" };
-const buzz::StaticQName QN_HEIGHT = { NS_EMPTY, "height" };
-const buzz::StaticQName QN_FRAMERATE = { NS_EMPTY, "framerate" };
-const char LN_NAME[] = "name";
-const char LN_VALUE[] = "value";
-const buzz::StaticQName QN_PAYLOADTYPE_PARAMETER_NAME = { NS_EMPTY, LN_NAME };
-const buzz::StaticQName QN_PAYLOADTYPE_PARAMETER_VALUE = { NS_EMPTY, LN_VALUE };
-const char PAYLOADTYPE_PARAMETER_BITRATE[] = "bitrate";
-const char PAYLOADTYPE_PARAMETER_HEIGHT[] = "height";
-const char PAYLOADTYPE_PARAMETER_WIDTH[] = "width";
-const char PAYLOADTYPE_PARAMETER_FRAMERATE[] = "framerate";
-const char LN_BANDWIDTH[] = "bandwidth";
-
-const char CN_AUDIO[] = "audio";
-const char CN_VIDEO[] = "video";
-const char CN_OTHER[] = "main";
-// other SDP related strings
-const char GN_TOGETHER[] = "TOGETHER";
-
-const char NS_JINGLE_RTP[] = "urn:xmpp:jingle:apps:rtp:1";
-const buzz::StaticQName QN_JINGLE_RTP_CONTENT =
-    { NS_JINGLE_RTP, LN_DESCRIPTION };
-const buzz::StaticQName QN_SSRC = { NS_EMPTY, "ssrc" };
-const buzz::StaticQName QN_JINGLE_RTP_PAYLOADTYPE =
-    { NS_JINGLE_RTP, LN_PAYLOADTYPE };
-const buzz::StaticQName QN_JINGLE_RTP_BANDWIDTH =
-    { NS_JINGLE_RTP, LN_BANDWIDTH };
-const buzz::StaticQName QN_JINGLE_RTCP_MUX = { NS_JINGLE_RTP, "rtcp-mux" };
-const buzz::StaticQName QN_PARAMETER = { NS_JINGLE_RTP, "parameter" };
-
-const char NS_GINGLE_AUDIO[] = "http://www.google.com/session/phone";
-const buzz::StaticQName QN_GINGLE_AUDIO_CONTENT =
-    { NS_GINGLE_AUDIO, LN_DESCRIPTION };
-const buzz::StaticQName QN_GINGLE_AUDIO_PAYLOADTYPE =
-    { NS_GINGLE_AUDIO, LN_PAYLOADTYPE };
-const buzz::StaticQName QN_GINGLE_AUDIO_SRCID = { NS_GINGLE_AUDIO, "src-id" };
-const char NS_GINGLE_VIDEO[] = "http://www.google.com/session/video";
-const buzz::StaticQName QN_GINGLE_VIDEO_CONTENT =
-    { NS_GINGLE_VIDEO, LN_DESCRIPTION };
-const buzz::StaticQName QN_GINGLE_VIDEO_PAYLOADTYPE =
-    { NS_GINGLE_VIDEO, LN_PAYLOADTYPE };
-const buzz::StaticQName QN_GINGLE_VIDEO_SRCID = { NS_GINGLE_VIDEO, "src-id" };
-const buzz::StaticQName QN_GINGLE_VIDEO_BANDWIDTH =
-    { NS_GINGLE_VIDEO, LN_BANDWIDTH };
-
-// Crypto support.
-const buzz::StaticQName QN_ENCRYPTION = { NS_JINGLE_RTP, "encryption" };
-const buzz::StaticQName QN_ENCRYPTION_REQUIRED = { NS_EMPTY, "required" };
-const buzz::StaticQName QN_CRYPTO = { NS_JINGLE_RTP, "crypto" };
-const buzz::StaticQName QN_GINGLE_AUDIO_CRYPTO_USAGE =
-    { NS_GINGLE_AUDIO, "usage" };
-const buzz::StaticQName QN_GINGLE_VIDEO_CRYPTO_USAGE =
-    { NS_GINGLE_VIDEO, "usage" };
-const buzz::StaticQName QN_CRYPTO_SUITE = { NS_EMPTY, "crypto-suite" };
-const buzz::StaticQName QN_CRYPTO_KEY_PARAMS = { NS_EMPTY, "key-params" };
-const buzz::StaticQName QN_CRYPTO_TAG = { NS_EMPTY, "tag" };
-const buzz::StaticQName QN_CRYPTO_SESSION_PARAMS =
-    { NS_EMPTY, "session-params" };
-
-// transports and candidates
-const char LN_TRANSPORT[] = "transport";
-const char LN_CANDIDATE[] = "candidate";
-const buzz::StaticQName QN_UFRAG = { cricket::NS_EMPTY, "ufrag" };
-const buzz::StaticQName QN_PWD = { cricket::NS_EMPTY, "pwd" };
-const buzz::StaticQName QN_COMPONENT = { cricket::NS_EMPTY, "component" };
-const buzz::StaticQName QN_IP = { cricket::NS_EMPTY, "ip" };
-const buzz::StaticQName QN_PORT = { cricket::NS_EMPTY, "port" };
-const buzz::StaticQName QN_NETWORK = { cricket::NS_EMPTY, "network" };
-const buzz::StaticQName QN_GENERATION = { cricket::NS_EMPTY, "generation" };
-const buzz::StaticQName QN_PRIORITY = { cricket::NS_EMPTY, "priority" };
-const buzz::StaticQName QN_PROTOCOL = { cricket::NS_EMPTY, "protocol" };
-const char JINGLE_CANDIDATE_TYPE_PEER_STUN[] = "prflx";
-const char JINGLE_CANDIDATE_TYPE_SERVER_STUN[] = "srflx";
-const char JINGLE_CANDIDATE_NAME_RTP[] = "1";
-const char JINGLE_CANDIDATE_NAME_RTCP[] = "2";
-
-// TODO Once we are full ICE-UDP compliant, use this namespace.
-// For now, just use the same as NS_GINGLE_P2P.
-// const char NS_JINGLE_ICE_UDP[] = "urn:xmpp:jingle:transports:ice-udp:1";
-const char NS_GINGLE_P2P[] = "http://www.google.com/transport/p2p";
-const buzz::StaticQName QN_GINGLE_P2P_TRANSPORT =
-    { NS_GINGLE_P2P, LN_TRANSPORT };
-const buzz::StaticQName QN_GINGLE_P2P_CANDIDATE =
-    { NS_GINGLE_P2P, LN_CANDIDATE };
-const buzz::StaticQName QN_GINGLE_P2P_UNKNOWN_CHANNEL_NAME =
-    { NS_GINGLE_P2P, "unknown-channel-name" };
-const buzz::StaticQName QN_GINGLE_CANDIDATE = { NS_GINGLE, LN_CANDIDATE };
-const buzz::StaticQName QN_ADDRESS = { cricket::NS_EMPTY, "address" };
-const buzz::StaticQName QN_USERNAME = { cricket::NS_EMPTY, "username" };
-const buzz::StaticQName QN_PASSWORD = { cricket::NS_EMPTY, "password" };
-const buzz::StaticQName QN_PREFERENCE = { cricket::NS_EMPTY, "preference" };
-const char GINGLE_CANDIDATE_TYPE_STUN[] = "stun";
-const char GINGLE_CANDIDATE_NAME_RTP[] = "rtp";
-const char GINGLE_CANDIDATE_NAME_RTCP[] = "rtcp";
-const char GINGLE_CANDIDATE_NAME_VIDEO_RTP[] = "video_rtp";
-const char GINGLE_CANDIDATE_NAME_VIDEO_RTCP[] = "video_rtcp";
-
-// terminate reasons and errors
-const char JINGLE_ERROR_BAD_REQUEST[] = "bad-request";
-const char JINGLE_ERROR_OUT_OF_ORDER[] = "out-of-order";
-const char JINGLE_ERROR_UNKNOWN_SESSION[] = "unknown-session";
-
-// Call terminate reasons from XEP-166
-const char STR_TERMINATE_DECLINE[] = "decline";
-const char STR_TERMINATE_SUCCESS[] = "success";
-const char STR_TERMINATE_ERROR[] = "general-error";
-const char STR_TERMINATE_INCOMPATIBLE_PARAMETERS[] = "incompatible-parameters";
-
-// Old terminate reasons used by cricket
-const char STR_TERMINATE_CALL_ENDED[] = "call-ended";
-const char STR_TERMINATE_RECIPIENT_UNAVAILABLE[] = "recipient-unavailable";
-const char STR_TERMINATE_RECIPIENT_BUSY[] = "recipient-busy";
-const char STR_TERMINATE_INSUFFICIENT_FUNDS[] = "insufficient-funds";
-const char STR_TERMINATE_NUMBER_MALFORMED[] = "number-malformed";
-const char STR_TERMINATE_NUMBER_DISALLOWED[] = "number-disallowed";
-const char STR_TERMINATE_PROTOCOL_ERROR[] = "protocol-error";
-const char STR_TERMINATE_INTERNAL_SERVER_ERROR[] = "internal-server-error";
-const char STR_TERMINATE_UNKNOWN_ERROR[] = "unknown-error";
-
-// Draft view and notify messages.
-const char STR_JINGLE_DRAFT_CONTENT_NAME_VIDEO[] = "video";
-const char STR_JINGLE_DRAFT_CONTENT_NAME_AUDIO[] = "audio";
-const buzz::StaticQName QN_NICK = { cricket::NS_EMPTY, "nick" };
-const buzz::StaticQName QN_TYPE = { cricket::NS_EMPTY, "type" };
-const buzz::StaticQName QN_JINGLE_DRAFT_VIEW = { NS_JINGLE_DRAFT, "view" };
-const char STR_JINGLE_DRAFT_VIEW_TYPE_NONE[] = "none";
-const char STR_JINGLE_DRAFT_VIEW_TYPE_STATIC[] = "static";
-const buzz::StaticQName QN_JINGLE_DRAFT_PARAMS = { NS_JINGLE_DRAFT, "params" };
-const buzz::StaticQName QN_JINGLE_DRAFT_STREAMS = { NS_JINGLE_DRAFT, "streams" };
-const buzz::StaticQName QN_JINGLE_DRAFT_STREAM = { NS_JINGLE_DRAFT, "stream" };
-const buzz::StaticQName QN_DISPLAY = { cricket::NS_EMPTY, "display" };
-const buzz::StaticQName QN_CNAME = { cricket::NS_EMPTY, "cname" };
-const buzz::StaticQName QN_JINGLE_DRAFT_SSRC = { NS_JINGLE_DRAFT, "ssrc" };
-const buzz::StaticQName QN_JINGLE_DRAFT_SSRC_GROUP =
-    { NS_JINGLE_DRAFT, "ssrc-group" };
-const buzz::StaticQName QN_SEMANTICS = { cricket::NS_EMPTY, "semantics" };
-const buzz::StaticQName QN_JINGLE_LEGACY_NOTIFY = { NS_JINGLE_DRAFT, "notify" };
-const buzz::StaticQName QN_JINGLE_LEGACY_SOURCE = { NS_JINGLE_DRAFT, "source" };
-
-// old stuff
-#ifdef FEATURE_ENABLE_VOICEMAIL
-const char NS_VOICEMAIL[] = "http://www.google.com/session/voicemail";
-const buzz::StaticQName QN_VOICEMAIL_REGARDING = { NS_VOICEMAIL, "regarding" };
-#endif
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/p2p/base/constants.h b/third_party/libjingle/source/talk/p2p/base/constants.h
deleted file mode 100644
index 0c84dd6..0000000
--- a/third_party/libjingle/source/talk/p2p/base/constants.h
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_P2P_BASE_CONSTANTS_H_
-#define TALK_P2P_BASE_CONSTANTS_H_
-
-#include <string>
-#include "talk/xmllite/qname.h"
-
-// This file contains constants related to signaling that are used in various
-// classes in this directory.
-
-namespace cricket {
-
-// NS_ == namespace
-// QN_ == buzz::QName (namespace + name)
-// LN_ == "local name" == QName::LocalPart()
-//   these are useful when you need to find a tag
-//   that has different namespaces (like <description> or <transport>)
-
-extern const char NS_EMPTY[];
-extern const char NS_JINGLE[];
-extern const char NS_JINGLE_DRAFT[];
-extern const char NS_GINGLE[];
-
-enum SignalingProtocol {
-  PROTOCOL_JINGLE,
-  PROTOCOL_GINGLE,
-  PROTOCOL_HYBRID,
-};
-
-// actions (aka Gingle <session> or Jingle <jingle>)
-extern const buzz::StaticQName QN_ACTION;
-extern const char LN_INITIATOR[];
-extern const buzz::StaticQName QN_INITIATOR;
-extern const buzz::StaticQName QN_CREATOR;
-
-extern const buzz::StaticQName QN_JINGLE;
-extern const buzz::StaticQName QN_JINGLE_CONTENT;
-extern const buzz::StaticQName QN_JINGLE_CONTENT_NAME;
-extern const buzz::StaticQName QN_JINGLE_CONTENT_MEDIA;
-extern const buzz::StaticQName QN_JINGLE_REASON;
-extern const char JINGLE_CONTENT_MEDIA_AUDIO[];
-extern const char JINGLE_CONTENT_MEDIA_VIDEO[];
-extern const char JINGLE_ACTION_SESSION_INITIATE[];
-extern const char JINGLE_ACTION_SESSION_INFO[];
-extern const char JINGLE_ACTION_SESSION_ACCEPT[];
-extern const char JINGLE_ACTION_SESSION_TERMINATE[];
-extern const char JINGLE_ACTION_TRANSPORT_INFO[];
-extern const char JINGLE_ACTION_TRANSPORT_ACCEPT[];
-extern const char JINGLE_ACTION_DESCRIPTION_INFO[];
-
-extern const buzz::StaticQName QN_GINGLE_SESSION;
-extern const char GINGLE_ACTION_INITIATE[];
-extern const char GINGLE_ACTION_INFO[];
-extern const char GINGLE_ACTION_ACCEPT[];
-extern const char GINGLE_ACTION_REJECT[];
-extern const char GINGLE_ACTION_TERMINATE[];
-extern const char GINGLE_ACTION_CANDIDATES[];
-extern const char GINGLE_ACTION_UPDATE[];
-
-extern const char LN_ERROR[];
-extern const buzz::StaticQName QN_GINGLE_REDIRECT;
-extern const char STR_REDIRECT_PREFIX[];
-
-// Session Contents (aka Gingle <session><description>
-//                   or Jingle <content><description>)
-extern const char LN_DESCRIPTION[];
-extern const char LN_PAYLOADTYPE[];
-extern const buzz::StaticQName QN_ID;
-extern const buzz::StaticQName QN_SID;
-extern const buzz::StaticQName QN_NAME;
-extern const buzz::StaticQName QN_CLOCKRATE;
-extern const buzz::StaticQName QN_BITRATE;
-extern const buzz::StaticQName QN_CHANNELS;
-extern const buzz::StaticQName QN_PARAMETER;
-extern const char LN_NAME[];
-extern const char LN_VALUE[];
-extern const buzz::StaticQName QN_PAYLOADTYPE_PARAMETER_NAME;
-extern const buzz::StaticQName QN_PAYLOADTYPE_PARAMETER_VALUE;
-extern const char PAYLOADTYPE_PARAMETER_BITRATE[];
-extern const char PAYLOADTYPE_PARAMETER_HEIGHT[];
-extern const char PAYLOADTYPE_PARAMETER_WIDTH[];
-extern const char PAYLOADTYPE_PARAMETER_FRAMERATE[];
-extern const char LN_BANDWIDTH[];
-
-// CN_ == "content name".  When we initiate a session, we choose the
-// name, and when we receive a Gingle session, we provide default
-// names (since Gingle has no content names).  But when we receive a
-// Jingle call, the content name can be anything, so don't rely on
-// these values being the same as the ones received.
-extern const char CN_AUDIO[];
-extern const char CN_VIDEO[];
-extern const char CN_OTHER[];
-// other SDP related strings
-// GN stands for group name
-extern const char GN_TOGETHER[];
-
-extern const char NS_JINGLE_RTP[];
-extern const buzz::StaticQName QN_JINGLE_RTP_CONTENT;
-extern const buzz::StaticQName QN_SSRC;
-extern const buzz::StaticQName QN_JINGLE_RTP_PAYLOADTYPE;
-extern const buzz::StaticQName QN_JINGLE_RTP_BANDWIDTH;
-extern const buzz::StaticQName QN_JINGLE_RTCP_MUX;
-
-extern const char NS_GINGLE_AUDIO[];
-extern const buzz::StaticQName QN_GINGLE_AUDIO_CONTENT;
-extern const buzz::StaticQName QN_GINGLE_AUDIO_PAYLOADTYPE;
-extern const buzz::StaticQName QN_GINGLE_AUDIO_SRCID;
-extern const char NS_GINGLE_VIDEO[];
-extern const buzz::StaticQName QN_GINGLE_VIDEO_CONTENT;
-extern const buzz::StaticQName QN_GINGLE_VIDEO_PAYLOADTYPE;
-extern const buzz::StaticQName QN_GINGLE_VIDEO_SRCID;
-extern const buzz::StaticQName QN_GINGLE_VIDEO_BANDWIDTH;
-
-// Crypto support.
-extern const buzz::StaticQName QN_ENCRYPTION;
-extern const buzz::StaticQName QN_ENCRYPTION_REQUIRED;
-extern const buzz::StaticQName QN_CRYPTO;
-extern const buzz::StaticQName QN_GINGLE_AUDIO_CRYPTO_USAGE;
-extern const buzz::StaticQName QN_GINGLE_VIDEO_CRYPTO_USAGE;
-extern const buzz::StaticQName QN_CRYPTO_SUITE;
-extern const buzz::StaticQName QN_CRYPTO_KEY_PARAMS;
-extern const buzz::StaticQName QN_CRYPTO_TAG;
-extern const buzz::StaticQName QN_CRYPTO_SESSION_PARAMS;
-
-// transports and candidates
-extern const char LN_TRANSPORT[];
-extern const char LN_CANDIDATE[];
-extern const buzz::StaticQName QN_JINGLE_P2P_TRANSPORT;
-extern const buzz::StaticQName QN_JINGLE_P2P_CANDIDATE;
-extern const buzz::StaticQName QN_UFRAG;
-extern const buzz::StaticQName QN_COMPONENT;
-extern const buzz::StaticQName QN_PWD;
-extern const buzz::StaticQName QN_IP;
-extern const buzz::StaticQName QN_PORT;
-extern const buzz::StaticQName QN_NETWORK;
-extern const buzz::StaticQName QN_GENERATION;
-extern const buzz::StaticQName QN_PRIORITY;
-extern const buzz::StaticQName QN_PROTOCOL;
-extern const char JINGLE_CANDIDATE_TYPE_PEER_STUN[];
-extern const char JINGLE_CANDIDATE_TYPE_SERVER_STUN[];
-extern const char JINGLE_CANDIDATE_NAME_RTP[];
-extern const char JINGLE_CANDIDATE_NAME_RTCP[];
-
-extern const char NS_GINGLE_P2P[];
-extern const buzz::StaticQName QN_GINGLE_P2P_TRANSPORT;
-extern const buzz::StaticQName QN_GINGLE_P2P_CANDIDATE;
-extern const buzz::StaticQName QN_GINGLE_P2P_UNKNOWN_CHANNEL_NAME;
-extern const buzz::StaticQName QN_GINGLE_CANDIDATE;
-extern const buzz::StaticQName QN_ADDRESS;
-extern const buzz::StaticQName QN_USERNAME;
-extern const buzz::StaticQName QN_PASSWORD;
-extern const buzz::StaticQName QN_PREFERENCE;
-extern const char GINGLE_CANDIDATE_TYPE_STUN[];
-extern const char GINGLE_CANDIDATE_NAME_RTP[];
-extern const char GINGLE_CANDIDATE_NAME_RTCP[];
-extern const char GINGLE_CANDIDATE_NAME_VIDEO_RTP[];
-extern const char GINGLE_CANDIDATE_NAME_VIDEO_RTCP[];
-
-extern const char NS_GINGLE_RAW[];
-extern const buzz::StaticQName QN_GINGLE_RAW_TRANSPORT;
-extern const buzz::StaticQName QN_GINGLE_RAW_CHANNEL;
-
-// terminate reasons and errors: see http://xmpp.org/extensions/xep-0166.html
-extern const char JINGLE_ERROR_BAD_REQUEST[];  // like parse error
-// got transport-info before session-initiate, for example
-extern const char JINGLE_ERROR_OUT_OF_ORDER[];
-extern const char JINGLE_ERROR_UNKNOWN_SESSION[];
-
-// Call terminate reasons from XEP-166
-extern const char STR_TERMINATE_DECLINE[];  // polite reject
-extern const char STR_TERMINATE_SUCCESS[];  // polite hangup
-extern const char STR_TERMINATE_ERROR[];  // something bad happened
-extern const char STR_TERMINATE_INCOMPATIBLE_PARAMETERS[];  // no codecs?
-
-// Old terminate reasons used by cricket
-extern const char STR_TERMINATE_CALL_ENDED[];
-extern const char STR_TERMINATE_RECIPIENT_UNAVAILABLE[];
-extern const char STR_TERMINATE_RECIPIENT_BUSY[];
-extern const char STR_TERMINATE_INSUFFICIENT_FUNDS[];
-extern const char STR_TERMINATE_NUMBER_MALFORMED[];
-extern const char STR_TERMINATE_NUMBER_DISALLOWED[];
-extern const char STR_TERMINATE_PROTOCOL_ERROR[];
-extern const char STR_TERMINATE_INTERNAL_SERVER_ERROR[];
-extern const char STR_TERMINATE_UNKNOWN_ERROR[];
-
-// Draft view and notify messages.
-extern const char STR_JINGLE_DRAFT_CONTENT_NAME_VIDEO[];
-extern const char STR_JINGLE_DRAFT_CONTENT_NAME_AUDIO[];
-extern const buzz::StaticQName QN_NICK;
-extern const buzz::StaticQName QN_TYPE;
-extern const buzz::StaticQName QN_JINGLE_DRAFT_VIEW;
-extern const char STR_JINGLE_DRAFT_VIEW_TYPE_NONE[];
-extern const char STR_JINGLE_DRAFT_VIEW_TYPE_STATIC[];
-extern const buzz::StaticQName QN_JINGLE_DRAFT_PARAMS;
-extern const buzz::StaticQName QN_WIDTH;
-extern const buzz::StaticQName QN_HEIGHT;
-extern const buzz::StaticQName QN_FRAMERATE;
-extern const buzz::StaticQName QN_JINGLE_DRAFT_STREAM;
-extern const buzz::StaticQName QN_JINGLE_DRAFT_STREAMS;
-extern const buzz::StaticQName QN_DISPLAY;
-extern const buzz::StaticQName QN_CNAME;
-extern const buzz::StaticQName QN_JINGLE_DRAFT_SSRC;
-extern const buzz::StaticQName QN_JINGLE_DRAFT_SSRC_GROUP;
-extern const buzz::StaticQName QN_SEMANTICS;
-extern const buzz::StaticQName QN_JINGLE_LEGACY_NOTIFY;
-extern const buzz::StaticQName QN_JINGLE_LEGACY_SOURCE;
-
-// old stuff
-#ifdef FEATURE_ENABLE_VOICEMAIL
-extern const char NS_VOICEMAIL[];
-extern const buzz::StaticQName QN_VOICEMAIL_REGARDING;
-#endif
-
-}  // namespace cricket
-
-#endif  // TALK_P2P_BASE_CONSTANTS_H_
diff --git a/third_party/libjingle/source/talk/p2p/base/fakesession.h b/third_party/libjingle/source/talk/p2p/base/fakesession.h
deleted file mode 100644
index 1928613..0000000
--- a/third_party/libjingle/source/talk/p2p/base/fakesession.h
+++ /dev/null
@@ -1,233 +0,0 @@
-// libjingle
-// Copyright 2009 Google Inc.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-//  1. Redistributions of source code must retain the above copyright notice,
-//     this list of conditions and the following disclaimer.
-//  2. Redistributions in binary form must reproduce the above copyright notice,
-//     this list of conditions and the following disclaimer in the documentation
-//     and/or other materials provided with the distribution.
-//  3. The name of the author may not be used to endorse or promote products
-//     derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef TALK_SESSION_PHONE_FAKESESSION_H_
-#define TALK_SESSION_PHONE_FAKESESSION_H_
-
-#include <map>
-#include <string>
-
-#include "talk/p2p/base/session.h"
-#include "talk/p2p/base/transport.h"
-#include "talk/p2p/base/transportchannel.h"
-#include "talk/p2p/base/transportchannelimpl.h"
-
-namespace cricket {
-
-class FakeTransport;
-
-// Fake transport channel class, which can be passed to anything that needs a
-// transport channel. Can be informed of another FakeTransportChannel via
-// SetDestination.
-class FakeTransportChannel : public TransportChannelImpl {
- public:
-  explicit FakeTransportChannel(Transport* transport,
-                                const std::string& name,
-                                const std::string& session_type)
-      : TransportChannelImpl(name, session_type),
-        transport_(transport),
-        dest_(NULL),
-        state_(STATE_INIT) {
-  }
-  ~FakeTransportChannel() {
-    Reset();
-  }
-
-  virtual Transport* GetTransport() {
-    return transport_;
-  }
-  virtual void Connect() {
-    if (state_ == STATE_INIT) {
-      state_ = STATE_CONNECTING;
-    }
-  }
-  virtual void Reset() {
-    if (state_ != STATE_INIT) {
-      state_ = STATE_INIT;
-      if (dest_) {
-        dest_->state_ = STATE_INIT;
-        dest_->dest_ = NULL;
-        dest_ = NULL;
-      }
-    }
-  }
-
-  void SetDestination(FakeTransportChannel* dest) {
-    if (state_ == STATE_CONNECTING && dest) {
-      // This simulates the delivery of candidates.
-      dest_ = dest;
-      dest_->dest_ = this;
-      state_ = STATE_CONNECTED;
-      dest_->state_ = STATE_CONNECTED;
-      set_writable(true);
-      dest_->set_writable(true);
-    } else if (state_ == STATE_CONNECTED && !dest) {
-      // Simulates loss of connectivity, by asymmetrically forgetting dest_.
-      dest_ = NULL;
-      state_ = STATE_CONNECTING;
-      set_writable(false);
-    }
-  }
-
-  virtual int SendPacket(const char *data, size_t len) {
-    if (state_ != STATE_CONNECTED) {
-      return -1;
-    }
-    dest_->SignalReadPacket(dest_, data, len);
-    return len;
-  }
-  virtual int SetOption(talk_base::Socket::Option opt, int value) {
-    return true;
-  }
-  virtual int GetError() {
-    return 0;
-  }
-
-  virtual void OnSignalingReady() {
-  }
-  virtual void OnCandidate(const Candidate& candidate) {
-  }
-
- private:
-  enum State { STATE_INIT, STATE_CONNECTING, STATE_CONNECTED };
-  Transport* transport_;
-  FakeTransportChannel* dest_;
-  State state_;
-};
-
-// Fake transport class, which can be passed to anything that needs a Transport.
-// Can be informed of another FakeTransport via SetDestination (low-tech way
-// of doing candidates)
-class FakeTransport : public Transport {
- public:
-  typedef std::map<std::string, FakeTransportChannel*> ChannelMap;
-  FakeTransport(talk_base::Thread* signaling_thread,
-                talk_base::Thread* worker_thread)
-      : Transport(signaling_thread, worker_thread, "test", NULL),
-        dest_(NULL) {
-  }
-  ~FakeTransport() {
-    DestroyAllChannels();
-  }
-
-  const ChannelMap& channels() const { return channels_; }
-
-  void SetDestination(FakeTransport* dest) {
-    dest_ = dest;
-    for (ChannelMap::iterator it = channels_.begin(); it != channels_.end();
-         ++it) {
-      SetChannelDestination(it->first, it->second);
-    }
-  }
-
- protected:
-  virtual TransportChannelImpl* CreateTransportChannel(
-      const std::string& name, const std::string& session_type) {
-    if (channels_.find(name) != channels_.end()) {
-      return NULL;
-    }
-    FakeTransportChannel* channel =
-        new FakeTransportChannel(this, name, session_type);
-    SetChannelDestination(name, channel);
-    channels_[name] = channel;
-    return channel;
-  }
-  virtual void DestroyTransportChannel(TransportChannelImpl* channel) {
-    channels_.erase(channel->name());
-    delete channel;
-  }
-
- private:
-  void SetChannelDestination(const std::string& name,
-                             FakeTransportChannel* channel) {
-    FakeTransportChannel* dest_channel = NULL;
-    if (dest_) {
-      dest_channel =
-          static_cast<FakeTransportChannel*>(dest_->GetChannel(name));
-    }
-    channel->SetDestination(dest_channel);
-  }
-
-  ChannelMap channels_;
-  FakeTransport* dest_;
-};
-
-// Fake session class, which can be passed into a BaseChannel object for
-// test purposes. Can be connected to other FakeSessions via Connect().
-class FakeSession : public BaseSession {
- public:
-  FakeSession()
-      : BaseSession(talk_base::Thread::Current(),
-                    talk_base::Thread::Current(),
-                    NULL, "", "", true),
-        fail_create_channel_(false) {
-  }
-
-  FakeTransport* GetTransport(const std::string& content_name) {
-    return static_cast<FakeTransport*>(
-        BaseSession::GetTransport(content_name));
-  }
-
-  void Connect(FakeSession* dest) {
-    // Simulate the exchange of candidates.
-    CompleteNegotiation();
-    dest->CompleteNegotiation();
-    for (TransportMap::const_iterator it = transport_proxies().begin();
-        it != transport_proxies().end(); ++it) {
-      static_cast<FakeTransport*>(it->second->impl())->SetDestination(
-          dest->GetTransport(it->first));
-    }
-  }
-
-  virtual cricket::TransportChannel* CreateChannel(
-      const std::string& content_name, const std::string& name) {
-    if (fail_create_channel_) {
-      return NULL;
-    }
-    return BaseSession::CreateChannel(content_name, name);
-  }
-
-  void set_fail_channel_creation(bool fail_channel_creation) {
-    fail_create_channel_ = fail_channel_creation;
-  }
-
- protected:
-  virtual Transport* CreateTransport() {
-    return new FakeTransport(signaling_thread(), worker_thread());
-  }
-  void CompleteNegotiation() {
-    for (TransportMap::const_iterator it = transport_proxies().begin();
-        it != transport_proxies().end(); ++it) {
-      it->second->CompleteNegotiation();
-    }
-  }
-
- private:
-  bool fail_create_channel_;
-};
-
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_FAKESESSION_H_
diff --git a/third_party/libjingle/source/talk/p2p/base/p2ptransport.cc b/third_party/libjingle/source/talk/p2p/base/p2ptransport.cc
deleted file mode 100644
index 5f55ef9..0000000
--- a/third_party/libjingle/source/talk/p2p/base/p2ptransport.cc
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/p2p/base/p2ptransport.h"
-
-#include <string>
-#include <vector>
-
-#include "talk/base/base64.h"
-#include "talk/base/common.h"
-#include "talk/base/stringencode.h"
-#include "talk/base/stringutils.h"
-#include "talk/p2p/base/constants.h"
-#include "talk/p2p/base/p2ptransportchannel.h"
-#include "talk/p2p/base/parsing.h"
-#include "talk/p2p/base/sessionmanager.h"
-#include "talk/p2p/base/sessionmessages.h"
-#include "talk/xmllite/qname.h"
-#include "talk/xmllite/xmlelement.h"
-#include "talk/xmpp/constants.h"
-
-namespace {
-
-// We only allow usernames to be this many characters or fewer.
-const size_t kMaxUsernameSize = 16;
-
-}  // namespace
-
-namespace cricket {
-
-P2PTransport::P2PTransport(talk_base::Thread* signaling_thread,
-                           talk_base::Thread* worker_thread,
-                           PortAllocator* allocator)
-    : Transport(signaling_thread, worker_thread,
-                NS_GINGLE_P2P, allocator) {
-}
-
-P2PTransport::~P2PTransport() {
-  DestroyAllChannels();
-}
-
-void P2PTransport::OnTransportError(const buzz::XmlElement* error) {
-  // Need to know if it was <unknown-channel name="xxx">.
-  ASSERT(error->Name().Namespace() == type());
-  if ((error->Name() == QN_GINGLE_P2P_UNKNOWN_CHANNEL_NAME)
-      && error->HasAttr(buzz::QN_NAME)) {
-    std::string channel_name = error->Attr(buzz::QN_NAME);
-    if (HasChannel(channel_name)) {
-      SignalChannelGone(this, channel_name);
-    }
-  }
-}
-
-
-bool P2PTransportParser::ParseCandidates(SignalingProtocol protocol,
-                                         const buzz::XmlElement* elem,
-                                         Candidates* candidates,
-                                         ParseError* error) {
-  // TODO: Once we implement standard ICE-UDP, parse the
-  // candidates according to XEP-176.
-  for (const buzz::XmlElement* candidate_elem = elem->FirstElement();
-       candidate_elem != NULL;
-       candidate_elem = candidate_elem->NextElement()) {
-    // Only look at local part because it might be <session><candidate>
-    //                                          or <tranport><candidate>.
-    if (candidate_elem->Name().LocalPart() == LN_CANDIDATE) {
-      Candidate candidate;
-      if (!ParseCandidate(candidate_elem, &candidate, error))
-        return false;
-      candidates->push_back(candidate);
-    }
-  }
-  return true;
-}
-
-bool P2PTransportParser::ParseCandidate(const buzz::XmlElement* elem,
-                                        Candidate* candidate,
-                                        ParseError* error) {
-  if (!elem->HasAttr(buzz::QN_NAME) ||
-      !elem->HasAttr(QN_ADDRESS) ||
-      !elem->HasAttr(QN_PORT) ||
-      !elem->HasAttr(QN_USERNAME) ||
-      !elem->HasAttr(QN_PREFERENCE) ||
-      !elem->HasAttr(QN_PROTOCOL) ||
-      !elem->HasAttr(QN_GENERATION)) {
-    return BadParse("candidate missing required attribute", error);
-  }
-
-  talk_base::SocketAddress address;
-  if (!ParseAddress(elem, QN_ADDRESS, QN_PORT, &address, error))
-    return false;
-
-  candidate->set_name(elem->Attr(buzz::QN_NAME));
-  candidate->set_address(address);
-  candidate->set_username(elem->Attr(QN_USERNAME));
-  candidate->set_preference_str(elem->Attr(QN_PREFERENCE));
-  candidate->set_protocol(elem->Attr(QN_PROTOCOL));
-  candidate->set_generation_str(elem->Attr(QN_GENERATION));
-  if (elem->HasAttr(QN_PASSWORD))
-    candidate->set_password(elem->Attr(QN_PASSWORD));
-  if (elem->HasAttr(buzz::QN_TYPE))
-    candidate->set_type(elem->Attr(buzz::QN_TYPE));
-  if (elem->HasAttr(QN_NETWORK))
-    candidate->set_network_name(elem->Attr(QN_NETWORK));
-
-  if (!VerifyUsernameFormat(candidate->username(), error))
-    return false;
-
-  return true;
-}
-
-bool P2PTransportParser::VerifyUsernameFormat(const std::string& username,
-                                              ParseError* error) {
-  if (username.size() > kMaxUsernameSize)
-    return BadParse("candidate username is too long", error);
-  if (!talk_base::Base64::IsBase64Encoded(username))
-    return BadParse(
-        "candidate username has non-base64 encoded characters", error);
-  return true;
-}
-
-static const buzz::StaticQName& GetCandidateQName(SignalingProtocol protocol) {
-  if (protocol == PROTOCOL_GINGLE) {
-    return QN_GINGLE_CANDIDATE;
-  } else {
-    // TODO: Once we implement standard ICE-UDP, use the
-    // XEP-176 namespace.
-    return QN_GINGLE_P2P_CANDIDATE;
-  }
-}
-
-bool P2PTransportParser::WriteCandidates(SignalingProtocol protocol,
-                                         const Candidates& candidates,
-                                         XmlElements* candidate_elems,
-                                         WriteError* error) {
-  // TODO: Once we implement standard ICE-UDP, parse the
-  // candidates according to XEP-176.
-  for (std::vector<Candidate>::const_iterator iter = candidates.begin();
-       iter != candidates.end(); ++iter) {
-    buzz::XmlElement* cand_elem =
-        new buzz::XmlElement(GetCandidateQName(protocol));
-    if (!WriteCandidate(*iter, cand_elem, error))
-      return false;
-    candidate_elems->push_back(cand_elem);
-  }
-  return true;
-}
-
-bool P2PTransportParser::WriteCandidate(const Candidate& candidate,
-                                        buzz::XmlElement* elem,
-                                        WriteError* error) {
-  elem->SetAttr(buzz::QN_NAME, candidate.name());
-  elem->SetAttr(QN_ADDRESS, candidate.address().IPAsString());
-  elem->SetAttr(QN_PORT, candidate.address().PortAsString());
-  elem->SetAttr(QN_PREFERENCE, candidate.preference_str());
-  elem->SetAttr(QN_USERNAME, candidate.username());
-  elem->SetAttr(QN_PROTOCOL, candidate.protocol());
-  elem->SetAttr(QN_GENERATION, candidate.generation_str());
-  if (candidate.password().size() > 0)
-    elem->SetAttr(QN_PASSWORD, candidate.password());
-  if (candidate.type().size() > 0)
-    elem->SetAttr(buzz::QN_TYPE, candidate.type());
-  if (candidate.network_name().size() > 0)
-    elem->SetAttr(QN_NETWORK, candidate.network_name());
-  return true;
-}
-
-TransportChannelImpl* P2PTransport::CreateTransportChannel(
-    const std::string& name, const std::string& content_type) {
-  return new P2PTransportChannel(name, content_type, this, port_allocator());
-}
-
-void P2PTransport::DestroyTransportChannel(TransportChannelImpl* channel) {
-  delete channel;
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/p2p/base/p2ptransport.h b/third_party/libjingle/source/talk/p2p/base/p2ptransport.h
deleted file mode 100644
index 084f487..0000000
--- a/third_party/libjingle/source/talk/p2p/base/p2ptransport.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_P2P_BASE_P2PTRANSPORT_H_
-#define TALK_P2P_BASE_P2PTRANSPORT_H_
-
-#include <string>
-#include <vector>
-#include "talk/p2p/base/transport.h"
-
-namespace cricket {
-
-class P2PTransport: public Transport {
- public:
-  P2PTransport(talk_base::Thread* signaling_thread,
-               talk_base::Thread* worker_thread,
-               PortAllocator* allocator);
-  virtual ~P2PTransport();
-
-  virtual void OnTransportError(const buzz::XmlElement* error);
-
- protected:
-  // Creates and destroys P2PTransportChannel.
-  virtual TransportChannelImpl* CreateTransportChannel(
-      const std::string& name, const std::string& content_type);
-  virtual void DestroyTransportChannel(TransportChannelImpl* channel);
-
-  friend class P2PTransportChannel;
-
-  DISALLOW_EVIL_CONSTRUCTORS(P2PTransport);
-};
-
-class P2PTransportParser : public TransportParser {
- public:
-  P2PTransportParser() {}
-  virtual bool ParseCandidates(SignalingProtocol protocol,
-                               const buzz::XmlElement* elem,
-                               Candidates* candidates,
-                               ParseError* error);
-  virtual bool WriteCandidates(SignalingProtocol protocol,
-                               const Candidates& candidates,
-                               XmlElements* candidate_elems,
-                               WriteError* error);
- private:
-  bool ParseCandidate(const buzz::XmlElement* elem,
-                      Candidate* candidate,
-                      ParseError* error);
-  bool WriteCandidate(const Candidate& candidate,
-                      buzz::XmlElement* elem,
-                      WriteError* error);
-  bool VerifyUsernameFormat(const std::string& username,
-                            ParseError* error);
-
-  DISALLOW_EVIL_CONSTRUCTORS(P2PTransportParser);
-};
-
-}  // namespace cricket
-
-#endif  // TALK_P2P_BASE_P2PTRANSPORT_H_
diff --git a/third_party/libjingle/source/talk/p2p/base/p2ptransportchannel.cc b/third_party/libjingle/source/talk/p2p/base/p2ptransportchannel.cc
deleted file mode 100644
index 17f52a7..0000000
--- a/third_party/libjingle/source/talk/p2p/base/p2ptransportchannel.cc
+++ /dev/null
@@ -1,941 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/p2p/base/p2ptransportchannel.h"
-
-#include <set>
-#include "talk/base/common.h"
-#include "talk/base/logging.h"
-#include "talk/p2p/base/common.h"
-
-namespace {
-
-// messages for queuing up work for ourselves
-const uint32 MSG_SORT = 1;
-const uint32 MSG_PING = 2;
-const uint32 MSG_ALLOCATE = 3;
-
-// When the socket is unwritable, we will use 10 Kbps (ignoring IP+UDP headers)
-// for pinging.  When the socket is writable, we will use only 1 Kbps because
-// we don't want to degrade the quality on a modem.  These numbers should work
-// well on a 28.8K modem, which is the slowest connection on which the voice
-// quality is reasonable at all.
-static const uint32 PING_PACKET_SIZE = 60 * 8;
-static const uint32 WRITABLE_DELAY = 1000 * PING_PACKET_SIZE / 1000;  // 480ms
-static const uint32 UNWRITABLE_DELAY = 1000 * PING_PACKET_SIZE / 10000;  // 50ms
-
-// If there is a current writable connection, then we will also try hard to
-// make sure it is pinged at this rate.
-static const uint32 MAX_CURRENT_WRITABLE_DELAY = 900;  // 2*WRITABLE_DELAY - bit
-
-// The minimum improvement in RTT that justifies a switch.
-static const double kMinImprovement = 10;
-
-// Amount of time that we wait when *losing* writability before we try doing
-// another allocation.
-static const int kAllocateDelay = 1 * 1000;  // 1 second
-
-// We will try creating a new allocator from scratch after a delay of this
-// length without becoming writable (or timing out).
-static const int kAllocatePeriod = 20 * 1000;  // 20 seconds
-
-cricket::Port::CandidateOrigin GetOrigin(cricket::Port* port,
-                                         cricket::Port* origin_port) {
-  if (!origin_port)
-    return cricket::Port::ORIGIN_MESSAGE;
-  else if (port == origin_port)
-    return cricket::Port::ORIGIN_THIS_PORT;
-  else
-    return cricket::Port::ORIGIN_OTHER_PORT;
-}
-
-// Compares two connections based only on static information about them.
-int CompareConnectionCandidates(cricket::Connection* a,
-                                cricket::Connection* b) {
-  // Combine local and remote preferences
-  ASSERT(a->local_candidate().preference() == a->port()->preference());
-  ASSERT(b->local_candidate().preference() == b->port()->preference());
-  double a_pref = a->local_candidate().preference()
-                * a->remote_candidate().preference();
-  double b_pref = b->local_candidate().preference()
-                * b->remote_candidate().preference();
-
-  // Now check combined preferences. Lower values get sorted last.
-  if (a_pref > b_pref)
-    return 1;
-  if (a_pref < b_pref)
-    return -1;
-
-  // If we're still tied at this point, prefer a younger generation.
-  return (a->remote_candidate().generation() + a->port()->generation()) -
-         (b->remote_candidate().generation() + b->port()->generation());
-}
-
-// Compare two connections based on their writability and static preferences.
-int CompareConnections(cricket::Connection *a, cricket::Connection *b) {
-  // Sort based on write-state.  Better states have lower values.
-  if (a->write_state() < b->write_state())
-    return 1;
-  if (a->write_state() > b->write_state())
-    return -1;
-
-  // Compare the candidate information.
-  return CompareConnectionCandidates(a, b);
-}
-
-// Wraps the comparison connection into a less than operator that puts higher
-// priority writable connections first.
-class ConnectionCompare {
- public:
-  bool operator()(const cricket::Connection *ca,
-                  const cricket::Connection *cb) {
-    cricket::Connection* a = const_cast<cricket::Connection*>(ca);
-    cricket::Connection* b = const_cast<cricket::Connection*>(cb);
-
-    // Compare first on writability and static preferences.
-    int cmp = CompareConnections(a, b);
-    if (cmp > 0)
-      return true;
-    if (cmp < 0)
-      return false;
-
-    // Otherwise, sort based on latency estimate.
-    return a->rtt() < b->rtt();
-
-    // Should we bother checking for the last connection that last received
-    // data? It would help rendezvous on the connection that is also receiving
-    // packets.
-    //
-    // TODO: Yes we should definitely do this.  The TCP protocol gains
-    // efficiency by being used bidirectionally, as opposed to two separate
-    // unidirectional streams.  This test should probably occur before
-    // comparison of local prefs (assuming combined prefs are the same).  We
-    // need to be careful though, not to bounce back and forth with both sides
-    // trying to rendevous with the other.
-  }
-};
-
-// Determines whether we should switch between two connections, based first on
-// static preferences and then (if those are equal) on latency estimates.
-bool ShouldSwitch(cricket::Connection* a_conn, cricket::Connection* b_conn) {
-  if (a_conn == b_conn)
-    return false;
-
-  if (!a_conn || !b_conn)  // don't think the latter should happen
-    return true;
-
-  int prefs_cmp = CompareConnections(a_conn, b_conn);
-  if (prefs_cmp < 0)
-    return true;
-  if (prefs_cmp > 0)
-    return false;
-
-  return b_conn->rtt() <= a_conn->rtt() + kMinImprovement;
-}
-
-}  // unnamed namespace
-
-namespace cricket {
-
-P2PTransportChannel::P2PTransportChannel(const std::string &name,
-                                         const std::string &content_type,
-                                         P2PTransport* transport,
-                                         PortAllocator *allocator) :
-    TransportChannelImpl(name, content_type),
-    transport_(transport),
-    allocator_(allocator),
-    worker_thread_(talk_base::Thread::Current()),
-    incoming_only_(false),
-    waiting_for_signaling_(false),
-    error_(0),
-    best_connection_(NULL),
-    pinging_started_(false),
-    sort_dirty_(false),
-    was_writable_(false),
-    was_timed_out_(true) {
-}
-
-P2PTransportChannel::~P2PTransportChannel() {
-  ASSERT(worker_thread_ == talk_base::Thread::Current());
-
-  for (uint32 i = 0; i < allocator_sessions_.size(); ++i)
-    delete allocator_sessions_[i];
-}
-
-// Add the allocator session to our list so that we know which sessions
-// are still active.
-void P2PTransportChannel::AddAllocatorSession(PortAllocatorSession* session) {
-  session->set_generation(static_cast<uint32>(allocator_sessions_.size()));
-  allocator_sessions_.push_back(session);
-
-  // We now only want to apply new candidates that we receive to the ports
-  // created by this new session because these are replacing those of the
-  // previous sessions.
-  ports_.clear();
-
-  session->SignalPortReady.connect(this, &P2PTransportChannel::OnPortReady);
-  session->SignalCandidatesReady.connect(
-      this, &P2PTransportChannel::OnCandidatesReady);
-  session->GetInitialPorts();
-  if (pinging_started_)
-    session->StartGetAllPorts();
-}
-
-// Go into the state of processing candidates, and running in general
-void P2PTransportChannel::Connect() {
-  ASSERT(worker_thread_ == talk_base::Thread::Current());
-
-  // Kick off an allocator session
-  Allocate();
-
-  // Start pinging as the ports come in.
-  thread()->Post(this, MSG_PING);
-}
-
-// Reset the socket, clear up any previous allocations and start over
-void P2PTransportChannel::Reset() {
-  ASSERT(worker_thread_ == talk_base::Thread::Current());
-
-  // Get rid of all the old allocators.  This should clean up everything.
-  for (uint32 i = 0; i < allocator_sessions_.size(); ++i)
-    delete allocator_sessions_[i];
-
-  allocator_sessions_.clear();
-  ports_.clear();
-  connections_.clear();
-  best_connection_ = NULL;
-
-  // Forget about all of the candidates we got before.
-  remote_candidates_.clear();
-
-  // Revert to the initial state.
-  set_readable(false);
-  set_writable(false);
-
-  // Reinitialize the rest of our state.
-  waiting_for_signaling_ = false;
-  pinging_started_ = false;
-  sort_dirty_ = false;
-  was_writable_ = false;
-  was_timed_out_ = true;
-
-  // If we allocated before, start a new one now.
-  if (transport_->connect_requested())
-    Allocate();
-
-  // Start pinging as the ports come in.
-  thread()->Clear(this);
-  thread()->Post(this, MSG_PING);
-}
-
-// A new port is available, attempt to make connections for it
-void P2PTransportChannel::OnPortReady(PortAllocatorSession *session,
-                                      Port* port) {
-  ASSERT(worker_thread_ == talk_base::Thread::Current());
-
-  // Set in-effect options on the new port
-  for (OptionMap::const_iterator it = options_.begin();
-       it != options_.end();
-       ++it) {
-    int val = port->SetOption(it->first, it->second);
-    if (val < 0) {
-      LOG_J(LS_WARNING, port) << "SetOption(" << it->first
-                              << ", " << it->second
-                              << ") failed: " << port->GetError();
-    }
-  }
-
-  // Remember the ports and candidates, and signal that candidates are ready.
-  // The session will handle this, and send an initiate/accept/modify message
-  // if one is pending.
-
-  ports_.push_back(port);
-  port->SignalUnknownAddress.connect(
-      this, &P2PTransportChannel::OnUnknownAddress);
-  port->SignalDestroyed.connect(this, &P2PTransportChannel::OnPortDestroyed);
-
-  // Attempt to create a connection from this new port to all of the remote
-  // candidates that we were given so far.
-
-  std::vector<RemoteCandidate>::iterator iter;
-  for (iter = remote_candidates_.begin(); iter != remote_candidates_.end();
-       ++iter) {
-    CreateConnection(port, *iter, iter->origin_port(), false);
-  }
-
-  SortConnections();
-}
-
-// A new candidate is available, let listeners know
-void P2PTransportChannel::OnCandidatesReady(
-    PortAllocatorSession *session, const std::vector<Candidate>& candidates) {
-  for (size_t i = 0; i < candidates.size(); ++i) {
-    SignalCandidateReady(this, candidates[i]);
-  }
-}
-
-// Handle stun packets
-void P2PTransportChannel::OnUnknownAddress(
-    Port *port, const talk_base::SocketAddress &address, StunMessage *stun_msg,
-    const std::string &remote_username) {
-  ASSERT(worker_thread_ == talk_base::Thread::Current());
-
-  // Port has received a valid stun packet from an address that no Connection
-  // is currently available for. See if the remote user name is in the remote
-  // candidate list. If it isn't return error to the stun request.
-
-  const Candidate *candidate = NULL;
-  std::vector<RemoteCandidate>::iterator it;
-  for (it = remote_candidates_.begin(); it != remote_candidates_.end(); ++it) {
-    if ((*it).username() == remote_username) {
-      candidate = &(*it);
-      break;
-    }
-  }
-  if (candidate == NULL) {
-    // Don't know about this username, the request is bogus
-    // This sometimes happens if a binding response comes in before the ACCEPT
-    // message.  It is totally valid; the retry state machine will try again.
-
-    port->SendBindingErrorResponse(stun_msg, address,
-        STUN_ERROR_STALE_CREDENTIALS, STUN_ERROR_REASON_STALE_CREDENTIALS);
-    delete stun_msg;
-    return;
-  }
-
-  // Check for connectivity to this address. Create connections
-  // to this address across all local ports. First, add this as a new remote
-  // address
-
-  Candidate new_remote_candidate = *candidate;
-  new_remote_candidate.set_address(address);
-  // new_remote_candidate.set_protocol(port->protocol());
-
-  // This remote username exists. Now create connections using this candidate,
-  // and resort
-
-  if (CreateConnections(new_remote_candidate, port, true)) {
-    // Send the pinger a successful stun response.
-    port->SendBindingResponse(stun_msg, address);
-
-    // Update the list of connections since we just added another.  We do this
-    // after sending the response since it could (in principle) delete the
-    // connection in question.
-    SortConnections();
-  } else {
-    // Hopefully this won't occur, because changing a destination address
-    // shouldn't cause a new connection to fail
-    ASSERT(false);
-    port->SendBindingErrorResponse(stun_msg, address, STUN_ERROR_SERVER_ERROR,
-        STUN_ERROR_REASON_SERVER_ERROR);
-  }
-
-  delete stun_msg;
-}
-
-void P2PTransportChannel::OnCandidate(const Candidate& candidate) {
-  ASSERT(worker_thread_ == talk_base::Thread::Current());
-
-  // Create connections to this remote candidate.
-  CreateConnections(candidate, NULL, false);
-
-  // Resort the connections list, which may have new elements.
-  SortConnections();
-}
-
-// Creates connections from all of the ports that we care about to the given
-// remote candidate.  The return value is true if we created a connection from
-// the origin port.
-bool P2PTransportChannel::CreateConnections(const Candidate &remote_candidate,
-                                            Port* origin_port,
-                                            bool readable) {
-  ASSERT(worker_thread_ == talk_base::Thread::Current());
-
-  // Add a new connection for this candidate to every port that allows such a
-  // connection (i.e., if they have compatible protocols) and that does not
-  // already have a connection to an equivalent candidate.  We must be careful
-  // to make sure that the origin port is included, even if it was pruned,
-  // since that may be the only port that can create this connection.
-
-  bool created = false;
-
-  std::vector<Port *>::reverse_iterator it;
-  for (it = ports_.rbegin(); it != ports_.rend(); ++it) {
-    if (CreateConnection(*it, remote_candidate, origin_port, readable)) {
-      if (*it == origin_port)
-        created = true;
-    }
-  }
-
-  if ((origin_port != NULL) &&
-      std::find(ports_.begin(), ports_.end(), origin_port) == ports_.end()) {
-    if (CreateConnection(origin_port, remote_candidate, origin_port, readable))
-      created = true;
-  }
-
-  // Remember this remote candidate so that we can add it to future ports.
-  RememberRemoteCandidate(remote_candidate, origin_port);
-
-  return created;
-}
-
-// Setup a connection object for the local and remote candidate combination.
-// And then listen to connection object for changes.
-bool P2PTransportChannel::CreateConnection(Port* port,
-                                           const Candidate& remote_candidate,
-                                           Port* origin_port,
-                                           bool readable) {
-  // Look for an existing connection with this remote address.  If one is not
-  // found, then we can create a new connection for this address.
-  Connection* connection = port->GetConnection(remote_candidate.address());
-  if (connection != NULL) {
-    // It is not legal to try to change any of the parameters of an existing
-    // connection; however, the other side can send a duplicate candidate.
-    if (!remote_candidate.IsEquivalent(connection->remote_candidate())) {
-      LOG(INFO) << "Attempt to change a remote candidate";
-      return false;
-    }
-  } else {
-    Port::CandidateOrigin origin = GetOrigin(port, origin_port);
-
-    // Don't create connection if this is a candidate we received in a
-    // message and we are not allowed to make outgoing connections.
-    if (origin == cricket::Port::ORIGIN_MESSAGE && incoming_only_)
-      return false;
-
-    connection = port->CreateConnection(remote_candidate, origin);
-    if (!connection)
-      return false;
-
-    connections_.push_back(connection);
-    connection->SignalReadPacket.connect(
-        this, &P2PTransportChannel::OnReadPacket);
-    connection->SignalStateChange.connect(
-        this, &P2PTransportChannel::OnConnectionStateChange);
-    connection->SignalDestroyed.connect(
-        this, &P2PTransportChannel::OnConnectionDestroyed);
-
-    LOG_J(LS_INFO, this) << "Created connection with origin=" << origin << ", ("
-                         << connections_.size() << " total)";
-  }
-
-  // If we are readable, it is because we are creating this in response to a
-  // ping from the other side.  This will cause the state to become readable.
-  if (readable)
-    connection->ReceivedPing();
-
-  return true;
-}
-
-// Maintain our remote candidate list, adding this new remote one.
-void P2PTransportChannel::RememberRemoteCandidate(
-    const Candidate& remote_candidate, Port* origin_port) {
-  // Remove any candidates whose generation is older than this one.  The
-  // presence of a new generation indicates that the old ones are not useful.
-  uint32 i = 0;
-  while (i < remote_candidates_.size()) {
-    if (remote_candidates_[i].generation() < remote_candidate.generation()) {
-      LOG(INFO) << "Pruning candidate from old generation: "
-                << remote_candidates_[i].address().ToString();
-      remote_candidates_.erase(remote_candidates_.begin() + i);
-    } else {
-      i += 1;
-    }
-  }
-
-  // Make sure this candidate is not a duplicate.
-  for (uint32 i = 0; i < remote_candidates_.size(); ++i) {
-    if (remote_candidates_[i].IsEquivalent(remote_candidate)) {
-      LOG(INFO) << "Duplicate candidate: "
-                << remote_candidate.address().ToString();
-      return;
-    }
-  }
-
-  // Try this candidate for all future ports.
-  remote_candidates_.push_back(RemoteCandidate(remote_candidate, origin_port));
-
-  // We have some candidates from the other side, we are now serious about
-  // this connection.  Let's do the StartGetAllPorts thing.
-  if (!pinging_started_) {
-    pinging_started_ = true;
-    for (size_t i = 0; i < allocator_sessions_.size(); ++i) {
-      if (!allocator_sessions_[i]->IsGettingAllPorts())
-        allocator_sessions_[i]->StartGetAllPorts();
-    }
-  }
-}
-
-// Send data to the other side, using our best connection
-int P2PTransportChannel::SendPacket(const char *data, size_t len) {
-  // This can get called on any thread that is convenient to write from!
-  if (best_connection_ == NULL) {
-    error_ = EWOULDBLOCK;
-    return SOCKET_ERROR;
-  }
-  int sent = best_connection_->Send(data, len);
-  if (sent <= 0) {
-    ASSERT(sent < 0);
-    error_ = best_connection_->GetError();
-  }
-  return sent;
-}
-
-// Begin allocate (or immediately re-allocate, if MSG_ALLOCATE pending)
-void P2PTransportChannel::Allocate() {
-  CancelPendingAllocate();
-  // Time for a new allocator, lets make sure we have a signalling channel
-  // to communicate candidates through first.
-  waiting_for_signaling_ = true;
-  SignalRequestSignaling();
-}
-
-// Cancels the pending allocate, if any.
-void P2PTransportChannel::CancelPendingAllocate() {
-  thread()->Clear(this, MSG_ALLOCATE);
-}
-
-// Monitor connection states
-void P2PTransportChannel::UpdateConnectionStates() {
-  uint32 now = talk_base::Time();
-
-  // We need to copy the list of connections since some may delete themselves
-  // when we call UpdateState.
-  for (uint32 i = 0; i < connections_.size(); ++i)
-    connections_[i]->UpdateState(now);
-}
-
-// Prepare for best candidate sorting
-void P2PTransportChannel::RequestSort() {
-  if (!sort_dirty_) {
-    worker_thread_->Post(this, MSG_SORT);
-    sort_dirty_ = true;
-  }
-}
-
-// Sort the available connections to find the best one.  We also monitor
-// the number of available connections and the current state so that we
-// can possibly kick off more allocators (for more connections).
-void P2PTransportChannel::SortConnections() {
-  ASSERT(worker_thread_ == talk_base::Thread::Current());
-
-  // Make sure the connection states are up-to-date since this affects how they
-  // will be sorted.
-  UpdateConnectionStates();
-
-  // Any changes after this point will require a re-sort.
-  sort_dirty_ = false;
-
-  // Get a list of the networks that we are using.
-  std::set<talk_base::Network*> networks;
-  for (uint32 i = 0; i < connections_.size(); ++i)
-    networks.insert(connections_[i]->port()->network());
-
-  // Find the best alternative connection by sorting.  It is important to note
-  // that amongst equal preference, writable connections, this will choose the
-  // one whose estimated latency is lowest.  So it is the only one that we
-  // need to consider switching to.
-
-  ConnectionCompare cmp;
-  std::stable_sort(connections_.begin(), connections_.end(), cmp);
-  LOG(LS_VERBOSE) << "Sorting available connections:";
-  for (uint32 i = 0; i < connections_.size(); ++i) {
-    LOG(LS_VERBOSE) << connections_[i]->ToString();
-  }
-
-  Connection* top_connection = NULL;
-  if (connections_.size() > 0)
-    top_connection = connections_[0];
-
-  // If necessary, switch to the new choice.
-  if (ShouldSwitch(best_connection_, top_connection))
-    SwitchBestConnectionTo(top_connection);
-
-  // We can prune any connection for which there is a writable connection on
-  // the same network with better or equal prefences.  We leave those with
-  // better preference just in case they become writable later (at which point,
-  // we would prune out the current best connection).  We leave connections on
-  // other networks because they may not be using the same resources and they
-  // may represent very distinct paths over which we can switch.
-  std::set<talk_base::Network*>::iterator network;
-  for (network = networks.begin(); network != networks.end(); ++network) {
-    Connection* primier = GetBestConnectionOnNetwork(*network);
-    if (!primier || (primier->write_state() != Connection::STATE_WRITABLE))
-      continue;
-
-    for (uint32 i = 0; i < connections_.size(); ++i) {
-      if ((connections_[i] != primier) &&
-          (connections_[i]->port()->network() == *network) &&
-          (CompareConnectionCandidates(primier, connections_[i]) >= 0)) {
-        connections_[i]->Prune();
-      }
-    }
-  }
-
-  // Count the number of connections in the various states.
-
-  int writable = 0;
-  int write_connect = 0;
-  int write_timeout = 0;
-
-  for (uint32 i = 0; i < connections_.size(); ++i) {
-    switch (connections_[i]->write_state()) {
-    case Connection::STATE_WRITABLE:
-      ++writable;
-      break;
-    case Connection::STATE_WRITE_CONNECT:
-      ++write_connect;
-      break;
-    case Connection::STATE_WRITE_TIMEOUT:
-      ++write_timeout;
-      break;
-    default:
-      ASSERT(false);
-    }
-  }
-
-  if (writable > 0) {
-    HandleWritable();
-  } else if (write_connect > 0) {
-    HandleNotWritable();
-  } else {
-    HandleAllTimedOut();
-  }
-
-  // Update the state of this channel.  This method is called whenever the
-  // state of any connection changes, so this is a good place to do this.
-  UpdateChannelState();
-
-  // Notify of connection state change
-  SignalConnectionMonitor(this);
-}
-
-// Track the best connection, and let listeners know
-void P2PTransportChannel::SwitchBestConnectionTo(Connection* conn) {
-  // Note: if conn is NULL, the previous best_connection_ has been destroyed,
-  // so don't use it.
-  // use it.
-  Connection* old_best_connection = best_connection_;
-  best_connection_ = conn;
-  if (best_connection_) {
-    if (old_best_connection) {
-      LOG_J(LS_INFO, this) << "Previous best connection: "
-                           << old_best_connection->ToString();
-    }
-    LOG_J(LS_INFO, this) << "New best connection: "
-                         << best_connection_->ToString();
-    SignalRouteChange(this, best_connection_->remote_candidate());
-  } else {
-    LOG_J(LS_INFO, this) << "No best connection";
-  }
-}
-
-void P2PTransportChannel::UpdateChannelState() {
-  // The Handle* functions already set the writable state.  We'll just double-
-  // check it here.
-  bool writable = ((best_connection_ != NULL)  &&
-      (best_connection_->write_state() ==
-      Connection::STATE_WRITABLE));
-  ASSERT(writable == this->writable());
-  if (writable != this->writable())
-    LOG(LS_ERROR) << "UpdateChannelState: writable state mismatch";
-
-  bool readable = false;
-  for (uint32 i = 0; i < connections_.size(); ++i) {
-    if (connections_[i]->read_state() == Connection::STATE_READABLE)
-      readable = true;
-  }
-  set_readable(readable);
-}
-
-// We checked the status of our connections and we had at least one that
-// was writable, go into the writable state.
-void P2PTransportChannel::HandleWritable() {
-  //
-  // One or more connections writable!
-  //
-  if (!writable()) {
-    for (uint32 i = 0; i < allocator_sessions_.size(); ++i) {
-      if (allocator_sessions_[i]->IsGettingAllPorts()) {
-        allocator_sessions_[i]->StopGetAllPorts();
-      }
-    }
-
-    // Stop further allocations.
-    CancelPendingAllocate();
-  }
-
-  // We're writable, obviously we aren't timed out
-  was_writable_ = true;
-  was_timed_out_ = false;
-  set_writable(true);
-}
-
-// We checked the status of our connections and we didn't have any that
-// were writable, go into the connecting state (kick off a new allocator
-// session).
-void P2PTransportChannel::HandleNotWritable() {
-  //
-  // No connections are writable but not timed out!
-  //
-  if (was_writable_) {
-    // If we were writable, let's kick off an allocator session immediately
-    was_writable_ = false;
-    Allocate();
-  }
-
-  // We were connecting, obviously not ALL timed out.
-  was_timed_out_ = false;
-  set_writable(false);
-}
-
-// We checked the status of our connections and not only weren't they writable
-// but they were also timed out, we really need a new allocator.
-void P2PTransportChannel::HandleAllTimedOut() {
-  //
-  // No connections... all are timed out!
-  //
-  if (!was_timed_out_) {
-    // We weren't timed out before, so kick off an allocator now (we'll still
-    // be in the fully timed out state until the allocator actually gives back
-    // new ports)
-    Allocate();
-  }
-
-  // NOTE: we start was_timed_out_ in the true state so that we don't get
-  // another allocator created WHILE we are in the process of building up
-  // our first allocator.
-  was_timed_out_ = true;
-  was_writable_ = false;
-  set_writable(false);
-}
-
-// If we have a best connection, return it, otherwise return top one in the
-// list (later we will mark it best).
-Connection* P2PTransportChannel::GetBestConnectionOnNetwork(
-    talk_base::Network* network) {
-  // If the best connection is on this network, then it wins.
-  if (best_connection_ && (best_connection_->port()->network() == network))
-    return best_connection_;
-
-  // Otherwise, we return the top-most in sorted order.
-  for (uint32 i = 0; i < connections_.size(); ++i) {
-    if (connections_[i]->port()->network() == network)
-      return connections_[i];
-  }
-
-  return NULL;
-}
-
-// Handle any queued up requests
-void P2PTransportChannel::OnMessage(talk_base::Message *pmsg) {
-  if (pmsg->message_id == MSG_SORT)
-    OnSort();
-  else if (pmsg->message_id == MSG_PING)
-    OnPing();
-  else if (pmsg->message_id == MSG_ALLOCATE)
-    Allocate();
-  else
-    ASSERT(false);
-}
-
-// Handle queued up sort request
-void P2PTransportChannel::OnSort() {
-  // Resort the connections based on the new statistics.
-  SortConnections();
-}
-
-// Handle queued up ping request
-void P2PTransportChannel::OnPing() {
-  // Make sure the states of the connections are up-to-date (since this affects
-  // which ones are pingable).
-  UpdateConnectionStates();
-
-  // Find the oldest pingable connection and have it do a ping.
-  Connection* conn = FindNextPingableConnection();
-  if (conn)
-    conn->Ping(talk_base::Time());
-
-  // Post ourselves a message to perform the next ping.
-  uint32 delay = writable() ? WRITABLE_DELAY : UNWRITABLE_DELAY;
-  thread()->PostDelayed(delay, this, MSG_PING);
-}
-
-// Is the connection in a state for us to even consider pinging the other side?
-bool P2PTransportChannel::IsPingable(Connection* conn) {
-  // An unconnected connection cannot be written to at all, so pinging is out
-  // of the question.
-  if (!conn->connected())
-    return false;
-
-  if (writable()) {
-    // If we are writable, then we only want to ping connections that could be
-    // better than this one, i.e., the ones that were not pruned.
-    return (conn->write_state() != Connection::STATE_WRITE_TIMEOUT);
-  } else {
-    // If we are not writable, then we need to try everything that might work.
-    // This includes both connections that do not have write timeout as well as
-    // ones that do not have read timeout.  A connection could be readable but
-    // be in write-timeout if we pruned it before.  Since the other side is
-    // still pinging it, it very well might still work.
-    return (conn->write_state() != Connection::STATE_WRITE_TIMEOUT) ||
-           (conn->read_state() != Connection::STATE_READ_TIMEOUT);
-  }
-}
-
-// Returns the next pingable connection to ping.  This will be the oldest
-// pingable connection unless we have a writable connection that is past the
-// maximum acceptable ping delay.
-Connection* P2PTransportChannel::FindNextPingableConnection() {
-  uint32 now = talk_base::Time();
-  if (best_connection_ &&
-      (best_connection_->write_state() == Connection::STATE_WRITABLE) &&
-      (best_connection_->last_ping_sent()
-       + MAX_CURRENT_WRITABLE_DELAY <= now)) {
-    return best_connection_;
-  }
-
-  Connection* oldest_conn = NULL;
-  uint32 oldest_time = 0xFFFFFFFF;
-  for (uint32 i = 0; i < connections_.size(); ++i) {
-    if (IsPingable(connections_[i])) {
-      if (connections_[i]->last_ping_sent() < oldest_time) {
-        oldest_time = connections_[i]->last_ping_sent();
-        oldest_conn = connections_[i];
-      }
-    }
-  }
-  return oldest_conn;
-}
-
-// return the number of "pingable" connections
-uint32 P2PTransportChannel::NumPingableConnections() {
-  uint32 count = 0;
-  for (uint32 i = 0; i < connections_.size(); ++i) {
-    if (IsPingable(connections_[i]))
-      count += 1;
-  }
-  return count;
-}
-
-// When a connection's state changes, we need to figure out who to use as
-// the best connection again.  It could have become usable, or become unusable.
-void P2PTransportChannel::OnConnectionStateChange(Connection *connection) {
-  ASSERT(worker_thread_ == talk_base::Thread::Current());
-
-  // We have to unroll the stack before doing this because we may be changing
-  // the state of connections while sorting.
-  RequestSort();
-}
-
-// When a connection is removed, edit it out, and then update our best
-// connection.
-void P2PTransportChannel::OnConnectionDestroyed(Connection *connection) {
-  ASSERT(worker_thread_ == talk_base::Thread::Current());
-
-  // Note: the previous best_connection_ may be destroyed by now, so don't
-  // use it.
-
-  // Remove this connection from the list.
-  std::vector<Connection*>::iterator iter =
-      std::find(connections_.begin(), connections_.end(), connection);
-  ASSERT(iter != connections_.end());
-  connections_.erase(iter);
-
-  LOG_J(LS_INFO, this) << "Removed connection ("
-    << static_cast<int>(connections_.size()) << " remaining)";
-
-  // If this is currently the best connection, then we need to pick a new one.
-  // The call to SortConnections will pick a new one.  It looks at the current
-  // best connection in order to avoid switching between fairly similar ones.
-  // Since this connection is no longer an option, we can just set best to NULL
-  // and re-choose a best assuming that there was no best connection.
-  if (best_connection_ == connection) {
-    SwitchBestConnectionTo(NULL);
-    RequestSort();
-  }
-}
-
-// When a port is destroyed remove it from our list of ports to use for
-// connection attempts.
-void P2PTransportChannel::OnPortDestroyed(Port* port) {
-  ASSERT(worker_thread_ == talk_base::Thread::Current());
-
-  // Remove this port from the list (if we didn't drop it already).
-  std::vector<Port*>::iterator iter =
-      std::find(ports_.begin(), ports_.end(), port);
-  if (iter != ports_.end())
-    ports_.erase(iter);
-
-  LOG(INFO) << "Removed port from p2p socket: "
-            << static_cast<int>(ports_.size()) << " remaining";
-}
-
-// We data is available, let listeners know
-void P2PTransportChannel::OnReadPacket(Connection *connection,
-                                       const char *data, size_t len) {
-  ASSERT(worker_thread_ == talk_base::Thread::Current());
-
-  // Let the client know of an incoming packet
-
-  SignalReadPacket(this, data, len);
-}
-
-// Set options on ourselves is simply setting options on all of our available
-// port objects.
-int P2PTransportChannel::SetOption(talk_base::Socket::Option opt, int value) {
-  OptionMap::iterator it = options_.find(opt);
-  if (it == options_.end()) {
-    options_.insert(std::make_pair(opt, value));
-  } else if (it->second == value) {
-    return 0;
-  } else {
-    it->second = value;
-  }
-
-  for (uint32 i = 0; i < ports_.size(); ++i) {
-    int val = ports_[i]->SetOption(opt, value);
-    if (val < 0) {
-      // Because this also occurs deferred, probably no point in reporting an
-      // error
-      LOG(WARNING) << "SetOption(" << opt << ", " << value << ") failed: "
-                   << ports_[i]->GetError();
-    }
-  }
-  return 0;
-}
-
-// When the signalling channel is ready, we can really kick off the allocator
-void P2PTransportChannel::OnSignalingReady() {
-  if (waiting_for_signaling_) {
-    waiting_for_signaling_ = false;
-    AddAllocatorSession(allocator_->CreateSession(name(), content_type()));
-    thread()->PostDelayed(kAllocatePeriod, this, MSG_ALLOCATE);
-  }
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/p2p/base/p2ptransportchannel.h b/third_party/libjingle/source/talk/p2p/base/p2ptransportchannel.h
deleted file mode 100644
index 0083d23..0000000
--- a/third_party/libjingle/source/talk/p2p/base/p2ptransportchannel.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// P2PTransportChannel wraps up the state management of the connection between
-// two P2P clients.  Clients have candidate ports for connecting, and
-// connections which are combinations of candidates from each end (Alice and
-// Bob each have candidates, one candidate from Alice and one candidate from
-// Bob are used to make a connection, repeat to make many connections).
-//
-// When all of the available connections become invalid (non-writable), we
-// kick off a process of determining more candidates and more connections.
-//
-#ifndef TALK_P2P_BASE_P2PTRANSPORTCHANNEL_H_
-#define TALK_P2P_BASE_P2PTRANSPORTCHANNEL_H_
-
-#include <map>
-#include <vector>
-#include <string>
-#include "talk/base/sigslot.h"
-#include "talk/p2p/base/candidate.h"
-#include "talk/p2p/base/port.h"
-#include "talk/p2p/base/portallocator.h"
-#include "talk/p2p/base/transport.h"
-#include "talk/p2p/base/transportchannelimpl.h"
-#include "talk/p2p/base/p2ptransport.h"
-
-namespace cricket {
-
-// Adds the port on which the candidate originated.
-class RemoteCandidate : public Candidate {
- public:
-  RemoteCandidate(const Candidate& c, Port* origin_port)
-    : Candidate(c), origin_port_(origin_port) {}
-
-  Port* origin_port() { return origin_port_; }
-
- private:
-  Port* origin_port_;
-};
-
-// P2PTransportChannel manages the candidates and connection process to keep
-// two P2P clients connected to each other.
-class P2PTransportChannel : public TransportChannelImpl,
-    public talk_base::MessageHandler {
- public:
-  P2PTransportChannel(const std::string &name,
-                      const std::string &content_type,
-                      P2PTransport* transport,
-                      PortAllocator *allocator);
-  virtual ~P2PTransportChannel();
-
-  // From TransportChannelImpl:
-  virtual Transport* GetTransport() { return transport_; }
-  virtual void Connect();
-  virtual void Reset();
-  virtual void OnSignalingReady();
-
-  // From TransportChannel:
-  virtual int SendPacket(const char *data, size_t len);
-  virtual int SetOption(talk_base::Socket::Option opt, int value);
-  virtual int GetError() { return error_; }
-
-  // This hack is here to allow the SocketMonitor to downcast to the
-  // P2PTransportChannel safely.
-  virtual P2PTransportChannel* GetP2PChannel() { return this; }
-
-  // These are used by the connection monitor.
-  sigslot::signal1<P2PTransportChannel*> SignalConnectionMonitor;
-  const std::vector<Connection *>& connections() const { return connections_; }
-  Connection* best_connection() const { return best_connection_; }
-
-  void set_incoming_only(bool value) { incoming_only_ = value; }
-
-  // Handler for internal messages.
-  virtual void OnMessage(talk_base::Message *pmsg);
-
-  virtual void OnCandidate(const Candidate& candidate);
-
- private:
-  void Allocate();
-  void CancelPendingAllocate();
-  void UpdateConnectionStates();
-  void RequestSort();
-  void SortConnections();
-  void SwitchBestConnectionTo(Connection* conn);
-  void UpdateChannelState();
-  void HandleWritable();
-  void HandleNotWritable();
-  void HandleAllTimedOut();
-  Connection* GetBestConnectionOnNetwork(talk_base::Network* network);
-  bool CreateConnections(const Candidate &remote_candidate, Port* origin_port,
-                         bool readable);
-  bool CreateConnection(Port* port, const Candidate& remote_candidate,
-                        Port* origin_port, bool readable);
-  void RememberRemoteCandidate(const Candidate& remote_candidate,
-                               Port* origin_port);
-  void OnUnknownAddress(Port *port, const talk_base::SocketAddress &addr,
-                        StunMessage *stun_msg,
-                        const std::string &remote_username);
-  void OnPortReady(PortAllocatorSession *session, Port* port);
-  void OnCandidatesReady(PortAllocatorSession *session,
-                         const std::vector<Candidate>& candidates);
-  void OnConnectionStateChange(Connection *connection);
-  void OnConnectionDestroyed(Connection *connection);
-  void OnPortDestroyed(Port* port);
-  void OnReadPacket(Connection *connection, const char *data, size_t len);
-  void OnSort();
-  void OnPing();
-  bool IsPingable(Connection* conn);
-  Connection* FindNextPingableConnection();
-  uint32 NumPingableConnections();
-  PortAllocatorSession* allocator_session() {
-    return allocator_sessions_.back();
-  }
-  void AddAllocatorSession(PortAllocatorSession* session);
-
-  talk_base::Thread* thread() const { return worker_thread_; }
-
-  P2PTransport* transport_;
-  PortAllocator *allocator_;
-  talk_base::Thread *worker_thread_;
-  bool incoming_only_;
-  bool waiting_for_signaling_;
-  int error_;
-  std::vector<PortAllocatorSession*> allocator_sessions_;
-  std::vector<Port *> ports_;
-  std::vector<Connection *> connections_;
-  Connection *best_connection_;
-  std::vector<RemoteCandidate> remote_candidates_;
-  // indicates whether StartGetAllCandidates has been called
-  bool pinging_started_;
-  bool sort_dirty_;  // indicates whether another sort is needed right now
-  bool was_writable_;
-  bool was_timed_out_;
-  typedef std::map<talk_base::Socket::Option, int> OptionMap;
-  OptionMap options_;
-
-  DISALLOW_EVIL_CONSTRUCTORS(P2PTransportChannel);
-};
-
-}  // namespace cricket
-
-#endif  // TALK_P2P_BASE_P2PTRANSPORTCHANNEL_H_
diff --git a/third_party/libjingle/source/talk/p2p/base/p2ptransportchannel_unittest.cc b/third_party/libjingle/source/talk/p2p/base/p2ptransportchannel_unittest.cc
deleted file mode 100644
index ae5ab62..0000000
--- a/third_party/libjingle/source/talk/p2p/base/p2ptransportchannel_unittest.cc
+++ /dev/null
@@ -1,659 +0,0 @@
-/*
- * libjingle
- * Copyright 2009 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/fakenetwork.h"
-#include "talk/base/firewallsocketserver.h"
-#include "talk/base/gunit.h"
-#include "talk/base/helpers.h"
-#include "talk/base/logging.h"
-#include "talk/base/natserver.h"
-#include "talk/base/natsocketfactory.h"
-#include "talk/base/physicalsocketserver.h"
-#include "talk/base/proxyserver.h"
-#include "talk/base/socketaddress.h"
-#include "talk/base/thread.h"
-#include "talk/base/virtualsocketserver.h"
-#include "talk/p2p/base/p2ptransportchannel.h"
-#include "talk/p2p/base/testrelayserver.h"
-#include "talk/p2p/base/teststunserver.h"
-#include "talk/p2p/client/basicportallocator.h"
-
-using talk_base::SocketAddress;
-
-static const int kDefaultTimeout = 1000;
-static const int kOnlyLocalPorts = cricket::PORTALLOCATOR_DISABLE_STUN |
-                                   cricket::PORTALLOCATOR_DISABLE_RELAY |
-                                   cricket::PORTALLOCATOR_DISABLE_TCP;
-// Addresses on the public internet.
-static const SocketAddress kPublicAddrs[2] =
-    { SocketAddress("11.11.11.11", 0), SocketAddress("22.22.22.22", 0) };
-// For configuring multihomed clients.
-static const SocketAddress kAlternateAddrs[2] =
-    { SocketAddress("11.11.11.101", 0), SocketAddress("22.22.22.202", 0) };
-// Addresses for HTTP proxy servers.
-static const SocketAddress kHttpsProxyAddrs[2] =
-    { SocketAddress("11.11.11.1", 443), SocketAddress("22.22.22.1", 443) };
-// Addresses for SOCKS proxy servers.
-static const SocketAddress kSocksProxyAddrs[2] =
-    { SocketAddress("11.11.11.1", 1080), SocketAddress("22.22.22.1", 1080) };
-// Internal addresses for NAT boxes.
-static const SocketAddress kNatAddrs[2] =
-    { SocketAddress("192.168.1.1", 0), SocketAddress("192.168.2.1", 0) };
-// Private addresses inside the NAT private networks.
-static const SocketAddress kPrivateAddrs[2] =
-    { SocketAddress("192.168.1.11", 0), SocketAddress("192.168.2.22", 0) };
-// For cascaded NATs, the internal addresses of the inner NAT boxes.
-static const SocketAddress kCascadedNatAddrs[2] =
-    { SocketAddress("192.168.10.1", 0), SocketAddress("192.168.20.1", 0) };
-// For cascaded NATs, private addresses inside the inner private networks.
-static const SocketAddress kCascadedPrivateAddrs[2] =
-    { SocketAddress("192.168.10.11", 0), SocketAddress("192.168.20.22", 0) };
-// The address of the public STUN server.
-static const SocketAddress kStunAddr("99.99.99.1", cricket::STUN_SERVER_PORT);
-// The addresses for the public relay server.
-static const SocketAddress kRelayUdpIntAddr("99.99.99.2", 5000);
-static const SocketAddress kRelayUdpExtAddr("99.99.99.3", 5001);
-static const SocketAddress kRelayTcpIntAddr("99.99.99.2", 5002);
-static const SocketAddress kRelayTcpExtAddr("99.99.99.3", 5003);
-static const SocketAddress kRelaySslTcpIntAddr("99.99.99.2", 5004);
-static const SocketAddress kRelaySslTcpExtAddr("99.99.99.3", 5005);
-
-// This test simulates 2 P2P endpoints that want to establish connectivity
-// with each other over various network topologies and conditions, which can be
-// specified in each individial test.
-// A virtual network (via VirtualSocketServer) along with virtual firewalls and
-// NATs (via Firewall/NATSocketServer) are used to simulate the various network
-// conditions. We can configure the IP addresses of the endpoints,
-// block various types of connectivity, or add arbitrary levels of NAT.
-// We also run a STUN server and a relay server on the virtual network to allow
-// our typical P2P mechanisms to do their thing.
-// For each case, we expect the P2P stack to eventually settle on a specific
-// form of connectivity to the other side. The test checks that the P2P
-// negotiation successfully establishes connectivity within a certain time,
-// and that the result is what we expect.
-// Note that this class is a base class for use by other tests, who will provide
-// specialized test behavior.
-class P2PTransportChannelTestBase : public testing::Test,
-                                    public sigslot::has_slots<> {
- public:
-  P2PTransportChannelTestBase()
-      : main_(talk_base::Thread::Current()),
-        pss_(new talk_base::PhysicalSocketServer),
-        vss_(new talk_base::VirtualSocketServer(pss_.get())),
-        nss_(new talk_base::NATSocketServer(vss_.get())),
-        ss_(new talk_base::FirewallSocketServer(nss_.get())),
-        ss_scope_(ss_.get()),
-        stun_server_(main_, kStunAddr),
-        relay_server_(main_, kRelayUdpIntAddr, kRelayUdpExtAddr,
-                      kRelayTcpIntAddr, kRelayTcpExtAddr,
-                      kRelaySslTcpIntAddr, kRelaySslTcpExtAddr),
-        socks_server1_(ss_.get(), kSocksProxyAddrs[0],
-                       ss_.get(), kSocksProxyAddrs[0]),
-        socks_server2_(ss_.get(), kSocksProxyAddrs[1],
-                       ss_.get(), kSocksProxyAddrs[1]),
-        allocator1_(&network_manager1_, kStunAddr,
-                    kRelayUdpIntAddr, kRelayTcpIntAddr, kRelaySslTcpIntAddr),
-        allocator2_(&network_manager2_, kStunAddr,
-                    kRelayUdpIntAddr, kRelayTcpIntAddr, kRelaySslTcpIntAddr) {
-  }
-
- protected:
-  enum Config {
-    OPEN,                           // Open to the Internet
-    NAT_FULL_CONE,                  // NAT, no filtering
-    NAT_ADDR_RESTRICTED,            // NAT, must send to an addr to recv
-    NAT_PORT_RESTRICTED,            // NAT, must send to an addr+port to recv
-    NAT_SYMMETRIC,                  // NAT, endpoint-dependent bindings
-    NAT_DOUBLE_CONE,                // Double NAT, both cone
-    NAT_SYMMETRIC_THEN_CONE,        // Double NAT, symmetric outer, cone inner
-    BLOCK_UDP,                      // Firewall, UDP in/out blocked
-    BLOCK_UDP_AND_INCOMING_TCP,     // Firewall, UDP in/out and TCP in blocked
-    BLOCK_ALL_BUT_OUTGOING_HTTP,    // Firewall, only TCP out on 80/443
-    PROXY_HTTPS,                    // All traffic through HTTPS proxy
-    PROXY_SOCKS,                    // All traffic through SOCKS proxy
-    NUM_CONFIGS
-  };
-
-  struct Result {
-    Result(const std::string& lt, const std::string lp,
-           const std::string& rt, const std::string rp, int wait)
-        : local_type(lt), local_proto(lp), remote_type(rt), remote_proto(rp),
-          connect_wait(wait) {
-    }
-    std::string local_type;
-    std::string local_proto;
-    std::string remote_type;
-    std::string remote_proto;
-    int connect_wait;
-  };
-
-  // Common results.
-  static const Result kLocalUdpToLocalUdp;
-  static const Result kLocalUdpToStunUdp;
-  static const Result kStunUdpToLocalUdp;
-  static const Result kStunUdpToStunUdp;
-  static const Result kLocalUdpToRelayUdp;
-  static const Result kLocalTcpToLocalTcp;
-
-  static void SetUpTestCase() {
-    // Ensure the RNG is inited.
-    talk_base::InitRandom(NULL, 0);
-  }
-
-  talk_base::NATSocketServer* nat() { return nss_.get(); }
-  talk_base::FirewallSocketServer* fw() { return ss_.get(); }
-
-  cricket::PortAllocator* GetAllocator(int endpoint) {
-    return (endpoint == 0) ? &allocator1_ : &allocator2_;
-  }
-  void AddAddress(int endpoint, const SocketAddress& addr) {
-    talk_base::FakeNetworkManager& manager = (endpoint == 0) ?
-        network_manager1_ : network_manager2_;
-    manager.AddInterface(addr);
-  }
-  void RemoveAddress(int endpoint, const SocketAddress& addr) {
-    talk_base::FakeNetworkManager& manager = (endpoint == 0) ?
-        network_manager1_ : network_manager2_;
-    manager.RemoveInterface(addr);
-  }
-  void SetProxy(int endpoint, talk_base::ProxyType type) {
-    talk_base::ProxyInfo info;
-    info.type = type;
-    info.address = (type == talk_base::PROXY_HTTPS) ?
-        kHttpsProxyAddrs[endpoint] : kSocksProxyAddrs[endpoint];
-    GetAllocator(endpoint)->set_proxy("unittest/1.0", info);
-  }
-  void SetAllocatorFlags(int endpoint, int flags) {
-    GetAllocator(endpoint)->set_flags(flags);
-  }
-
-  void Test(const Result& expected) {
-    int32 connect_start = talk_base::Time(), connect_time;
-
-    // Create the channels and wait for them to connect.
-    CreateChannels();
-    EXPECT_TRUE_WAIT_MARGIN(ch1_.get() != NULL && ch2_.get() != NULL &&
-                            ch1_->readable() && ch1_->writable() &&
-                            ch2_->readable() && ch2_->writable(),
-                            expected.connect_wait,
-                            1000);
-    connect_time = talk_base::TimeSince(connect_start);
-    if (connect_time < expected.connect_wait) {
-      LOG(LS_INFO) << "Connect time: " << connect_time << " ms";
-    } else {
-      LOG(LS_INFO) << "Connect time: " << "TIMEOUT ("
-                   << expected.connect_wait << " ms)";
-    }
-
-    // Allow a few turns of the crank for the best connections to emerge.
-    // This may take up to 2 seconds.
-    if (ch1_->best_connection() && ch2_->best_connection()) {
-      int32 converge_start = talk_base::Time(), converge_time;
-      int converge_wait = 2000;
-      EXPECT_TRUE_WAIT_MARGIN(
-          LocalCandidate(ch1_.get())->type() == expected.local_type &&
-          LocalCandidate(ch1_.get())->protocol() == expected.local_proto &&
-          RemoteCandidate(ch1_.get())->type() == expected.remote_type &&
-          RemoteCandidate(ch1_.get())->protocol() == expected.remote_proto,
-          converge_wait,
-          converge_wait);
-
-      // Also do EXPECT_EQ on each part so that failures are more verbose.
-      EXPECT_EQ(expected.local_type, LocalCandidate(ch1_.get())->type());
-      EXPECT_EQ(expected.local_proto, LocalCandidate(ch1_.get())->protocol());
-      EXPECT_EQ(expected.remote_type, RemoteCandidate(ch1_.get())->type());
-      EXPECT_EQ(expected.remote_proto, RemoteCandidate(ch1_.get())->protocol());
-
-      /* TODO: Check ch2 candidates.
-      EXPECT_EQ(expected.local_type2, LocalCandidate(ch1_.get())->type());
-      EXPECT_EQ(expected.local_proto2, LocalCandidate(ch1_.get())->protocol());
-      EXPECT_EQ(expected.remote_type2, RemoteCandidate(ch1_.get())->type());
-      EXPECT_EQ(expected.remote_proto2, RemoteCandidate(ch1_.get())->protocol());
-      */
-
-      converge_time = talk_base::TimeSince(converge_start);
-      if (converge_time < converge_wait) {
-        LOG(LS_INFO) << "Converge time: " << converge_time << " ms";
-      } else {
-        LOG(LS_INFO) << "Converge time: " << "TIMEOUT ("
-                     << converge_wait << " ms)";
-      }
-    }
-
-    // TODO: Send some data and make sure it gets there.
-
-    // Destroy the channels, and wait for them to be fully cleaned up.
-    DestroyChannels();
-  }
-
-  void CreateChannels() {
-    ch1_.reset(new cricket::P2PTransportChannel("a", "unittest",
-                                                NULL, &allocator1_));
-    ch2_.reset(new cricket::P2PTransportChannel("b", "unittest",
-                                                NULL, &allocator2_));
-    ch1_->SignalRequestSignaling.connect(ch1_.get(),
-        &cricket::P2PTransportChannel::OnSignalingReady);
-    ch2_->SignalRequestSignaling.connect(ch2_.get(),
-        &cricket::P2PTransportChannel::OnSignalingReady);
-    ch1_->SignalCandidateReady.connect(this,
-        &P2PTransportChannelTestBase::OnCandidate);
-    ch2_->SignalCandidateReady.connect(this,
-        &P2PTransportChannelTestBase::OnCandidate);
-    ch1_->Connect();
-    ch2_->Connect();
-  }
-  void DestroyChannels() {
-    ch1_.reset();
-    ch2_.reset();
-  }
-  cricket::P2PTransportChannel* ch1() { return ch1_.get(); }
-  cricket::P2PTransportChannel* ch2() { return ch2_.get(); }
-
-  // We pass the candidates directly to the other side.
-  void OnCandidate(cricket::TransportChannelImpl* ch,
-                   const cricket::Candidate& c) {
-    if (ch == ch1_.get()) {
-      LOG(LS_INFO) << "Candidate(1->2): " << c.type() << ", " << c.protocol()
-                   << ", " << c.address().ToString() << ", " << c.username()
-                   << ", " << c.generation();
-      ch2_->OnCandidate(c);
-    } else {
-      LOG(LS_INFO) << "Candidate(2->1): " << c.type() << ", " << c.protocol()
-                   << ", " << c.address().ToString() << ", " << c.username()
-                   << ", " << c.generation();
-      ch1_->OnCandidate(c);
-    }
-  }
-  static const cricket::Candidate* LocalCandidate(
-      cricket::P2PTransportChannel* ch) {
-    return (ch && ch->best_connection()) ?
-        &ch->best_connection()->local_candidate() : NULL;
-  }
-  static const cricket::Candidate* RemoteCandidate(
-      cricket::P2PTransportChannel* ch) {
-    return (ch && ch->best_connection()) ?
-        &ch->best_connection()->remote_candidate() : NULL;
-  }
-
- private:
-  enum { MSG_CONNECT, MSG_DISCONNECT };
-  talk_base::Thread* main_;
-  talk_base::scoped_ptr<talk_base::PhysicalSocketServer> pss_;
-  talk_base::scoped_ptr<talk_base::VirtualSocketServer> vss_;
-  talk_base::scoped_ptr<talk_base::NATSocketServer> nss_;
-  talk_base::scoped_ptr<talk_base::FirewallSocketServer> ss_;
-  talk_base::SocketServerScope ss_scope_;
-  cricket::TestStunServer stun_server_;
-  cricket::TestRelayServer relay_server_;
-  talk_base::SocksProxyServer socks_server1_;
-  talk_base::SocksProxyServer socks_server2_;
-  talk_base::FakeNetworkManager network_manager1_;
-  talk_base::FakeNetworkManager network_manager2_;
-  cricket::BasicPortAllocator allocator1_;
-  cricket::BasicPortAllocator allocator2_;
-  talk_base::scoped_ptr<cricket::P2PTransportChannel> ch1_;
-  talk_base::scoped_ptr<cricket::P2PTransportChannel> ch2_;
-};
-
-// The tests have only a few outcomes, which we predefine.
-const P2PTransportChannelTestBase::Result P2PTransportChannelTestBase::
-    kLocalUdpToLocalUdp("local", "udp", "local", "udp", 1000);
-const P2PTransportChannelTestBase::Result P2PTransportChannelTestBase::
-    kLocalUdpToStunUdp("local", "udp", "stun", "udp", 1000);
-const P2PTransportChannelTestBase::Result P2PTransportChannelTestBase::
-    kStunUdpToLocalUdp("stun", "udp", "local", "udp", 1000);
-const P2PTransportChannelTestBase::Result P2PTransportChannelTestBase::
-    kStunUdpToStunUdp("stun", "udp", "stun", "udp", 1000);
-const P2PTransportChannelTestBase::Result P2PTransportChannelTestBase::
-    kLocalUdpToRelayUdp("local", "udp", "relay", "udp", 2000);
-const P2PTransportChannelTestBase::Result P2PTransportChannelTestBase::
-    kLocalTcpToLocalTcp("local", "tcp", "local", "tcp", 3000);
-
-// Test the matrix of all the connectivity types we expect to see in the wild.
-// Just test every combination of the configs in the Config enum.
-class P2PTransportChannelTest : public P2PTransportChannelTestBase {
- protected:
-  static const Result* kMatrix[NUM_CONFIGS][NUM_CONFIGS];
-  void ConfigureEndpoints(Config config1, Config config2) {
-    ConfigureEndpoint(0, config1);
-    ConfigureEndpoint(1, config2);
-  }
-  void ConfigureEndpoint(int endpoint, Config config) {
-    switch (config) {
-      case OPEN:
-        AddAddress(endpoint, kPublicAddrs[endpoint]);
-        break;
-      case NAT_FULL_CONE:
-      case NAT_ADDR_RESTRICTED:
-      case NAT_PORT_RESTRICTED:
-      case NAT_SYMMETRIC:
-        AddAddress(endpoint, kPrivateAddrs[endpoint]);
-        // Add a single NAT of the desired type
-        nat()->AddTranslator(kPublicAddrs[endpoint], kNatAddrs[endpoint],
-            static_cast<talk_base::NATType>(config - NAT_FULL_CONE))->
-            AddClient(kPrivateAddrs[endpoint]);
-        break;
-      case NAT_DOUBLE_CONE:
-      case NAT_SYMMETRIC_THEN_CONE:
-        AddAddress(endpoint, kCascadedPrivateAddrs[endpoint]);
-        // Add a two cascaded NATs of the desired types
-        nat()->AddTranslator(kPublicAddrs[endpoint], kNatAddrs[endpoint],
-            (config == NAT_DOUBLE_CONE) ?
-                talk_base::NAT_OPEN_CONE : talk_base::NAT_SYMMETRIC)->
-            AddTranslator(kPrivateAddrs[endpoint], kCascadedNatAddrs[endpoint],
-                talk_base::NAT_OPEN_CONE)->
-                AddClient(kCascadedPrivateAddrs[endpoint]);
-        break;
-      case BLOCK_UDP:
-      case BLOCK_UDP_AND_INCOMING_TCP:
-      case BLOCK_ALL_BUT_OUTGOING_HTTP:
-      case PROXY_HTTPS:
-      case PROXY_SOCKS:
-        AddAddress(endpoint, kPublicAddrs[endpoint]);
-        // Block all UDP
-        fw()->AddRule(false, talk_base::FP_UDP, talk_base::FD_ANY,
-                      kPublicAddrs[endpoint]);
-        if (config == BLOCK_UDP_AND_INCOMING_TCP) {
-          // Block TCP inbound to the endpoint
-          fw()->AddRule(false, talk_base::FP_TCP, SocketAddress(),
-                        kPublicAddrs[endpoint]);
-        } else if (config == BLOCK_ALL_BUT_OUTGOING_HTTP) {
-          // Block all TCP to/from the endpoint except 80/443 out
-          fw()->AddRule(true, talk_base::FP_TCP, kPublicAddrs[endpoint],
-                        SocketAddress(talk_base::IPAddress(INADDR_ANY), 80));
-          fw()->AddRule(true, talk_base::FP_TCP, kPublicAddrs[endpoint],
-                        SocketAddress(talk_base::IPAddress(INADDR_ANY), 443));
-          fw()->AddRule(false, talk_base::FP_TCP, talk_base::FD_ANY,
-                        kPublicAddrs[endpoint]);
-        } else if (config == PROXY_HTTPS) {
-          // Block all TCP to/from the endpoint except to the proxy server
-          fw()->AddRule(true, talk_base::FP_TCP, kPublicAddrs[endpoint],
-                        kHttpsProxyAddrs[endpoint]);
-          fw()->AddRule(false, talk_base::FP_TCP, talk_base::FD_ANY,
-                        kPublicAddrs[endpoint]);
-          SetProxy(endpoint, talk_base::PROXY_HTTPS);
-        } else if (config == PROXY_SOCKS) {
-          // Block all TCP to/from the endpoint except to the proxy server
-          fw()->AddRule(true, talk_base::FP_TCP, kPublicAddrs[endpoint],
-                        kSocksProxyAddrs[endpoint]);
-          fw()->AddRule(false, talk_base::FP_TCP, talk_base::FD_ANY,
-                        kPublicAddrs[endpoint]);
-          SetProxy(endpoint, talk_base::PROXY_SOCKS5);
-        }
-        break;
-      default:
-        break;
-    }
-  }
-};
-
-// Shorthands for use in the test matrix.
-#define LULU &kLocalUdpToLocalUdp
-#define LUSU &kLocalUdpToStunUdp
-#define SULU &kStunUdpToLocalUdp
-#define SUSU &kStunUdpToStunUdp
-#define LURU &kLocalUdpToRelayUdp
-#define LTLT &kLocalTcpToLocalTcp
-// TODO: Enable these once TestRelayServer can accept external TCP.
-#define LTRT NULL
-#define LSRS NULL
-
-// Test matrix. Originator behavior defined by rows, receiever by columns.
-// TODO: Fix NULLs caused by lack of TCP support in NATSocket.
-// TODO: Fix NULLs caused by no HTTP proxy support.
-// TODO: Rearrange rows/columns from best to worst.
-const P2PTransportChannelTest::Result*
-    P2PTransportChannelTest::kMatrix[NUM_CONFIGS][NUM_CONFIGS] = {
-//      OPEN  CONE  ADDR  PORT  SYMM  2CON  SCON  !UDP  !TCP  HTTP  PRXH  PRXS
-/*OP*/ {LULU, LULU, LULU, LULU, LULU, LULU, LULU, LTLT, LTLT, LSRS, NULL, LTLT},
-/*CO*/ {LULU, LULU, LULU, SULU, SULU, LULU, SULU, NULL, NULL, LSRS, NULL, LTRT},
-/*AD*/ {LULU, LULU, LULU, SUSU, SUSU, LULU, SUSU, NULL, NULL, LSRS, NULL, LTRT},
-/*PO*/ {LULU, LUSU, SUSU, SUSU, LURU, LUSU, LURU, NULL, NULL, LSRS, NULL, LTRT},
-/*SY*/ {LULU, LUSU, SUSU, LURU, LURU, LUSU, LURU, NULL, NULL, LSRS, NULL, LTRT},
-/*2C*/ {LULU, LULU, LULU, SULU, SULU, LULU, SULU, NULL, NULL, LSRS, NULL, LTRT},
-/*SC*/ {LULU, LUSU, SUSU, LURU, LURU, LUSU, LURU, NULL, NULL, LSRS, NULL, LTRT},
-/*!U*/ {LTLT, NULL, NULL, NULL, NULL, NULL, NULL, LTLT, LTLT, LSRS, NULL, LTRT},
-/*!T*/ {LTRT, NULL, NULL, NULL, NULL, NULL, NULL, LTLT, LTRT, LSRS, NULL, LTRT},
-/*HT*/ {LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, NULL, LSRS},
-/*PR*/ {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-/*PR*/ {LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LSRS, NULL, LTRT},
-};
-
-// The actual tests that exercise all the various configurations.
-// Test names are of the form P2PTransportChannelTest_TestOPENToNAT_FULL_CONE
-#define P2P_TEST_DECLARATION(x, y, z) \
-  TEST_F(P2PTransportChannelTest, z##Test##x##To##y) { \
-    ConfigureEndpoints(x, y); \
-    if (kMatrix[x][y] != NULL) \
-      Test(*kMatrix[x][y]); \
-    else \
-      LOG(LS_WARNING) << "Not yet implemented"; \
-  }
-
-#define P2P_TEST(x, y) \
-  P2P_TEST_DECLARATION(x, y,)
-
-#define FLAKY_P2P_TEST(x, y) \
-  P2P_TEST_DECLARATION(x, y, DISABLED_)
-
-#define P2P_TEST_SET(x) \
-  P2P_TEST(x, OPEN) \
-  P2P_TEST(x, NAT_FULL_CONE) \
-  P2P_TEST(x, NAT_ADDR_RESTRICTED) \
-  P2P_TEST(x, NAT_PORT_RESTRICTED) \
-  P2P_TEST(x, NAT_SYMMETRIC) \
-  P2P_TEST(x, NAT_DOUBLE_CONE) \
-  P2P_TEST(x, NAT_SYMMETRIC_THEN_CONE) \
-  P2P_TEST(x, BLOCK_UDP) \
-  P2P_TEST(x, BLOCK_UDP_AND_INCOMING_TCP) \
-  P2P_TEST(x, BLOCK_ALL_BUT_OUTGOING_HTTP) \
-  P2P_TEST(x, PROXY_HTTPS) \
-  P2P_TEST(x, PROXY_SOCKS)
-
-#define FLAKY_P2P_TEST_SET(x) \
-  P2P_TEST(x, OPEN) \
-  P2P_TEST(x, NAT_FULL_CONE) \
-  FLAKY_P2P_TEST(x, NAT_ADDR_RESTRICTED) \
-  P2P_TEST(x, NAT_PORT_RESTRICTED) \
-  P2P_TEST(x, NAT_SYMMETRIC) \
-  P2P_TEST(x, NAT_DOUBLE_CONE) \
-  P2P_TEST(x, NAT_SYMMETRIC_THEN_CONE) \
-  P2P_TEST(x, BLOCK_UDP) \
-  P2P_TEST(x, BLOCK_UDP_AND_INCOMING_TCP) \
-  P2P_TEST(x, BLOCK_ALL_BUT_OUTGOING_HTTP) \
-  P2P_TEST(x, PROXY_HTTPS) \
-  P2P_TEST(x, PROXY_SOCKS)
-
-P2P_TEST_SET(OPEN)
-P2P_TEST_SET(NAT_FULL_CONE)
-FLAKY_P2P_TEST_SET(NAT_ADDR_RESTRICTED)
-FLAKY_P2P_TEST_SET(NAT_PORT_RESTRICTED)
-FLAKY_P2P_TEST_SET(NAT_SYMMETRIC)
-P2P_TEST_SET(NAT_DOUBLE_CONE)
-FLAKY_P2P_TEST_SET(NAT_SYMMETRIC_THEN_CONE)
-P2P_TEST_SET(BLOCK_UDP)
-P2P_TEST_SET(BLOCK_UDP_AND_INCOMING_TCP)
-P2P_TEST_SET(BLOCK_ALL_BUT_OUTGOING_HTTP)
-P2P_TEST_SET(PROXY_HTTPS)
-P2P_TEST_SET(PROXY_SOCKS)
-
-// Test that a host behind NAT cannot be reached when incoming_only
-// is set to true.
-TEST_F(P2PTransportChannelTest, IncomingOnlyBlocked) {
-  ConfigureEndpoints(NAT_FULL_CONE, OPEN);
-
-  CreateChannels();
-  ch1()->set_incoming_only(true);
-
-  // Sleep for 1 second and verify that the channels are not connected.
-  talk_base::Thread::SleepMs(1000);
-
-  EXPECT_FALSE(ch1()->readable());
-  EXPECT_FALSE(ch1()->writable());
-  EXPECT_FALSE(ch2()->readable());
-  EXPECT_FALSE(ch2()->writable());
-
-  DestroyChannels();
-}
-
-// Test that a peer behind NAT can connect to a peer that has
-// incoming_only flag set.
-TEST_F(P2PTransportChannelTest, IncomingOnlyOpen) {
-  ConfigureEndpoints(OPEN, NAT_FULL_CONE);
-
-  CreateChannels();
-  ch1()->set_incoming_only(true);
-
-  EXPECT_TRUE_WAIT_MARGIN(ch1() != NULL && ch2() != NULL &&
-                          ch1()->readable() && ch1()->writable() &&
-                          ch2()->readable() && ch2()->writable(),
-                          1000, 1000);
-
-  DestroyChannels();
-}
-
-// Test what happens when we have 2 users behind the same NAT. This can lead
-// to interesting behavior because the STUN server will only give out the
-// address of the outermost NAT.
-class P2PTransportChannelSameNatTest : public P2PTransportChannelTestBase {
- protected:
-  void ConfigureEndpoints(Config nat_type, Config config1, Config config2) {
-    ASSERT(nat_type >= NAT_FULL_CONE && nat_type <= NAT_SYMMETRIC);
-    talk_base::NATSocketServer::Translator* outer_nat =
-        nat()->AddTranslator(kPublicAddrs[0], kNatAddrs[0],
-            static_cast<talk_base::NATType>(nat_type - NAT_FULL_CONE));
-    ConfigureEndpoint(outer_nat, 0, config1);
-    ConfigureEndpoint(outer_nat, 1, config2);
-  }
-  void ConfigureEndpoint(talk_base::NATSocketServer::Translator* nat,
-                         int endpoint, Config config) {
-    ASSERT(config <= NAT_SYMMETRIC);
-    if (config == OPEN) {
-      AddAddress(endpoint, kPrivateAddrs[endpoint]);
-      nat->AddClient(kPrivateAddrs[endpoint]);
-    } else {
-      AddAddress(endpoint, kCascadedPrivateAddrs[endpoint]);
-      nat->AddTranslator(kPrivateAddrs[endpoint], kCascadedNatAddrs[endpoint],
-          static_cast<talk_base::NATType>(config - NAT_FULL_CONE))->AddClient(
-              kCascadedPrivateAddrs[endpoint]);
-    }
-  }
-};
-
-TEST_F(P2PTransportChannelSameNatTest, TestConesBehindSameCone) {
-  ConfigureEndpoints(NAT_FULL_CONE, NAT_FULL_CONE, NAT_FULL_CONE);
-  Test(kLocalUdpToLocalUdp);
-}
-
-// Test what happens when we have multiple available pathways.
-// In the future we will try different RTTs and configs for the different
-// interfaces, so that we can simulate a user with Ethernet and VPN networks.
-class P2PTransportChannelMultihomedTest : public P2PTransportChannelTestBase {
-};
-
-// Test that we can establish connectivity when both peers are multihomed.
-TEST_F(P2PTransportChannelMultihomedTest, TestBasic) {
-  AddAddress(0, kPublicAddrs[0]);
-  AddAddress(0, kAlternateAddrs[0]);
-  AddAddress(1, kPublicAddrs[1]);
-  AddAddress(1, kAlternateAddrs[1]);
-  Test(kLocalUdpToLocalUdp);
-}
-
-// Test that we can quickly switch links if an interface goes down.
-TEST_F(P2PTransportChannelMultihomedTest, TestFailover) {
-  AddAddress(0, kPublicAddrs[0]);
-  AddAddress(1, kPublicAddrs[1]);
-  AddAddress(1, kAlternateAddrs[1]);
-  // Use only local ports for simplicity.
-  SetAllocatorFlags(0, kOnlyLocalPorts);
-  SetAllocatorFlags(1, kOnlyLocalPorts);
-
-  // Create channels and let them go writable, as usual.
-  CreateChannels();
-  EXPECT_TRUE_WAIT(ch1()->readable() && ch1()->writable() &&
-                   ch2()->readable() && ch2()->writable(),
-                   1000);
-  EXPECT_TRUE(
-      ch1()->best_connection() && ch2()->best_connection() &&
-      LocalCandidate(ch1())->address().EqualIPs(kPublicAddrs[0]) &&
-      RemoteCandidate(ch1())->address().EqualIPs(kPublicAddrs[1]));
-
-  // Blackhole any traffic to or from the public addrs.
-  LOG(LS_INFO) << "Failing over...";
-  fw()->AddRule(false, talk_base::FP_ANY, talk_base::FD_ANY,
-                kPublicAddrs[1]);
-
-  // We should detect loss of connectivity within 5 seconds or so.
-  EXPECT_TRUE_WAIT(!ch1()->writable(), 7000);
-
-  // We should switch over to use the alternate addr immediately
-  // when we lose writability.
-  EXPECT_TRUE_WAIT(
-      ch1()->best_connection() && ch2()->best_connection() &&
-      LocalCandidate(ch1())->address().EqualIPs(kPublicAddrs[0]) &&
-      RemoteCandidate(ch1())->address().EqualIPs(kAlternateAddrs[1]),
-      3000);
-
-  DestroyChannels();
-}
-
-// Test that we can switch links in a coordinated fashion.
-TEST_F(P2PTransportChannelMultihomedTest, TestDrain) {
-  AddAddress(0, kPublicAddrs[0]);
-  AddAddress(1, kPublicAddrs[1]);
-  // Use only local ports for simplicity.
-  SetAllocatorFlags(0, kOnlyLocalPorts);
-  SetAllocatorFlags(1, kOnlyLocalPorts);
-
-  // Create channels and let them go writable, as usual.
-  CreateChannels();
-  EXPECT_TRUE_WAIT(ch1()->readable() && ch1()->writable() &&
-                   ch2()->readable() && ch2()->writable(),
-                   1000);
-  EXPECT_TRUE(
-      ch1()->best_connection() && ch2()->best_connection() &&
-      LocalCandidate(ch1())->address().EqualIPs(kPublicAddrs[0]) &&
-      RemoteCandidate(ch1())->address().EqualIPs(kPublicAddrs[1]));
-
-  // Remove the public interface, add the alternate interface, and allocate
-  // a new generation of candidates for the new interface (via Connect()).
-  LOG(LS_INFO) << "Draining...";
-  AddAddress(1, kAlternateAddrs[1]);
-  RemoveAddress(1, kPublicAddrs[1]);
-  ch2()->Connect();
-
-  // We should switch over to use the alternate address after
-  // an exchange of pings.
-  EXPECT_TRUE_WAIT(
-      ch1()->best_connection() && ch2()->best_connection() &&
-      LocalCandidate(ch1())->address().EqualIPs(kPublicAddrs[0]) &&
-      RemoteCandidate(ch1())->address().EqualIPs(kAlternateAddrs[1]),
-      3000);
-
-  DestroyChannels();
-}
diff --git a/third_party/libjingle/source/talk/p2p/base/parsing.cc b/third_party/libjingle/source/talk/p2p/base/parsing.cc
deleted file mode 100644
index f302956..0000000
--- a/third_party/libjingle/source/talk/p2p/base/parsing.cc
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * libjingle
- * Copyright 2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/p2p/base/parsing.h"
-
-#include <algorithm>
-#include <stdlib.h>
-#include "talk/base/stringutils.h"
-
-namespace {
-static const char kTrue[] = "true";
-static const char kOne[] = "1";
-}
-
-namespace cricket {
-
-bool BadParse(const std::string& text, ParseError* err) {
-  if (err != NULL) {
-    err->text = text;
-  }
-  return false;
-}
-
-bool BadWrite(const std::string& text, WriteError* err) {
-  if (err != NULL) {
-    err->text = text;
-  }
-  return false;
-}
-
-std::string GetXmlAttr(const buzz::XmlElement* elem,
-                       const buzz::QName& name,
-                       const std::string& def) {
-  std::string val = elem->Attr(name);
-  return val.empty() ? def : val;
-}
-
-std::string GetXmlAttr(const buzz::XmlElement* elem,
-                       const buzz::QName& name,
-                       const char* def) {
-    return GetXmlAttr(elem, name, std::string(def));
-}
-
-bool GetXmlAttr(const buzz::XmlElement* elem,
-                const buzz::QName& name, bool def) {
-  std::string val = elem->Attr(name);
-  std::transform(val.begin(), val.end(), val.begin(), tolower);
-
-  return val.empty() ? def : (val == kTrue || val == kOne);
-}
-
-int GetXmlAttr(const buzz::XmlElement* elem,
-               const buzz::QName& name, int def) {
-  std::string val = elem->Attr(name);
-  return val.empty() ? def : atoi(val.c_str());
-}
-
-const buzz::XmlElement* GetXmlChild(const buzz::XmlElement* parent,
-                                    const std::string& name) {
-  for (const buzz::XmlElement* child = parent->FirstElement();
-       child != NULL;
-       child = child->NextElement()) {
-    if (child->Name().LocalPart() == name) {
-      return child;
-    }
-  }
-  return NULL;
-}
-
-const buzz::XmlElement* GetXmlElement(const XmlElements& elems,
-                                      const buzz::QName& name) {
-  for (XmlElements::const_iterator iter = elems.begin();
-       iter != elems.end(); ++iter) {
-    const buzz::XmlElement* elem = *iter;
-    if (elem->Name() == name) {
-      return elem;
-    }
-  }
-  return NULL;
-}
-
-bool RequireXmlChild(const buzz::XmlElement* parent,
-                     const std::string& name,
-                     const buzz::XmlElement** child,
-                     ParseError* error) {
-  *child = GetXmlChild(parent, name);
-  if (*child == NULL) {
-    return BadParse("element '" + parent->Name().Merged() +
-                    "' missing required child '" + name,
-                    error);
-  } else {
-    return true;
-  }
-}
-
-bool RequireXmlAttr(const buzz::XmlElement* elem,
-                    const buzz::QName& name,
-                    std::string* value,
-                    ParseError* error) {
-  if (!elem->HasAttr(name)) {
-    return BadParse("element '" + elem->Name().Merged() +
-                    "' missing required attribute '"
-                    + name.Merged() + "'",
-                    error);
-  } else {
-    *value = elem->Attr(name);
-    return true;
-  }
-}
-
-void AddXmlAttrIfNonEmpty(buzz::XmlElement* elem,
-                          const buzz::QName name,
-                          const std::string& value) {
-  if (!value.empty()) {
-    elem->AddAttr(name, value);
-  }
-}
-
-void AddXmlChildren(buzz::XmlElement* parent,
-                    const std::vector<buzz::XmlElement*>& children) {
-  for (std::vector<buzz::XmlElement*>::const_iterator iter = children.begin();
-       iter != children.end();
-       iter++) {
-    parent->AddElement(*iter);
-  }
-}
-
-void CopyXmlChildren(const buzz::XmlElement* source, buzz::XmlElement* dest) {
-  for (const buzz::XmlElement* child = source->FirstElement();
-       child != NULL;
-       child = child->NextElement()) {
-    dest->AddElement(new buzz::XmlElement(*child));
-  }
-}
-
-std::vector<buzz::XmlElement*> CopyOfXmlChildren(const buzz::XmlElement* elem) {
-  std::vector<buzz::XmlElement*> children;
-  for (const buzz::XmlElement* child = elem->FirstElement();
-       child != NULL;
-       child = child->NextElement()) {
-    children.push_back(new buzz::XmlElement(*child));
-  }
-  return children;
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/p2p/base/parsing.h b/third_party/libjingle/source/talk/p2p/base/parsing.h
deleted file mode 100644
index 589d9d7..0000000
--- a/third_party/libjingle/source/talk/p2p/base/parsing.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * libjingle
- * Copyright 2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_P2P_BASE_PARSING_H_
-#define TALK_P2P_BASE_PARSING_H_
-
-#include <string>
-#include <vector>
-#include "talk/base/basictypes.h"
-#include "talk/base/stringencode.h"
-#include "talk/xmllite/xmlelement.h"  // Needed to delete ParseError.extra.
-
-namespace cricket {
-
-typedef std::vector<buzz::XmlElement*> XmlElements;
-
-// We decided "bool Parse(in, out*, error*)" is generally the best
-// parse signature.  "out Parse(in)" doesn't allow for errors.
-// "error* Parse(in, out*)" doesn't allow flexible memory management.
-
-// The error type for parsing.
-struct ParseError {
- public:
-  // explains the error
-  std::string text;
-  // provide details about what wasn't parsable
-  const buzz::XmlElement* extra;
-
-  ParseError() : extra(NULL) {}
-
-  ~ParseError() {
-    delete extra;
-  }
-
-  void SetText(const std::string& text) {
-    this->text = text;
-  }
-};
-
-// The error type for writing.
-struct WriteError {
-  std::string text;
-
-  void SetText(const std::string& text) {
-    this->text = text;
-  }
-};
-
-// Convenience method for returning a message when parsing fails.
-bool BadParse(const std::string& text, ParseError* err);
-
-// Convenience method for returning a message when writing fails.
-bool BadWrite(const std::string& text, WriteError* error);
-
-// helper XML functions
-std::string GetXmlAttr(const buzz::XmlElement* elem,
-                       const buzz::QName& name,
-                       const std::string& def);
-std::string GetXmlAttr(const buzz::XmlElement* elem,
-                       const buzz::QName& name,
-                       const char* def);
-// Return true if the value is "true" or "1".
-bool GetXmlAttr(const buzz::XmlElement* elem,
-                const buzz::QName& name, bool def);
-int GetXmlAttr(const buzz::XmlElement* elem,
-               const buzz::QName& name, int def);
-
-template <class T>
-bool AddXmlAttr(buzz::XmlElement* elem,
-                const buzz::QName& name, const T& val) {
-  std::string buf;
-  if (!talk_base::ToString(val, &buf)) {
-    return false;
-  }
-  elem->AddAttr(name, buf);
-  return true;
-}
-
-template <class T>
-bool SetXmlBody(buzz::XmlElement* elem, const T& val) {
-  std::string buf;
-  if (!talk_base::ToString(val, &buf)) {
-    return false;
-  }
-  elem->SetBodyText(buf);
-  return true;
-}
-
-const buzz::XmlElement* GetXmlChild(const buzz::XmlElement* parent,
-                                    const std::string& name);
-const buzz::XmlElement* GetXmlElement(const XmlElements& elems,
-                                      const buzz::QName& name);
-
-bool RequireXmlChild(const buzz::XmlElement* parent,
-                     const std::string& name,
-                     const buzz::XmlElement** child,
-                     ParseError* error);
-bool RequireXmlAttr(const buzz::XmlElement* elem,
-                    const buzz::QName& name,
-                    std::string* value,
-                    ParseError* error);
-void AddXmlAttrIfNonEmpty(buzz::XmlElement* elem,
-                          const buzz::QName name,
-                          const std::string& value);
-void AddXmlChildren(buzz::XmlElement* parent,
-                    const std::vector<buzz::XmlElement*>& children);
-void CopyXmlChildren(const buzz::XmlElement* source, buzz::XmlElement* dest);
-std::vector<buzz::XmlElement*> CopyOfXmlChildren(const buzz::XmlElement* elem);
-
-}  // namespace cricket
-
-#endif  // TALK_P2P_BASE_PARSING_H_
diff --git a/third_party/libjingle/source/talk/p2p/base/port.cc b/third_party/libjingle/source/talk/p2p/base/port.cc
deleted file mode 100644
index a016f63..0000000
--- a/third_party/libjingle/source/talk/p2p/base/port.cc
+++ /dev/null
@@ -1,889 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/p2p/base/port.h"
-
-#include <algorithm>
-#include <vector>
-
-#include "talk/base/helpers.h"
-#include "talk/base/logging.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/base/stringutils.h"
-#include "talk/p2p/base/common.h"
-
-namespace {
-
-// The length of time we wait before timing out readability on a connection.
-const uint32 CONNECTION_READ_TIMEOUT = 30 * 1000;   // 30 seconds
-
-// The length of time we wait before timing out writability on a connection.
-const uint32 CONNECTION_WRITE_TIMEOUT = 15 * 1000;  // 15 seconds
-
-// The length of time we wait before we become unwritable.
-const uint32 CONNECTION_WRITE_CONNECT_TIMEOUT = 5 * 1000;  // 5 seconds
-
-// The number of pings that must fail to respond before we become unwritable.
-const uint32 CONNECTION_WRITE_CONNECT_FAILURES = 5;
-
-// This is the length of time that we wait for a ping response to come back.
-const int CONNECTION_RESPONSE_TIMEOUT = 5 * 1000;   // 5 seconds
-
-// Determines whether we have seen at least the given maximum number of
-// pings fail to have a response.
-inline bool TooManyFailures(
-    const std::vector<uint32>& pings_since_last_response,
-    uint32 maximum_failures,
-    uint32 rtt_estimate,
-    uint32 now) {
-
-  // If we haven't sent that many pings, then we can't have failed that many.
-  if (pings_since_last_response.size() < maximum_failures)
-    return false;
-
-  // Check if the window in which we would expect a response to the ping has
-  // already elapsed.
-  return pings_since_last_response[maximum_failures - 1] + rtt_estimate < now;
-}
-
-// Determines whether we have gone too long without seeing any response.
-inline bool TooLongWithoutResponse(
-    const std::vector<uint32>& pings_since_last_response,
-    uint32 maximum_time,
-    uint32 now) {
-
-  if (pings_since_last_response.size() == 0)
-    return false;
-
-  return pings_since_last_response[0] + maximum_time < now;
-}
-
-// We will restrict RTT estimates (when used for determining state) to be
-// within a reasonable range.
-const uint32 MINIMUM_RTT = 100;   // 0.1 seconds
-const uint32 MAXIMUM_RTT = 3000;  // 3 seconds
-
-// When we don't have any RTT data, we have to pick something reasonable.  We
-// use a large value just in case the connection is really slow.
-const uint32 DEFAULT_RTT = MAXIMUM_RTT;
-
-// Computes our estimate of the RTT given the current estimate.
-inline uint32 ConservativeRTTEstimate(uint32 rtt) {
-  return talk_base::_max(MINIMUM_RTT, talk_base::_min(MAXIMUM_RTT, 2 * rtt));
-}
-
-// Weighting of the old rtt value to new data.
-const int RTT_RATIO = 3;  // 3 : 1
-
-// The delay before we begin checking if this port is useless.
-const int kPortTimeoutDelay = 30 * 1000;  // 30 seconds
-
-const uint32 MSG_CHECKTIMEOUT = 1;
-const uint32 MSG_DELETE = 1;
-}
-
-namespace cricket {
-
-static const char* const PROTO_NAMES[] = { "udp", "tcp", "ssltcp" };
-
-const char* ProtoToString(ProtocolType proto) {
-  return PROTO_NAMES[proto];
-}
-
-bool StringToProto(const char* value, ProtocolType* proto) {
-  for (size_t i = 0; i <= PROTO_LAST; ++i) {
-    if (strcmp(PROTO_NAMES[i], value) == 0) {
-      *proto = static_cast<ProtocolType>(i);
-      return true;
-    }
-  }
-  return false;
-}
-
-Port::Port(talk_base::Thread* thread, const std::string& type,
-           talk_base::PacketSocketFactory* factory, talk_base::Network* network,
-           const talk_base::IPAddress& ip, int min_port, int max_port)
-    : thread_(thread),
-      factory_(factory),
-      type_(type),
-      network_(network),
-      ip_(ip),
-      min_port_(min_port),
-      max_port_(max_port),
-      generation_(0),
-      preference_(-1),
-      lifetime_(LT_PRESTART),
-      enable_port_packets_(false) {
-  ASSERT(factory_ != NULL);
-
-  set_username_fragment(talk_base::CreateRandomString(16));
-  set_password(talk_base::CreateRandomString(16));
-  LOG_J(LS_INFO, this) << "Port created";
-}
-
-Port::~Port() {
-  // Delete all of the remaining connections.  We copy the list up front
-  // because each deletion will cause it to be modified.
-
-  std::vector<Connection*> list;
-
-  AddressMap::iterator iter = connections_.begin();
-  while (iter != connections_.end()) {
-    list.push_back(iter->second);
-    ++iter;
-  }
-
-  for (uint32 i = 0; i < list.size(); i++)
-    delete list[i];
-}
-
-Connection* Port::GetConnection(const talk_base::SocketAddress& remote_addr) {
-  AddressMap::const_iterator iter = connections_.find(remote_addr);
-  if (iter != connections_.end())
-    return iter->second;
-  else
-    return NULL;
-}
-
-void Port::AddAddress(const talk_base::SocketAddress& address,
-                      const std::string& protocol,
-                      bool final) {
-  Candidate c;
-  c.set_name(name_);
-  c.set_type(type_);
-  c.set_protocol(protocol);
-  c.set_address(address);
-  c.set_preference(preference_);
-  c.set_username(username_frag_);
-  c.set_password(password_);
-  c.set_network_name(network_->name());
-  c.set_generation(generation_);
-  candidates_.push_back(c);
-
-  if (final)
-    SignalAddressReady(this);
-}
-
-void Port::AddConnection(Connection* conn) {
-  connections_[conn->remote_candidate().address()] = conn;
-  conn->SignalDestroyed.connect(this, &Port::OnConnectionDestroyed);
-  SignalConnectionCreated(this, conn);
-}
-
-void Port::OnReadPacket(
-    const char* data, size_t size, const talk_base::SocketAddress& addr) {
-  // If the user has enabled port packets, just hand this over.
-  if (enable_port_packets_) {
-    SignalReadPacket(this, data, size, addr);
-    return;
-  }
-
-  // If this is an authenticated STUN request, then signal unknown address and
-  // send back a proper binding response.
-  StunMessage* msg;
-  std::string remote_username;
-  if (!GetStunMessage(data, size, addr, &msg, &remote_username)) {
-    LOG_J(LS_ERROR, this) << "Received non-STUN packet from unknown address ("
-                          << addr.ToString() << ")";
-  } else if (!msg) {
-    // STUN message handled already
-  } else if (msg->type() == STUN_BINDING_REQUEST) {
-    SignalUnknownAddress(this, addr, msg, remote_username);
-  } else {
-    // NOTE(tschmelcher): STUN_BINDING_RESPONSE is benign. It occurs if we
-    // pruned a connection for this port while it had STUN requests in flight,
-    // because we then get back responses for them, which this code correctly
-    // does not handle.
-    if (msg->type() != STUN_BINDING_RESPONSE) {
-      LOG_J(LS_ERROR, this) << "Received unexpected STUN message type ("
-                            << msg->type() << ") from unknown address ("
-                            << addr.ToString() << ")";
-    }
-    delete msg;
-  }
-}
-
-bool Port::GetStunMessage(const char* data, size_t size,
-                          const talk_base::SocketAddress& addr,
-                          StunMessage** out_msg, std::string* out_username) {
-  // NOTE: This could clearly be optimized to avoid allocating any memory.
-  //       However, at the data rates we'll be looking at on the client side,
-  //       this probably isn't worth worrying about.
-  ASSERT(out_msg != NULL);
-  ASSERT(out_username != NULL);
-  *out_msg = NULL;
-  out_username->clear();
-
-  // Parse the request message.  If the packet is not a complete and correct
-  // STUN message, then ignore it.
-  talk_base::scoped_ptr<StunMessage> stun_msg(new StunMessage());
-  talk_base::ByteBuffer buf(data, size);
-  if (!stun_msg->Read(&buf) || (buf.Length() > 0)) {
-    return false;
-  }
-
-  // The packet must include a username that either begins or ends with our
-  // fragment.  It should begin with our fragment if it is a request and it
-  // should end with our fragment if it is a response.
-  const StunByteStringAttribute* username_attr =
-      stun_msg->GetByteString(STUN_ATTR_USERNAME);
-
-  int remote_frag_len = (username_attr ? username_attr->length() : 0);
-  remote_frag_len -= static_cast<int>(username_frag_.size());
-
-  if (stun_msg->type() == STUN_BINDING_REQUEST) {
-    if (remote_frag_len < 0) {
-      // Username not present or corrupted, don't reply.
-      LOG_J(LS_ERROR, this) << "Received STUN request without username from "
-                            << addr.ToString();
-      return true;
-    } else if (std::memcmp(username_attr->bytes(), username_frag_.c_str(),
-                           username_frag_.size()) != 0) {
-      LOG_J(LS_ERROR, this) << "Received STUN request with bad local username "
-                            << std::string(username_attr->bytes(),
-                                           username_attr->length())
-                            << " from "
-                            << addr.ToString();
-      SendBindingErrorResponse(stun_msg.get(), addr, STUN_ERROR_BAD_REQUEST,
-                               STUN_ERROR_REASON_BAD_REQUEST);
-      return true;
-    }
-
-    out_username->assign(username_attr->bytes() + username_frag_.size(),
-                         username_attr->bytes() + username_attr->length());
-  } else if ((stun_msg->type() == STUN_BINDING_RESPONSE)
-      || (stun_msg->type() == STUN_BINDING_ERROR_RESPONSE)) {
-    if (remote_frag_len < 0) {
-      LOG_J(LS_ERROR, this) << "Received STUN response without username from "
-                            << addr.ToString();
-      // Do not send error response to a response
-      return true;
-    } else if (std::memcmp(username_attr->bytes() + remote_frag_len,
-                           username_frag_.c_str(),
-                           username_frag_.size()) != 0) {
-      LOG_J(LS_ERROR, this) << "Received STUN response with bad local username "
-                            << std::string(username_attr->bytes(),
-                                           username_attr->length())
-                            << " from "
-                            << addr.ToString();
-      // Do not send error response to a response
-      return true;
-    }
-
-    out_username->assign(username_attr->bytes(),
-                         username_attr->bytes() + remote_frag_len);
-
-    if (stun_msg->type() == STUN_BINDING_ERROR_RESPONSE) {
-      if (const StunErrorCodeAttribute* error_code = stun_msg->GetErrorCode()) {
-        LOG_J(LS_ERROR, this) << "Received STUN binding error:"
-                              << " class="
-                              << static_cast<int>(error_code->error_class())
-                              << " number="
-                              << static_cast<int>(error_code->number())
-                              << " reason='" << error_code->reason() << "'"
-                              << " from " << addr.ToString();
-        // Return message to allow error-specific processing
-      } else {
-        LOG_J(LS_ERROR, this) << "Received STUN binding error without a error "
-                              << "code from " << addr.ToString();
-        // Drop corrupt message
-        return true;
-      }
-    }
-  } else {
-    LOG_J(LS_ERROR, this) << "Received STUN packet with invalid type ("
-                          << stun_msg->type() << ") from " << addr.ToString();
-    return true;
-  }
-
-  // Return the STUN message found.
-  *out_msg = stun_msg.release();
-  return true;
-}
-
-void Port::SendBindingResponse(StunMessage* request,
-                               const talk_base::SocketAddress& addr) {
-  ASSERT(request->type() == STUN_BINDING_REQUEST);
-
-  // Retrieve the username from the request.
-  const StunByteStringAttribute* username_attr =
-      request->GetByteString(STUN_ATTR_USERNAME);
-  ASSERT(username_attr != NULL);
-  if (username_attr == NULL) {
-    // No valid username, skip the response.
-    return;
-  }
-
-  // Fill in the response message.
-  StunMessage response;
-  response.SetType(STUN_BINDING_RESPONSE);
-  response.SetTransactionID(request->transaction_id());
-
-  StunByteStringAttribute* username2_attr =
-      StunAttribute::CreateByteString(STUN_ATTR_USERNAME);
-  username2_attr->CopyBytes(username_attr->bytes(), username_attr->length());
-  response.AddAttribute(username2_attr);
-
-  StunAddressAttribute* addr_attr =
-      StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
-  addr_attr->SetPort(addr.port());
-  addr_attr->SetIP(addr.ipaddr());
-  response.AddAttribute(addr_attr);
-
-  // Send the response message.
-  // NOTE: If we wanted to, this is where we would add the HMAC.
-  talk_base::ByteBuffer buf;
-  response.Write(&buf);
-  if (SendTo(buf.Data(), buf.Length(), addr, false) < 0) {
-    LOG_J(LS_ERROR, this) << "Failed to send STUN ping response to "
-                          << addr.ToString();
-  }
-
-  // The fact that we received a successful request means that this connection
-  // (if one exists) should now be readable.
-  Connection* conn = GetConnection(addr);
-  ASSERT(conn != NULL);
-  if (conn)
-    conn->ReceivedPing();
-}
-
-void Port::SendBindingErrorResponse(StunMessage* request,
-                                    const talk_base::SocketAddress& addr,
-                                    int error_code, const std::string& reason) {
-  ASSERT(request->type() == STUN_BINDING_REQUEST);
-
-  // Retrieve the username from the request. If it didn't have one, we
-  // shouldn't be responding at all.
-  const StunByteStringAttribute* username_attr =
-      request->GetByteString(STUN_ATTR_USERNAME);
-  ASSERT(username_attr != NULL);
-  if (username_attr == NULL) {
-    // No valid username, skip the response.
-    return;
-  }
-
-  // Fill in the response message.
-  StunMessage response;
-  response.SetType(STUN_BINDING_ERROR_RESPONSE);
-  response.SetTransactionID(request->transaction_id());
-
-  StunByteStringAttribute* username2_attr =
-      StunAttribute::CreateByteString(STUN_ATTR_USERNAME);
-  username2_attr->CopyBytes(username_attr->bytes(), username_attr->length());
-  response.AddAttribute(username2_attr);
-
-  StunErrorCodeAttribute* error_attr = StunAttribute::CreateErrorCode();
-  error_attr->SetErrorCode(error_code);
-  error_attr->SetReason(reason);
-  response.AddAttribute(error_attr);
-
-  // Send the response message.
-  // NOTE: If we wanted to, this is where we would add the HMAC.
-  talk_base::ByteBuffer buf;
-  response.Write(&buf);
-  SendTo(buf.Data(), buf.Length(), addr, false);
-  LOG_J(LS_INFO, this) << "Sending STUN binding error: reason=" << reason
-                       << " to " << addr.ToString();
-}
-
-void Port::OnMessage(talk_base::Message *pmsg) {
-  ASSERT(pmsg->message_id == MSG_CHECKTIMEOUT);
-  ASSERT(lifetime_ == LT_PRETIMEOUT);
-  lifetime_ = LT_POSTTIMEOUT;
-  CheckTimeout();
-}
-
-std::string Port::ToString() const {
-  std::stringstream ss;
-  ss << "Port[" << name_ << ":" << generation_ << ":" << type_
-     << ":" << network_->ToString() << "]";
-  return ss.str();
-}
-
-void Port::EnablePortPackets() {
-  enable_port_packets_ = true;
-}
-
-void Port::Start() {
-  // The port sticks around for a minimum lifetime, after which
-  // we destroy it when it drops to zero connections.
-  if (lifetime_ == LT_PRESTART) {
-    lifetime_ = LT_PRETIMEOUT;
-    thread_->PostDelayed(kPortTimeoutDelay, this, MSG_CHECKTIMEOUT);
-  } else {
-    LOG_J(LS_WARNING, this) << "Port restart attempted";
-  }
-}
-
-void Port::OnConnectionDestroyed(Connection* conn) {
-  AddressMap::iterator iter =
-      connections_.find(conn->remote_candidate().address());
-  ASSERT(iter != connections_.end());
-  connections_.erase(iter);
-
-  CheckTimeout();
-}
-
-void Port::Destroy() {
-  ASSERT(connections_.empty());
-  LOG_J(LS_INFO, this) << "Port deleted";
-  SignalDestroyed(this);
-  delete this;
-}
-
-void Port::CheckTimeout() {
-  // If this port has no connections, then there's no reason to keep it around.
-  // When the connections time out (both read and write), they will delete
-  // themselves, so if we have any connections, they are either readable or
-  // writable (or still connecting).
-  if ((lifetime_ == LT_POSTTIMEOUT) && connections_.empty()) {
-    Destroy();
-  }
-}
-
-// A ConnectionRequest is a simple STUN ping used to determine writability.
-class ConnectionRequest : public StunRequest {
- public:
-  explicit ConnectionRequest(Connection* connection) : connection_(connection) {
-  }
-
-  virtual ~ConnectionRequest() {
-  }
-
-  virtual void Prepare(StunMessage* request) {
-    request->SetType(STUN_BINDING_REQUEST);
-    StunByteStringAttribute* username_attr =
-        StunAttribute::CreateByteString(STUN_ATTR_USERNAME);
-    std::string username = connection_->remote_candidate().username();
-    username.append(connection_->port()->username_fragment());
-    username_attr->CopyBytes(username.c_str(), username.size());
-    request->AddAttribute(username_attr);
-  }
-
-  virtual void OnResponse(StunMessage* response) {
-    connection_->OnConnectionRequestResponse(this, response);
-  }
-
-  virtual void OnErrorResponse(StunMessage* response) {
-    connection_->OnConnectionRequestErrorResponse(this, response);
-  }
-
-  virtual void OnTimeout() {
-    connection_->OnConnectionRequestTimeout(this);
-  }
-
-  virtual int GetNextDelay() {
-    // Each request is sent only once.  After a single delay , the request will
-    // time out.
-    timeout_ = true;
-    return CONNECTION_RESPONSE_TIMEOUT;
-  }
-
- private:
-  Connection* connection_;
-};
-
-//
-// Connection
-//
-
-Connection::Connection(Port* port, size_t index,
-                       const Candidate& remote_candidate)
-  : port_(port), local_candidate_index_(index),
-    remote_candidate_(remote_candidate), read_state_(STATE_READ_TIMEOUT),
-    write_state_(STATE_WRITE_CONNECT), connected_(true), pruned_(false),
-    requests_(port->thread()), rtt_(DEFAULT_RTT),
-    last_ping_sent_(0), last_ping_received_(0), last_data_received_(0),
-    reported_(false) {
-  // Wire up to send stun packets
-  requests_.SignalSendPacket.connect(this, &Connection::OnSendStunPacket);
-  LOG_J(LS_INFO, this) << "Connection created";
-}
-
-Connection::~Connection() {
-}
-
-const Candidate& Connection::local_candidate() const {
-  ASSERT(local_candidate_index_ < port_->candidates().size());
-  return port_->candidates()[local_candidate_index_];
-}
-
-void Connection::set_read_state(ReadState value) {
-  ReadState old_value = read_state_;
-  read_state_ = value;
-  if (value != old_value) {
-    LOG_J(LS_VERBOSE, this) << "set_read_state";
-    SignalStateChange(this);
-    CheckTimeout();
-  }
-}
-
-void Connection::set_write_state(WriteState value) {
-  WriteState old_value = write_state_;
-  write_state_ = value;
-  if (value != old_value) {
-    LOG_J(LS_VERBOSE, this) << "set_write_state";
-    SignalStateChange(this);
-    CheckTimeout();
-  }
-}
-
-void Connection::set_connected(bool value) {
-  bool old_value = connected_;
-  connected_ = value;
-  if (value != old_value) {
-    LOG_J(LS_VERBOSE, this) << "set_connected";
-  }
-}
-
-void Connection::OnSendStunPacket(const void* data, size_t size,
-                                  StunRequest* req) {
-  if (port_->SendTo(data, size, remote_candidate_.address(), false) < 0) {
-    LOG_J(LS_WARNING, this) << "Failed to send STUN ping " << req->id();
-  }
-}
-
-void Connection::OnReadPacket(const char* data, size_t size) {
-  StunMessage* msg;
-  std::string remote_username;
-  const talk_base::SocketAddress& addr(remote_candidate_.address());
-  if (!port_->GetStunMessage(data, size, addr, &msg, &remote_username)) {
-    // The packet did not parse as a valid STUN message
-
-    // If this connection is readable, then pass along the packet.
-    if (read_state_ == STATE_READABLE) {
-      // readable means data from this address is acceptable
-      // Send it on!
-
-      last_data_received_ = talk_base::Time();
-      recv_rate_tracker_.Update(size);
-      SignalReadPacket(this, data, size);
-
-      // If timed out sending writability checks, start up again
-      if (!pruned_ && (write_state_ == STATE_WRITE_TIMEOUT))
-        set_write_state(STATE_WRITE_CONNECT);
-    } else {
-      // Not readable means the remote address hasn't sent a valid
-      // binding request yet.
-
-      LOG_J(LS_WARNING, this)
-        << "Received non-STUN packet from an unreadable connection.";
-    }
-  } else if (!msg) {
-    // The packet was STUN, but was already handled internally.
-  } else if (remote_username != remote_candidate_.username()) {
-    // The packet had the right local username, but the remote username was
-    // not the right one for the remote address.
-    if (msg->type() == STUN_BINDING_REQUEST) {
-      LOG_J(LS_ERROR, this) << "Received STUN request with bad remote username "
-                            << remote_username;
-      port_->SendBindingErrorResponse(msg, addr, STUN_ERROR_BAD_REQUEST,
-                                      STUN_ERROR_REASON_BAD_REQUEST);
-    } else if (msg->type() == STUN_BINDING_RESPONSE ||
-               msg->type() == STUN_BINDING_ERROR_RESPONSE) {
-      LOG_J(LS_ERROR, this) << "Received STUN response with bad remote username"
-                            " " << remote_username;
-    }
-    delete msg;
-  } else {
-    // The packet is STUN, with the right username.
-    // If this is a STUN request, then update the readable bit and respond.
-    // If this is a STUN response, then update the writable bit.
-
-    switch (msg->type()) {
-    case STUN_BINDING_REQUEST:
-      // Incoming, validated stun request from remote peer.
-      // This call will also set the connection readable.
-
-      port_->SendBindingResponse(msg, addr);
-
-      // If timed out sending writability checks, start up again
-      if (!pruned_ && (write_state_ == STATE_WRITE_TIMEOUT))
-        set_write_state(STATE_WRITE_CONNECT);
-      break;
-
-    case STUN_BINDING_RESPONSE:
-    case STUN_BINDING_ERROR_RESPONSE:
-      // Response from remote peer. Does it match request sent?
-      // This doesn't just check, it makes callbacks if transaction
-      // id's match
-      requests_.CheckResponse(msg);
-      break;
-
-    default:
-      ASSERT(false);
-      break;
-    }
-
-    // Done with the message; delete
-
-    delete msg;
-  }
-}
-
-void Connection::Prune() {
-  if (!pruned_) {
-    LOG_J(LS_VERBOSE, this) << "Connection pruned";
-    pruned_ = true;
-    requests_.Clear();
-    set_write_state(STATE_WRITE_TIMEOUT);
-  }
-}
-
-void Connection::Destroy() {
-  LOG_J(LS_VERBOSE, this) << "Connection destroyed";
-  set_read_state(STATE_READ_TIMEOUT);
-  set_write_state(STATE_WRITE_TIMEOUT);
-}
-
-void Connection::UpdateState(uint32 now) {
-  uint32 rtt = ConservativeRTTEstimate(rtt_);
-
-  std::string pings;
-  for (size_t i = 0; i < pings_since_last_response_.size(); ++i) {
-    char buf[32];
-    talk_base::sprintfn(buf, sizeof(buf), "%u",
-        pings_since_last_response_[i]);
-    pings.append(buf).append(" ");
-  }
-  LOG_J(LS_VERBOSE, this) << "UpdateState(): pings_since_last_response_=" <<
-      pings << ", rtt=" << rtt << ", now=" << now;
-
-  // Check the readable state.
-  //
-  // Since we don't know how many pings the other side has attempted, the best
-  // test we can do is a simple window.
-
-  if ((read_state_ == STATE_READABLE) &&
-      (last_ping_received_ + CONNECTION_READ_TIMEOUT <= now)) {
-    LOG_J(LS_INFO, this) << "Unreadable after "
-                         << now - last_ping_received_
-                         << " ms without a ping, rtt=" << rtt;
-    set_read_state(STATE_READ_TIMEOUT);
-  }
-
-  // Check the writable state.  (The order of these checks is important.)
-  //
-  // Before becoming unwritable, we allow for a fixed number of pings to fail
-  // (i.e., receive no response).  We also have to give the response time to
-  // get back, so we include a conservative estimate of this.
-  //
-  // Before timing out writability, we give a fixed amount of time.  This is to
-  // allow for changes in network conditions.
-
-  if ((write_state_ == STATE_WRITABLE) &&
-      TooManyFailures(pings_since_last_response_,
-                      CONNECTION_WRITE_CONNECT_FAILURES,
-                      rtt,
-                      now) &&
-      TooLongWithoutResponse(pings_since_last_response_,
-                             CONNECTION_WRITE_CONNECT_TIMEOUT,
-                             now)) {
-    uint32 max_pings = CONNECTION_WRITE_CONNECT_FAILURES;
-    LOG_J(LS_INFO, this) << "Unwritable after " << max_pings
-                         << " ping failures and "
-                         << now - pings_since_last_response_[0]
-                         << " ms without a response,"
-                         << " ms since last received ping="
-                         << now - last_ping_received_
-                         << " ms since last received data="
-                         << now - last_data_received_
-                         << " rtt=" << rtt;
-    set_write_state(STATE_WRITE_CONNECT);
-  }
-
-  if ((write_state_ == STATE_WRITE_CONNECT) &&
-      TooLongWithoutResponse(pings_since_last_response_,
-                             CONNECTION_WRITE_TIMEOUT,
-                             now)) {
-    LOG_J(LS_INFO, this) << "Timed out after "
-                         << now - pings_since_last_response_[0]
-                         << " ms without a response, rtt=" << rtt;
-    set_write_state(STATE_WRITE_TIMEOUT);
-  }
-}
-
-void Connection::Ping(uint32 now) {
-  ASSERT(connected_);
-  last_ping_sent_ = now;
-  pings_since_last_response_.push_back(now);
-  ConnectionRequest *req = new ConnectionRequest(this);
-  LOG_J(LS_VERBOSE, this) << "Sending STUN ping " << req->id() << " at " << now;
-  requests_.Send(req);
-}
-
-void Connection::ReceivedPing() {
-  last_ping_received_ = talk_base::Time();
-  set_read_state(STATE_READABLE);
-}
-
-std::string Connection::ToString() const {
-  const char CONNECT_STATE_ABBREV[2] = {
-    '-',  // not connected (false)
-    'C',  // connected (true)
-  };
-  const char READ_STATE_ABBREV[2] = {
-    'R',  // STATE_READABLE
-    '-',  // STATE_READ_TIMEOUT
-  };
-  const char WRITE_STATE_ABBREV[3] = {
-    'W',  // STATE_WRITABLE
-    'w',  // STATE_WRITE_CONNECT
-    '-',  // STATE_WRITE_TIMEOUT
-  };
-  const Candidate& local = local_candidate();
-  const Candidate& remote = remote_candidate();
-  std::stringstream ss;
-  ss << "Conn[" << local.name() << ":" << local.generation()
-     << ":" << local.type() << ":" << local.protocol()
-     << ":" << local.address().ToString()
-     << "->" << remote.name() << ":" << remote.generation()
-     << ":" << remote.type() << ":"
-     << remote.protocol() << ":" << remote.address().ToString()
-     << "|"
-     << CONNECT_STATE_ABBREV[connected()]
-     << READ_STATE_ABBREV[read_state()]
-     << WRITE_STATE_ABBREV[write_state()]
-     << "|";
-  if (rtt_ < DEFAULT_RTT) {
-    ss << rtt_ << "]";
-  } else {
-    ss << "-]";
-  }
-  return ss.str();
-}
-
-void Connection::OnConnectionRequestResponse(ConnectionRequest* request,
-                                             StunMessage* response) {
-  // We've already validated that this is a STUN binding response with
-  // the correct local and remote username for this connection.
-  // So if we're not already, become writable. We may be bringing a pruned
-  // connection back to life, but if we don't really want it, we can always
-  // prune it again.
-  uint32 rtt = request->Elapsed();
-  set_write_state(STATE_WRITABLE);
-
-  std::string pings;
-  for (size_t i = 0; i < pings_since_last_response_.size(); ++i) {
-    char buf[32];
-    talk_base::sprintfn(buf, sizeof(buf), "%u",
-        pings_since_last_response_[i]);
-    pings.append(buf).append(" ");
-  }
-
-  LOG_J(LS_VERBOSE, this) << "Received STUN ping response " << request->id()
-                          << ", pings_since_last_response_=" << pings
-                          << ", rtt=" << rtt;
-
-  pings_since_last_response_.clear();
-  rtt_ = (RTT_RATIO * rtt_ + rtt) / (RTT_RATIO + 1);
-}
-
-void Connection::OnConnectionRequestErrorResponse(ConnectionRequest* request,
-                                                  StunMessage* response) {
-  const StunErrorCodeAttribute* error = response->GetErrorCode();
-  uint32 error_code = error ?
-      error->error_code() : static_cast<uint32>(STUN_ERROR_GLOBAL_FAILURE);
-
-  if ((error_code == STUN_ERROR_UNKNOWN_ATTRIBUTE)
-      || (error_code == STUN_ERROR_SERVER_ERROR)
-      || (error_code == STUN_ERROR_UNAUTHORIZED)) {
-    // Recoverable error, retry
-  } else if (error_code == STUN_ERROR_STALE_CREDENTIALS) {
-    // Race failure, retry
-  } else {
-    // This is not a valid connection.
-    LOG_J(LS_ERROR, this) << "Received STUN error response, code="
-                          << error_code << "; killing connection";
-    set_write_state(STATE_WRITE_TIMEOUT);
-  }
-}
-
-void Connection::OnConnectionRequestTimeout(ConnectionRequest* request) {
-  // Log at LS_INFO if we miss a ping on a writable connection.
-  talk_base::LoggingSeverity sev = (write_state_ == STATE_WRITABLE) ?
-      talk_base::LS_INFO : talk_base::LS_VERBOSE;
-  LOG_JV(sev, this) << "Timing-out STUN ping " << request->id()
-                    << " after " << request->Elapsed() << " ms";
-}
-
-void Connection::CheckTimeout() {
-  // If both read and write have timed out, then this connection can contribute
-  // no more to p2p socket unless at some later date readability were to come
-  // back.  However, we gave readability a long time to timeout, so at this
-  // point, it seems fair to get rid of this connection.
-  if ((read_state_ == STATE_READ_TIMEOUT) &&
-      (write_state_ == STATE_WRITE_TIMEOUT)) {
-    port_->thread()->Post(this, MSG_DELETE);
-  }
-}
-
-void Connection::OnMessage(talk_base::Message *pmsg) {
-  ASSERT(pmsg->message_id == MSG_DELETE);
-
-  LOG_J(LS_INFO, this) << "Connection deleted";
-  SignalDestroyed(this);
-  delete this;
-}
-
-size_t Connection::recv_bytes_second() {
-  return recv_rate_tracker_.units_second();
-}
-
-size_t Connection::recv_total_bytes() {
-  return recv_rate_tracker_.total_units();
-}
-
-size_t Connection::sent_bytes_second() {
-  return send_rate_tracker_.units_second();
-}
-
-size_t Connection::sent_total_bytes() {
-  return send_rate_tracker_.total_units();
-}
-
-ProxyConnection::ProxyConnection(Port* port, size_t index,
-                                 const Candidate& candidate)
-  : Connection(port, index, candidate), error_(0) {
-}
-
-int ProxyConnection::Send(const void* data, size_t size) {
-  if (write_state() != STATE_WRITABLE) {
-    error_ = EWOULDBLOCK;
-    return SOCKET_ERROR;
-  }
-  int sent = port_->SendTo(data, size, remote_candidate_.address(), true);
-  if (sent <= 0) {
-    ASSERT(sent < 0);
-    error_ = port_->GetError();
-  } else {
-    send_rate_tracker_.Update(sent);
-  }
-  return sent;
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/p2p/base/port.h b/third_party/libjingle/source/talk/p2p/base/port.h
deleted file mode 100644
index 396fce0..0000000
--- a/third_party/libjingle/source/talk/p2p/base/port.h
+++ /dev/null
@@ -1,424 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_P2P_BASE_PORT_H_
-#define TALK_P2P_BASE_PORT_H_
-
-#include <string>
-#include <vector>
-#include <map>
-
-#include "talk/base/network.h"
-#include "talk/base/packetsocketfactory.h"
-#include "talk/base/proxyinfo.h"
-#include "talk/base/ratetracker.h"
-#include "talk/base/sigslot.h"
-#include "talk/base/socketaddress.h"
-#include "talk/base/thread.h"
-#include "talk/p2p/base/candidate.h"
-#include "talk/p2p/base/stun.h"
-#include "talk/p2p/base/stunrequest.h"
-
-namespace talk_base {
-class AsyncPacketSocket;
-}
-
-namespace cricket {
-
-class Connection;
-class ConnectionRequest;
-
-enum ProtocolType {
-  PROTO_UDP,
-  PROTO_TCP,
-  PROTO_SSLTCP,
-  PROTO_LAST = PROTO_SSLTCP
-};
-
-const char* ProtoToString(ProtocolType proto);
-bool StringToProto(const char* value, ProtocolType* proto);
-
-struct ProtocolAddress {
-  talk_base::SocketAddress address;
-  ProtocolType proto;
-
-  ProtocolAddress(const talk_base::SocketAddress& a, ProtocolType p)
-    : address(a), proto(p) { }
-};
-
-// Represents a local communication mechanism that can be used to create
-// connections to similar mechanisms of the other client.  Subclasses of this
-// one add support for specific mechanisms like local UDP ports.
-class Port : public talk_base::MessageHandler, public sigslot::has_slots<> {
- public:
-  Port(talk_base::Thread* thread, const std::string& type,
-       talk_base::PacketSocketFactory* factory, talk_base::Network* network,
-       const talk_base::IPAddress& ip, int min_port, int max_port);
-  virtual ~Port();
-
-  // The thread on which this port performs its I/O.
-  talk_base::Thread* thread() { return thread_; }
-
-  // The factory used to create the sockets of this port.
-  talk_base::PacketSocketFactory* socket_factory() const { return factory_; }
-  void set_socket_factory(talk_base::PacketSocketFactory* factory) {
-    factory_ = factory;
-  }
-
-  // Each port is identified by a name (for debugging purposes).
-  const std::string& name() const { return name_; }
-  void set_name(const std::string& name) { name_ = name; }
-
-  // In order to establish a connection to this Port (so that real data can be
-  // sent through), the other side must send us a STUN binding request that is
-  // authenticated with this username and password.
-  // Fills in the username fragment and password.  These will be initially set
-  // in the constructor to random values.  Subclasses or tests can override.
-  // TODO: Change this to "username" rather than "username_fragment".
-  const std::string& username_fragment() const { return username_frag_; }
-  void set_username_fragment(const std::string& username) {
-    username_frag_ = username;
-  }
-
-  const std::string& password() const { return password_; }
-  void set_password(const std::string& password) { password_ = password; }
-
-
-  // A value in [0,1] that indicates the preference for this port versus other
-  // ports on this client.  (Larger indicates more preference.)
-  float preference() const { return preference_; }
-  void set_preference(float preference) { preference_ = preference; }
-
-  // Identifies the port type.
-  const std::string& type() const { return type_; }
-
-  // Identifies network that this port was allocated on.
-  talk_base::Network* network() { return network_; }
-
-  // Identifies the generation that this port was created in.
-  uint32 generation() { return generation_; }
-  void set_generation(uint32 generation) { generation_ = generation; }
-
-  // PrepareAddress will attempt to get an address for this port that other
-  // clients can send to.  It may take some time before the address is read.
-  // Once it is ready, we will send SignalAddressReady.  If errors are
-  // preventing the port from getting an address, it may send
-  // SignalAddressError.
-  virtual void PrepareAddress() = 0;
-  sigslot::signal1<Port*> SignalAddressReady;
-  sigslot::signal1<Port*> SignalAddressError;
-
-  // Provides all of the above information in one handy object.
-  const std::vector<Candidate>& candidates() const { return candidates_; }
-
-  // Returns a map containing all of the connections of this port, keyed by the
-  // remote address.
-  typedef std::map<talk_base::SocketAddress, Connection*> AddressMap;
-  const AddressMap& connections() { return connections_; }
-
-  // Returns the connection to the given address or NULL if none exists.
-  Connection* GetConnection(const talk_base::SocketAddress& remote_addr);
-
-  // Creates a new connection to the given address.
-  enum CandidateOrigin { ORIGIN_THIS_PORT, ORIGIN_OTHER_PORT, ORIGIN_MESSAGE };
-  virtual Connection* CreateConnection(const Candidate& remote_candidate,
-    CandidateOrigin origin) = 0;
-
-  // Called each time a connection is created.
-  sigslot::signal2<Port*, Connection*> SignalConnectionCreated;
-
-  // Sends the given packet to the given address, provided that the address is
-  // that of a connection or an address that has sent to us already.
-  virtual int SendTo(
-      const void* data, size_t size, const talk_base::SocketAddress& addr,
-      bool payload) = 0;
-
-  // Indicates that we received a successful STUN binding request from an
-  // address that doesn't correspond to any current connection.  To turn this
-  // into a real connection, call CreateConnection.
-  sigslot::signal4<Port*, const talk_base::SocketAddress&, StunMessage*,
-                   const std::string&> SignalUnknownAddress;
-
-  // Sends a response message (normal or error) to the given request.  One of
-  // these methods should be called as a response to SignalUnknownAddress.
-  // NOTE: You MUST call CreateConnection BEFORE SendBindingResponse.
-  void SendBindingResponse(StunMessage* request,
-                           const talk_base::SocketAddress& addr);
-  void SendBindingErrorResponse(
-      StunMessage* request, const talk_base::SocketAddress& addr,
-      int error_code, const std::string& reason);
-
-  // Indicates that errors occurred when performing I/O.
-  sigslot::signal2<Port*, int> SignalReadError;
-  sigslot::signal2<Port*, int> SignalWriteError;
-
-  // Functions on the underlying socket(s).
-  virtual int SetOption(talk_base::Socket::Option opt, int value) = 0;
-  virtual int GetError() = 0;
-
-  void set_proxy(const std::string& user_agent,
-                 const talk_base::ProxyInfo& proxy) {
-    user_agent_ = user_agent;
-    proxy_ = proxy;
-  }
-  const std::string& user_agent() { return user_agent_; }
-  const talk_base::ProxyInfo& proxy() { return proxy_; }
-
-  // Normally, packets arrive through a connection (or they result signaling of
-  // unknown address).  Calling this method turns off delivery of packets
-  // through their respective connection and instead delivers every packet
-  // through this port.
-  void EnablePortPackets();
-  sigslot::signal4<Port*, const char*, size_t, const talk_base::SocketAddress&>
-      SignalReadPacket;
-
-  // Indicates to the port that its official use has now begun.  This will
-  // start the timer that checks to see if the port is being used.
-  void Start();
-
-  // Called if the port has no connections and is no longer useful.
-  void Destroy();
-
-  // Signaled when this port decides to delete itself because it no longer has
-  // any usefulness.
-  sigslot::signal1<Port*> SignalDestroyed;
-
-  virtual void OnMessage(talk_base::Message *pmsg);
-
-  // Debugging description of this port
-  std::string ToString() const;
-
- protected:
-  // Fills in the local address of the port.
-  void AddAddress(const talk_base::SocketAddress& address,
-                  const std::string& protocol, bool final);
-
-  // Adds the given connection to the list.  (Deleting removes them.)
-  void AddConnection(Connection* conn);
-
-  // Called when a packet is received from an unknown address that is not
-  // currently a connection.  If this is an authenticated STUN binding request,
-  // then we will signal the client.
-  void OnReadPacket(const char* data, size_t size,
-                    const talk_base::SocketAddress& addr);
-
-
-  // If the given data comprises a complete and correct STUN message then the
-  // return value is true, otherwise false. If the message username corresponds
-  // with this port's username fragment, msg will contain the parsed STUN
-  // message.  Otherwise, the function may send a STUN response internally.
-  // remote_username contains the remote fragment of the STUN username.
-  bool GetStunMessage(const char* data, size_t size,
-                      const talk_base::SocketAddress& addr,
-                      StunMessage** out_msg, std::string* out_username);
-
-  // TODO: make these members private
-  talk_base::Thread* thread_;
-  talk_base::PacketSocketFactory* factory_;
-  std::string type_;
-  talk_base::Network* network_;
-  talk_base::IPAddress ip_;
-  int min_port_;
-  int max_port_;
-  uint32 generation_;
-  std::string name_;
-  std::string username_frag_;
-  std::string password_;
-  float preference_;
-  std::vector<Candidate> candidates_;
-  AddressMap connections_;
-  enum Lifetime { LT_PRESTART, LT_PRETIMEOUT, LT_POSTTIMEOUT } lifetime_;
-  bool enable_port_packets_;
-
- private:
-  // Called when one of our connections deletes itself.
-  void OnConnectionDestroyed(Connection* conn);
-
-  // Checks if this port is useless, and hence, should be destroyed.
-  void CheckTimeout();
-
-  // Information to use when going through a proxy.
-  std::string user_agent_;
-  talk_base::ProxyInfo proxy_;
-
-  friend class Connection;
-};
-
-// Represents a communication link between a port on the local client and a
-// port on the remote client.
-class Connection : public talk_base::MessageHandler,
-    public sigslot::has_slots<> {
- public:
-  virtual ~Connection();
-
-  // The local port where this connection sends and receives packets.
-  Port* port() { return port_; }
-  const Port* port() const { return port_; }
-
-  // Returns the description of the local port
-  virtual const Candidate& local_candidate() const;
-
-  // Returns the description of the remote port to which we communicate.
-  const Candidate& remote_candidate() const { return remote_candidate_; }
-
-  enum ReadState {
-    STATE_READABLE     = 0,  // we have received pings recently
-    STATE_READ_TIMEOUT = 1   // we haven't received pings in a while
-  };
-
-  ReadState read_state() const { return read_state_; }
-
-  enum WriteState {
-    STATE_WRITABLE      = 0,  // we have received ping responses recently
-    STATE_WRITE_CONNECT = 1,  // we have had a few ping failures
-    STATE_WRITE_TIMEOUT = 2   // we have had a large number of ping failures
-  };
-
-  WriteState write_state() const { return write_state_; }
-
-  // Determines whether the connection has finished connecting.  This can only
-  // be false for TCP connections.
-  bool connected() const { return connected_; }
-
-  // Estimate of the round-trip time over this connection.
-  uint32 rtt() const { return rtt_; }
-
-  size_t sent_total_bytes();
-  size_t sent_bytes_second();
-  size_t recv_total_bytes();
-  size_t recv_bytes_second();
-  sigslot::signal1<Connection*> SignalStateChange;
-
-  // Sent when the connection has decided that it is no longer of value.  It
-  // will delete itself immediately after this call.
-  sigslot::signal1<Connection*> SignalDestroyed;
-
-  // The connection can send and receive packets asynchronously.  This matches
-  // the interface of AsyncPacketSocket, which may use UDP or TCP under the
-  // covers.
-  virtual int Send(const void* data, size_t size) = 0;
-
-  // Error if Send() returns < 0
-  virtual int GetError() = 0;
-
-  sigslot::signal3<Connection*, const char*, size_t> SignalReadPacket;
-
-  // Called when a packet is received on this connection.
-  void OnReadPacket(const char* data, size_t size);
-
-  // Called when a connection is determined to be no longer useful to us.  We
-  // still keep it around in case the other side wants to use it.  But we can
-  // safely stop pinging on it and we can allow it to time out if the other
-  // side stops using it as well.
-  bool pruned() const { return pruned_; }
-  void Prune();
-
-  // Makes the connection go away.
-  void Destroy();
-
-  // Checks that the state of this connection is up-to-date.  The argument is
-  // the current time, which is compared against various timeouts.
-  void UpdateState(uint32 now);
-
-  // Called when this connection should try checking writability again.
-  uint32 last_ping_sent() const { return last_ping_sent_; }
-  void Ping(uint32 now);
-
-  // Called whenever a valid ping is received on this connection.  This is
-  // public because the connection intercepts the first ping for us.
-  void ReceivedPing();
-
-  // Debugging description of this connection
-  std::string ToString() const;
-
-  bool reported() const { return reported_; }
-  void set_reported(bool reported) { reported_ = reported;}
-
- protected:
-  // Constructs a new connection to the given remote port.
-  Connection(Port* port, size_t index, const Candidate& candidate);
-
-  // Called back when StunRequestManager has a stun packet to send
-  void OnSendStunPacket(const void* data, size_t size, StunRequest* req);
-
-  // Callbacks from ConnectionRequest
-  void OnConnectionRequestResponse(ConnectionRequest* req,
-                                   StunMessage* response);
-  void OnConnectionRequestErrorResponse(ConnectionRequest* req,
-                                        StunMessage* response);
-  void OnConnectionRequestTimeout(ConnectionRequest* req);
-
-  // Changes the state and signals if necessary.
-  void set_read_state(ReadState value);
-  void set_write_state(WriteState value);
-  void set_connected(bool value);
-
-  // Checks if this connection is useless, and hence, should be destroyed.
-  void CheckTimeout();
-
-  void OnMessage(talk_base::Message *pmsg);
-
-  Port* port_;
-  size_t local_candidate_index_;
-  Candidate remote_candidate_;
-  ReadState read_state_;
-  WriteState write_state_;
-  bool connected_;
-  bool pruned_;
-  StunRequestManager requests_;
-  uint32 rtt_;
-  uint32 last_ping_sent_;      // last time we sent a ping to the other side
-  uint32 last_ping_received_;  // last time we received a ping from the other
-                               // side
-  uint32 last_data_received_;
-  std::vector<uint32> pings_since_last_response_;
-
-  talk_base::RateTracker recv_rate_tracker_;
-  talk_base::RateTracker send_rate_tracker_;
-
- private:
-  bool reported_;
-
-  friend class Port;
-  friend class ConnectionRequest;
-};
-
-// ProxyConnection defers all the interesting work to the port
-class ProxyConnection : public Connection {
- public:
-  ProxyConnection(Port* port, size_t index, const Candidate& candidate);
-
-  virtual int Send(const void* data, size_t size);
-  virtual int GetError() { return error_; }
-
- private:
-  int error_;
-};
-
-}  // namespace cricket
-
-#endif  // TALK_P2P_BASE_PORT_H_
diff --git a/third_party/libjingle/source/talk/p2p/base/port_unittest.cc b/third_party/libjingle/source/talk/p2p/base/port_unittest.cc
deleted file mode 100644
index 1bdac3d..0000000
--- a/third_party/libjingle/source/talk/p2p/base/port_unittest.cc
+++ /dev/null
@@ -1,760 +0,0 @@
-/*
- * libjingle
- * Copyright 2004 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/basicpacketsocketfactory.h"
-#include "talk/base/gunit.h"
-#include "talk/base/helpers.h"
-#include "talk/base/host.h"
-#include "talk/base/logging.h"
-#include "talk/base/natserver.h"
-#include "talk/base/natsocketfactory.h"
-#include "talk/base/physicalsocketserver.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/base/socketaddress.h"
-#include "talk/base/stringutils.h"
-#include "talk/base/thread.h"
-#include "talk/base/virtualsocketserver.h"
-#include "talk/p2p/base/relayport.h"
-#include "talk/p2p/base/stunport.h"
-#include "talk/p2p/base/tcpport.h"
-#include "talk/p2p/base/udpport.h"
-#include "talk/p2p/base/teststunserver.h"
-#include "talk/p2p/base/testrelayserver.h"
-
-using talk_base::AsyncPacketSocket;
-using talk_base::NATType;
-using talk_base::NAT_OPEN_CONE;
-using talk_base::NAT_ADDR_RESTRICTED;
-using talk_base::NAT_PORT_RESTRICTED;
-using talk_base::NAT_SYMMETRIC;
-using talk_base::PacketSocketFactory;
-using talk_base::scoped_ptr;
-using talk_base::Socket;
-using talk_base::SocketAddress;
-using namespace cricket;
-
-static const int kTimeout = 1000;
-static const SocketAddress kLocalAddr1 = SocketAddress("192.168.1.2", 0);
-static const SocketAddress kLocalAddr2 = SocketAddress("192.168.1.3", 0);
-static const SocketAddress kNatAddr1 = SocketAddress("77.77.77.77",
-                                                    talk_base::NAT_SERVER_PORT);
-static const SocketAddress kNatAddr2 = SocketAddress("88.88.88.88",
-                                                    talk_base::NAT_SERVER_PORT);
-static const SocketAddress kStunAddr = SocketAddress("99.99.99.1",
-                                                     STUN_SERVER_PORT);
-static const SocketAddress kRelayUdpIntAddr("99.99.99.2", 5000);
-static const SocketAddress kRelayUdpExtAddr("99.99.99.3", 5001);
-static const SocketAddress kRelayTcpIntAddr("99.99.99.2", 5002);
-static const SocketAddress kRelayTcpExtAddr("99.99.99.3", 5003);
-static const SocketAddress kRelaySslTcpIntAddr("99.99.99.2", 5004);
-static const SocketAddress kRelaySslTcpExtAddr("99.99.99.3", 5005);
-
-static Candidate GetCandidate(Port* port) {
-  assert(port->candidates().size() == 1);
-  return port->candidates()[0];
-}
-
-static SocketAddress GetAddress(Port* port) {
-  return GetCandidate(port).address();
-}
-
-class TestChannel : public sigslot::has_slots<> {
- public:
-  TestChannel(Port* p1, Port* p2)
-      : src_(p1), dst_(p2), address_count_(0), conn_(NULL),
-        remote_request_(NULL) {
-    src_->SignalAddressReady.connect(this, &TestChannel::OnAddressReady);
-    src_->SignalUnknownAddress.connect(this, &TestChannel::OnUnknownAddress);
-  }
-
-  int address_count() { return address_count_; }
-  Connection* conn() { return conn_; }
-  const SocketAddress& remote_address() { return remote_address_; }
-  const std::string remote_fragment() { return remote_frag_; }
-
-  void Start() {
-    src_->PrepareAddress();
-  }
-  void CreateConnection() {
-    conn_ = src_->CreateConnection(GetCandidate(dst_), Port::ORIGIN_MESSAGE);
-  }
-  void AcceptConnection() {
-    ASSERT_TRUE(remote_request_ != NULL);
-    Candidate c = GetCandidate(dst_);
-    c.set_address(remote_address_);
-    conn_ = src_->CreateConnection(c, Port::ORIGIN_MESSAGE);
-    src_->SendBindingResponse(remote_request_, remote_address_);
-    delete remote_request_;
-  }
-  void Ping() {
-    conn_->Ping(0);
-  }
-  void Stop() {
-    conn_->SignalDestroyed.connect(this, &TestChannel::OnDestroyed);
-    conn_->Destroy();
-  }
-
-  void OnAddressReady(Port* port) {
-    address_count_++;
-  }
-
-  void OnUnknownAddress(Port* port, const SocketAddress& addr,
-                        StunMessage* msg, const std::string& rf) {
-    ASSERT_EQ(src_.get(), port);
-    if (!remote_address_.IsAny()) {
-      ASSERT_EQ(remote_address_, addr);
-      delete remote_request_;
-    }
-    remote_address_ = addr;
-    remote_request_ = msg;
-    remote_frag_ = rf;
-  }
-
-  void OnDestroyed(Connection* conn) {
-    ASSERT_EQ(conn_, conn);
-    conn_ = NULL;
-  }
-
- private:
-  talk_base::Thread* thread_;
-  talk_base::scoped_ptr<Port> src_;
-  Port* dst_;
-
-  int address_count_;
-  Connection* conn_;
-  SocketAddress remote_address_;
-  StunMessage* remote_request_;
-  std::string remote_frag_;
-};
-
-class PortTest : public testing::Test {
- public:
-  PortTest()
-      : main_(talk_base::Thread::Current()),
-        pss_(new talk_base::PhysicalSocketServer),
-        ss_(new talk_base::VirtualSocketServer(pss_.get())),
-        ss_scope_(ss_.get()),
-        network_("unittest", "unittest", talk_base::IPAddress(INADDR_ANY)),
-        socket_factory_(talk_base::Thread::Current()),
-        nat_factory1_(ss_.get(), kNatAddr1),
-        nat_factory2_(ss_.get(), kNatAddr2),
-        nat_socket_factory1_(&nat_factory1_),
-        nat_socket_factory2_(&nat_factory2_),
-        stun_server_(main_, kStunAddr),
-        relay_server_(main_, kRelayUdpIntAddr, kRelayUdpExtAddr,
-                      kRelayTcpIntAddr, kRelayTcpExtAddr,
-                      kRelaySslTcpIntAddr, kRelaySslTcpExtAddr) {
-  }
-
- protected:
-  static void SetUpTestCase() {
-    // Ensure the RNG is inited.
-    talk_base::InitRandom(NULL, 0);
-  }
-
-  void TestLocalToLocal() {
-    UDPPort* port1 = CreateUdpPort(kLocalAddr1);
-    UDPPort* port2 = CreateUdpPort(kLocalAddr2);
-    TestConnectivity("udp", port1, "udp", port2, true, true, true, true);
-  }
-  void TestLocalToStun(NATType type) {
-    UDPPort* port1 = CreateUdpPort(kLocalAddr1);
-    nat_server2_.reset(CreateNatServer(kNatAddr2, type));
-    StunPort* port2 = CreateStunPort(kLocalAddr2, &nat_socket_factory2_);
-    TestConnectivity("udp", port1, StunName(type), port2,
-                     type == NAT_OPEN_CONE, true, type != NAT_SYMMETRIC, true);
-  }
-  void TestLocalToRelay(ProtocolType proto) {
-    UDPPort* port1 = CreateUdpPort(kLocalAddr1);
-    RelayPort* port2 = CreateRelayPort(kLocalAddr2, proto, PROTO_UDP);
-    TestConnectivity("udp", port1, RelayName(proto), port2,
-                     true, true, true, true);
-  }
-  void TestStunToLocal(NATType type) {
-    nat_server1_.reset(CreateNatServer(kNatAddr1, type));
-    StunPort* port1 = CreateStunPort(kLocalAddr1, &nat_socket_factory1_);
-    UDPPort* port2 = CreateUdpPort(kLocalAddr2);
-    TestConnectivity(StunName(type), port1, "udp", port2,
-                     true, type != NAT_SYMMETRIC, true, true);
-  }
-  void TestStunToStun(NATType type1, NATType type2) {
-    nat_server1_.reset(CreateNatServer(kNatAddr1, type1));
-    StunPort* port1 = CreateStunPort(kLocalAddr1, &nat_socket_factory1_);
-    nat_server2_.reset(CreateNatServer(kNatAddr2, type2));
-    StunPort* port2 = CreateStunPort(kLocalAddr2, &nat_socket_factory2_);
-    TestConnectivity(StunName(type1), port1, StunName(type2), port2,
-                     type2 == NAT_OPEN_CONE,
-                     type1 != NAT_SYMMETRIC, type2 != NAT_SYMMETRIC,
-                     type1 + type2 < (NAT_PORT_RESTRICTED + NAT_SYMMETRIC));
-  }
-  void TestStunToRelay(NATType type, ProtocolType proto) {
-    nat_server1_.reset(CreateNatServer(kNatAddr1, type));
-    StunPort* port1 = CreateStunPort(kLocalAddr1, &nat_socket_factory1_);
-    RelayPort* port2 = CreateRelayPort(kLocalAddr2, proto, PROTO_UDP);
-    TestConnectivity(StunName(type), port1, RelayName(proto), port2,
-                     true, type != NAT_SYMMETRIC, true, true);
-  }
-  void TestTcpToTcp() {
-    TCPPort* port1 = CreateTcpPort(kLocalAddr1);
-    TCPPort* port2 = CreateTcpPort(kLocalAddr2);
-    TestConnectivity("tcp", port1, "tcp", port2, true, false, true, true);
-  }
-  void TestTcpToRelay(ProtocolType proto) {
-    TCPPort* port1 = CreateTcpPort(kLocalAddr1);
-    RelayPort* port2 = CreateRelayPort(kLocalAddr2, proto, PROTO_TCP);
-    TestConnectivity("tcp", port1, RelayName(proto), port2,
-                     true, false, true, true);
-  }
-  void TestSslTcpToRelay(ProtocolType proto) {
-    TCPPort* port1 = CreateTcpPort(kLocalAddr1);
-    RelayPort* port2 = CreateRelayPort(kLocalAddr2, proto, PROTO_SSLTCP);
-    TestConnectivity("ssltcp", port1, RelayName(proto), port2,
-                     true, false, true, true);
-  }
-
-  // helpers for above functions
-  UDPPort* CreateUdpPort(const SocketAddress& addr) {
-    return CreateUdpPort(addr, &socket_factory_);
-  }
-  UDPPort* CreateUdpPort(const SocketAddress& addr,
-                         PacketSocketFactory* socket_factory) {
-    return UDPPort::Create(main_, socket_factory, &network_,
-                           addr.ipaddr(), 0, 0);
-  }
-  TCPPort* CreateTcpPort(const SocketAddress& addr) {
-    return CreateTcpPort(addr, &socket_factory_);
-  }
-  TCPPort* CreateTcpPort(const SocketAddress& addr,
-                         PacketSocketFactory* socket_factory) {
-    return TCPPort::Create(main_, socket_factory, &network_,
-                           addr.ipaddr(), 0, 0, true);
-  }
-  StunPort* CreateStunPort(const SocketAddress& addr,
-                           talk_base::PacketSocketFactory* factory) {
-    return StunPort::Create(main_, factory, &network_,
-                            addr.ipaddr(), 0, 0, kStunAddr);
-  }
-  RelayPort* CreateRelayPort(const SocketAddress& addr,
-                             ProtocolType int_proto, ProtocolType ext_proto) {
-    std::string user = talk_base::CreateRandomString(16);
-    std::string pass = talk_base::CreateRandomString(16);
-    RelayPort* port = RelayPort::Create(main_, &socket_factory_, &network_,
-                                        addr.ipaddr(), 0, 0, user, pass, "");
-    SocketAddress addrs[] =
-        { kRelayUdpIntAddr, kRelayTcpIntAddr, kRelaySslTcpIntAddr };
-    port->AddServerAddress(ProtocolAddress(addrs[int_proto], int_proto));
-    // TODO: Add an external address for ext_proto, so that the
-    // other side can connect to this port using a non-UDP protocol.
-    return port;
-  }
-  talk_base::NATServer* CreateNatServer(const SocketAddress& addr,
-                                        talk_base::NATType type) {
-    return new talk_base::NATServer(type, ss_.get(), addr, ss_.get(), addr);
-  }
-  static const char* StunName(NATType type) {
-    switch (type) {
-      case NAT_OPEN_CONE:       return "stun(open cone)";
-      case NAT_ADDR_RESTRICTED: return "stun(addr restricted)";
-      case NAT_PORT_RESTRICTED: return "stun(port restricted)";
-      case NAT_SYMMETRIC:       return "stun(symmetric)";
-      default:                  return "stun(?)";
-    }
-  }
-  static const char* RelayName(ProtocolType type) {
-    switch (type) {
-      case PROTO_UDP:           return "relay(udp)";
-      case PROTO_TCP:           return "relay(tcp)";
-      case PROTO_SSLTCP:        return "relay(ssltcp)";
-      default:                  return "relay(?)";
-    }
-  }
-
-  // this does all the work
-  void TestConnectivity(const char* name1, Port* port1,
-                        const char* name2, Port* port2,
-                        bool accept, bool same_addr1,
-                        bool same_addr2, bool possible);
-
- private:
-  talk_base::Thread* main_;
-  talk_base::scoped_ptr<talk_base::PhysicalSocketServer> pss_;
-  talk_base::scoped_ptr<talk_base::VirtualSocketServer> ss_;
-  talk_base::SocketServerScope ss_scope_;
-  talk_base::Network network_;
-  talk_base::BasicPacketSocketFactory socket_factory_;
-  talk_base::scoped_ptr<talk_base::NATServer> nat_server1_;
-  talk_base::scoped_ptr<talk_base::NATServer> nat_server2_;
-  talk_base::NATSocketFactory nat_factory1_;
-  talk_base::NATSocketFactory nat_factory2_;
-  talk_base::BasicPacketSocketFactory nat_socket_factory1_;
-  talk_base::BasicPacketSocketFactory nat_socket_factory2_;
-  TestStunServer stun_server_;
-  TestRelayServer relay_server_;
-};
-
-void PortTest::TestConnectivity(const char* name1, Port* port1,
-                                const char* name2, Port* port2,
-                                bool accept, bool same_addr1,
-                                bool same_addr2, bool possible) {
-  LOG(LS_INFO) << "Test: " << name1 << " to " << name2 << ": ";
-  port1->set_name("src");
-  port2->set_name("dst");
-
-  // Set up channels.
-  TestChannel ch1(port1, port2);
-  TestChannel ch2(port2, port1);
-  EXPECT_EQ(0, ch1.address_count());
-  EXPECT_EQ(0, ch2.address_count());
-
-  // Acquire addresses.
-  ch1.Start();
-  ch2.Start();
-  ASSERT_EQ_WAIT(1, ch1.address_count(), kTimeout);
-  ASSERT_EQ_WAIT(1, ch2.address_count(), kTimeout);
-
-  // Send a ping from src to dst. This may or may not make it.
-  ch1.CreateConnection();
-  ASSERT_TRUE(ch1.conn() != NULL);
-  EXPECT_TRUE_WAIT(ch1.conn()->connected(), kTimeout);  // for TCP connect
-  ch1.Ping();
-  WAIT(!ch2.remote_address().IsAny(), kTimeout);
-
-  if (accept) {
-    // We are able to send a ping from src to dst. This is the case when
-    // sending to UDP ports and cone NATs.
-    EXPECT_TRUE(ch1.remote_address().IsAny());
-    EXPECT_EQ(ch2.remote_fragment(), port1->username_fragment());
-
-    // Ensure the ping came from the same address used for src.
-    // This is the case unless the source NAT was symmetric.
-    if (same_addr1) EXPECT_EQ(ch2.remote_address(), GetAddress(port1));
-    EXPECT_TRUE(same_addr2);
-
-    // Send a ping from dst to src.
-    ch2.AcceptConnection();
-    ASSERT_TRUE(ch2.conn() != NULL);
-    ch2.Ping();
-    EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, ch2.conn()->write_state(),
-                   kTimeout);
-  } else {
-    // We can't send a ping from src to dst, so flip it around. This will happen
-    // when the destination NAT is addr/port restricted or symmetric.
-    EXPECT_TRUE(ch1.remote_address().IsAny());
-    EXPECT_TRUE(ch2.remote_address().IsAny());
-
-    // Send a ping from dst to src. Again, this may or may not make it.
-    ch2.CreateConnection();
-    ASSERT_TRUE(ch2.conn() != NULL);
-    ch2.Ping();
-    WAIT(ch2.conn()->write_state() == Connection::STATE_WRITABLE, kTimeout);
-
-    if (same_addr1 && same_addr2) {
-      // The new ping got back to the source.
-      EXPECT_EQ(Connection::STATE_READABLE, ch1.conn()->read_state());
-      EXPECT_EQ(Connection::STATE_WRITABLE, ch2.conn()->write_state());
-
-      // First connection may not be writable if the first ping did not get
-      // through.  So we will have to do another.
-      if (ch1.conn()->write_state() == Connection::STATE_WRITE_CONNECT) {
-        ch1.Ping();
-        EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, ch1.conn()->write_state(),
-                       kTimeout);
-      }
-    } else if (!same_addr1 && possible) {
-      // The new ping went to the candidate address, but that address was bad.
-      // This will happen when the source NAT is symmetric.
-      EXPECT_TRUE(ch1.remote_address().IsAny());
-      EXPECT_TRUE(ch2.remote_address().IsAny());
-
-      // However, since we have now sent a ping to the source IP, we should be
-      // able to get a ping from it. This gives us the real source address.
-      ch1.Ping();
-      EXPECT_TRUE_WAIT(!ch2.remote_address().IsAny(), kTimeout);
-      EXPECT_EQ(Connection::STATE_READ_TIMEOUT, ch2.conn()->read_state());
-      EXPECT_TRUE(ch1.remote_address().IsAny());
-
-      // Pick up the actual address and establish the connection.
-      ch2.AcceptConnection();
-      ASSERT_TRUE(ch2.conn() != NULL);
-      ch2.Ping();
-      EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, ch2.conn()->write_state(),
-                     kTimeout);
-    } else if (!same_addr2 && possible) {
-      // The new ping came in, but from an unexpected address. This will happen
-      // when the destination NAT is symmetric.
-      EXPECT_FALSE(ch1.remote_address().IsAny());
-      EXPECT_EQ(Connection::STATE_READ_TIMEOUT, ch1.conn()->read_state());
-
-      // Update our address and complete the connection.
-      ch1.AcceptConnection();
-      ch1.Ping();
-      EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, ch1.conn()->write_state(),
-                     kTimeout);
-    } else {  // (!possible)
-      // There should be s no way for the pings to reach each other. Check it.
-      EXPECT_TRUE(ch1.remote_address().IsAny());
-      EXPECT_TRUE(ch2.remote_address().IsAny());
-      ch1.Ping();
-      WAIT(!ch2.remote_address().IsAny(), kTimeout);
-      EXPECT_TRUE(ch1.remote_address().IsAny());
-      EXPECT_TRUE(ch2.remote_address().IsAny());
-    }
-  }
-
-  // Everything should be good, unless we know the situation is impossible.
-  ASSERT_TRUE(ch1.conn() != NULL);
-  ASSERT_TRUE(ch2.conn() != NULL);
-  if (possible) {
-    EXPECT_EQ(Connection::STATE_READABLE, ch1.conn()->read_state());
-    EXPECT_EQ(Connection::STATE_WRITABLE, ch1.conn()->write_state());
-    EXPECT_EQ(Connection::STATE_READABLE, ch2.conn()->read_state());
-    EXPECT_EQ(Connection::STATE_WRITABLE, ch2.conn()->write_state());
-  } else {
-    EXPECT_NE(Connection::STATE_READABLE, ch1.conn()->read_state());
-    EXPECT_NE(Connection::STATE_WRITABLE, ch1.conn()->write_state());
-    EXPECT_NE(Connection::STATE_READABLE, ch2.conn()->read_state());
-    EXPECT_NE(Connection::STATE_WRITABLE, ch2.conn()->write_state());
-  }
-
-  // Tear down and ensure that goes smoothly.
-  ch1.Stop();
-  ch2.Stop();
-  EXPECT_TRUE_WAIT(ch1.conn() == NULL, kTimeout);
-  EXPECT_TRUE_WAIT(ch2.conn() == NULL, kTimeout);
-}
-
-class FakePacketSocketFactory : public talk_base::PacketSocketFactory {
- public:
-  FakePacketSocketFactory()
-      : next_udp_socket_(NULL),
-        next_server_tcp_socket_(NULL),
-        next_client_tcp_socket_(NULL) {
-  }
-  virtual ~FakePacketSocketFactory() { }
-
-  virtual AsyncPacketSocket* CreateUdpSocket(
-      const SocketAddress& address, int min_port, int max_port) {
-    EXPECT_TRUE(next_udp_socket_ != NULL);
-    AsyncPacketSocket* result = next_udp_socket_;
-    next_udp_socket_ = NULL;
-    return result;
-  }
-
-  virtual AsyncPacketSocket* CreateServerTcpSocket(
-      const SocketAddress& local_address, int min_port, int max_port,
-      bool ssl) {
-    EXPECT_TRUE(next_server_tcp_socket_ != NULL);
-    AsyncPacketSocket* result = next_server_tcp_socket_;
-    next_server_tcp_socket_ = NULL;
-    return result;
-  }
-
-  // TODO: |proxy_info| and |user_agent| should be set
-  // per-factory and not when socket is created.
-  virtual AsyncPacketSocket* CreateClientTcpSocket(
-      const SocketAddress& local_address, const SocketAddress& remote_address,
-      const talk_base::ProxyInfo& proxy_info,
-      const std::string& user_agent, bool ssl) {
-    EXPECT_TRUE(next_client_tcp_socket_ != NULL);
-    AsyncPacketSocket* result = next_client_tcp_socket_;
-    next_client_tcp_socket_ = NULL;
-    return result;
-  }
-
-  void set_next_udp_socket(AsyncPacketSocket* next_udp_socket) {
-    next_udp_socket_ = next_udp_socket;
-  }
-  void set_next_server_tcp_socket(AsyncPacketSocket* next_server_tcp_socket) {
-    next_server_tcp_socket_ = next_server_tcp_socket;
-  }
-  void set_next_client_tcp_socket(AsyncPacketSocket* next_client_tcp_socket) {
-    next_client_tcp_socket_ = next_client_tcp_socket;
-  }
-
- private:
-  AsyncPacketSocket* next_udp_socket_;
-  AsyncPacketSocket* next_server_tcp_socket_;
-  AsyncPacketSocket* next_client_tcp_socket_;
-};
-
-class FakeAsyncPacketSocket : public AsyncPacketSocket {
- public:
-  // Returns current local address. Address may be set to NULL if the
-  // socket is not bound yet (GetState() returns STATE_BINDING).
-  virtual SocketAddress GetLocalAddress() const {
-    return SocketAddress();
-  }
-
-  // Returns remote address. Returns zeroes if this is not a client TCP socket.
-  virtual SocketAddress GetRemoteAddress() const {
-    return SocketAddress();
-  }
-
-  // Send a packet.
-  virtual int Send(const void *pv, size_t cb) {
-    return cb;
-  }
-  virtual int SendTo(const void *pv, size_t cb, const SocketAddress& addr) {
-    return cb;
-  }
-  virtual int Close() {
-    return 0;
-  }
-
-  virtual State GetState() const { return state_; }
-  virtual int GetOption(Socket::Option opt, int* value) { return 0; }
-  virtual int SetOption(Socket::Option opt, int value) { return 0; }
-  virtual int GetError() const { return 0; }
-  virtual void SetError(int error) { }
-
-  void set_state(State state) { state_ = state; }
-
- private:
-  State state_;
-};
-
-// Local -> XXXX
-TEST_F(PortTest, TestLocalToLocal) {
-  TestLocalToLocal();
-}
-
-TEST_F(PortTest, TestLocalToConeNat) {
-  TestLocalToStun(NAT_OPEN_CONE);
-}
-
-TEST_F(PortTest, TestLocalToARNat) {
-  TestLocalToStun(NAT_ADDR_RESTRICTED);
-}
-
-TEST_F(PortTest, TestLocalToPRNat) {
-  TestLocalToStun(NAT_PORT_RESTRICTED);
-}
-
-TEST_F(PortTest, TestLocalToSymNat) {
-  TestLocalToStun(NAT_SYMMETRIC);
-}
-
-TEST_F(PortTest, TestLocalToRelay) {
-  TestLocalToRelay(PROTO_UDP);
-}
-
-TEST_F(PortTest, TestLocalToTcpRelay) {
-  TestLocalToRelay(PROTO_TCP);
-}
-
-TEST_F(PortTest, TestLocalToSslTcpRelay) {
-  TestLocalToRelay(PROTO_SSLTCP);
-}
-
-// Cone NAT -> XXXX
-TEST_F(PortTest, TestConeNatToLocal) {
-  TestStunToLocal(NAT_OPEN_CONE);
-}
-
-TEST_F(PortTest, TestConeNatToConeNat) {
-  TestStunToStun(NAT_OPEN_CONE, NAT_OPEN_CONE);
-}
-
-TEST_F(PortTest, TestConeNatToARNat) {
-  TestStunToStun(NAT_OPEN_CONE, NAT_ADDR_RESTRICTED);
-}
-
-TEST_F(PortTest, TestConeNatToPRNat) {
-  TestStunToStun(NAT_OPEN_CONE, NAT_PORT_RESTRICTED);
-}
-
-TEST_F(PortTest, TestConeNatToSymNat) {
-  TestStunToStun(NAT_OPEN_CONE, NAT_SYMMETRIC);
-}
-
-TEST_F(PortTest, TestConeNatToRelay) {
-  TestStunToRelay(NAT_OPEN_CONE, PROTO_UDP);
-}
-
-TEST_F(PortTest, TestConeNatToTcpRelay) {
-  TestStunToRelay(NAT_OPEN_CONE, PROTO_TCP);
-}
-
-// Address-restricted NAT -> XXXX
-TEST_F(PortTest, TestARNatToLocal) {
-  TestStunToLocal(NAT_ADDR_RESTRICTED);
-}
-
-TEST_F(PortTest, TestARNatToConeNat) {
-  TestStunToStun(NAT_ADDR_RESTRICTED, NAT_OPEN_CONE);
-}
-
-TEST_F(PortTest, TestARNatToARNat) {
-  TestStunToStun(NAT_ADDR_RESTRICTED, NAT_ADDR_RESTRICTED);
-}
-
-TEST_F(PortTest, TestARNatToPRNat) {
-  TestStunToStun(NAT_ADDR_RESTRICTED, NAT_PORT_RESTRICTED);
-}
-
-TEST_F(PortTest, TestARNatToSymNat) {
-  TestStunToStun(NAT_ADDR_RESTRICTED, NAT_SYMMETRIC);
-}
-
-TEST_F(PortTest, TestARNatToRelay) {
-  TestStunToRelay(NAT_ADDR_RESTRICTED, PROTO_UDP);
-}
-
-TEST_F(PortTest, TestARNATNatToTcpRelay) {
-  TestStunToRelay(NAT_ADDR_RESTRICTED, PROTO_TCP);
-}
-
-// Port-restricted NAT -> XXXX
-TEST_F(PortTest, TestPRNatToLocal) {
-  TestStunToLocal(NAT_PORT_RESTRICTED);
-}
-
-TEST_F(PortTest, TestPRNatToConeNat) {
-  TestStunToStun(NAT_PORT_RESTRICTED, NAT_OPEN_CONE);
-}
-
-TEST_F(PortTest, TestPRNatToARNat) {
-  TestStunToStun(NAT_PORT_RESTRICTED, NAT_ADDR_RESTRICTED);
-}
-
-TEST_F(PortTest, TestPRNatToPRNat) {
-  TestStunToStun(NAT_PORT_RESTRICTED, NAT_PORT_RESTRICTED);
-}
-
-TEST_F(PortTest, TestPRNatToSymNat) {
-  // Will "fail"
-  TestStunToStun(NAT_PORT_RESTRICTED, NAT_SYMMETRIC);
-}
-
-TEST_F(PortTest, TestPRNatToRelay) {
-  TestStunToRelay(NAT_PORT_RESTRICTED, PROTO_UDP);
-}
-
-TEST_F(PortTest, TestPRNatToTcpRelay) {
-  TestStunToRelay(NAT_PORT_RESTRICTED, PROTO_TCP);
-}
-
-// Symmetric NAT -> XXXX
-TEST_F(PortTest, TestSymNatToLocal) {
-  TestStunToLocal(NAT_SYMMETRIC);
-}
-
-TEST_F(PortTest, TestSymNatToConeNat) {
-  TestStunToStun(NAT_SYMMETRIC, NAT_OPEN_CONE);
-}
-
-TEST_F(PortTest, TestSymNatToARNat) {
-  TestStunToStun(NAT_SYMMETRIC, NAT_ADDR_RESTRICTED);
-}
-
-TEST_F(PortTest, TestSymNatToPRNat) {
-  // Will "fail"
-  TestStunToStun(NAT_SYMMETRIC, NAT_PORT_RESTRICTED);
-}
-
-TEST_F(PortTest, TestSymNatToSymNat) {
-  // Will "fail"
-  TestStunToStun(NAT_SYMMETRIC, NAT_SYMMETRIC);
-}
-
-TEST_F(PortTest, TestSymNatToRelay) {
-  TestStunToRelay(NAT_SYMMETRIC, PROTO_UDP);
-}
-
-TEST_F(PortTest, TestSymNatToTcpRelay) {
-  TestStunToRelay(NAT_SYMMETRIC, PROTO_TCP);
-}
-
-// Outbound TCP -> XXXX
-TEST_F(PortTest, TestTcpToTcp) {
-  TestTcpToTcp();
-}
-
-/* TODO: Enable these once testrelayserver can accept external TCP.
-TEST_F(PortTest, TestTcpToTcpRelay) {
-  TestTcpToRelay(PROTO_TCP);
-}
-
-TEST_F(PortTest, TestTcpToSslTcpRelay) {
-  TestTcpToRelay(PROTO_SSLTCP);
-}
-*/
-
-// Outbound SSLTCP -> XXXX
-/* TODO: Enable these once testrelayserver can accept external SSL.
-TEST_F(PortTest, TestSslTcpToTcpRelay) {
-  TestSslTcpToRelay(PROTO_TCP);
-}
-
-TEST_F(PortTest, TestSslTcpToSslTcpRelay) {
-  TestSslTcpToRelay(PROTO_SSLTCP);
-}
-*/
-
-TEST_F(PortTest, TestTcpNoDelay) {
-  TCPPort* port1 = CreateTcpPort(kLocalAddr1);
-  int option_value = -1;
-  int success = port1->GetOption(talk_base::Socket::OPT_NODELAY,
-                                 &option_value);
-  ASSERT_EQ(0, success);  // GetOption() should complete successfully w/ 0
-  ASSERT_EQ(1, option_value);
-  delete port1;
-}
-
-TEST_F(PortTest, TestDelayedBindingUdp) {
-  FakeAsyncPacketSocket *socket = new FakeAsyncPacketSocket();
-  FakePacketSocketFactory socket_factory;
-
-  socket_factory.set_next_udp_socket(socket);
-  scoped_ptr<UDPPort> port(
-      CreateUdpPort(kLocalAddr1, &socket_factory));
-
-  socket->set_state(AsyncPacketSocket::STATE_BINDING);
-  port->PrepareAddress();
-
-  EXPECT_EQ(0U, port->candidates().size());
-  socket->SignalAddressReady(socket, kLocalAddr2);
-
-  EXPECT_EQ(1U, port->candidates().size());
-}
-
-TEST_F(PortTest, TestDelayedBindingTcp) {
-  FakeAsyncPacketSocket *socket = new FakeAsyncPacketSocket();
-  FakePacketSocketFactory socket_factory;
-
-  socket_factory.set_next_server_tcp_socket(socket);
-  scoped_ptr<TCPPort> port(
-      CreateTcpPort(kLocalAddr1, &socket_factory));
-
-  socket->set_state(AsyncPacketSocket::STATE_BINDING);
-  port->PrepareAddress();
-
-  EXPECT_EQ(0U, port->candidates().size());
-  socket->SignalAddressReady(socket, kLocalAddr2);
-
-  EXPECT_EQ(1U, port->candidates().size());
-}
diff --git a/third_party/libjingle/source/talk/p2p/base/portallocator.h b/third_party/libjingle/source/talk/p2p/base/portallocator.h
deleted file mode 100644
index 175bdbc..0000000
--- a/third_party/libjingle/source/talk/p2p/base/portallocator.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_P2P_BASE_PORTALLOCATOR_H_
-#define TALK_P2P_BASE_PORTALLOCATOR_H_
-
-#include <string>
-#include <vector>
-
-#include "talk/base/sigslot.h"
-#include "talk/p2p/base/port.h"
-
-namespace cricket {
-
-// PortAllocator is responsible for allocating Port types for a given
-// P2PSocket. It also handles port freeing.
-//
-// Clients can override this class to control port allocation, including
-// what kinds of ports are allocated.
-
-const uint32 PORTALLOCATOR_DISABLE_UDP = 0x01;
-const uint32 PORTALLOCATOR_DISABLE_STUN = 0x02;
-const uint32 PORTALLOCATOR_DISABLE_RELAY = 0x04;
-const uint32 PORTALLOCATOR_DISABLE_TCP = 0x08;
-const uint32 PORTALLOCATOR_ENABLE_SHAKER = 0x10;
-
-const uint32 kDefaultPortAllocatorFlags = 0;
-
-class PortAllocatorSession : public sigslot::has_slots<> {
- public:
-  explicit PortAllocatorSession(uint32 flags) : flags_(flags) {}
-
-  // Subclasses should clean up any ports created.
-  virtual ~PortAllocatorSession() {}
-
-  uint32 flags() const { return flags_; }
-  void set_flags(uint32 flags) { flags_ = flags; }
-
-  // Prepares an initial set of ports to try.
-  virtual void GetInitialPorts() = 0;
-
-  // Starts and stops the flow of additional ports to try.
-  virtual void StartGetAllPorts() = 0;
-  virtual void StopGetAllPorts() = 0;
-  virtual bool IsGettingAllPorts() = 0;
-
-  sigslot::signal2<PortAllocatorSession*, Port*> SignalPortReady;
-  sigslot::signal2<PortAllocatorSession*,
-                   const std::vector<Candidate>&> SignalCandidatesReady;
-
-  uint32 generation() { return generation_; }
-  void set_generation(uint32 generation) { generation_ = generation; }
-
- private:
-  uint32 flags_;
-  uint32 generation_;
-};
-
-class PortAllocator {
- public:
-  PortAllocator() :
-      flags_(kDefaultPortAllocatorFlags),
-      min_port_(0),
-      max_port_(0) {
-  }
-  virtual ~PortAllocator() {}
-
-  virtual PortAllocatorSession *CreateSession(const std::string &name,
-      const std::string &session_type) = 0;
-
-  uint32 flags() const { return flags_; }
-  void set_flags(uint32 flags) { flags_ = flags; }
-
-  const std::string& user_agent() const { return agent_; }
-  const talk_base::ProxyInfo& proxy() const { return proxy_; }
-  void set_proxy(const std::string& agent, const talk_base::ProxyInfo& proxy) {
-    agent_ = agent;
-    proxy_ = proxy;
-  }
-
-  // Gets/Sets the port range to use when choosing client ports.
-  int min_port() const { return min_port_; }
-  int max_port() const { return max_port_; }
-  bool SetPortRange(int min_port, int max_port) {
-    if (min_port > max_port) {
-      return false;
-    }
-
-    min_port_ = min_port;
-    max_port_ = max_port;
-    return true;
-  }
-
- protected:
-  uint32 flags_;
-  std::string agent_;
-  talk_base::ProxyInfo proxy_;
-  int min_port_;
-  int max_port_;
-};
-
-}  // namespace cricket
-
-#endif  // TALK_P2P_BASE_PORTALLOCATOR_H_
diff --git a/third_party/libjingle/source/talk/p2p/base/pseudotcp.cc b/third_party/libjingle/source/talk/p2p/base/pseudotcp.cc
deleted file mode 100644
index 99a1f43..0000000
--- a/third_party/libjingle/source/talk/p2p/base/pseudotcp.cc
+++ /dev/null
@@ -1,1278 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/p2p/base/pseudotcp.h"
-
-#include <cstdio>
-#include <cstdlib>
-#include <set>
-
-#include "talk/base/basictypes.h"
-#include "talk/base/bytebuffer.h"
-#include "talk/base/byteorder.h"
-#include "talk/base/common.h"
-#include "talk/base/logging.h"
-#include "talk/base/socket.h"
-#include "talk/base/stringutils.h"
-#include "talk/base/timeutils.h"
-
-// The following logging is for detailed (packet-level) analysis only.
-#define _DBG_NONE     0
-#define _DBG_NORMAL   1
-#define _DBG_VERBOSE  2
-#define _DEBUGMSG _DBG_NONE
-
-namespace cricket {
-
-//////////////////////////////////////////////////////////////////////
-// Network Constants
-//////////////////////////////////////////////////////////////////////
-
-// Standard MTUs
-const uint16 PACKET_MAXIMUMS[] = {
-  65535,    // Theoretical maximum, Hyperchannel
-  32000,    // Nothing
-  17914,    // 16Mb IBM Token Ring
-  8166,   // IEEE 802.4
-  //4464,   // IEEE 802.5 (4Mb max)
-  4352,   // FDDI
-  //2048,   // Wideband Network
-  2002,   // IEEE 802.5 (4Mb recommended)
-  //1536,   // Expermental Ethernet Networks
-  //1500,   // Ethernet, Point-to-Point (default)
-  1492,   // IEEE 802.3
-  1006,   // SLIP, ARPANET
-  //576,    // X.25 Networks
-  //544,    // DEC IP Portal
-  //512,    // NETBIOS
-  508,    // IEEE 802/Source-Rt Bridge, ARCNET
-  296,    // Point-to-Point (low delay)
-  //68,     // Official minimum
-  0,      // End of list marker
-};
-
-const uint32 MAX_PACKET = 65535;
-// Note: we removed lowest level because packet overhead was larger!
-const uint32 MIN_PACKET = 296;
-
-const uint32 IP_HEADER_SIZE = 20; // (+ up to 40 bytes of options?)
-const uint32 ICMP_HEADER_SIZE = 8;
-const uint32 UDP_HEADER_SIZE = 8;
-// TODO: Make JINGLE_HEADER_SIZE transparent to this code?
-const uint32 JINGLE_HEADER_SIZE = 64; // when relay framing is in use
-
-// Default size for receive and send buffer.
-const uint32 DEFAULT_RCV_BUF_SIZE = 60 * 1024;
-const uint32 DEFAULT_SND_BUF_SIZE = 90 * 1024;
-
-//////////////////////////////////////////////////////////////////////
-// Global Constants and Functions
-//////////////////////////////////////////////////////////////////////
-//
-//    0                   1                   2                   3
-//    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-//    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-//  0 |                      Conversation Number                      |
-//    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-//  4 |                        Sequence Number                        |
-//    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-//  8 |                     Acknowledgment Number                     |
-//    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-//    |               |   |U|A|P|R|S|F|                               |
-// 12 |    Control    |   |R|C|S|S|Y|I|            Window             |
-//    |               |   |G|K|H|T|N|N|                               |
-//    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// 16 |                       Timestamp sending                       |
-//    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// 20 |                      Timestamp receiving                      |
-//    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// 24 |                             data                              |
-//    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-//
-//////////////////////////////////////////////////////////////////////
-
-#define PSEUDO_KEEPALIVE 0
-
-const uint32 MAX_SEQ = 0xFFFFFFFF;
-const uint32 HEADER_SIZE = 24;
-const uint32 PACKET_OVERHEAD = HEADER_SIZE + UDP_HEADER_SIZE + IP_HEADER_SIZE + JINGLE_HEADER_SIZE;
-
-const uint32 MIN_RTO   =   250; // 250 ms (RFC1122, Sec 4.2.3.1 "fractions of a second")
-const uint32 DEF_RTO   =  3000; // 3 seconds (RFC1122, Sec 4.2.3.1)
-const uint32 MAX_RTO   = 60000; // 60 seconds
-const uint32 DEF_ACK_DELAY = 100; // 100 milliseconds
-
-const uint8 FLAG_CTL = 0x02;
-const uint8 FLAG_RST = 0x04;
-
-const uint8 CTL_CONNECT = 0;
-//const uint8 CTL_REDIRECT = 1;
-const uint8 CTL_EXTRA = 255;
-
-// TCP options.
-const uint8 TCP_OPT_EOL = 0;  // End of list.
-const uint8 TCP_OPT_NOOP = 1;  // No-op.
-const uint8 TCP_OPT_MSS = 2;  // Maximum segment size.
-const uint8 TCP_OPT_WND_SCALE = 3;  // Window scale factor.
-
-/*
-const uint8 FLAG_FIN = 0x01;
-const uint8 FLAG_SYN = 0x02;
-const uint8 FLAG_ACK = 0x10;
-*/
-
-const uint32 CTRL_BOUND = 0x80000000;
-
-const long DEFAULT_TIMEOUT = 4000; // If there are no pending clocks, wake up every 4 seconds
-const long CLOSED_TIMEOUT = 60 * 1000; // If the connection is closed, once per minute
-
-#if PSEUDO_KEEPALIVE
-// !?! Rethink these times
-const uint32 IDLE_PING = 20 * 1000; // 20 seconds (note: WinXP SP2 firewall udp timeout is 90 seconds)
-const uint32 IDLE_TIMEOUT = 90 * 1000; // 90 seconds;
-#endif // PSEUDO_KEEPALIVE
-
-//////////////////////////////////////////////////////////////////////
-// Helper Functions
-//////////////////////////////////////////////////////////////////////
-
-inline void long_to_bytes(uint32 val, void* buf) {
-  *static_cast<uint32*>(buf) = talk_base::HostToNetwork32(val);
-}
-
-inline void short_to_bytes(uint16 val, void* buf) {
-  *static_cast<uint16*>(buf) = talk_base::HostToNetwork16(val);
-}
-
-inline uint32 bytes_to_long(const void* buf) {
-  return talk_base::NetworkToHost32(*static_cast<const uint32*>(buf));
-}
-
-inline uint16 bytes_to_short(const void* buf) {
-  return talk_base::NetworkToHost16(*static_cast<const uint16*>(buf));
-}
-
-uint32 bound(uint32 lower, uint32 middle, uint32 upper) {
-  return talk_base::_min(talk_base::_max(lower, middle), upper);
-}
-
-//////////////////////////////////////////////////////////////////////
-// Debugging Statistics
-//////////////////////////////////////////////////////////////////////
-
-#if 0  // Not used yet
-
-enum Stat {
-  S_SENT_PACKET,   // All packet sends
-  S_RESENT_PACKET, // All packet sends that are retransmits
-  S_RECV_PACKET,   // All packet receives
-  S_RECV_NEW,      // All packet receives that are too new
-  S_RECV_OLD,      // All packet receives that are too old
-  S_NUM_STATS
-};
-
-const char* const STAT_NAMES[S_NUM_STATS] = {
-  "snt",
-  "snt-r",
-  "rcv"
-  "rcv-n",
-  "rcv-o"
-};
-
-int g_stats[S_NUM_STATS];
-inline void Incr(Stat s) { ++g_stats[s]; }
-void ReportStats() {
-  char buffer[256];
-  size_t len = 0;
-  for (int i = 0; i < S_NUM_STATS; ++i) {
-    len += talk_base::sprintfn(buffer, ARRAY_SIZE(buffer), "%s%s:%d",
-                               (i == 0) ? "" : ",", STAT_NAMES[i], g_stats[i]);
-    g_stats[i] = 0;
-  }
-  LOG(LS_INFO) << "Stats[" << buffer << "]";
-}
-
-#endif
-
-//////////////////////////////////////////////////////////////////////
-// PseudoTcp
-//////////////////////////////////////////////////////////////////////
-
-uint32 PseudoTcp::Now() {
-#if 0  // Use this to synchronize timers with logging timestamps (easier debug)
-  return talk_base::TimeSince(StartTime());
-#else
-  return talk_base::Time();
-#endif
-}
-
-PseudoTcp::PseudoTcp(IPseudoTcpNotify* notify, uint32 conv)
-    : m_notify(notify),
-      m_shutdown(SD_NONE),
-      m_error(0),
-      m_rbuf_len(DEFAULT_RCV_BUF_SIZE),
-      m_rbuf(m_rbuf_len),
-      m_sbuf_len(DEFAULT_SND_BUF_SIZE),
-      m_sbuf(m_sbuf_len) {
-
-  // Sanity check on buffer sizes (needed for OnTcpWriteable notification logic)
-  ASSERT(m_rbuf_len + MIN_PACKET < m_sbuf_len);
-
-  uint32 now = Now();
-
-  m_state = TCP_LISTEN;
-  m_conv = conv;
-  m_rcv_wnd = m_rbuf_len;
-  m_rwnd_scale = m_swnd_scale = 0;
-  m_snd_nxt = 0;
-  m_snd_wnd = 1;
-  m_snd_una = m_rcv_nxt = 0;
-  m_bReadEnable = true;
-  m_bWriteEnable = false;
-  m_t_ack = 0;
-
-  m_msslevel = 0;
-  m_largest = 0;
-  ASSERT(MIN_PACKET > PACKET_OVERHEAD);
-  m_mss = MIN_PACKET - PACKET_OVERHEAD;
-  m_mtu_advise = MAX_PACKET;
-
-  m_rto_base = 0;
-
-  m_cwnd = 2 * m_mss;
-  m_ssthresh = m_rbuf_len;
-  m_lastrecv = m_lastsend = m_lasttraffic = now;
-  m_bOutgoing = false;
-
-  m_dup_acks = 0;
-  m_recover = 0;
-
-  m_ts_recent = m_ts_lastack = 0;
-
-  m_rx_rto = DEF_RTO;
-  m_rx_srtt = m_rx_rttvar = 0;
-
-  m_use_nagling = true;
-  m_ack_delay = DEF_ACK_DELAY;
-  m_support_wnd_scale = true;
-}
-
-PseudoTcp::~PseudoTcp() {
-}
-
-int PseudoTcp::Connect() {
-  if (m_state != TCP_LISTEN) {
-    m_error = EINVAL;
-    return -1;
-  }
-
-  m_state = TCP_SYN_SENT;
-  LOG(LS_INFO) << "State: TCP_SYN_SENT";
-
-  queueConnectMessage();
-  attemptSend();
-
-  return 0;
-}
-
-void PseudoTcp::NotifyMTU(uint16 mtu) {
-  m_mtu_advise = mtu;
-  if (m_state == TCP_ESTABLISHED) {
-    adjustMTU();
-  }
-}
-
-void PseudoTcp::NotifyClock(uint32 now) {
-  if (m_state == TCP_CLOSED)
-    return;
-
-    // Check if it's time to retransmit a segment
-  if (m_rto_base && (talk_base::TimeDiff(m_rto_base + m_rx_rto, now) <= 0)) {
-    if (m_slist.empty()) {
-      ASSERT(false);
-    } else {
-      // Note: (m_slist.front().xmit == 0)) {
-      // retransmit segments
-#if _DEBUGMSG >= _DBG_NORMAL
-      LOG(LS_INFO) << "timeout retransmit (rto: " << m_rx_rto
-                   << ") (rto_base: " << m_rto_base
-                   << ") (now: " << now
-                   << ") (dup_acks: " << static_cast<unsigned>(m_dup_acks)
-                   << ")";
-#endif // _DEBUGMSG
-      if (!transmit(m_slist.begin(), now)) {
-        closedown(ECONNABORTED);
-        return;
-      }
-
-      uint32 nInFlight = m_snd_nxt - m_snd_una;
-      m_ssthresh = talk_base::_max(nInFlight / 2, 2 * m_mss);
-      //LOG(LS_INFO) << "m_ssthresh: " << m_ssthresh << "  nInFlight: " << nInFlight << "  m_mss: " << m_mss;
-      m_cwnd = m_mss;
-
-      // Back off retransmit timer.  Note: the limit is lower when connecting.
-      uint32 rto_limit = (m_state < TCP_ESTABLISHED) ? DEF_RTO : MAX_RTO;
-      m_rx_rto = talk_base::_min(rto_limit, m_rx_rto * 2);
-      m_rto_base = now;
-    }
-  }
-
-  // Check if it's time to probe closed windows
-  if ((m_snd_wnd == 0)
-        && (talk_base::TimeDiff(m_lastsend + m_rx_rto, now) <= 0)) {
-    if (talk_base::TimeDiff(now, m_lastrecv) >= 15000) {
-      closedown(ECONNABORTED);
-      return;
-    }
-
-    // probe the window
-    packet(m_snd_nxt - 1, 0, 0, 0);
-    m_lastsend = now;
-
-    // back off retransmit timer
-    m_rx_rto = talk_base::_min(MAX_RTO, m_rx_rto * 2);
-  }
-
-  // Check if it's time to send delayed acks
-  if (m_t_ack && (talk_base::TimeDiff(m_t_ack + m_ack_delay, now) <= 0)) {
-    packet(m_snd_nxt, 0, 0, 0);
-  }
-
-#if PSEUDO_KEEPALIVE
-  // Check for idle timeout
-  if ((m_state == TCP_ESTABLISHED) && (TimeDiff(m_lastrecv + IDLE_TIMEOUT, now) <= 0)) {
-    closedown(ECONNABORTED);
-    return;
-  }
-
-  // Check for ping timeout (to keep udp mapping open)
-  if ((m_state == TCP_ESTABLISHED) && (TimeDiff(m_lasttraffic + (m_bOutgoing ? IDLE_PING * 3/2 : IDLE_PING), now) <= 0)) {
-    packet(m_snd_nxt, 0, 0, 0);
-  }
-#endif // PSEUDO_KEEPALIVE
-}
-
-bool PseudoTcp::NotifyPacket(const char* buffer, size_t len) {
-  if (len > MAX_PACKET) {
-    LOG_F(WARNING) << "packet too large";
-    return false;
-  }
-  return parse(reinterpret_cast<const uint8 *>(buffer), uint32(len));
-}
-
-bool PseudoTcp::GetNextClock(uint32 now, long& timeout) {
-  return clock_check(now, timeout);
-}
-
-void PseudoTcp::GetOption(Option opt, int* value) {
-  if (opt == OPT_NODELAY) {
-    *value = m_use_nagling ? 0 : 1;
-  } else if (opt == OPT_ACKDELAY) {
-    *value = m_ack_delay;
-  } else if (opt == OPT_SNDBUF) {
-    *value = m_sbuf_len;
-  } else if (opt == OPT_RCVBUF) {
-    *value = m_rbuf_len;
-  } else {
-    ASSERT(false);
-  }
-}
-void PseudoTcp::SetOption(Option opt, int value) {
-  if (opt == OPT_NODELAY) {
-    m_use_nagling = value == 0;
-  } else if (opt == OPT_ACKDELAY) {
-    m_ack_delay = value;
-  } else if (opt == OPT_SNDBUF) {
-    ASSERT(m_state == TCP_LISTEN);
-    resizeSendBuffer(value);
-  } else if (opt == OPT_RCVBUF) {
-    ASSERT(m_state == TCP_LISTEN);
-    resizeReceiveBuffer(value);
-  } else {
-    ASSERT(false);
-  }
-}
-
-//
-// IPStream Implementation
-//
-
-int PseudoTcp::Recv(char* buffer, size_t len) {
-  if (m_state != TCP_ESTABLISHED) {
-    m_error = ENOTCONN;
-    return SOCKET_ERROR;
-  }
-
-  size_t read = 0;
-  talk_base::StreamResult result = m_rbuf.Read(buffer, len, &read, NULL);
-
-  // If there's no data in |m_rbuf|.
-  if (result == talk_base::SR_BLOCK) {
-    m_bReadEnable = true;
-    m_error = EWOULDBLOCK;
-    return SOCKET_ERROR;
-  }
-  ASSERT(result == talk_base::SR_SUCCESS);
-
-  size_t available_space = 0;
-  m_rbuf.GetWriteRemaining(&available_space);
-
-  if (uint32(available_space) - m_rcv_wnd >=
-      talk_base::_min<uint32>(m_rbuf_len / 2, m_mss)) {
-    bool bWasClosed = (m_rcv_wnd == 0); // !?! Not sure about this was closed business
-    m_rcv_wnd = available_space;
-
-    if (bWasClosed) {
-      attemptSend(sfImmediateAck);
-    }
-  }
-
-  return read;
-}
-
-int PseudoTcp::Send(const char* buffer, size_t len) {
-  if (m_state != TCP_ESTABLISHED) {
-    m_error = ENOTCONN;
-    return SOCKET_ERROR;
-  }
-
-  size_t available_space = 0;
-  m_sbuf.GetWriteRemaining(&available_space);
-
-  if (!available_space) {
-    m_bWriteEnable = true;
-    m_error = EWOULDBLOCK;
-    return SOCKET_ERROR;
-  }
-
-  int written = queue(buffer, uint32(len), false);
-  attemptSend();
-  return written;
-}
-
-void PseudoTcp::Close(bool force) {
-  LOG_F(LS_VERBOSE) << "(" << (force ? "true" : "false") << ")";
-  m_shutdown = force ? SD_FORCEFUL : SD_GRACEFUL;
-}
-
-int PseudoTcp::GetError() {
-  return m_error;
-}
-
-//
-// Internal Implementation
-//
-
-uint32 PseudoTcp::queue(const char* data, uint32 len, bool bCtrl) {
-  size_t available_space = 0;
-  m_sbuf.GetWriteRemaining(&available_space);
-
-  if (len > static_cast<uint32>(available_space)) {
-    ASSERT(!bCtrl);
-    len = static_cast<uint32>(available_space);
-  }
-
-  // We can concatenate data if the last segment is the same type
-  // (control v. regular data), and has not been transmitted yet
-  if (!m_slist.empty() && (m_slist.back().bCtrl == bCtrl) && (m_slist.back().xmit == 0)) {
-    m_slist.back().len += len;
-  } else {
-    size_t snd_buffered = 0;
-    m_sbuf.GetBuffered(&snd_buffered);
-    SSegment sseg(m_snd_una + snd_buffered, len, bCtrl);
-    m_slist.push_back(sseg);
-  }
-
-  size_t written = 0;
-  m_sbuf.Write(data, len, &written, NULL);
-  return written;
-}
-
-IPseudoTcpNotify::WriteResult PseudoTcp::packet(uint32 seq, uint8 flags,
-                                                uint32 offset, uint32 len) {
-  ASSERT(HEADER_SIZE + len <= MAX_PACKET);
-
-  uint32 now = Now();
-
-  uint8 buffer[MAX_PACKET];
-  long_to_bytes(m_conv, buffer);
-  long_to_bytes(seq, buffer + 4);
-  long_to_bytes(m_rcv_nxt, buffer + 8);
-  buffer[12] = 0;
-  buffer[13] = flags;
-  short_to_bytes(static_cast<uint16>(m_rcv_wnd >> m_rwnd_scale), buffer + 14);
-
-  // Timestamp computations
-  long_to_bytes(now, buffer + 16);
-  long_to_bytes(m_ts_recent, buffer + 20);
-  m_ts_lastack = m_rcv_nxt;
-
-  if (len) {
-    size_t bytes_read = 0;
-    talk_base::StreamResult result = m_sbuf.ReadOffset(buffer + HEADER_SIZE,
-                                                       len,
-                                                       offset,
-                                                       &bytes_read);
-    UNUSED(result);
-    ASSERT(result == talk_base::SR_SUCCESS);
-    ASSERT(static_cast<uint32>(bytes_read) == len);
-  }
-
-#if _DEBUGMSG >= _DBG_VERBOSE
-  LOG(LS_INFO) << "<-- <CONV=" << m_conv
-               << "><FLG=" << static_cast<unsigned>(flags)
-               << "><SEQ=" << seq << ":" << seq + len
-               << "><ACK=" << m_rcv_nxt
-               << "><WND=" << m_rcv_wnd
-               << "><TS="  << (now % 10000)
-               << "><TSR=" << (m_ts_recent % 10000)
-               << "><LEN=" << len << ">";
-#endif // _DEBUGMSG
-
-  IPseudoTcpNotify::WriteResult wres = m_notify->TcpWritePacket(this, reinterpret_cast<char *>(buffer), len + HEADER_SIZE);
-  // Note: When len is 0, this is an ACK packet.  We don't read the return value for those,
-  // and thus we won't retry.  So go ahead and treat the packet as a success (basically simulate
-  // as if it were dropped), which will prevent our timers from being messed up.
-  if ((wres != IPseudoTcpNotify::WR_SUCCESS) && (0 != len))
-    return wres;
-
-  m_t_ack = 0;
-  if (len > 0) {
-    m_lastsend = now;
-  }
-  m_lasttraffic = now;
-  m_bOutgoing = true;
-
-  return IPseudoTcpNotify::WR_SUCCESS;
-}
-
-bool PseudoTcp::parse(const uint8* buffer, uint32 size) {
-  if (size < 12)
-    return false;
-
-  Segment seg;
-  seg.conv = bytes_to_long(buffer);
-  seg.seq = bytes_to_long(buffer + 4);
-  seg.ack = bytes_to_long(buffer + 8);
-  seg.flags = buffer[13];
-  seg.wnd = bytes_to_short(buffer + 14);
-
-  seg.tsval = bytes_to_long(buffer + 16);
-  seg.tsecr = bytes_to_long(buffer + 20);
-
-  seg.data = reinterpret_cast<const char *>(buffer) + HEADER_SIZE;
-  seg.len = size - HEADER_SIZE;
-
-#if _DEBUGMSG >= _DBG_VERBOSE
-  LOG(LS_INFO) << "--> <CONV=" << seg.conv
-               << "><FLG=" << static_cast<unsigned>(seg.flags)
-               << "><SEQ=" << seg.seq << ":" << seg.seq + seg.len
-               << "><ACK=" << seg.ack
-               << "><WND=" << seg.wnd
-               << "><TS="  << (seg.tsval % 10000)
-               << "><TSR=" << (seg.tsecr % 10000)
-               << "><LEN=" << seg.len << ">";
-#endif // _DEBUGMSG
-
-  return process(seg);
-}
-
-bool PseudoTcp::clock_check(uint32 now, long& nTimeout) {
-  if (m_shutdown == SD_FORCEFUL)
-    return false;
-
-  size_t snd_buffered = 0;
-  m_sbuf.GetBuffered(&snd_buffered);
-  if ((m_shutdown == SD_GRACEFUL)
-      && ((m_state != TCP_ESTABLISHED)
-          || ((snd_buffered == 0) && (m_t_ack == 0)))) {
-    return false;
-  }
-
-  if (m_state == TCP_CLOSED) {
-    nTimeout = CLOSED_TIMEOUT;
-    return true;
-  }
-
-  nTimeout = DEFAULT_TIMEOUT;
-
-  if (m_t_ack) {
-    nTimeout = talk_base::_min<int32>(nTimeout,
-      talk_base::TimeDiff(m_t_ack + m_ack_delay, now));
-  }
-  if (m_rto_base) {
-    nTimeout = talk_base::_min<int32>(nTimeout,
-      talk_base::TimeDiff(m_rto_base + m_rx_rto, now));
-  }
-  if (m_snd_wnd == 0) {
-    nTimeout = talk_base::_min<int32>(nTimeout, talk_base::TimeDiff(m_lastsend + m_rx_rto, now));
-  }
-#if PSEUDO_KEEPALIVE
-  if (m_state == TCP_ESTABLISHED) {
-    nTimeout = talk_base::_min<int32>(nTimeout,
-      talk_base::TimeDiff(m_lasttraffic + (m_bOutgoing ? IDLE_PING * 3/2 : IDLE_PING), now));
-  }
-#endif // PSEUDO_KEEPALIVE
-  return true;
-}
-
-bool PseudoTcp::process(Segment& seg) {
-  // If this is the wrong conversation, send a reset!?! (with the correct conversation?)
-  if (seg.conv != m_conv) {
-    //if ((seg.flags & FLAG_RST) == 0) {
-    //  packet(tcb, seg.ack, 0, FLAG_RST, 0, 0);
-    //}
-    LOG_F(LS_ERROR) << "wrong conversation";
-    return false;
-  }
-
-  uint32 now = Now();
-  m_lasttraffic = m_lastrecv = now;
-  m_bOutgoing = false;
-
-  if (m_state == TCP_CLOSED) {
-    // !?! send reset?
-    LOG_F(LS_ERROR) << "closed";
-    return false;
-  }
-
-  // Check if this is a reset segment
-  if (seg.flags & FLAG_RST) {
-    closedown(ECONNRESET);
-    return false;
-  }
-
-  // Check for control data
-  bool bConnect = false;
-  if (seg.flags & FLAG_CTL) {
-    if (seg.len == 0) {
-      LOG_F(LS_ERROR) << "Missing control code";
-      return false;
-    } else if (seg.data[0] == CTL_CONNECT) {
-      bConnect = true;
-
-      // TCP options are in the remainder of the payload after CTL_CONNECT.
-      parseOptions(&seg.data[1], seg.len - 1);
-
-      if (m_state == TCP_LISTEN) {
-        m_state = TCP_SYN_RECEIVED;
-        LOG(LS_INFO) << "State: TCP_SYN_RECEIVED";
-        //m_notify->associate(addr);
-        queueConnectMessage();
-      } else if (m_state == TCP_SYN_SENT) {
-        m_state = TCP_ESTABLISHED;
-        LOG(LS_INFO) << "State: TCP_ESTABLISHED";
-        adjustMTU();
-        if (m_notify) {
-          m_notify->OnTcpOpen(this);
-        }
-        //notify(evOpen);
-      }
-    } else {
-      LOG_F(LS_WARNING) << "Unknown control code: " << seg.data[0];
-      return false;
-    }
-  }
-
-  // Update timestamp
-  if ((seg.seq <= m_ts_lastack) && (m_ts_lastack < seg.seq + seg.len)) {
-    m_ts_recent = seg.tsval;
-  }
-
-  // Check if this is a valuable ack
-  if ((seg.ack > m_snd_una) && (seg.ack <= m_snd_nxt)) {
-    // Calculate round-trip time
-    if (seg.tsecr) {
-      long rtt = talk_base::TimeDiff(now, seg.tsecr);
-      if (rtt >= 0) {
-        if (m_rx_srtt == 0) {
-          m_rx_srtt = rtt;
-          m_rx_rttvar = rtt / 2;
-        } else {
-          m_rx_rttvar = (3 * m_rx_rttvar + abs(long(rtt - m_rx_srtt))) / 4;
-          m_rx_srtt = (7 * m_rx_srtt + rtt) / 8;
-        }
-        m_rx_rto = bound(MIN_RTO, m_rx_srtt +
-            talk_base::_max<uint32>(1, 4 * m_rx_rttvar), MAX_RTO);
-#if _DEBUGMSG >= _DBG_VERBOSE
-        LOG(LS_INFO) << "rtt: " << rtt
-                     << "  srtt: " << m_rx_srtt
-                     << "  rto: " << m_rx_rto;
-#endif // _DEBUGMSG
-      } else {
-        ASSERT(false);
-      }
-    }
-
-    m_snd_wnd = static_cast<uint32>(seg.wnd) << m_swnd_scale;
-
-    uint32 nAcked = seg.ack - m_snd_una;
-    m_snd_una = seg.ack;
-
-    m_rto_base = (m_snd_una == m_snd_nxt) ? 0 : now;
-
-    m_sbuf.ConsumeReadData(nAcked);
-
-    for (uint32 nFree = nAcked; nFree > 0; ) {
-      ASSERT(!m_slist.empty());
-      if (nFree < m_slist.front().len) {
-        m_slist.front().len -= nFree;
-        nFree = 0;
-      } else {
-        if (m_slist.front().len > m_largest) {
-          m_largest = m_slist.front().len;
-        }
-        nFree -= m_slist.front().len;
-        m_slist.pop_front();
-      }
-    }
-
-    if (m_dup_acks >= 3) {
-      if (m_snd_una >= m_recover) { // NewReno
-        uint32 nInFlight = m_snd_nxt - m_snd_una;
-        m_cwnd = talk_base::_min(m_ssthresh, nInFlight + m_mss); // (Fast Retransmit)
-#if _DEBUGMSG >= _DBG_NORMAL
-        LOG(LS_INFO) << "exit recovery";
-#endif // _DEBUGMSG
-        m_dup_acks = 0;
-      } else {
-#if _DEBUGMSG >= _DBG_NORMAL
-        LOG(LS_INFO) << "recovery retransmit";
-#endif // _DEBUGMSG
-        if (!transmit(m_slist.begin(), now)) {
-          closedown(ECONNABORTED);
-          return false;
-        }
-        m_cwnd += m_mss - talk_base::_min(nAcked, m_cwnd);
-      }
-    } else {
-      m_dup_acks = 0;
-      // Slow start, congestion avoidance
-      if (m_cwnd < m_ssthresh) {
-        m_cwnd += m_mss;
-      } else {
-        m_cwnd += talk_base::_max<uint32>(1, m_mss * m_mss / m_cwnd);
-      }
-    }
-  } else if (seg.ack == m_snd_una) {
-    // !?! Note, tcp says don't do this... but otherwise how does a closed window become open?
-    m_snd_wnd = static_cast<uint32>(seg.wnd) << m_swnd_scale;
-
-    // Check duplicate acks
-    if (seg.len > 0) {
-      // it's a dup ack, but with a data payload, so don't modify m_dup_acks
-    } else if (m_snd_una != m_snd_nxt) {
-      m_dup_acks += 1;
-      if (m_dup_acks == 3) { // (Fast Retransmit)
-#if _DEBUGMSG >= _DBG_NORMAL
-        LOG(LS_INFO) << "enter recovery";
-        LOG(LS_INFO) << "recovery retransmit";
-#endif // _DEBUGMSG
-        if (!transmit(m_slist.begin(), now)) {
-          closedown(ECONNABORTED);
-          return false;
-        }
-        m_recover = m_snd_nxt;
-        uint32 nInFlight = m_snd_nxt - m_snd_una;
-        m_ssthresh = talk_base::_max(nInFlight / 2, 2 * m_mss);
-        //LOG(LS_INFO) << "m_ssthresh: " << m_ssthresh << "  nInFlight: " << nInFlight << "  m_mss: " << m_mss;
-        m_cwnd = m_ssthresh + 3 * m_mss;
-      } else if (m_dup_acks > 3) {
-        m_cwnd += m_mss;
-      }
-    } else {
-      m_dup_acks = 0;
-    }
-  }
-
-  // !?! A bit hacky
-  if ((m_state == TCP_SYN_RECEIVED) && !bConnect) {
-    m_state = TCP_ESTABLISHED;
-    LOG(LS_INFO) << "State: TCP_ESTABLISHED";
-    adjustMTU();
-    if (m_notify) {
-      m_notify->OnTcpOpen(this);
-    }
-    //notify(evOpen);
-  }
-
-  // If we make room in the send queue, notify the user
-  // The goal it to make sure we always have at least enough data to fill the
-  // window.  We'd like to notify the app when we are halfway to that point.
-  const uint32 kIdealRefillSize = (m_sbuf_len + m_rbuf_len) / 2;
-  size_t snd_buffered = 0;
-  m_sbuf.GetBuffered(&snd_buffered);
-  if (m_bWriteEnable && static_cast<uint32>(snd_buffered) < kIdealRefillSize) {
-    m_bWriteEnable = false;
-    if (m_notify) {
-      m_notify->OnTcpWriteable(this);
-    }
-    //notify(evWrite);
-  }
-
-  // Conditions were acks must be sent:
-  // 1) Segment is too old (they missed an ACK) (immediately)
-  // 2) Segment is too new (we missed a segment) (immediately)
-  // 3) Segment has data (so we need to ACK!) (delayed)
-  // ... so the only time we don't need to ACK, is an empty segment that points to rcv_nxt!
-
-  SendFlags sflags = sfNone;
-  if (seg.seq != m_rcv_nxt) {
-    sflags = sfImmediateAck; // (Fast Recovery)
-  } else if (seg.len != 0) {
-    if (m_ack_delay == 0) {
-      sflags = sfImmediateAck;
-    } else {
-      sflags = sfDelayedAck;
-    }
-  }
-#if _DEBUGMSG >= _DBG_NORMAL
-  if (sflags == sfImmediateAck) {
-    if (seg.seq > m_rcv_nxt) {
-      LOG_F(LS_INFO) << "too new";
-    } else if (seg.seq + seg.len <= m_rcv_nxt) {
-      LOG_F(LS_INFO) << "too old";
-    }
-  }
-#endif // _DEBUGMSG
-
-  // Adjust the incoming segment to fit our receive buffer
-  if (seg.seq < m_rcv_nxt) {
-    uint32 nAdjust = m_rcv_nxt - seg.seq;
-    if (nAdjust < seg.len) {
-      seg.seq += nAdjust;
-      seg.data += nAdjust;
-      seg.len -= nAdjust;
-    } else {
-      seg.len = 0;
-    }
-  }
-
-  size_t available_space = 0;
-  m_rbuf.GetWriteRemaining(&available_space);
-
-  if ((seg.seq + seg.len - m_rcv_nxt) > static_cast<uint32>(available_space)) {
-    uint32 nAdjust = seg.seq + seg.len - m_rcv_nxt - static_cast<uint32>(available_space);
-    if (nAdjust < seg.len) {
-      seg.len -= nAdjust;
-    } else {
-      seg.len = 0;
-    }
-  }
-
-  bool bIgnoreData = (seg.flags & FLAG_CTL) || (m_shutdown != SD_NONE);
-  bool bNewData = false;
-
-  if (seg.len > 0) {
-    if (bIgnoreData) {
-      if (seg.seq == m_rcv_nxt) {
-        m_rcv_nxt += seg.len;
-      }
-    } else {
-      uint32 nOffset = seg.seq - m_rcv_nxt;
-
-      talk_base::StreamResult result = m_rbuf.WriteOffset(seg.data, seg.len,
-                                                          nOffset, NULL);
-      ASSERT(result == talk_base::SR_SUCCESS);
-      UNUSED(result);
-
-      if (seg.seq == m_rcv_nxt) {
-        m_rbuf.ConsumeWriteBuffer(seg.len);
-        m_rcv_nxt += seg.len;
-        m_rcv_wnd -= seg.len;
-        bNewData = true;
-
-        RList::iterator it = m_rlist.begin();
-        while ((it != m_rlist.end()) && (it->seq <= m_rcv_nxt)) {
-          if (it->seq + it->len > m_rcv_nxt) {
-            sflags = sfImmediateAck; // (Fast Recovery)
-            uint32 nAdjust = (it->seq + it->len) - m_rcv_nxt;
-#if _DEBUGMSG >= _DBG_NORMAL
-            LOG(LS_INFO) << "Recovered " << nAdjust << " bytes (" << m_rcv_nxt << " -> " << m_rcv_nxt + nAdjust << ")";
-#endif // _DEBUGMSG
-            m_rbuf.ConsumeWriteBuffer(nAdjust);
-            m_rcv_nxt += nAdjust;
-            m_rcv_wnd -= nAdjust;
-          }
-          it = m_rlist.erase(it);
-        }
-      } else {
-#if _DEBUGMSG >= _DBG_NORMAL
-        LOG(LS_INFO) << "Saving " << seg.len << " bytes (" << seg.seq << " -> " << seg.seq + seg.len << ")";
-#endif // _DEBUGMSG
-        RSegment rseg;
-        rseg.seq = seg.seq;
-        rseg.len = seg.len;
-        RList::iterator it = m_rlist.begin();
-        while ((it != m_rlist.end()) && (it->seq < rseg.seq)) {
-          ++it;
-        }
-        m_rlist.insert(it, rseg);
-      }
-    }
-  }
-
-  attemptSend(sflags);
-
-  // If we have new data, notify the user
-  if (bNewData && m_bReadEnable) {
-    m_bReadEnable = false;
-    if (m_notify) {
-      m_notify->OnTcpReadable(this);
-    }
-    //notify(evRead);
-  }
-
-  return true;
-}
-
-bool PseudoTcp::transmit(const SList::iterator& seg, uint32 now) {
-  if (seg->xmit >= ((m_state == TCP_ESTABLISHED) ? 15 : 30)) {
-    LOG_F(LS_VERBOSE) << "too many retransmits";
-    return false;
-  }
-
-  uint32 nTransmit = talk_base::_min(seg->len, m_mss);
-
-  while (true) {
-    uint32 seq = seg->seq;
-    uint8 flags = (seg->bCtrl ? FLAG_CTL : 0);
-    IPseudoTcpNotify::WriteResult wres = packet(seq,
-                                                flags,
-                                                seg->seq - m_snd_una,
-                                                nTransmit);
-
-    if (wres == IPseudoTcpNotify::WR_SUCCESS)
-      break;
-
-    if (wres == IPseudoTcpNotify::WR_FAIL) {
-      LOG_F(LS_VERBOSE) << "packet failed";
-      return false;
-    }
-
-    ASSERT(wres == IPseudoTcpNotify::WR_TOO_LARGE);
-
-    while (true) {
-      if (PACKET_MAXIMUMS[m_msslevel + 1] == 0) {
-        LOG_F(LS_VERBOSE) << "MTU too small";
-        return false;
-      }
-      // !?! We need to break up all outstanding and pending packets and then retransmit!?!
-
-      m_mss = PACKET_MAXIMUMS[++m_msslevel] - PACKET_OVERHEAD;
-      m_cwnd = 2 * m_mss; // I added this... haven't researched actual formula
-      if (m_mss < nTransmit) {
-        nTransmit = m_mss;
-        break;
-      }
-    }
-#if _DEBUGMSG >= _DBG_NORMAL
-    LOG(LS_INFO) << "Adjusting mss to " << m_mss << " bytes";
-#endif // _DEBUGMSG
-  }
-
-  if (nTransmit < seg->len) {
-    LOG_F(LS_VERBOSE) << "mss reduced to " << m_mss;
-
-    SSegment subseg(seg->seq + nTransmit, seg->len - nTransmit, seg->bCtrl);
-    //subseg.tstamp = seg->tstamp;
-    subseg.xmit = seg->xmit;
-    seg->len = nTransmit;
-
-    SList::iterator next = seg;
-    m_slist.insert(++next, subseg);
-  }
-
-  if (seg->xmit == 0) {
-    m_snd_nxt += seg->len;
-  }
-  seg->xmit += 1;
-  //seg->tstamp = now;
-  if (m_rto_base == 0) {
-    m_rto_base = now;
-  }
-
-  return true;
-}
-
-void PseudoTcp::attemptSend(SendFlags sflags) {
-  uint32 now = Now();
-
-  if (talk_base::TimeDiff(now, m_lastsend) > static_cast<long>(m_rx_rto)) {
-    m_cwnd = m_mss;
-  }
-
-#if _DEBUGMSG
-  bool bFirst = true;
-  UNUSED(bFirst);
-#endif // _DEBUGMSG
-
-  while (true) {
-    uint32 cwnd = m_cwnd;
-    if ((m_dup_acks == 1) || (m_dup_acks == 2)) { // Limited Transmit
-      cwnd += m_dup_acks * m_mss;
-    }
-    uint32 nWindow = talk_base::_min(m_snd_wnd, cwnd);
-    uint32 nInFlight = m_snd_nxt - m_snd_una;
-    uint32 nUseable = (nInFlight < nWindow) ? (nWindow - nInFlight) : 0;
-
-    size_t snd_buffered = 0;
-    m_sbuf.GetBuffered(&snd_buffered);
-    uint32 nAvailable =
-        talk_base::_min(static_cast<uint32>(snd_buffered) - nInFlight, m_mss);
-
-    if (nAvailable > nUseable) {
-      if (nUseable * 4 < nWindow) {
-        // RFC 813 - avoid SWS
-        nAvailable = 0;
-      } else {
-        nAvailable = nUseable;
-      }
-    }
-
-#if _DEBUGMSG >= _DBG_VERBOSE
-    if (bFirst) {
-      size_t available_space = 0;
-      m_sbuf.GetWriteRemaining(&available_space);
-
-      bFirst = false;
-      LOG(LS_INFO) << "[cwnd: " << m_cwnd
-                   << "  nWindow: " << nWindow
-                   << "  nInFlight: " << nInFlight
-                   << "  nAvailable: " << nAvailable
-                   << "  nQueued: " << snd_buffered
-                   << "  nEmpty: " << available_space
-                   << "  ssthresh: " << m_ssthresh << "]";
-    }
-#endif // _DEBUGMSG
-
-    if (nAvailable == 0) {
-      if (sflags == sfNone)
-        return;
-
-      // If this is an immediate ack, or the second delayed ack
-      if ((sflags == sfImmediateAck) || m_t_ack) {
-        packet(m_snd_nxt, 0, 0, 0);
-      } else {
-        m_t_ack = Now();
-      }
-      return;
-    }
-
-    // Nagle's algorithm.
-    // If there is data already in-flight, and we haven't a full segment of
-    // data ready to send then hold off until we get more to send, or the
-    // in-flight data is acknowledged.
-    if (m_use_nagling && (m_snd_nxt > m_snd_una) && (nAvailable < m_mss))  {
-      return;
-    }
-
-    // Find the next segment to transmit
-    SList::iterator it = m_slist.begin();
-    while (it->xmit > 0) {
-      ++it;
-      ASSERT(it != m_slist.end());
-    }
-    SList::iterator seg = it;
-
-    // If the segment is too large, break it into two
-    if (seg->len > nAvailable) {
-      SSegment subseg(seg->seq + nAvailable, seg->len - nAvailable, seg->bCtrl);
-      seg->len = nAvailable;
-      m_slist.insert(++it, subseg);
-    }
-
-    if (!transmit(seg, now)) {
-      LOG_F(LS_VERBOSE) << "transmit failed";
-      // TODO: consider closing socket
-      return;
-    }
-
-    sflags = sfNone;
-  }
-}
-
-void
-PseudoTcp::closedown(uint32 err) {
-  LOG(LS_INFO) << "State: TCP_CLOSED";
-  m_state = TCP_CLOSED;
-  if (m_notify) {
-    m_notify->OnTcpClosed(this, err);
-  }
-  //notify(evClose, err);
-}
-
-void
-PseudoTcp::adjustMTU() {
-  // Determine our current mss level, so that we can adjust appropriately later
-  for (m_msslevel = 0; PACKET_MAXIMUMS[m_msslevel + 1] > 0; ++m_msslevel) {
-    if (static_cast<uint16>(PACKET_MAXIMUMS[m_msslevel]) <= m_mtu_advise) {
-      break;
-    }
-  }
-  m_mss = m_mtu_advise - PACKET_OVERHEAD;
-  // !?! Should we reset m_largest here?
-#if _DEBUGMSG >= _DBG_NORMAL
-  LOG(LS_INFO) << "Adjusting mss to " << m_mss << " bytes";
-#endif // _DEBUGMSG
-  // Enforce minimums on ssthresh and cwnd
-  m_ssthresh = talk_base::_max(m_ssthresh, 2 * m_mss);
-  m_cwnd = talk_base::_max(m_cwnd, m_mss);
-}
-
-bool
-PseudoTcp::isReceiveBufferFull() const {
-  size_t available_space = 0;
-  m_rbuf.GetWriteRemaining(&available_space);
-  return !available_space;
-}
-
-void
-PseudoTcp::disableWindowScale() {
-  m_support_wnd_scale = false;
-}
-
-void
-PseudoTcp::queueConnectMessage() {
-  talk_base::ByteBuffer buf(talk_base::ByteBuffer::ORDER_NETWORK);
-
-  buf.WriteUInt8(CTL_CONNECT);
-  if (m_support_wnd_scale) {
-    buf.WriteUInt8(TCP_OPT_WND_SCALE);
-    buf.WriteUInt8(1);
-    buf.WriteUInt8(m_rwnd_scale);
-  }
-  m_snd_wnd = buf.Length();
-  queue(buf.Data(), buf.Length(), true);
-}
-
-void
-PseudoTcp::parseOptions(const char* data, uint32 len) {
-  std::set<uint8> options_specified;
-
-  // See http://www.freesoft.org/CIE/Course/Section4/8.htm for
-  // parsing the options list.
-  talk_base::ByteBuffer buf(data, len);
-  while (buf.Length()) {
-    uint8 kind = TCP_OPT_EOL;
-    buf.ReadUInt8(&kind);
-
-    if (kind == TCP_OPT_EOL) {
-      // End of option list.
-      break;
-    } else if (kind == TCP_OPT_NOOP) {
-      // No op.
-      continue;
-    }
-
-    // Length of this option.
-    ASSERT(len != 0);
-    UNUSED(len);
-    uint8 opt_len = 0;
-    buf.ReadUInt8(&opt_len);
-
-    // Content of this option.
-    if (opt_len <= buf.Length()) {
-      applyOption(kind, buf.Data(), opt_len);
-      buf.Consume(opt_len);
-    } else {
-      LOG(LS_ERROR) << "Invalid option length received.";
-      return;
-    }
-    options_specified.insert(kind);
-  }
-
-  if (options_specified.find(TCP_OPT_WND_SCALE) == options_specified.end()) {
-    LOG(LS_WARNING) << "Peer doesn't support window scaling";
-
-    if (m_rwnd_scale > 0) {
-      // Peer doesn't support TCP options and window scaling.
-      // Revert receive buffer size to default value.
-      resizeReceiveBuffer(DEFAULT_RCV_BUF_SIZE);
-      m_swnd_scale = 0;
-    }
-  }
-}
-
-void
-PseudoTcp::applyOption(char kind, const char* data, uint32 len) {
-  if (kind == TCP_OPT_MSS) {
-    LOG(LS_WARNING) << "Peer specified MSS option which is not supported.";
-    // TODO: Implement.
-  } else if (kind == TCP_OPT_WND_SCALE) {
-    // Window scale factor.
-    // http://www.ietf.org/rfc/rfc1323.txt
-    if (len != 1) {
-      LOG_F(WARNING) << "Invalid window scale option received.";
-      return;
-    }
-    applyWindowScaleOption(data[0]);
-  }
-}
-
-void
-PseudoTcp::applyWindowScaleOption(uint8 scale_factor) {
-  m_swnd_scale = scale_factor;
-}
-
-void
-PseudoTcp::resizeSendBuffer(uint32 new_size) {
-  m_sbuf_len = new_size;
-  m_sbuf.SetCapacity(new_size);
-}
-
-void
-PseudoTcp::resizeReceiveBuffer(uint32 new_size) {
-  uint8 scale_factor = 0;
-
-  // Determine the scale factor such that the scaled window size can fit
-  // in a 16-bit unsigned integer.
-  while (new_size > 0xFFFF) {
-    ++scale_factor;
-    new_size >>= 1;
-  }
-
-  // Determine the proper size of the buffer.
-  new_size <<= scale_factor;
-  bool result = m_rbuf.SetCapacity(new_size);
-
-  // Make sure the new buffer is large enough to contain data in the old
-  // buffer. This should always be true because this method is called either
-  // before connection is established or when peers are exchanging connect
-  // messages.
-  ASSERT(result);
-  UNUSED(result);
-  m_rbuf_len = new_size;
-  m_rwnd_scale = scale_factor;
-  m_ssthresh = new_size;
-
-  size_t available_space = 0;
-  m_rbuf.GetWriteRemaining(&available_space);
-  m_rcv_wnd = available_space;
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/p2p/base/pseudotcp.h b/third_party/libjingle/source/talk/p2p/base/pseudotcp.h
deleted file mode 100644
index f07a555..0000000
--- a/third_party/libjingle/source/talk/p2p/base/pseudotcp.h
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_P2P_BASE_PSEUDOTCP_H_
-#define TALK_P2P_BASE_PSEUDOTCP_H_
-
-#include <list>
-
-#include "talk/base/basictypes.h"
-#include "talk/base/stream.h"
-
-namespace cricket {
-
-//////////////////////////////////////////////////////////////////////
-// IPseudoTcpNotify
-//////////////////////////////////////////////////////////////////////
-
-class PseudoTcp;
-
-class IPseudoTcpNotify {
- public:
-  virtual ~IPseudoTcpNotify() {}
-  // Notification of tcp events
-  virtual void OnTcpOpen(PseudoTcp* tcp) = 0;
-  virtual void OnTcpReadable(PseudoTcp* tcp) = 0;
-  virtual void OnTcpWriteable(PseudoTcp* tcp) = 0;
-  virtual void OnTcpClosed(PseudoTcp* tcp, uint32 error) = 0;
-
-  // Write the packet onto the network
-  enum WriteResult { WR_SUCCESS, WR_TOO_LARGE, WR_FAIL };
-  virtual WriteResult TcpWritePacket(PseudoTcp* tcp,
-                                     const char* buffer, size_t len) = 0;
-};
-
-//////////////////////////////////////////////////////////////////////
-// PseudoTcp
-//////////////////////////////////////////////////////////////////////
-
-class PseudoTcp {
- public:
-  static uint32 Now();
-
-  PseudoTcp(IPseudoTcpNotify* notify, uint32 conv);
-  virtual ~PseudoTcp();
-
-  int Connect();
-  int Recv(char* buffer, size_t len);
-  int Send(const char* buffer, size_t len);
-  void Close(bool force);
-  int GetError();
-
-  enum TcpState {
-    TCP_LISTEN, TCP_SYN_SENT, TCP_SYN_RECEIVED, TCP_ESTABLISHED, TCP_CLOSED
-  };
-  TcpState State() const { return m_state; }
-
-  // Call this when the PMTU changes.
-  void NotifyMTU(uint16 mtu);
-
-  // Call this based on timeout value returned from GetNextClock.
-  // It's ok to call this too frequently.
-  void NotifyClock(uint32 now);
-
-  // Call this whenever a packet arrives.
-  // Returns true if the packet was processed successfully.
-  bool NotifyPacket(const char * buffer, size_t len);
-
-  // Call this to determine the next time NotifyClock should be called.
-  // Returns false if the socket is ready to be destroyed.
-  bool GetNextClock(uint32 now, long& timeout);
-
-  // Call these to get/set option values to tailor this PseudoTcp
-  // instance's behaviour for the kind of data it will carry.
-  // If an unrecognized option is set or got, an assertion will fire.
-  //
-  // Setting options for OPT_RCVBUF or OPT_SNDBUF after Connect() is called
-  // will result in an assertion.
-  enum Option {
-    OPT_NODELAY,      // Whether to enable Nagle's algorithm (0 == off)
-    OPT_ACKDELAY,     // The Delayed ACK timeout (0 == off).
-    OPT_RCVBUF,       // Set the receive buffer size, in bytes.
-    OPT_SNDBUF,       // Set the send buffer size, in bytes.
-  };
-  void GetOption(Option opt, int* value);
-  void SetOption(Option opt, int value);
-
- protected:
-  enum SendFlags { sfNone, sfDelayedAck, sfImmediateAck };
-
-  struct Segment {
-    uint32 conv, seq, ack;
-    uint8 flags;
-    uint16 wnd;
-    const char * data;
-    uint32 len;
-    uint32 tsval, tsecr;
-  };
-
-  struct SSegment {
-    SSegment(uint32 s, uint32 l, bool c)
-        : seq(s), len(l), /*tstamp(0),*/ xmit(0), bCtrl(c) {
-    }
-    uint32 seq, len;
-    //uint32 tstamp;
-    uint8 xmit;
-    bool bCtrl;
-  };
-  typedef std::list<SSegment> SList;
-
-  struct RSegment {
-    uint32 seq, len;
-  };
-
-  uint32 queue(const char* data, uint32 len, bool bCtrl);
-
-  // Creates a packet and submits it to the network. This method can either
-  // send payload or just an ACK packet.
-  //
-  // |seq| is the sequence number of this packet.
-  // |flags| is the flags for sending this packet.
-  // |offset| is the offset to read from |m_sbuf|.
-  // |len| is the number of bytes to read from |m_sbuf| as payload. If this
-  // value is 0 then this is an ACK packet, otherwise this packet has payload.
-  IPseudoTcpNotify::WriteResult packet(uint32 seq, uint8 flags,
-                                       uint32 offset, uint32 len);
-  bool parse(const uint8* buffer, uint32 size);
-
-  void attemptSend(SendFlags sflags = sfNone);
-
-  void closedown(uint32 err = 0);
-
-  bool clock_check(uint32 now, long& nTimeout);
-
-  bool process(Segment& seg);
-  bool transmit(const SList::iterator& seg, uint32 now);
-
-  void adjustMTU();
-
- protected:
-  // This method is used in test only to query receive buffer state.
-  bool isReceiveBufferFull() const;
-
-  // This method is only used in tests, to disable window scaling
-  // support for testing backward compatibility.
-  void disableWindowScale();
-
- private:
-  // Queue the connect message with TCP options.
-  void queueConnectMessage();
-
-  // Parse TCP options in the header.
-  void parseOptions(const char* data, uint32 len);
-
-  // Apply a TCP option that has been read from the header.
-  void applyOption(char kind, const char* data, uint32 len);
-
-  // Apply window scale option.
-  void applyWindowScaleOption(uint8 scale_factor);
-
-  // Resize the send buffer with |new_size| in bytes.
-  void resizeSendBuffer(uint32 new_size);
-
-  // Resize the receive buffer with |new_size| in bytes. This call adjusts
-  // window scale factor |m_swnd_scale| accordingly.
-  void resizeReceiveBuffer(uint32 new_size);
-
-  IPseudoTcpNotify* m_notify;
-  enum Shutdown { SD_NONE, SD_GRACEFUL, SD_FORCEFUL } m_shutdown;
-  int m_error;
-
-  // TCB data
-  TcpState m_state;
-  uint32 m_conv;
-  bool m_bReadEnable, m_bWriteEnable, m_bOutgoing;
-  uint32 m_lasttraffic;
-
-  // Incoming data
-  typedef std::list<RSegment> RList;
-  RList m_rlist;
-  uint32 m_rbuf_len, m_rcv_nxt, m_rcv_wnd, m_lastrecv;
-  uint8 m_rwnd_scale;  // Window scale factor.
-  talk_base::FifoBuffer m_rbuf;
-
-  // Outgoing data
-  SList m_slist;
-  uint32 m_sbuf_len, m_snd_nxt, m_snd_wnd, m_lastsend, m_snd_una;
-  uint8 m_swnd_scale;  // Window scale factor.
-  talk_base::FifoBuffer m_sbuf;
-
-  // Maximum segment size, estimated protocol level, largest segment sent
-  uint32 m_mss, m_msslevel, m_largest, m_mtu_advise;
-  // Retransmit timer
-  uint32 m_rto_base;
-
-  // Timestamp tracking
-  uint32 m_ts_recent, m_ts_lastack;
-
-  // Round-trip calculation
-  uint32 m_rx_rttvar, m_rx_srtt, m_rx_rto;
-
-  // Congestion avoidance, Fast retransmit/recovery, Delayed ACKs
-  uint32 m_ssthresh, m_cwnd;
-  uint8 m_dup_acks;
-  uint32 m_recover;
-  uint32 m_t_ack;
-
-  // Configuration options
-  bool m_use_nagling;
-  uint32 m_ack_delay;
-
-  // This is used by unit tests to test backward compatibility of
-  // PseudoTcp implementations that don't support window scaling.
-  bool m_support_wnd_scale;
-};
-
-}  // namespace cricket
-
-#endif  // TALK_P2P_BASE_PSEUDOTCP_H_
diff --git a/third_party/libjingle/source/talk/p2p/base/pseudotcp_unittest.cc b/third_party/libjingle/source/talk/p2p/base/pseudotcp_unittest.cc
deleted file mode 100644
index 7bf5874..0000000
--- a/third_party/libjingle/source/talk/p2p/base/pseudotcp_unittest.cc
+++ /dev/null
@@ -1,845 +0,0 @@
-/*
- * libjingle
- * Copyright 2011 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <vector>
-
-#include "talk/base/gunit.h"
-#include "talk/base/helpers.h"
-#include "talk/base/messagehandler.h"
-#include "talk/base/stream.h"
-#include "talk/base/thread.h"
-#include "talk/base/timeutils.h"
-#include "talk/p2p/base/pseudotcp.h"
-
-using cricket::PseudoTcp;
-
-static const int kConnectTimeoutMs = 10000;  // ~3 * default RTO of 3000ms
-static const int kTransferTimeoutMs = 15000;
-static const int kBlockSize = 4096;
-
-class PseudoTcpForTest : public cricket::PseudoTcp {
- public:
-  PseudoTcpForTest(cricket::IPseudoTcpNotify* notify, uint32 conv)
-      : PseudoTcp(notify, conv) {
-  }
-
-  bool isReceiveBufferFull() const {
-    return PseudoTcp::isReceiveBufferFull();
-  }
-
-  void disableWindowScale() {
-    PseudoTcp::disableWindowScale();
-  }
-};
-
-class PseudoTcpTestBase : public testing::Test,
-                      public talk_base::MessageHandler,
-                      public cricket::IPseudoTcpNotify {
- public:
-  PseudoTcpTestBase()
-      : local_(this, 1),
-        remote_(this, 1),
-        have_connected_(false),
-        have_disconnected_(false),
-        local_mtu_(65535),
-        remote_mtu_(65535),
-        delay_(0),
-        loss_(0) {
-    // Set use of the test RNG to get predictable loss patterns.
-    talk_base::SetRandomTestMode(true);
-  }
-  ~PseudoTcpTestBase() {
-    // Put it back for the next test.
-    talk_base::SetRandomTestMode(false);
-  }
-  void SetLocalMtu(int mtu) {
-    local_.NotifyMTU(mtu);
-    local_mtu_ = mtu;
-  }
-  void SetRemoteMtu(int mtu) {
-    remote_.NotifyMTU(mtu);
-    remote_mtu_ = mtu;
-  }
-  void SetDelay(int delay) {
-    delay_ = delay;
-  }
-  void SetLoss(int percent) {
-    loss_ = percent;
-  }
-  void SetOptNagling(bool enable_nagles) {
-    local_.SetOption(PseudoTcp::OPT_NODELAY, !enable_nagles);
-    remote_.SetOption(PseudoTcp::OPT_NODELAY, !enable_nagles);
-  }
-  void SetOptAckDelay(int ack_delay) {
-    local_.SetOption(PseudoTcp::OPT_ACKDELAY, ack_delay);
-    remote_.SetOption(PseudoTcp::OPT_ACKDELAY, ack_delay);
-  }
-  void SetOptSndBuf(int size) {
-    local_.SetOption(PseudoTcp::OPT_SNDBUF, size);
-    remote_.SetOption(PseudoTcp::OPT_SNDBUF, size);
-  }
-  void SetRemoteOptRcvBuf(int size) {
-    remote_.SetOption(PseudoTcp::OPT_RCVBUF, size);
-  }
-  void SetLocalOptRcvBuf(int size) {
-    local_.SetOption(PseudoTcp::OPT_RCVBUF, size);
-  }
-  void DisableRemoteWindowScale() {
-    remote_.disableWindowScale();
-  }
-  void DisableLocalWindowScale() {
-    local_.disableWindowScale();
-  }
-
- protected:
-  int Connect() {
-    int ret = local_.Connect();
-    if (ret == 0) {
-      UpdateLocalClock();
-    }
-    return ret;
-  }
-  void Close() {
-    local_.Close(false);
-    UpdateLocalClock();
-  }
-
-  enum { MSG_LPACKET, MSG_RPACKET, MSG_LCLOCK, MSG_RCLOCK, MSG_IOCOMPLETE,
-         MSG_WRITE};
-  virtual void OnTcpOpen(PseudoTcp* tcp) {
-    // Consider ourselves connected when the local side gets OnTcpOpen.
-    // OnTcpWriteable isn't fired at open, so we trigger it now.
-    LOG(LS_VERBOSE) << "Opened";
-    if (tcp == &local_) {
-      have_connected_ = true;
-      OnTcpWriteable(tcp);
-    }
-  }
-  // Test derived from the base should override
-  //   virtual void OnTcpReadable(PseudoTcp* tcp)
-  // and
-  //   virtual void OnTcpWritable(PseudoTcp* tcp)
-  virtual void OnTcpClosed(PseudoTcp* tcp, uint32 error) {
-    // Consider ourselves closed when the remote side gets OnTcpClosed.
-    // TODO: OnTcpClosed is only ever notified in case of error in
-    // the current implementation.  Solicited close is not (yet) supported.
-    LOG(LS_VERBOSE) << "Closed";
-    EXPECT_EQ(0U, error);
-    if (tcp == &remote_) {
-      have_disconnected_ = true;
-    }
-  }
-  virtual WriteResult TcpWritePacket(PseudoTcp* tcp,
-                                     const char* buffer, size_t len) {
-    // Randomly drop the desired percentage of packets.
-    // Also drop packets that are larger than the configured MTU.
-    if (talk_base::CreateRandomId() % 100 < static_cast<uint32>(loss_)) {
-      LOG(LS_VERBOSE) << "Randomly dropping packet, size=" << len;
-    } else if (len > static_cast<size_t>(
-        talk_base::_min(local_mtu_, remote_mtu_))) {
-      LOG(LS_VERBOSE) << "Dropping packet that exceeds path MTU, size=" << len;
-    } else {
-      int id = (tcp == &local_) ? MSG_RPACKET : MSG_LPACKET;
-      std::string packet(buffer, len);
-      talk_base::Thread::Current()->PostDelayed(delay_, this, id,
-          talk_base::WrapMessageData(packet));
-    }
-    return WR_SUCCESS;
-  }
-
-  void UpdateLocalClock() { UpdateClock(&local_, MSG_LCLOCK); }
-  void UpdateRemoteClock() { UpdateClock(&remote_, MSG_RCLOCK); }
-  void UpdateClock(PseudoTcp* tcp, uint32 message) {
-    long interval;  // NOLINT
-    tcp->GetNextClock(PseudoTcp::Now(), interval);
-    interval = talk_base::_max<int>(interval, 0L);  // sometimes interval is < 0
-    talk_base::Thread::Current()->Clear(this, message);
-    talk_base::Thread::Current()->PostDelayed(interval, this, message);
-  }
-
-  virtual void OnMessage(talk_base::Message* message) {
-    switch (message->message_id) {
-      case MSG_LPACKET: {
-        const std::string& s(
-            talk_base::UseMessageData<std::string>(message->pdata));
-        local_.NotifyPacket(s.c_str(), s.size());
-        UpdateLocalClock();
-        break;
-      }
-      case MSG_RPACKET: {
-        const std::string& s(
-            talk_base::UseMessageData<std::string>(message->pdata));
-        remote_.NotifyPacket(s.c_str(), s.size());
-        UpdateRemoteClock();
-        break;
-      }
-      case MSG_LCLOCK:
-        local_.NotifyClock(PseudoTcp::Now());
-        UpdateLocalClock();
-        break;
-      case MSG_RCLOCK:
-        remote_.NotifyClock(PseudoTcp::Now());
-        UpdateRemoteClock();
-        break;
-      default:
-        break;
-    }
-    delete message->pdata;
-  }
-
-  PseudoTcpForTest local_;
-  PseudoTcpForTest remote_;
-  talk_base::MemoryStream send_stream_;
-  talk_base::MemoryStream recv_stream_;
-  bool have_connected_;
-  bool have_disconnected_;
-  int local_mtu_;
-  int remote_mtu_;
-  int delay_;
-  int loss_;
-};
-
-class PseudoTcpTest : public PseudoTcpTestBase {
- public:
-  void TestTransfer(int size) {
-    uint32 start, elapsed;
-    size_t received;
-    // Create some dummy data to send.
-    send_stream_.ReserveSize(size);
-    for (int i = 0; i < size; ++i) {
-      char ch = static_cast<char>(i);
-      send_stream_.Write(&ch, 1, NULL, NULL);
-    }
-    send_stream_.Rewind();
-    // Prepare the receive stream.
-    recv_stream_.ReserveSize(size);
-    // Connect and wait until connected.
-    start = talk_base::Time();
-    EXPECT_EQ(0, Connect());
-    EXPECT_TRUE_WAIT(have_connected_, kConnectTimeoutMs);
-    // Sending will start from OnTcpWriteable and complete when all data has
-    // been received.
-    EXPECT_TRUE_WAIT(have_disconnected_, kTransferTimeoutMs);
-    elapsed = talk_base::TimeSince(start);
-    recv_stream_.GetSize(&received);
-    // Ensure we closed down OK and we got the right data.
-    // TODO: Ensure the errors are cleared properly.
-    //EXPECT_EQ(0, local_.GetError());
-    //EXPECT_EQ(0, remote_.GetError());
-    EXPECT_EQ(static_cast<size_t>(size), received);
-    EXPECT_EQ(0, memcmp(send_stream_.GetBuffer(),
-                        recv_stream_.GetBuffer(), size));
-    LOG(LS_INFO) << "Transferred " << received << " bytes in " << elapsed
-                 << " ms (" << size * 8 / elapsed << " Kbps)";
-  }
-
- private:
-  // IPseudoTcpNotify interface
-
-  virtual void OnTcpReadable(PseudoTcp* tcp) {
-    // Stream bytes to the recv stream as they arrive.
-    if (tcp == &remote_) {
-      ReadData();
-
-      // TODO: OnTcpClosed() is currently only notified on error -
-      // there is no on-the-wire equivalent of TCP FIN.
-      // So we fake the notification when all the data has been read.
-      size_t received, required;
-      recv_stream_.GetPosition(&received);
-      send_stream_.GetSize(&required);
-      if (received == required)
-        OnTcpClosed(&remote_, 0);
-    }
-  }
-  virtual void OnTcpWriteable(PseudoTcp* tcp) {
-    // Write bytes from the send stream when we can.
-    // Shut down when we've sent everything.
-    if (tcp == &local_) {
-      LOG(LS_VERBOSE) << "Flow Control Lifted";
-      bool done;
-      WriteData(&done);
-      if (done) {
-        Close();
-      }
-    }
-  }
-
-  void ReadData() {
-    char block[kBlockSize];
-    size_t position;
-    int rcvd;
-    do {
-      rcvd = remote_.Recv(block, sizeof(block));
-      if (rcvd != -1) {
-        recv_stream_.Write(block, rcvd, NULL, NULL);
-        recv_stream_.GetPosition(&position);
-        LOG(LS_VERBOSE) << "Received: " << position;
-      }
-    } while (rcvd > 0);
-  }
-  void WriteData(bool* done) {
-    size_t position, tosend;
-    int sent;
-    char block[kBlockSize];
-    do {
-      send_stream_.GetPosition(&position);
-      if (send_stream_.Read(block, sizeof(block), &tosend, NULL) !=
-          talk_base::SR_EOS) {
-        sent = local_.Send(block, tosend);
-        UpdateLocalClock();
-        if (sent != -1) {
-          send_stream_.SetPosition(position + sent);
-          LOG(LS_VERBOSE) << "Sent: " << position + sent;
-        } else {
-          send_stream_.SetPosition(position);
-          LOG(LS_VERBOSE) << "Flow Controlled";
-        }
-      } else {
-        sent = tosend = 0;
-      }
-    } while (sent > 0);
-    *done = (tosend == 0);
-  }
-
- private:
-  talk_base::MemoryStream send_stream_;
-  talk_base::MemoryStream recv_stream_;
-};
-
-
-class PseudoTcpTestPingPong : public PseudoTcpTestBase {
- public:
-  PseudoTcpTestPingPong()
-      : iterations_remaining_(0),
-	sender_(NULL),
-	receiver_(NULL),
-	bytes_per_send_(0) {
-  }
-  void SetBytesPerSend(int bytes) {
-    bytes_per_send_ = bytes;
-  }
-  void TestPingPong(int size, int iterations) {
-    uint32 start, elapsed;
-    iterations_remaining_ = iterations;
-    receiver_ = &remote_;
-    sender_ = &local_;
-    // Create some dummy data to send.
-    send_stream_.ReserveSize(size);
-    for (int i = 0; i < size; ++i) {
-      char ch = static_cast<char>(i);
-      send_stream_.Write(&ch, 1, NULL, NULL);
-    }
-    send_stream_.Rewind();
-    // Prepare the receive stream.
-    recv_stream_.ReserveSize(size);
-    // Connect and wait until connected.
-    start = talk_base::Time();
-    EXPECT_EQ(0, Connect());
-    EXPECT_TRUE_WAIT(have_connected_, kConnectTimeoutMs);
-    // Sending will start from OnTcpWriteable and stop when the required
-    // number of iterations have completed.
-    EXPECT_TRUE_WAIT(have_disconnected_, kTransferTimeoutMs);
-    elapsed = talk_base::TimeSince(start);
-    LOG(LS_INFO) << "Performed " << iterations << " pings in "
-                 << elapsed << " ms";
-  }
-
- private:
-  // IPseudoTcpNotify interface
-
-  virtual void OnTcpReadable(PseudoTcp* tcp) {
-    if (tcp != receiver_) {
-      LOG_F(LS_ERROR) << "unexpected OnTcpReadable";
-      return;
-    }
-    // Stream bytes to the recv stream as they arrive.
-    ReadData();
-    // If we've received the desired amount of data, rewind things
-    // and send it back the other way!
-    size_t position, desired;
-    recv_stream_.GetPosition(&position);
-    send_stream_.GetSize(&desired);
-    if (position == desired) {
-      if (receiver_ == &local_ && --iterations_remaining_ == 0) {
-        Close();
-        // TODO: Fake OnTcpClosed() on the receiver for now.
-        OnTcpClosed(&remote_, 0);
-        return;
-      }
-      PseudoTcp* tmp = receiver_;
-      receiver_ = sender_;
-      sender_ = tmp;
-      recv_stream_.Rewind();
-      send_stream_.Rewind();
-      OnTcpWriteable(sender_);
-    }
-  }
-  virtual void OnTcpWriteable(PseudoTcp* tcp) {
-    if (tcp != sender_)
-      return;
-    // Write bytes from the send stream when we can.
-    // Shut down when we've sent everything.
-    LOG(LS_VERBOSE) << "Flow Control Lifted";
-    WriteData();
-  }
-
-  void ReadData() {
-    char block[kBlockSize];
-    size_t position;
-    int rcvd;
-    do {
-      rcvd = receiver_->Recv(block, sizeof(block));
-      if (rcvd != -1) {
-        recv_stream_.Write(block, rcvd, NULL, NULL);
-        recv_stream_.GetPosition(&position);
-        LOG(LS_VERBOSE) << "Received: " << position;
-      }
-    } while (rcvd > 0);
-  }
-  void WriteData() {
-    size_t position, tosend;
-    int sent;
-    char block[kBlockSize];
-    do {
-      send_stream_.GetPosition(&position);
-      tosend = bytes_per_send_ ? bytes_per_send_ : sizeof(block);
-      if (send_stream_.Read(block, tosend, &tosend, NULL) !=
-          talk_base::SR_EOS) {
-        sent = sender_->Send(block, tosend);
-        UpdateLocalClock();
-        if (sent != -1) {
-          send_stream_.SetPosition(position + sent);
-          LOG(LS_VERBOSE) << "Sent: " << position + sent;
-        } else {
-          send_stream_.SetPosition(position);
-          LOG(LS_VERBOSE) << "Flow Controlled";
-        }
-      } else {
-        sent = tosend = 0;
-      }
-    } while (sent > 0);
-  }
-
- private:
-  int iterations_remaining_;
-  PseudoTcp* sender_;
-  PseudoTcp* receiver_;
-  int bytes_per_send_;
-};
-
-// Fill the receiver window until it is full, drain it and then
-// fill it with the same amount. This is to test that receiver window
-// contracts and enlarges correctly.
-class PseudoTcpTestReceiveWindow : public PseudoTcpTestBase {
- public:
-  // Not all the data are transfered, |size| just need to be big enough
-  // to fill up the receiver window twice.
-  void TestTransfer(int size) {
-    // Create some dummy data to send.
-    send_stream_.ReserveSize(size);
-    for (int i = 0; i < size; ++i) {
-      char ch = static_cast<char>(i);
-      send_stream_.Write(&ch, 1, NULL, NULL);
-    }
-    send_stream_.Rewind();
-
-    // Prepare the receive stream.
-    recv_stream_.ReserveSize(size);
-
-    // Connect and wait until connected.
-    EXPECT_EQ(0, Connect());
-    EXPECT_TRUE_WAIT(have_connected_, kConnectTimeoutMs);
-
-    talk_base::Thread::Current()->Post(this, MSG_WRITE);
-    EXPECT_TRUE_WAIT(have_disconnected_, kTransferTimeoutMs);
-
-    ASSERT_EQ(2u, send_position_.size());
-    ASSERT_EQ(2u, recv_position_.size());
-
-    const size_t estimated_recv_window = recv_position_[0];
-
-    // The difference in consecutive send positions should equal the
-    // receive window size or match very closely. This verifies that receive
-    // window is open after receiver drained all the data.
-    const size_t send_position_diff = send_position_[1] - send_position_[0];
-    EXPECT_GE(1024u, estimated_recv_window - send_position_diff);
-
-    // Receiver drained the receive window twice.
-    EXPECT_EQ(2 * estimated_recv_window, recv_position_[1]);
-  }
-
-  virtual void OnMessage(talk_base::Message* message) {
-    int message_id = message->message_id;
-    PseudoTcpTestBase::OnMessage(message);
-
-    switch (message_id) {
-      case MSG_WRITE: {
-        WriteData();
-        break;
-      }
-      default:
-        break;
-    }
-  }
-
-  uint32 EstimateReceiveWindowSize() const {
-    return recv_position_[0];
-  }
-
-  uint32 EstimateSendWindowSize() const {
-    return send_position_[0] - recv_position_[0];
-  }
-
- private:
-  // IPseudoTcpNotify interface
-  virtual void OnTcpReadable(PseudoTcp* tcp) {
-  }
-
-  virtual void OnTcpWriteable(PseudoTcp* tcp) {
-  }
-
-  void ReadUntilIOPending() {
-    char block[kBlockSize];
-    size_t position;
-    int rcvd;
-
-    do {
-      rcvd = remote_.Recv(block, sizeof(block));
-      if (rcvd != -1) {
-        recv_stream_.Write(block, rcvd, NULL, NULL);
-        recv_stream_.GetPosition(&position);
-        LOG(LS_VERBOSE) << "Received: " << position;
-      }
-    } while (rcvd > 0);
-
-    recv_stream_.GetPosition(&position);
-    recv_position_.push_back(position);
-
-    // Disconnect if we have done two transfers.
-    if (recv_position_.size() == 2u) {
-      Close();
-      OnTcpClosed(&remote_, 0);
-    } else {
-      WriteData();
-    }
-  }
-
-  void WriteData() {
-    size_t position, tosend;
-    int sent;
-    char block[kBlockSize];
-    do {
-      send_stream_.GetPosition(&position);
-      if (send_stream_.Read(block, sizeof(block), &tosend, NULL) !=
-          talk_base::SR_EOS) {
-        sent = local_.Send(block, tosend);
-        UpdateLocalClock();
-        if (sent != -1) {
-          send_stream_.SetPosition(position + sent);
-          LOG(LS_VERBOSE) << "Sent: " << position + sent;
-        } else {
-          send_stream_.SetPosition(position);
-          LOG(LS_VERBOSE) << "Flow Controlled";
-        }
-      } else {
-        sent = tosend = 0;
-      }
-    } while (sent > 0);
-
-    if (remote_.isReceiveBufferFull()) {
-      send_stream_.GetPosition(&position);
-      send_position_.push_back(position);
-
-      // Drain the receiver buffer.
-      ReadUntilIOPending();
-    } else {
-      // If the receiver side is not full then keep writing.
-      talk_base::Thread::Current()->PostDelayed(10, this, MSG_WRITE);
-    }
-  }
-
- private:
-  talk_base::MemoryStream send_stream_;
-  talk_base::MemoryStream recv_stream_;
-
-  std::vector<size_t> send_position_;
-  std::vector<size_t> recv_position_;
-};
-
-// Basic end-to-end data transfer tests
-
-// Test the normal case of sending data from one side to the other.
-TEST_F(PseudoTcpTest, TestSend) {
-  SetLocalMtu(1500);
-  SetRemoteMtu(1500);
-  TestTransfer(1000000);
-}
-
-// Test sending data with a 50 ms RTT. Transmission should take longer due
-// to a slower ramp-up in send rate.
-TEST_F(PseudoTcpTest, TestSendWithDelay) {
-  SetLocalMtu(1500);
-  SetRemoteMtu(1500);
-  SetDelay(50);
-  TestTransfer(1000000);
-}
-
-// Test sending data with packet loss. Transmission should take much longer due
-// to send back-off when loss occurs.
-TEST_F(PseudoTcpTest, TestSendWithLoss) {
-  SetLocalMtu(1500);
-  SetRemoteMtu(1500);
-  SetLoss(10);
-  TestTransfer(100000);  // less data so test runs faster
-}
-
-// Test sending data with a 50 ms RTT and 10% packet loss. Transmission should
-// take much longer due to send back-off and slower detection of loss.
-TEST_F(PseudoTcpTest, TestSendWithDelayAndLoss) {
-  SetLocalMtu(1500);
-  SetRemoteMtu(1500);
-  SetDelay(50);
-  SetLoss(10);
-  TestTransfer(100000);  // less data so test runs faster
-}
-
-// Test sending data with 10% packet loss and Nagling disabled.  Transmission
-// should take about the same time as with Nagling enabled.
-TEST_F(PseudoTcpTest, TestSendWithLossAndOptNaglingOff) {
-  SetLocalMtu(1500);
-  SetRemoteMtu(1500);
-  SetLoss(10);
-  SetOptNagling(false);
-  TestTransfer(100000);  // less data so test runs faster
-}
-
-// Test sending data with 10% packet loss and Delayed ACK disabled.
-// Transmission should be slightly faster than with it enabled.
-TEST_F(PseudoTcpTest, TestSendWithLossAndOptAckDelayOff) {
-  SetLocalMtu(1500);
-  SetRemoteMtu(1500);
-  SetLoss(10);
-  SetOptAckDelay(0);
-  TestTransfer(100000);
-}
-
-// Test sending data with 50ms delay and Nagling disabled.
-TEST_F(PseudoTcpTest, TestSendWithDelayAndOptNaglingOff) {
-  SetLocalMtu(1500);
-  SetRemoteMtu(1500);
-  SetDelay(50);
-  SetOptNagling(false);
-  TestTransfer(100000);  // less data so test runs faster
-}
-
-// Test sending data with 50ms delay and Delayed ACK disabled.
-TEST_F(PseudoTcpTest, TestSendWithDelayAndOptAckDelayOff) {
-  SetLocalMtu(1500);
-  SetRemoteMtu(1500);
-  SetDelay(50);
-  SetOptAckDelay(0);
-  TestTransfer(100000);  // less data so test runs faster
-}
-
-// Test a large receive buffer with a sender that doesn't support scaling.
-TEST_F(PseudoTcpTest, TestSendRemoteNoWindowScale) {
-  SetLocalMtu(1500);
-  SetRemoteMtu(1500);
-  SetLocalOptRcvBuf(100000);
-  DisableRemoteWindowScale();
-  TestTransfer(1000000);
-}
-
-// Test a large sender-side receive buffer with a receiver that doesn't support
-// scaling.
-TEST_F(PseudoTcpTest, TestSendLocalNoWindowScale) {
-  SetLocalMtu(1500);
-  SetRemoteMtu(1500);
-  SetRemoteOptRcvBuf(100000);
-  DisableLocalWindowScale();
-  TestTransfer(1000000);
-}
-
-// Test when both sides use window scaling.
-TEST_F(PseudoTcpTest, TestSendBothUseWindowScale) {
-  SetLocalMtu(1500);
-  SetRemoteMtu(1500);
-  SetRemoteOptRcvBuf(100000);
-  SetLocalOptRcvBuf(100000);
-  TestTransfer(1000000);
-}
-
-// Test using a large window scale value.
-TEST_F(PseudoTcpTest, TestSendLargeInFlight) {
-  SetLocalMtu(1500);
-  SetRemoteMtu(1500);
-  SetRemoteOptRcvBuf(100000);
-  SetLocalOptRcvBuf(100000);
-  SetOptSndBuf(150000);
-  TestTransfer(1000000);
-}
-
-TEST_F(PseudoTcpTest, TestSendBothUseLargeWindowScale) {
-  SetLocalMtu(1500);
-  SetRemoteMtu(1500);
-  SetRemoteOptRcvBuf(1000000);
-  SetLocalOptRcvBuf(1000000);
-  TestTransfer(10000000);
-}
-
-// Test using a small receive buffer.
-TEST_F(PseudoTcpTest, TestSendSmallReceiveBuffer) {
-  SetLocalMtu(1500);
-  SetRemoteMtu(1500);
-  SetRemoteOptRcvBuf(10000);
-  SetLocalOptRcvBuf(10000);
-  TestTransfer(1000000);
-}
-
-// Test using a very small receive buffer.
-TEST_F(PseudoTcpTest, TestSendVerySmallReceiveBuffer) {
-  SetLocalMtu(1500);
-  SetRemoteMtu(1500);
-  SetRemoteOptRcvBuf(100);
-  SetLocalOptRcvBuf(100);
-  TestTransfer(100000);
-}
-
-// Ping-pong (request/response) tests
-
-// Test sending <= 1x MTU of data in each ping/pong.  Should take <10ms.
-TEST_F(PseudoTcpTestPingPong, TestPingPong1xMtu) {
-  SetLocalMtu(1500);
-  SetRemoteMtu(1500);
-  TestPingPong(100, 100);
-}
-
-// Test sending 2x-3x MTU of data in each ping/pong.  Should take <10ms.
-TEST_F(PseudoTcpTestPingPong, TestPingPong3xMtu) {
-  SetLocalMtu(1500);
-  SetRemoteMtu(1500);
-  TestPingPong(400, 100);
-}
-
-// Test sending 1x-2x MTU of data in each ping/pong.
-// Should take ~1s, due to interaction between Nagling and Delayed ACK.
-TEST_F(PseudoTcpTestPingPong, TestPingPong2xMtu) {
-  SetLocalMtu(1500);
-  SetRemoteMtu(1500);
-  TestPingPong(2000, 5);
-}
-
-// Test sending 1x-2x MTU of data in each ping/pong with Delayed ACK off.
-// Should take <10ms.
-TEST_F(PseudoTcpTestPingPong, TestPingPong2xMtuWithAckDelayOff) {
-  SetLocalMtu(1500);
-  SetRemoteMtu(1500);
-  SetOptAckDelay(0);
-  TestPingPong(2000, 100);
-}
-
-// Test sending 1x-2x MTU of data in each ping/pong with Nagling off.
-// Should take <10ms.
-TEST_F(PseudoTcpTestPingPong, TestPingPong2xMtuWithNaglingOff) {
-  SetLocalMtu(1500);
-  SetRemoteMtu(1500);
-  SetOptNagling(false);
-  TestPingPong(2000, 5);
-}
-
-// Test sending a ping as pair of short (non-full) segments.
-// Should take ~1s, due to Delayed ACK interaction with Nagling.
-TEST_F(PseudoTcpTestPingPong, TestPingPongShortSegments) {
-  SetLocalMtu(1500);
-  SetRemoteMtu(1500);
-  SetOptAckDelay(5000);
-  SetBytesPerSend(50); // i.e. two Send calls per payload
-  TestPingPong(100, 5);
-}
-
-// Test sending ping as a pair of short (non-full) segments, with Nagling off.
-// Should take <10ms.
-TEST_F(PseudoTcpTestPingPong, TestPingPongShortSegmentsWithNaglingOff) {
-  SetLocalMtu(1500);
-  SetRemoteMtu(1500);
-  SetOptNagling(false);
-  SetBytesPerSend(50); // i.e. two Send calls per payload
-  TestPingPong(100, 5);
-}
-
-// Test sending <= 1x MTU of data ping/pong, in two segments, no Delayed ACK.
-// Should take ~1s.
-TEST_F(PseudoTcpTestPingPong, TestPingPongShortSegmentsWithAckDelayOff) {
-  SetLocalMtu(1500);
-  SetRemoteMtu(1500);
-  SetBytesPerSend(50); // i.e. two Send calls per payload
-  SetOptAckDelay(0);
-  TestPingPong(100, 5);
-}
-
-// Test that receive window expands and contract correctly.
-TEST_F(PseudoTcpTestReceiveWindow, TestReceiveWindow) {
-  SetLocalMtu(1500);
-  SetRemoteMtu(1500);
-  SetOptNagling(false);
-  SetOptAckDelay(0);
-  TestTransfer(1024 * 1000);
-}
-
-// Test setting send window size to a very small value.
-TEST_F(PseudoTcpTestReceiveWindow, TestSetVerySmallSendWindowSize) {
-  SetLocalMtu(1500);
-  SetRemoteMtu(1500);
-  SetOptNagling(false);
-  SetOptAckDelay(0);
-  SetOptSndBuf(900);
-  TestTransfer(1024 * 1000);
-  EXPECT_EQ(900u, EstimateSendWindowSize());
-}
-
-// Test setting receive window size to a value other than default.
-TEST_F(PseudoTcpTestReceiveWindow, TestSetReceiveWindowSize) {
-  SetLocalMtu(1500);
-  SetRemoteMtu(1500);
-  SetOptNagling(false);
-  SetOptAckDelay(0);
-  SetRemoteOptRcvBuf(100000);
-  SetLocalOptRcvBuf(100000);
-  TestTransfer(1024 * 1000);
-  EXPECT_EQ(100000u, EstimateReceiveWindowSize());
-}
-
-/* Test sending data with mismatched MTUs. We should detect this and reduce
-// our packet size accordingly.
-// TODO: This doesn't actually work right now. The current code
-// doesn't detect if the MTU is set too high on either side.
-TEST_F(PseudoTcpTest, TestSendWithMismatchedMtus) {
-  SetLocalMtu(1500);
-  SetRemoteMtu(1280);
-  TestTransfer(1000000);
-}
-*/
diff --git a/third_party/libjingle/source/talk/p2p/base/rawtransport.cc b/third_party/libjingle/source/talk/p2p/base/rawtransport.cc
deleted file mode 100644
index b07d69c..0000000
--- a/third_party/libjingle/source/talk/p2p/base/rawtransport.cc
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string>
-#include <vector>
-#include "talk/p2p/base/rawtransport.h"
-#include "talk/base/common.h"
-#include "talk/p2p/base/constants.h"
-#include "talk/p2p/base/parsing.h"
-#include "talk/p2p/base/sessionmanager.h"
-#include "talk/p2p/base/rawtransportchannel.h"
-#include "talk/xmllite/qname.h"
-#include "talk/xmllite/xmlelement.h"
-#include "talk/xmpp/constants.h"
-
-#if defined(FEATURE_ENABLE_PSTN)
-namespace cricket {
-
-RawTransport::RawTransport(talk_base::Thread* signaling_thread,
-                           talk_base::Thread* worker_thread,
-                           PortAllocator* allocator)
-    : Transport(signaling_thread, worker_thread,
-                NS_GINGLE_RAW, allocator) {
-}
-
-RawTransport::~RawTransport() {
-  DestroyAllChannels();
-}
-
-bool RawTransport::ParseCandidates(SignalingProtocol protocol,
-                                   const buzz::XmlElement* elem,
-                                   Candidates* candidates,
-                                   ParseError* error) {
-  ASSERT(elem->FirstChild() == NULL);
-  for (const buzz::XmlElement* cand_elem = elem->FirstElement();
-       cand_elem != NULL;
-       cand_elem = cand_elem->NextElement()) {
-    if (cand_elem->Name() == QN_GINGLE_RAW_CHANNEL) {
-      talk_base::SocketAddress addr;
-      if (!ParseRawAddress(cand_elem, &addr, error))
-        return false;
-
-      Candidate candidate;
-      candidate.set_name(cand_elem->Attr(buzz::QN_NAME));
-      candidate.set_address(addr);
-      candidates->push_back(candidate);
-    }
-  }
-  return true;
-}
-
-bool RawTransport::WriteCandidates(SignalingProtocol protocol,
-                                   const Candidates& candidates,
-                                   XmlElements* candidate_elems,
-                                   WriteError* error) {
-  for (std::vector<Candidate>::const_iterator
-       cand = candidates.begin();
-       cand != candidates.end();
-       ++cand) {
-    ASSERT(cand->protocol() == "udp");
-    talk_base::SocketAddress addr = cand->address();
-
-    buzz::XmlElement* elem = new buzz::XmlElement(QN_GINGLE_RAW_CHANNEL);
-    elem->SetAttr(buzz::QN_NAME, type());
-    elem->SetAttr(QN_ADDRESS, addr.IPAsString());
-    elem->SetAttr(QN_PORT, addr.PortAsString());
-    candidate_elems->push_back(elem);
-  }
-  return true;
-}
-
-bool RawTransport::ParseRawAddress(const buzz::XmlElement* elem,
-                                   talk_base::SocketAddress* addr,
-                                   ParseError* error) {
-  // Make sure the required attributes exist
-  if (!elem->HasAttr(buzz::QN_NAME) ||
-      !elem->HasAttr(QN_ADDRESS) ||
-      !elem->HasAttr(QN_PORT)) {
-    return BadParse("channel missing required attribute", error);
-  }
-
-  // Make sure the channel named actually exists.
-  if (!HasChannel(elem->Attr(buzz::QN_NAME)))
-    return BadParse("channel named does not exist", error);
-
-  // Parse the address.
-  if (!ParseAddress(elem, QN_ADDRESS, QN_PORT, addr, error))
-    return false;
-
-  return true;
-}
-
-TransportChannelImpl* RawTransport::CreateTransportChannel(
-    const std::string& name, const std::string& content_type) {
-  return new RawTransportChannel(name, content_type, this,
-                                 worker_thread(),
-                                 port_allocator());
-}
-
-void RawTransport::DestroyTransportChannel(TransportChannelImpl* channel) {
-  delete channel;
-}
-
-}  // namespace cricket
-#endif  // defined(FEATURE_ENABLE_PSTN)
diff --git a/third_party/libjingle/source/talk/p2p/base/rawtransport.h b/third_party/libjingle/source/talk/p2p/base/rawtransport.h
deleted file mode 100644
index 6734130..0000000
--- a/third_party/libjingle/source/talk/p2p/base/rawtransport.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_P2P_BASE_RAWTRANSPORT_H_
-#define TALK_P2P_BASE_RAWTRANSPORT_H_
-
-#include <string>
-#include "talk/p2p/base/transport.h"
-
-#if defined(FEATURE_ENABLE_PSTN)
-namespace cricket {
-
-// Implements a transport that only sends raw packets, no STUN.  As a result,
-// it cannot do pings to determine connectivity, so it only uses a single port
-// that it thinks will work.
-class RawTransport: public Transport, public TransportParser {
- public:
-  RawTransport(talk_base::Thread* signaling_thread,
-               talk_base::Thread* worker_thread,
-               PortAllocator* allocator);
-  virtual ~RawTransport();
-
-  virtual bool ParseCandidates(SignalingProtocol protocol,
-                               const buzz::XmlElement* elem,
-                               Candidates* candidates,
-                               ParseError* error);
-  virtual bool WriteCandidates(SignalingProtocol protocol,
-                               const Candidates& candidates,
-                               XmlElements* candidate_elems,
-                               WriteError* error);
-
- protected:
-  // Creates and destroys raw channels.
-  virtual TransportChannelImpl* CreateTransportChannel(
-     const std::string& name, const std::string &content_type);
-  virtual void DestroyTransportChannel(TransportChannelImpl* channel);
-
- private:
-  // Parses the given element, which should describe the address to use for a
-  // given channel.  This will return false and signal an error if the address
-  // or channel name is bad.
-  bool ParseRawAddress(const buzz::XmlElement* elem,
-                       talk_base::SocketAddress* addr,
-                       ParseError* error);
-
-  friend class RawTransportChannel;  // For ParseAddress.
-
-  DISALLOW_EVIL_CONSTRUCTORS(RawTransport);
-};
-
-}  // namespace cricket
-
-#endif  // defined(FEATURE_ENABLE_PSTN)
-
-#endif  // TALK_P2P_BASE_RAWTRANSPORT_H_
diff --git a/third_party/libjingle/source/talk/p2p/base/rawtransportchannel.cc b/third_party/libjingle/source/talk/p2p/base/rawtransportchannel.cc
deleted file mode 100644
index 8736053..0000000
--- a/third_party/libjingle/source/talk/p2p/base/rawtransportchannel.cc
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/p2p/base/rawtransportchannel.h"
-
-#include <string>
-#include <vector>
-#include "talk/base/common.h"
-#include "talk/p2p/base/constants.h"
-#include "talk/p2p/base/port.h"
-#include "talk/p2p/base/portallocator.h"
-#include "talk/p2p/base/rawtransport.h"
-#include "talk/p2p/base/relayport.h"
-#include "talk/p2p/base/sessionmanager.h"
-#include "talk/p2p/base/stunport.h"
-#include "talk/xmllite/qname.h"
-#include "talk/xmllite/xmlelement.h"
-#include "talk/xmpp/constants.h"
-
-#if defined(FEATURE_ENABLE_PSTN)
-
-namespace {
-
-const uint32 MSG_DESTROY_UNUSED_PORTS = 1;
-
-}  // namespace
-
-namespace cricket {
-
-RawTransportChannel::RawTransportChannel(const std::string &name,
-                                         const std::string &content_type,
-                                         RawTransport* transport,
-                                         talk_base::Thread *worker_thread,
-                                         PortAllocator *allocator)
-  : TransportChannelImpl(name, content_type),
-    raw_transport_(transport),
-    allocator_(allocator),
-    allocator_session_(NULL),
-    stun_port_(NULL),
-    relay_port_(NULL),
-    port_(NULL),
-    use_relay_(false) {
-  if (worker_thread == NULL)
-    worker_thread_ = raw_transport_->worker_thread();
-  else
-    worker_thread_ = worker_thread;
-}
-
-RawTransportChannel::~RawTransportChannel() {
-  delete allocator_session_;
-}
-
-int RawTransportChannel::SendPacket(const char *data, size_t size) {
-  if (port_ == NULL)
-    return -1;
-  if (remote_address_.IsAny())
-    return -1;
-  return port_->SendTo(data, size, remote_address_, true);
-}
-
-int RawTransportChannel::SetOption(talk_base::Socket::Option opt, int value) {
-  // TODO: allow these to be set before we have a port
-  if (port_ == NULL)
-    return -1;
-  return port_->SetOption(opt, value);
-}
-
-int RawTransportChannel::GetError() {
-  return (port_ != NULL) ? port_->GetError() : 0;
-}
-
-void RawTransportChannel::Connect() {
-  // Create an allocator that only returns stun and relay ports.
-  allocator_session_ = allocator_->CreateSession(name(), content_type());
-
-  uint32 flags = PORTALLOCATOR_DISABLE_UDP | PORTALLOCATOR_DISABLE_TCP;
-
-#if !defined(FEATURE_ENABLE_STUN_CLASSIFICATION)
-  flags |= PORTALLOCATOR_DISABLE_RELAY;
-#endif
-  allocator_session_->set_flags(flags);
-  allocator_session_->SignalPortReady.connect(
-      this, &RawTransportChannel::OnPortReady);
-  allocator_session_->SignalCandidatesReady.connect(
-      this, &RawTransportChannel::OnCandidatesReady);
-
-  // The initial ports will include stun.
-  allocator_session_->GetInitialPorts();
-}
-
-void RawTransportChannel::Reset() {
-  set_readable(false);
-  set_writable(false);
-
-  delete allocator_session_;
-
-  allocator_session_ = NULL;
-  stun_port_ = NULL;
-  relay_port_ = NULL;
-  port_ = NULL;
-  remote_address_ = talk_base::SocketAddress();
-}
-
-void RawTransportChannel::OnCandidate(const Candidate& candidate) {
-  remote_address_ = candidate.address();
-  ASSERT(!remote_address_.IsAny());
-  set_readable(true);
-
-  // We can write once we have a port and a remote address.
-  if (port_ != NULL)
-    SetWritable();
-}
-
-void RawTransportChannel::OnRemoteAddress(
-    const talk_base::SocketAddress& remote_address) {
-  remote_address_ = remote_address;
-  set_readable(true);
-
-  if (port_ != NULL)
-    SetWritable();
-}
-
-// Note about stun classification
-// Code to classify our NAT type and use the relay port if we are behind an
-// asymmetric NAT is under a FEATURE_ENABLE_STUN_CLASSIFICATION #define.
-// To turn this one we will have to enable a second stun address and make sure
-// that the relay server works for raw UDP.
-//
-// Another option is to classify the NAT type early and not offer the raw
-// transport type at all if we can't support it.
-
-void RawTransportChannel::OnPortReady(
-    PortAllocatorSession* session, Port* port) {
-  ASSERT(session == allocator_session_);
-
-  if (port->type() == STUN_PORT_TYPE) {
-    stun_port_ = static_cast<StunPort*>(port);
-
-#if defined(FEATURE_ENABLE_STUN_CLASSIFICATION)
-    // We need a secondary address to determine the NAT type.
-    stun_port_->PrepareSecondaryAddress();
-#endif
-  } else if (port->type() == RELAY_PORT_TYPE) {
-    relay_port_ = static_cast<RelayPort*>(port);
-  } else {
-    ASSERT(false);
-  }
-}
-
-void RawTransportChannel::OnCandidatesReady(
-    PortAllocatorSession *session, const std::vector<Candidate>& candidates) {
-  ASSERT(session == allocator_session_);
-  ASSERT(candidates.size() >= 1);
-
-  // The most recent candidate is the one we haven't seen yet.
-  Candidate c = candidates[candidates.size() - 1];
-
-  if (c.type() == STUN_PORT_TYPE) {
-    ASSERT(stun_port_ != NULL);
-
-#if defined(FEATURE_ENABLE_STUN_CLASSIFICATION)
-    // We need to wait until we have two addresses.
-    if (stun_port_->candidates().size() < 2)
-      return;
-
-    // This is the second address.  If these addresses are the same, then we
-    // are not behind a symmetric NAT.  Hence, a stun port should be sufficient.
-    if (stun_port_->candidates()[0].address() ==
-        stun_port_->candidates()[1].address()) {
-      SetPort(stun_port_);
-      return;
-    }
-
-    // We will need to use relay.
-    use_relay_ = true;
-
-    // If we weren't given a relay port, we'll need to request it.
-    if (relay_port_ == NULL) {
-      allocator_session_->StartGetAllPorts();
-      return;
-    }
-
-    // If we already have a relay address, we're good.  Otherwise, we will need
-    // to wait until one arrives.
-    if (relay_port_->candidates().size() > 0)
-      SetPort(relay_port_);
-#else  // defined(FEATURE_ENABLE_STUN_CLASSIFICATION)
-    // Always use the stun port.  We don't classify right now so just assume it
-    // will work fine.
-    SetPort(stun_port_);
-#endif
-  } else if (c.type() == RELAY_PORT_TYPE) {
-    if (use_relay_)
-      SetPort(relay_port_);
-  } else {
-    ASSERT(false);
-  }
-}
-
-void RawTransportChannel::SetPort(Port* port) {
-  ASSERT(port_ == NULL);
-  port_ = port;
-
-  // We don't need any ports other than the one we picked.
-  allocator_session_->StopGetAllPorts();
-  worker_thread_->Post(
-      this, MSG_DESTROY_UNUSED_PORTS, NULL);
-
-  // Send a message to the other client containing our address.
-
-  ASSERT(port_->candidates().size() >= 1);
-  ASSERT(port_->candidates()[0].protocol() == "udp");
-  SignalCandidateReady(this, port_->candidates()[0]);
-
-  // Read all packets from this port.
-  port_->EnablePortPackets();
-  port_->SignalReadPacket.connect(this, &RawTransportChannel::OnReadPacket);
-
-  // We can write once we have a port and a remote address.
-  if (!remote_address_.IsAny())
-    SetWritable();
-}
-
-void RawTransportChannel::SetWritable() {
-  ASSERT(port_ != NULL);
-  ASSERT(!remote_address_.IsAny());
-
-  set_writable(true);
-
-  Candidate remote_candidate;
-  remote_candidate.set_address(remote_address_);
-  SignalRouteChange(this, remote_candidate);
-}
-
-void RawTransportChannel::OnReadPacket(
-    Port* port, const char* data, size_t size,
-    const talk_base::SocketAddress& addr) {
-  ASSERT(port_ == port);
-  SignalReadPacket(this, data, size);
-}
-
-void RawTransportChannel::OnMessage(talk_base::Message* msg) {
-  ASSERT(msg->message_id == MSG_DESTROY_UNUSED_PORTS);
-  ASSERT(port_ != NULL);
-  if (port_ != stun_port_) {
-    stun_port_->Destroy();
-    stun_port_ = NULL;
-  }
-  if (port_ != relay_port_ && relay_port_ != NULL) {
-    relay_port_->Destroy();
-    relay_port_ = NULL;
-  }
-}
-
-}  // namespace cricket
-#endif  // defined(FEATURE_ENABLE_PSTN)
diff --git a/third_party/libjingle/source/talk/p2p/base/rawtransportchannel.h b/third_party/libjingle/source/talk/p2p/base/rawtransportchannel.h
deleted file mode 100644
index f99c9c4..0000000
--- a/third_party/libjingle/source/talk/p2p/base/rawtransportchannel.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_P2P_BASE_RAWTRANSPORTCHANNEL_H_
-#define TALK_P2P_BASE_RAWTRANSPORTCHANNEL_H_
-
-#include <string>
-#include <vector>
-#include "talk/base/messagequeue.h"
-#include "talk/p2p/base/transportchannelimpl.h"
-#include "talk/p2p/base/rawtransport.h"
-#include "talk/p2p/base/candidate.h"
-
-#if defined(FEATURE_ENABLE_PSTN)
-
-namespace talk_base {
-class Thread;
-}
-
-namespace cricket {
-
-class Port;
-class Connection;
-class StunPort;
-class RelayPort;
-class PortAllocator;
-class PortAllocatorSession;
-
-// Implements a channel that just sends bare packets once we have received the
-// address of the other side.  We pick a single address to send them based on
-// a simple investigation of NAT type.
-class RawTransportChannel : public TransportChannelImpl,
-    public talk_base::MessageHandler {
- public:
-  RawTransportChannel(const std::string &name,
-                      const std::string &content_type,
-                      RawTransport* transport,
-                      talk_base::Thread *worker_thread,
-                      PortAllocator *allocator);
-  virtual ~RawTransportChannel();
-
-  // Implementation of normal channel packet sending.
-  virtual int SendPacket(const char *data, size_t len);
-  virtual int SetOption(talk_base::Socket::Option opt, int value);
-  virtual int GetError();
-
-  // Returns the raw transport that created this channel.
-  virtual Transport* GetTransport() { return raw_transport_; }
-
-  // Creates an allocator session to start figuring out which type of
-  // port we should send to the other client.  This will send
-  // SignalAvailableCandidate once we have decided.
-  virtual void Connect();
-
-  // Resets state back to unconnected.
-  virtual void Reset();
-
-  // We don't actually worry about signaling since we can't send new candidates.
-  virtual void OnSignalingReady() {}
-
-  // Handles a message setting the remote address.  We are writable once we
-  // have this since we now know where to send.
-  virtual void OnCandidate(const Candidate& candidate);
-
-  void OnRemoteAddress(const talk_base::SocketAddress& remote_address);
-
-
- private:
-  RawTransport* raw_transport_;
-  talk_base::Thread *worker_thread_;
-  PortAllocator* allocator_;
-  PortAllocatorSession* allocator_session_;
-  StunPort* stun_port_;
-  RelayPort* relay_port_;
-  Port* port_;
-  bool use_relay_;
-  talk_base::SocketAddress remote_address_;
-
-  // Called when the allocator creates another port.
-  void OnPortReady(PortAllocatorSession* session, Port* port);
-
-  // Called when one of the ports we are using has determined its address.
-  void OnCandidatesReady(PortAllocatorSession *session,
-                         const std::vector<Candidate>& candidates);
-
-  // Called once we have chosen the port to use for communication with the
-  // other client.  This will send its address and prepare the port for use.
-  void SetPort(Port* port);
-
-  // Called once we have a port and a remote address.  This will set mark the
-  // channel as writable and signal the route to the client.
-  void SetWritable();
-
-  // Called when we receive a packet from the other client.
-  void OnReadPacket(Port* port, const char* data, size_t size,
-                    const talk_base::SocketAddress& addr);
-
-  // Handles a message to destroy unused ports.
-  virtual void OnMessage(talk_base::Message *msg);
-
-  DISALLOW_EVIL_CONSTRUCTORS(RawTransportChannel);
-};
-
-}  // namespace cricket
-
-#endif  // defined(FEATURE_ENABLE_PSTN)
-#endif  // TALK_P2P_BASE_RAWTRANSPORTCHANNEL_H_
diff --git a/third_party/libjingle/source/talk/p2p/base/relayport.cc b/third_party/libjingle/source/talk/p2p/base/relayport.cc
deleted file mode 100644
index c6c066a..0000000
--- a/third_party/libjingle/source/talk/p2p/base/relayport.cc
+++ /dev/null
@@ -1,795 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/asyncpacketsocket.h"
-#include "talk/base/helpers.h"
-#include "talk/base/logging.h"
-#include "talk/p2p/base/relayport.h"
-
-namespace cricket {
-
-static const uint32 kMessageConnectTimeout = 1;
-static const int kKeepAliveDelay           = 10 * 60 * 1000;
-static const int kRetryTimeout             = 50 * 1000;  // ICE says 50 secs
-// How long to wait for a socket to connect to remote host in milliseconds
-// before trying another connection.
-static const int kSoftConnectTimeoutMs     = 3 * 1000;
-
-// Handles a connection to one address/port/protocol combination for a
-// particular RelayEntry.
-class RelayConnection : public sigslot::has_slots<> {
- public:
-  RelayConnection(const ProtocolAddress* protocol_address,
-                  talk_base::AsyncPacketSocket* socket,
-                  talk_base::Thread* thread);
-  ~RelayConnection();
-  talk_base::AsyncPacketSocket* socket() const { return socket_; }
-
-  const ProtocolAddress* protocol_address() {
-    return protocol_address_;
-  }
-
-  talk_base::SocketAddress GetAddress() const {
-    return protocol_address_->address;
-  }
-
-  ProtocolType GetProtocol() const {
-    return protocol_address_->proto;
-  }
-
-  int SetSocketOption(talk_base::Socket::Option opt, int value);
-
-  // Validates a response to a STUN allocate request.
-  bool CheckResponse(StunMessage* msg);
-
-  // Sends data to the relay server.
-  int Send(const void* pv, size_t cb);
-
-  // Sends a STUN allocate request message to the relay server.
-  void SendAllocateRequest(RelayEntry* entry, int delay);
-
-  // Return the latest error generated by the socket.
-  int GetError() { return socket_->GetError(); }
-
-  // Called on behalf of a StunRequest to write data to the socket.  This is
-  // already STUN intended for the server, so no wrapping is necessary.
-  void OnSendPacket(const void* data, size_t size, StunRequest* req);
-
- private:
-  talk_base::AsyncPacketSocket* socket_;
-  const ProtocolAddress* protocol_address_;
-  StunRequestManager *request_manager_;
-};
-
-// Manages a number of connections to the relayserver, one for each
-// available protocol. We aim to use each connection for only a
-// specific destination address so that we can avoid wrapping every
-// packet in a STUN send / data indication.
-class RelayEntry : public talk_base::MessageHandler,
-                   public sigslot::has_slots<> {
- public:
-  RelayEntry(RelayPort* port, const talk_base::SocketAddress& ext_addr);
-  ~RelayEntry();
-
-  RelayPort* port() { return port_; }
-
-  const talk_base::SocketAddress& address() const { return ext_addr_; }
-  void set_address(const talk_base::SocketAddress& addr) { ext_addr_ = addr; }
-
-  bool connected() const { return connected_; }
-  bool locked() const { return locked_; }
-
-  // Returns the last error on the socket of this entry.
-  int GetError();
-
-  // Returns the most preferred connection of the given
-  // ones. Connections are rated based on protocol in the order of:
-  // UDP, TCP and SSLTCP, where UDP is the most preferred protocol
-  static RelayConnection* GetBestConnection(RelayConnection* conn1,
-                                            RelayConnection* conn2);
-
-  // Sends the STUN requests to the server to initiate this connection.
-  void Connect();
-
-  // Called when this entry becomes connected.  The address given is the one
-  // exposed to the outside world on the relay server.
-  void OnConnect(const talk_base::SocketAddress& mapped_addr,
-                 RelayConnection* socket);
-
-  // Sends a packet to the given destination address using the socket of this
-  // entry.  This will wrap the packet in STUN if necessary.
-  int SendTo(const void* data, size_t size,
-    const talk_base::SocketAddress& addr);
-
-  // Schedules a keep-alive allocate request.
-  void ScheduleKeepAlive();
-
-  void SetServerIndex(size_t sindex) { server_index_ = sindex; }
-
-  // Sets this option on the socket of each connection.
-  int SetSocketOption(talk_base::Socket::Option opt, int value);
-
-  size_t ServerIndex() const { return server_index_; }
-
-  // Try a different server address
-  void HandleConnectFailure(talk_base::AsyncPacketSocket* socket);
-
-  // Implementation of the MessageHandler Interface.
-  virtual void OnMessage(talk_base::Message *pmsg);
-
- private:
-  RelayPort* port_;
-  talk_base::SocketAddress ext_addr_;
-  size_t server_index_;
-  bool connected_;
-  bool locked_;
-  RelayConnection* current_connection_;
-
-  // Called when a TCP connection is established or fails
-  void OnSocketConnect(talk_base::AsyncPacketSocket* socket);
-  void OnSocketClose(talk_base::AsyncPacketSocket* socket, int error);
-
-  // Called when a packet is received on this socket.
-  void OnReadPacket(talk_base::AsyncPacketSocket* socket,
-                    const char* data, size_t size,
-                    const talk_base::SocketAddress& remote_addr);
-
-  // Sends the given data on the socket to the server with no wrapping.  This
-  // returns the number of bytes written or -1 if an error occurred.
-  int SendPacket(const void* data, size_t size);
-};
-
-// Handles an allocate request for a particular RelayEntry.
-class AllocateRequest : public StunRequest {
- public:
-  AllocateRequest(RelayEntry* entry, RelayConnection* connection);
-  virtual ~AllocateRequest() {}
-
-  virtual void Prepare(StunMessage* request);
-
-  virtual int GetNextDelay();
-
-  virtual void OnResponse(StunMessage* response);
-  virtual void OnErrorResponse(StunMessage* response);
-  virtual void OnTimeout();
-
- private:
-  RelayEntry* entry_;
-  RelayConnection* connection_;
-  uint32 start_time_;
-};
-
-const char RELAY_PORT_TYPE[] = "relay";
-
-RelayPort::RelayPort(
-    talk_base::Thread* thread, talk_base::PacketSocketFactory* factory,
-    talk_base::Network* network, const talk_base::IPAddress& ip,
-    int min_port, int max_port, const std::string& username,
-    const std::string& password, const std::string& magic_cookie)
-    : Port(thread, RELAY_PORT_TYPE, factory, network, ip, min_port, max_port),
-      ready_(false),
-      magic_cookie_(magic_cookie),
-      error_(0) {
-  entries_.push_back(
-      new RelayEntry(this, talk_base::SocketAddress()));
-
-  set_username_fragment(username);
-  set_password(password);
-  if (magic_cookie_.size() == 0) {
-    magic_cookie_.append(TURN_MAGIC_COOKIE_VALUE,
-                         sizeof(TURN_MAGIC_COOKIE_VALUE));
-  }
-}
-
-RelayPort::~RelayPort() {
-  for (size_t i = 0; i < entries_.size(); ++i)
-    delete entries_[i];
-  thread_->Clear(this);
-}
-
-void RelayPort::AddServerAddress(const ProtocolAddress& addr) {
-  // Since HTTP proxies usually only allow 443,
-  // let's up the priority on PROTO_SSLTCP
-  if (addr.proto == PROTO_SSLTCP &&
-      (proxy().type == talk_base::PROXY_HTTPS ||
-       proxy().type == talk_base::PROXY_UNKNOWN)) {
-    server_addr_.push_front(addr);
-  } else {
-    server_addr_.push_back(addr);
-  }
-}
-
-void RelayPort::AddExternalAddress(const ProtocolAddress& addr) {
-  std::string proto_name = ProtoToString(addr.proto);
-  for (std::vector<Candidate>::const_iterator it = candidates().begin();
-       it != candidates().end(); ++it) {
-    if ((it->address() == addr.address) && (it->protocol() == proto_name)) {
-      LOG(INFO) << "Redundant relay address: " << proto_name
-                << " @ " << addr.address.ToString();
-      return;
-    }
-  }
-  AddAddress(addr.address, proto_name, false);
-}
-
-void RelayPort::SetReady() {
-  if (!ready_) {
-    ready_ = true;
-    SignalAddressReady(this);
-  }
-}
-
-const ProtocolAddress * RelayPort::ServerAddress(size_t index) const {
-  if (index < server_addr_.size())
-    return &server_addr_[index];
-  return NULL;
-}
-
-bool RelayPort::HasMagicCookie(const char* data, size_t size) {
-  if (size < 24 + magic_cookie_.size()) {
-    return false;
-  } else {
-    return 0 == std::memcmp(data + 24,
-                            magic_cookie_.c_str(),
-                            magic_cookie_.size());
-  }
-}
-
-void RelayPort::PrepareAddress() {
-  // We initiate a connect on the first entry.  If this completes, it will fill
-  // in the server address as the address of this port.
-  ASSERT(entries_.size() == 1);
-  entries_[0]->Connect();
-  ready_ = false;
-}
-
-Connection* RelayPort::CreateConnection(const Candidate& address,
-                                        CandidateOrigin origin) {
-  // We only create conns to non-udp sockets if they are incoming on this port
-  if ((address.protocol() != "udp") && (origin != ORIGIN_THIS_PORT)) {
-    return 0;
-  }
-
-  // We don't support loopback on relays
-  if (address.type() == type()) {
-    return 0;
-  }
-
-  size_t index = 0;
-  for (size_t i = 0; i < candidates().size(); ++i) {
-    const Candidate& local = candidates()[i];
-    if (local.protocol() == address.protocol()) {
-      index = i;
-      break;
-    }
-  }
-
-  Connection * conn = new ProxyConnection(this, index, address);
-  AddConnection(conn);
-  return conn;
-}
-
-int RelayPort::SendTo(const void* data, size_t size,
-                      const talk_base::SocketAddress& addr, bool payload) {
-  // Try to find an entry for this specific address.  Note that the first entry
-  // created was not given an address initially, so it can be set to the first
-  // address that comes along.
-  RelayEntry* entry = 0;
-
-  for (size_t i = 0; i < entries_.size(); ++i) {
-    if (entries_[i]->address().IsAny() && payload) {
-      entry = entries_[i];
-      entry->set_address(addr);
-      break;
-    } else if (entries_[i]->address() == addr) {
-      entry = entries_[i];
-      break;
-    }
-  }
-
-  // If we did not find one, then we make a new one.  This will not be useable
-  // until it becomes connected, however.
-  if (!entry && payload) {
-    entry = new RelayEntry(this, addr);
-    if (!entries_.empty()) {
-      entry->SetServerIndex(entries_[0]->ServerIndex());
-    }
-    entry->Connect();
-    entries_.push_back(entry);
-  }
-
-  // If the entry is connected, then we can send on it (though wrapping may
-  // still be necessary).  Otherwise, we can't yet use this connection, so we
-  // default to the first one.
-  if (!entry || !entry->connected()) {
-    ASSERT(!entries_.empty());
-    entry = entries_[0];
-    if (!entry->connected()) {
-      error_ = EWOULDBLOCK;
-      return SOCKET_ERROR;
-    }
-  }
-
-  // Send the actual contents to the server using the usual mechanism.
-  int sent = entry->SendTo(data, size, addr);
-  if (sent <= 0) {
-    ASSERT(sent < 0);
-    error_ = entry->GetError();
-    return SOCKET_ERROR;
-  }
-  // The caller of the function is expecting the number of user data bytes,
-  // rather than the size of the packet.
-  return size;
-}
-
-int RelayPort::SetOption(talk_base::Socket::Option opt, int value) {
-  int result = 0;
-  for (size_t i = 0; i < entries_.size(); ++i) {
-    if (entries_[i]->SetSocketOption(opt, value) < 0) {
-      result = -1;
-      error_ = entries_[i]->GetError();
-    }
-  }
-  options_.push_back(OptionValue(opt, value));
-  return result;
-}
-
-int RelayPort::GetError() {
-  return error_;
-}
-
-void RelayPort::OnReadPacket(
-    const char* data, size_t size,
-    const talk_base::SocketAddress& remote_addr) {
-  if (Connection* conn = GetConnection(remote_addr)) {
-    conn->OnReadPacket(data, size);
-  } else {
-    Port::OnReadPacket(data, size, remote_addr);
-  }
-}
-
-RelayConnection::RelayConnection(const ProtocolAddress* protocol_address,
-                                 talk_base::AsyncPacketSocket* socket,
-                                 talk_base::Thread* thread)
-    : socket_(socket),
-      protocol_address_(protocol_address) {
-  request_manager_ = new StunRequestManager(thread);
-  request_manager_->SignalSendPacket.connect(this,
-                                             &RelayConnection::OnSendPacket);
-}
-
-RelayConnection::~RelayConnection() {
-  delete request_manager_;
-  delete socket_;
-}
-
-int RelayConnection::SetSocketOption(talk_base::Socket::Option opt,
-                                     int value) {
-  if (socket_) {
-    return socket_->SetOption(opt, value);
-  }
-  return 0;
-}
-
-bool RelayConnection::CheckResponse(StunMessage* msg) {
-  return request_manager_->CheckResponse(msg);
-}
-
-void RelayConnection::OnSendPacket(const void* data, size_t size,
-                                   StunRequest* req) {
-  int sent = socket_->SendTo(data, size, GetAddress());
-  if (sent <= 0) {
-    LOG(LS_VERBOSE) << "OnSendPacket: failed sending to " << GetAddress() <<
-        std::strerror(socket_->GetError());
-    ASSERT(sent < 0);
-  }
-}
-
-int RelayConnection::Send(const void* pv, size_t cb) {
-  return socket_->SendTo(pv, cb, GetAddress());
-}
-
-void RelayConnection::SendAllocateRequest(RelayEntry* entry, int delay) {
-  request_manager_->SendDelayed(new AllocateRequest(entry, this), delay);
-}
-
-RelayEntry::RelayEntry(RelayPort* port,
-                       const talk_base::SocketAddress& ext_addr)
-    : port_(port), ext_addr_(ext_addr),
-      server_index_(0), connected_(false), locked_(false),
-      current_connection_(NULL) {
-}
-
-RelayEntry::~RelayEntry() {
-  // Remove all RelayConnections and dispose sockets.
-  delete current_connection_;
-  current_connection_ = NULL;
-}
-
-void RelayEntry::Connect() {
-  // If we're already connected, return.
-  if (connected_)
-    return;
-
-  // If we've exhausted all options, bail out.
-  const ProtocolAddress* ra = port()->ServerAddress(server_index_);
-  if (!ra) {
-    LOG(LS_WARNING) << "No more relay addresses left to try";
-    return;
-  }
-
-  // Remove any previous connection.
-  if (current_connection_) {
-    port()->thread()->Dispose(current_connection_);
-    current_connection_ = NULL;
-  }
-
-  // Try to set up our new socket.
-  LOG(LS_INFO) << "Connecting to relay via " << ProtoToString(ra->proto) <<
-      " @ " << ra->address.ToString();
-
-  talk_base::AsyncPacketSocket* socket = NULL;
-
-  if (ra->proto == PROTO_UDP) {
-    // UDP sockets are simple.
-    socket = port_->socket_factory()->CreateUdpSocket(
-        talk_base::SocketAddress(port_->ip_, 0),
-        port_->min_port_, port_->max_port_);
-  } else if (ra->proto == PROTO_TCP || ra->proto == PROTO_SSLTCP) {
-    socket = port_->socket_factory()->CreateClientTcpSocket(
-        talk_base::SocketAddress(port_->ip_, 0), ra->address,
-        port_->proxy(), port_->user_agent(), ra->proto == PROTO_SSLTCP);
-  } else {
-    LOG(LS_WARNING) << "Unknown protocol (" << ra->proto << ")";
-  }
-
-  if (!socket) {
-    LOG(LS_WARNING) << "Socket creation failed";
-  }
-
-  // If we failed to get a socket, move on to the next protocol.
-  if (!socket) {
-    port()->thread()->Post(this, kMessageConnectTimeout);
-    return;
-  }
-
-  // Otherwise, create the new connection and configure any socket options.
-  socket->SignalReadPacket.connect(this, &RelayEntry::OnReadPacket);
-  current_connection_ = new RelayConnection(ra, socket, port()->thread());
-  for (size_t i = 0; i < port_->options().size(); ++i) {
-    current_connection_->SetSocketOption(port_->options()[i].first,
-                                         port_->options()[i].second);
-  }
-
-  // If we're trying UDP, start binding requests.
-  // If we're trying TCP, wait for connection with a fixed timeout.
-  if ((ra->proto == PROTO_TCP) || (ra->proto == PROTO_SSLTCP)) {
-    socket->SignalClose.connect(this, &RelayEntry::OnSocketClose);
-    socket->SignalConnect.connect(this, &RelayEntry::OnSocketConnect);
-    port()->thread()->PostDelayed(kSoftConnectTimeoutMs, this,
-                                  kMessageConnectTimeout);
-  } else {
-    current_connection_->SendAllocateRequest(this, 0);
-  }
-}
-
-int RelayEntry::GetError() {
-  if (current_connection_ != NULL) {
-    return current_connection_->GetError();
-  }
-  return 0;
-}
-
-RelayConnection* RelayEntry::GetBestConnection(RelayConnection* conn1,
-                                               RelayConnection* conn2) {
-  return conn1->GetProtocol() <= conn2->GetProtocol() ? conn1 : conn2;
-}
-
-void RelayEntry::OnConnect(const talk_base::SocketAddress& mapped_addr,
-                           RelayConnection* connection) {
-  // We are connected, notify our parent.
-  ProtocolType proto = PROTO_UDP;
-  LOG(INFO) << "Relay allocate succeeded: " << ProtoToString(proto)
-            << " @ " << mapped_addr.ToString();
-  connected_ = true;
-
-  port_->AddExternalAddress(ProtocolAddress(mapped_addr, proto));
-  port_->SetReady();
-}
-
-int RelayEntry::SendTo(const void* data, size_t size,
-                       const talk_base::SocketAddress& addr) {
-  // If this connection is locked to the address given, then we can send the
-  // packet with no wrapper.
-  if (locked_ && (ext_addr_ == addr))
-    return SendPacket(data, size);
-
-  // Otherwise, we must wrap the given data in a STUN SEND request so that we
-  // can communicate the destination address to the server.
-  //
-  // Note that we do not use a StunRequest here.  This is because there is
-  // likely no reason to resend this packet. If it is late, we just drop it.
-  // The next send to this address will try again.
-
-  StunMessage request;
-  request.SetType(STUN_SEND_REQUEST);
-  request.SetTransactionID(
-      talk_base::CreateRandomString(kStunTransactionIdLength));
-
-  StunByteStringAttribute* magic_cookie_attr =
-      StunAttribute::CreateByteString(STUN_ATTR_MAGIC_COOKIE);
-  magic_cookie_attr->CopyBytes(port_->magic_cookie().c_str(),
-                               port_->magic_cookie().size());
-  request.AddAttribute(magic_cookie_attr);
-
-  StunByteStringAttribute* username_attr =
-      StunAttribute::CreateByteString(STUN_ATTR_USERNAME);
-  username_attr->CopyBytes(port_->username_fragment().c_str(),
-                           port_->username_fragment().size());
-  request.AddAttribute(username_attr);
-
-  StunAddressAttribute* addr_attr =
-      StunAttribute::CreateAddress(STUN_ATTR_DESTINATION_ADDRESS);
-  addr_attr->SetIP(addr.ipaddr());
-  addr_attr->SetPort(addr.port());
-  request.AddAttribute(addr_attr);
-
-  // Attempt to lock
-  if (ext_addr_ == addr) {
-    StunUInt32Attribute* options_attr =
-      StunAttribute::CreateUInt32(STUN_ATTR_OPTIONS);
-    options_attr->SetValue(0x1);
-    request.AddAttribute(options_attr);
-  }
-
-  StunByteStringAttribute* data_attr =
-      StunAttribute::CreateByteString(STUN_ATTR_DATA);
-  data_attr->CopyBytes(data, size);
-  request.AddAttribute(data_attr);
-
-  // TODO: compute the HMAC.
-
-  talk_base::ByteBuffer buf;
-  request.Write(&buf);
-
-  return SendPacket(buf.Data(), buf.Length());
-}
-
-void RelayEntry::ScheduleKeepAlive() {
-  if (current_connection_) {
-    current_connection_->SendAllocateRequest(this, kKeepAliveDelay);
-  }
-}
-
-int RelayEntry::SetSocketOption(talk_base::Socket::Option opt, int value) {
-  // Set the option on all available sockets.
-  int socket_error = 0;
-  if (current_connection_) {
-    socket_error = current_connection_->SetSocketOption(opt, value);
-  }
-  return socket_error;
-}
-
-void RelayEntry::HandleConnectFailure(
-    talk_base::AsyncPacketSocket* socket) {
-  // Make sure it's the current connection that has failed, it might
-  // be an old socked that has not yet been disposed.
-  if (!socket || socket == current_connection_->socket()) {
-    if (current_connection_)
-      port()->SignalConnectFailure(current_connection_->protocol_address());
-
-    // Try to connect to the next server address.
-    server_index_ += 1;
-    Connect();
-  }
-}
-
-void RelayEntry::OnMessage(talk_base::Message *pmsg) {
-  ASSERT(pmsg->message_id == kMessageConnectTimeout);
-  if (current_connection_) {
-    const ProtocolAddress* ra = current_connection_->protocol_address();
-    LOG(LS_WARNING) << "Relay " << ra->proto << " connection to " <<
-        ra->address << " timed out";
-
-    // Currently we connect to each server address in sequence. If we
-    // have more addresses to try, treat this is an error and move on to
-    // the next address, otherwise give this connection more time and
-    // await the real timeout.
-    //
-    // TODO: Connect to servers in parallel to speed up connect time
-    // and to avoid giving up too early.
-    port_->SignalSoftTimeout(ra);
-    HandleConnectFailure(current_connection_->socket());
-  } else {
-    HandleConnectFailure(NULL);
-  }
-}
-
-void RelayEntry::OnSocketConnect(talk_base::AsyncPacketSocket* socket) {
-  LOG(INFO) << "relay tcp connected to " <<
-      socket->GetRemoteAddress().ToString();
-  if (current_connection_ != NULL) {
-    current_connection_->SendAllocateRequest(this, 0);
-  }
-}
-
-void RelayEntry::OnSocketClose(talk_base::AsyncPacketSocket* socket,
-                               int error) {
-  PLOG(LERROR, error) << "Relay connection failed: socket closed";
-  HandleConnectFailure(socket);
-}
-
-void RelayEntry::OnReadPacket(talk_base::AsyncPacketSocket* socket,
-                              const char* data, size_t size,
-                              const talk_base::SocketAddress& remote_addr) {
-  // ASSERT(remote_addr == port_->server_addr());
-  // TODO: are we worried about this?
-
-  if (current_connection_ == NULL || socket != current_connection_->socket()) {
-    // This packet comes from an unknown address.
-    LOG(WARNING) << "Dropping packet: unknown address";
-    return;
-  }
-
-  // If the magic cookie is not present, then this is an unwrapped packet sent
-  // by the server,  The actual remote address is the one we recorded.
-  if (!port_->HasMagicCookie(data, size)) {
-    if (locked_) {
-      port_->OnReadPacket(data, size, ext_addr_);
-    } else {
-      LOG(WARNING) << "Dropping packet: entry not locked";
-    }
-    return;
-  }
-
-  talk_base::ByteBuffer buf(data, size);
-  StunMessage msg;
-  if (!msg.Read(&buf)) {
-    LOG(INFO) << "Incoming packet was not STUN";
-    return;
-  }
-
-  // The incoming packet should be a STUN ALLOCATE response, SEND response, or
-  // DATA indication.
-  if (current_connection_->CheckResponse(&msg)) {
-    return;
-  } else if (msg.type() == STUN_SEND_RESPONSE) {
-    if (const StunUInt32Attribute* options_attr =
-        msg.GetUInt32(STUN_ATTR_OPTIONS)) {
-      if (options_attr->value() & 0x1) {
-        locked_ = true;
-      }
-    }
-    return;
-  } else if (msg.type() != STUN_DATA_INDICATION) {
-    LOG(INFO) << "Received BAD stun type from server: " << msg.type();
-    return;
-  }
-
-  // This must be a data indication.
-
-  const StunAddressAttribute* addr_attr =
-      msg.GetAddress(STUN_ATTR_SOURCE_ADDRESS2);
-  if (!addr_attr) {
-    LOG(INFO) << "Data indication has no source address";
-    return;
-  } else if (addr_attr->family() != 1) {
-    LOG(INFO) << "Source address has bad family";
-    return;
-  }
-
-  talk_base::SocketAddress remote_addr2(addr_attr->ipaddr(), addr_attr->port());
-
-  const StunByteStringAttribute* data_attr = msg.GetByteString(STUN_ATTR_DATA);
-  if (!data_attr) {
-    LOG(INFO) << "Data indication has no data";
-    return;
-  }
-
-  // Process the actual data and remote address in the normal manner.
-  port_->OnReadPacket(data_attr->bytes(), data_attr->length(), remote_addr2);
-}
-
-int RelayEntry::SendPacket(const void* data, size_t size) {
-  int sent = 0;
-  if (current_connection_) {
-    // We are connected, no need to send packets anywere else than to
-    // the current connection.
-    sent = current_connection_->Send(data, size);
-  }
-  return sent;
-}
-
-AllocateRequest::AllocateRequest(RelayEntry* entry,
-                                 RelayConnection* connection) :
-    entry_(entry), connection_(connection) {
-  start_time_ = talk_base::Time();
-}
-
-void AllocateRequest::Prepare(StunMessage* request) {
-  request->SetType(STUN_ALLOCATE_REQUEST);
-
-  StunByteStringAttribute* magic_cookie_attr =
-      StunAttribute::CreateByteString(STUN_ATTR_MAGIC_COOKIE);
-  magic_cookie_attr->CopyBytes(
-      entry_->port()->magic_cookie().c_str(),
-      entry_->port()->magic_cookie().size());
-  request->AddAttribute(magic_cookie_attr);
-
-  StunByteStringAttribute* username_attr =
-      StunAttribute::CreateByteString(STUN_ATTR_USERNAME);
-  username_attr->CopyBytes(
-      entry_->port()->username_fragment().c_str(),
-      entry_->port()->username_fragment().size());
-  request->AddAttribute(username_attr);
-}
-
-int AllocateRequest::GetNextDelay() {
-  int delay = 100 * talk_base::_max(1 << count_, 2);
-  count_ += 1;
-  if (count_ == 5)
-    timeout_ = true;
-  return delay;
-}
-
-void AllocateRequest::OnResponse(StunMessage* response) {
-  const StunAddressAttribute* addr_attr =
-      response->GetAddress(STUN_ATTR_MAPPED_ADDRESS);
-  if (!addr_attr) {
-    LOG(INFO) << "Allocate response missing mapped address.";
-  } else if (addr_attr->family() != 1) {
-    LOG(INFO) << "Mapped address has bad family";
-  } else {
-    talk_base::SocketAddress addr(addr_attr->ipaddr(), addr_attr->port());
-    entry_->OnConnect(addr, connection_);
-  }
-
-  // We will do a keep-alive regardless of whether this request suceeds.
-  // This should have almost no impact on network usage.
-  entry_->ScheduleKeepAlive();
-}
-
-void AllocateRequest::OnErrorResponse(StunMessage* response) {
-  const StunErrorCodeAttribute* attr = response->GetErrorCode();
-  if (!attr) {
-    LOG(INFO) << "Bad allocate response error code";
-  } else {
-    LOG(INFO) << "Allocate error response:"
-              << " code=" << static_cast<int>(attr->error_code())
-              << " reason='" << attr->reason() << "'";
-  }
-
-  if (talk_base::TimeSince(start_time_) <= kRetryTimeout)
-    entry_->ScheduleKeepAlive();
-}
-
-void AllocateRequest::OnTimeout() {
-  LOG(INFO) << "Allocate request timed out";
-  entry_->HandleConnectFailure(connection_->socket());
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/p2p/base/relayport.h b/third_party/libjingle/source/talk/p2p/base/relayport.h
deleted file mode 100644
index 2137606..0000000
--- a/third_party/libjingle/source/talk/p2p/base/relayport.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_P2P_BASE_RELAYPORT_H_
-#define TALK_P2P_BASE_RELAYPORT_H_
-
-#include <deque>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "talk/p2p/base/port.h"
-#include "talk/p2p/base/stunrequest.h"
-
-namespace cricket {
-
-extern const char RELAY_PORT_TYPE[];
-class RelayEntry;
-class RelayConnection;
-
-// Communicates using an allocated port on the relay server. For each
-// remote candidate that we try to send data to a RelayEntry instance
-// is created. The RelayEntry will try to reach the remote destination
-// by connecting to all available server addresses in a pre defined
-// order with a small delay in between. When a connection is
-// successful all other connection attemts are aborted.
-class RelayPort : public Port {
- public:
-  typedef std::pair<talk_base::Socket::Option, int> OptionValue;
-
-  // RelayPort doesn't yet do anything fancy in the ctor.
-  static RelayPort* Create(
-      talk_base::Thread* thread, talk_base::PacketSocketFactory* factory,
-      talk_base::Network* network, const talk_base::IPAddress& ip,
-      int min_port, int max_port, const std::string& username,
-      const std::string& password, const std::string& magic_cookie) {
-    return new RelayPort(thread, factory, network, ip, min_port, max_port,
-                         username, password, magic_cookie);
-  }
-  virtual ~RelayPort();
-
-  void AddServerAddress(const ProtocolAddress& addr);
-  void AddExternalAddress(const ProtocolAddress& addr);
-
-  const std::vector<OptionValue>& options() const { return options_; }
-  const std::string& magic_cookie() const { return magic_cookie_; }
-  bool HasMagicCookie(const char* data, size_t size);
-
-  virtual void PrepareAddress();
-  virtual Connection* CreateConnection(const Candidate& address,
-                                       CandidateOrigin origin);
-  virtual int SetOption(talk_base::Socket::Option opt, int value);
-  virtual int GetError();
-
-  const ProtocolAddress * ServerAddress(size_t index) const;
-  bool IsReady() { return ready_; }
-
-  // Used for testing.
-  sigslot::signal1<const ProtocolAddress*> SignalConnectFailure;
-  sigslot::signal1<const ProtocolAddress*> SignalSoftTimeout;
-
- protected:
-  RelayPort(talk_base::Thread* thread, talk_base::PacketSocketFactory* factory,
-            talk_base::Network*, const talk_base::IPAddress& ip,
-            int min_port, int max_port, const std::string& username,
-            const std::string& password, const std::string& magic_cookie);
-  bool Init();
-
-  void SetReady();
-
-  virtual int SendTo(const void* data, size_t size,
-                     const talk_base::SocketAddress& addr, bool payload);
-
-  // Dispatches the given packet to the port or connection as appropriate.
-  void OnReadPacket(const char* data, size_t size,
-                    const talk_base::SocketAddress& remote_addr);
-
- private:
-  friend class RelayEntry;
-
-  std::deque<ProtocolAddress> server_addr_;
-  bool ready_;
-  std::vector<RelayEntry*> entries_;
-  std::vector<OptionValue> options_;
-  std::string magic_cookie_;
-  int error_;
-};
-
-}  // namespace cricket
-
-#endif  // TALK_P2P_BASE_RELAYPORT_H_
diff --git a/third_party/libjingle/source/talk/p2p/base/relayport_unittest.cc b/third_party/libjingle/source/talk/p2p/base/relayport_unittest.cc
deleted file mode 100644
index 688e635..0000000
--- a/third_party/libjingle/source/talk/p2p/base/relayport_unittest.cc
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
- * libjingle
- * Copyright 2009 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/basicpacketsocketfactory.h"
-#include "talk/base/logging.h"
-#include "talk/base/gunit.h"
-#include "talk/base/helpers.h"
-#include "talk/base/physicalsocketserver.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/base/socketadapters.h"
-#include "talk/base/socketaddress.h"
-#include "talk/base/thread.h"
-#include "talk/base/virtualsocketserver.h"
-#include "talk/p2p/base/relayport.h"
-#include "talk/p2p/base/relayserver.h"
-
-using talk_base::SocketAddress;
-
-static const SocketAddress kLocalAddress = SocketAddress("192.168.1.2", 0);
-static const SocketAddress kRelayUdpAddr = SocketAddress("99.99.99.1", 5000);
-static const SocketAddress kRelayTcpAddr = SocketAddress("99.99.99.2", 5001);
-static const SocketAddress kRelaySslAddr = SocketAddress("99.99.99.3", 443);
-static const SocketAddress kRelayExtAddr = SocketAddress("99.99.99.3", 5002);
-
-static const int kTimeoutMs = 1000;
-static const int kMaxTimeoutMs = 5000;
-
-// Tests connecting a RelayPort to a fake relay server
-// (cricket::RelayServer) using all currently available protocols. The
-// network layer is faked out by using a VirtualSocketServer for
-// creating sockets. The test will monitor the current state of the
-// RelayPort and created sockets by listening for signals such as,
-// SignalConnectFailure, SignalConnectTimeout, SignalSocketClosed and
-// SignalReadPacket.
-class RelayPortTest : public testing::Test,
-                      public sigslot::has_slots<> {
- public:
-  RelayPortTest()
-      : main_(talk_base::Thread::Current()),
-        physical_socket_server_(new talk_base::PhysicalSocketServer),
-        virtual_socket_server_(new talk_base::VirtualSocketServer(
-            physical_socket_server_.get())),
-        ss_scope_(virtual_socket_server_.get()),
-        network_("unittest", "unittest", talk_base::IPAddress(INADDR_ANY)),
-        socket_factory_(talk_base::Thread::Current()),
-        username_(talk_base::CreateRandomString(16)),
-        password_(talk_base::CreateRandomString(16)),
-        relay_port_(cricket::RelayPort::Create(main_, &socket_factory_,
-                                               &network_,
-                                               kLocalAddress.ipaddr(),
-                                               0, 0, username_, password_, "")),
-        relay_server_(new cricket::RelayServer(main_)) {
-  }
-
-  void OnReadPacket(talk_base::AsyncPacketSocket* socket,
-                    const char* data, size_t size,
-                    const talk_base::SocketAddress& remote_addr) {
-    received_packet_count_[socket]++;
-  }
-
-  void OnConnectFailure(const cricket::ProtocolAddress* addr) {
-    failed_connections_.push_back(*addr);
-  }
-
-  void OnSoftTimeout(const cricket::ProtocolAddress* addr) {
-    soft_timedout_connections_.push_back(*addr);
-  }
-
- protected:
-  static void SetUpTestCase() {
-    // Ensure the RNG is inited.
-    talk_base::InitRandom(NULL, 0);
-  }
-
-  virtual void SetUp() {
-    // The relay server needs an external socket to work properly.
-    talk_base::AsyncUDPSocket* ext_socket =
-        CreateAsyncUdpSocket(kRelayExtAddr);
-    relay_server_->AddExternalSocket(ext_socket);
-
-    // Listen for failures.
-    relay_port_->SignalConnectFailure.
-        connect(this, &RelayPortTest::OnConnectFailure);
-
-    // Listen for soft timeouts.
-    relay_port_->SignalSoftTimeout.
-        connect(this, &RelayPortTest::OnSoftTimeout);
-  }
-
-  // Udp has the highest 'goodness' value of the three different
-  // protocols used for connecting to the relay server. As soon as
-  // PrepareAddress is called, the RelayPort will start trying to
-  // connect to the given UDP address. As soon as a response to the
-  // sent STUN allocate request message has been received, the
-  // RelayPort will consider the connection to be complete and will
-  // abort any other connection attempts.
-  void TestConnectUdp() {
-    // Add a UDP socket to the relay server.
-    talk_base::AsyncUDPSocket* internal_udp_socket =
-        CreateAsyncUdpSocket(kRelayUdpAddr);
-    talk_base::AsyncSocket* server_socket = CreateServerSocket(kRelayTcpAddr);
-
-    relay_server_->AddInternalSocket(internal_udp_socket);
-    relay_server_->AddInternalServerSocket(server_socket, cricket::PROTO_TCP);
-
-    // Now add our relay addresses to the relay port and let it start.
-    relay_port_->AddServerAddress(
-        cricket::ProtocolAddress(kRelayUdpAddr, cricket::PROTO_UDP));
-    relay_port_->AddServerAddress(
-        cricket::ProtocolAddress(kRelayTcpAddr, cricket::PROTO_TCP));
-    relay_port_->PrepareAddress();
-
-    // Should be connected.
-    EXPECT_TRUE_WAIT(relay_port_->IsReady(), kTimeoutMs);
-
-    // Make sure that we are happy with UDP, ie. not continuing with
-    // TCP, SSLTCP, etc.
-    WAIT(relay_server_->HasConnection(kRelayTcpAddr), kTimeoutMs);
-
-    // Should have only one connection.
-    EXPECT_EQ(1, relay_server_->GetConnectionCount());
-
-    // Should be the UDP address.
-    EXPECT_TRUE(relay_server_->HasConnection(kRelayUdpAddr));
-  }
-
-  // TCP has the second best 'goodness' value, and as soon as UDP
-  // connection has failed, the RelayPort will attempt to connect via
-  // TCP. Here we add a fake UDP address together with a real TCP
-  // address to simulate an UDP failure. As soon as UDP has failed the
-  // RelayPort will try the TCP adress and succed.
-  void TestConnectTcp() {
-    // Create a fake UDP address for relay port to simulate a failure.
-    cricket::ProtocolAddress fake_protocol_address =
-        cricket::ProtocolAddress(kRelayUdpAddr, cricket::PROTO_UDP);
-
-    // Create a server socket for the RelayServer.
-    talk_base::AsyncSocket* server_socket = CreateServerSocket(kRelayTcpAddr);
-    relay_server_->AddInternalServerSocket(server_socket, cricket::PROTO_TCP);
-
-    // Add server addresses to the relay port and let it start.
-    relay_port_->AddServerAddress(
-        cricket::ProtocolAddress(fake_protocol_address));
-    relay_port_->AddServerAddress(
-        cricket::ProtocolAddress(kRelayTcpAddr, cricket::PROTO_TCP));
-    relay_port_->PrepareAddress();
-
-    EXPECT_FALSE(relay_port_->IsReady());
-
-    // Should have timed out in 200 + 200 + 400 + 800 + 1600 ms.
-    EXPECT_TRUE_WAIT(HasFailed(&fake_protocol_address), 3600);
-
-    // Wait until relayport is ready.
-    EXPECT_TRUE_WAIT(relay_port_->IsReady(), kMaxTimeoutMs);
-
-    // Should have only one connection.
-    EXPECT_EQ(1, relay_server_->GetConnectionCount());
-
-    // Should be the TCP address.
-    EXPECT_TRUE(relay_server_->HasConnection(kRelayTcpAddr));
-  }
-
-  void TestConnectSslTcp() {
-    // Create a fake TCP address for relay port to simulate a failure.
-    // We skip UDP here since transition from UDP to TCP has been
-    // tested above.
-    cricket::ProtocolAddress fake_protocol_address =
-        cricket::ProtocolAddress(kRelayTcpAddr, cricket::PROTO_TCP);
-
-    // Create a ssl server socket for the RelayServer.
-    talk_base::AsyncSocket* ssl_server_socket =
-        CreateServerSocket(kRelaySslAddr);
-    relay_server_->AddInternalServerSocket(ssl_server_socket,
-                                           cricket::PROTO_SSLTCP);
-
-    // Create a tcp server socket that listens on the fake address so
-    // the relay port can attempt to connect to it.
-    talk_base::scoped_ptr<talk_base::AsyncSocket> tcp_server_socket(
-        CreateServerSocket(kRelayTcpAddr));
-
-    // Add server addresses to the relay port and let it start.
-    relay_port_->AddServerAddress(fake_protocol_address);
-    relay_port_->AddServerAddress(
-        cricket::ProtocolAddress(kRelaySslAddr, cricket::PROTO_SSLTCP));
-    relay_port_->PrepareAddress();
-    EXPECT_FALSE(relay_port_->IsReady());
-
-    // Should have timed out in 3000 ms(relayport.cc, kSoftConnectTimeoutMs).
-    EXPECT_TRUE_WAIT_MARGIN(HasTimedOut(&fake_protocol_address), 3000, 100);
-
-    // Wait until relayport is ready.
-    EXPECT_TRUE_WAIT(relay_port_->IsReady(), kMaxTimeoutMs);
-
-    // Should have only one connection.
-    EXPECT_EQ(1, relay_server_->GetConnectionCount());
-
-    // Should be the SSLTCP address.
-    EXPECT_TRUE(relay_server_->HasConnection(kRelaySslAddr));
-  }
-
- private:
-  talk_base::AsyncUDPSocket* CreateAsyncUdpSocket(const SocketAddress addr) {
-    talk_base::AsyncSocket* socket =
-        virtual_socket_server_->CreateAsyncSocket(SOCK_DGRAM);
-    talk_base::AsyncUDPSocket* packet_socket =
-        talk_base::AsyncUDPSocket::Create(socket, addr);
-    EXPECT_TRUE(packet_socket != NULL);
-    packet_socket->SignalReadPacket.connect(this, &RelayPortTest::OnReadPacket);
-    return packet_socket;
-  }
-
-  talk_base::AsyncSocket* CreateServerSocket(const SocketAddress addr) {
-    talk_base::AsyncSocket* socket =
-        virtual_socket_server_->CreateAsyncSocket(SOCK_STREAM);
-    EXPECT_GE(socket->Bind(addr), 0);
-    EXPECT_GE(socket->Listen(5), 0);
-    return socket;
-  }
-
-  bool HasFailed(cricket::ProtocolAddress* addr) {
-    for (size_t i = 0; i < failed_connections_.size(); i++) {
-      if (failed_connections_[i].address == addr->address &&
-          failed_connections_[i].proto == addr->proto) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  bool HasTimedOut(cricket::ProtocolAddress* addr) {
-    for (size_t i = 0; i < soft_timedout_connections_.size(); i++) {
-      if (soft_timedout_connections_[i].address == addr->address &&
-          soft_timedout_connections_[i].proto == addr->proto) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  typedef std::map<talk_base::AsyncPacketSocket*, int> PacketMap;
-
-  talk_base::Thread* main_;
-  talk_base::scoped_ptr<talk_base::PhysicalSocketServer>
-      physical_socket_server_;
-  talk_base::scoped_ptr<talk_base::VirtualSocketServer> virtual_socket_server_;
-  talk_base::SocketServerScope ss_scope_;
-  talk_base::Network network_;
-  talk_base::BasicPacketSocketFactory socket_factory_;
-  std::string username_;
-  std::string password_;
-  talk_base::scoped_ptr<cricket::RelayPort> relay_port_;
-  talk_base::scoped_ptr<cricket::RelayServer> relay_server_;
-  std::vector<cricket::ProtocolAddress> failed_connections_;
-  std::vector<cricket::ProtocolAddress> soft_timedout_connections_;
-  PacketMap received_packet_count_;
-};
-
-TEST_F(RelayPortTest, ConnectUdp) {
-  TestConnectUdp();
-}
-
-TEST_F(RelayPortTest, ConnectTcp) {
-  TestConnectTcp();
-}
-
-TEST_F(RelayPortTest, ConnectSslTcp) {
-  TestConnectSslTcp();
-}
diff --git a/third_party/libjingle/source/talk/p2p/base/relayserver.cc b/third_party/libjingle/source/talk/p2p/base/relayserver.cc
deleted file mode 100644
index b17da5b..0000000
--- a/third_party/libjingle/source/talk/p2p/base/relayserver.cc
+++ /dev/null
@@ -1,758 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/p2p/base/relayserver.h"
-
-#ifdef POSIX
-#include <errno.h>
-#endif  // POSIX
-
-#include <algorithm>
-
-#include "talk/base/asynctcpsocket.h"
-#include "talk/base/helpers.h"
-#include "talk/base/logging.h"
-#include "talk/base/socketadapters.h"
-
-namespace cricket {
-
-// By default, we require a ping every 90 seconds.
-const int MAX_LIFETIME = 15 * 60 * 1000;
-
-// The number of bytes in each of the usernames we use.
-const uint32 USERNAME_LENGTH = 16;
-
-static const uint32 kMessageAcceptConnection = 1;
-
-// Calls SendTo on the given socket and logs any bad results.
-void Send(talk_base::AsyncPacketSocket* socket, const char* bytes, size_t size,
-          const talk_base::SocketAddress& addr) {
-  int result = socket->SendTo(bytes, size, addr);
-  if (result < static_cast<int>(size)) {
-    LOG(LS_ERROR) << "SendTo wrote only " << result << " of " << size
-                  << " bytes";
-  } else if (result < 0) {
-    LOG_ERR(LS_ERROR) << "SendTo";
-  }
-}
-
-// Sends the given STUN message on the given socket.
-void SendStun(const StunMessage& msg,
-              talk_base::AsyncPacketSocket* socket,
-              const talk_base::SocketAddress& addr) {
-  talk_base::ByteBuffer buf;
-  msg.Write(&buf);
-  Send(socket, buf.Data(), buf.Length(), addr);
-}
-
-// Constructs a STUN error response and sends it on the given socket.
-void SendStunError(const StunMessage& msg, talk_base::AsyncPacketSocket* socket,
-                   const talk_base::SocketAddress& remote_addr, int error_code,
-                   const char* error_desc, const std::string& magic_cookie) {
-  StunMessage err_msg;
-  err_msg.SetType(GetStunErrorResponseType(msg.type()));
-  err_msg.SetTransactionID(msg.transaction_id());
-
-  StunByteStringAttribute* magic_cookie_attr =
-      StunAttribute::CreateByteString(cricket::STUN_ATTR_MAGIC_COOKIE);
-  if (magic_cookie.size() == 0) {
-    magic_cookie_attr->CopyBytes(cricket::TURN_MAGIC_COOKIE_VALUE,
-                                 sizeof(cricket::TURN_MAGIC_COOKIE_VALUE));
-  } else {
-    magic_cookie_attr->CopyBytes(magic_cookie.c_str(), magic_cookie.size());
-  }
-  err_msg.AddAttribute(magic_cookie_attr);
-
-  StunErrorCodeAttribute* err_code = StunAttribute::CreateErrorCode();
-  err_code->SetErrorClass(error_code / 100);
-  err_code->SetNumber(error_code % 100);
-  err_code->SetReason(error_desc);
-  err_msg.AddAttribute(err_code);
-
-  SendStun(err_msg, socket, remote_addr);
-}
-
-RelayServer::RelayServer(talk_base::Thread* thread)
-  : thread_(thread), log_bindings_(true) {
-}
-
-RelayServer::~RelayServer() {
-  // Deleting the binding will cause it to be removed from the map.
-  while (!bindings_.empty())
-    delete bindings_.begin()->second;
-  for (size_t i = 0; i < internal_sockets_.size(); ++i)
-    delete internal_sockets_[i];
-  for (size_t i = 0; i < external_sockets_.size(); ++i)
-    delete external_sockets_[i];
-  while (!server_sockets_.empty()) {
-    talk_base::AsyncSocket* socket = server_sockets_.begin()->first;
-    server_sockets_.erase(server_sockets_.begin()->first);
-    delete socket;
-  }
-}
-
-void RelayServer::AddInternalSocket(talk_base::AsyncPacketSocket* socket) {
-  ASSERT(internal_sockets_.end() ==
-      std::find(internal_sockets_.begin(), internal_sockets_.end(), socket));
-  internal_sockets_.push_back(socket);
-  socket->SignalReadPacket.connect(this, &RelayServer::OnInternalPacket);
-}
-
-void RelayServer::RemoveInternalSocket(talk_base::AsyncPacketSocket* socket) {
-  SocketList::iterator iter =
-      std::find(internal_sockets_.begin(), internal_sockets_.end(), socket);
-  ASSERT(iter != internal_sockets_.end());
-  internal_sockets_.erase(iter);
-  socket->SignalReadPacket.disconnect(this);
-}
-
-void RelayServer::AddExternalSocket(talk_base::AsyncPacketSocket* socket) {
-  ASSERT(external_sockets_.end() ==
-      std::find(external_sockets_.begin(), external_sockets_.end(), socket));
-  external_sockets_.push_back(socket);
-  socket->SignalReadPacket.connect(this, &RelayServer::OnExternalPacket);
-}
-
-void RelayServer::RemoveExternalSocket(talk_base::AsyncPacketSocket* socket) {
-  SocketList::iterator iter =
-      std::find(external_sockets_.begin(), external_sockets_.end(), socket);
-  ASSERT(iter != external_sockets_.end());
-  external_sockets_.erase(iter);
-  socket->SignalReadPacket.disconnect(this);
-}
-
-void RelayServer::AddInternalServerSocket(talk_base::AsyncSocket* socket,
-                                          cricket::ProtocolType proto) {
-  ASSERT(server_sockets_.end() ==
-         server_sockets_.find(socket));
-  server_sockets_[socket] = proto;
-  socket->SignalReadEvent.connect(this, &RelayServer::OnReadEvent);
-}
-
-void RelayServer::RemoveInternalServerSocket(
-    talk_base::AsyncSocket* socket) {
-  ServerSocketMap::iterator iter = server_sockets_.find(socket);
-  ASSERT(iter != server_sockets_.end());
-  server_sockets_.erase(iter);
-  socket->SignalReadEvent.disconnect(this);
-}
-
-int RelayServer::GetConnectionCount() const {
-  return connections_.size();
-}
-
-talk_base::SocketAddressPair RelayServer::GetConnection(int connection) const {
-  int i = 0;
-  for (ConnectionMap::const_iterator it = connections_.begin();
-       it != connections_.end(); ++it) {
-    if (i == connection) {
-      return it->second->addr_pair();
-    }
-    ++i;
-  }
-  return talk_base::SocketAddressPair();
-}
-
-bool RelayServer::HasConnection(const talk_base::SocketAddress& address) const {
-  for (ConnectionMap::const_iterator it = connections_.begin();
-       it != connections_.end(); ++it) {
-    if (it->second->addr_pair().destination() == address) {
-      return true;
-    }
-  }
-  return false;
-}
-
-void RelayServer::OnReadEvent(talk_base::AsyncSocket* socket) {
-  ServerSocketMap::iterator iter = server_sockets_.find(socket);
-  ASSERT(iter != server_sockets_.end());
-  AcceptConnection(socket);
-}
-
-void RelayServer::OnInternalPacket(
-    talk_base::AsyncPacketSocket* socket, const char* bytes, size_t size,
-    const talk_base::SocketAddress& remote_addr) {
-
-  // Get the address of the connection we just received on.
-  talk_base::SocketAddressPair ap(remote_addr, socket->GetLocalAddress());
-  ASSERT(!ap.destination().IsAny());
-
-  // If this did not come from an existing connection, it should be a STUN
-  // allocate request.
-  ConnectionMap::iterator piter = connections_.find(ap);
-  if (piter == connections_.end()) {
-    HandleStunAllocate(bytes, size, ap, socket);
-    return;
-  }
-
-  RelayServerConnection* int_conn = piter->second;
-
-  // Handle STUN requests to the server itself.
-  if (int_conn->binding()->HasMagicCookie(bytes, size)) {
-    HandleStun(int_conn, bytes, size);
-    return;
-  }
-
-  // Otherwise, this is a non-wrapped packet that we are to forward.  Make sure
-  // that this connection has been locked.  (Otherwise, we would not know what
-  // address to forward to.)
-  if (!int_conn->locked()) {
-    LOG(LS_WARNING) << "Dropping packet: connection not locked";
-    return;
-  }
-
-  // Forward this to the destination address into the connection.
-  RelayServerConnection* ext_conn = int_conn->binding()->GetExternalConnection(
-      int_conn->default_destination());
-  if (ext_conn && ext_conn->locked()) {
-    // TODO: Check the HMAC.
-    ext_conn->Send(bytes, size);
-  } else {
-    // This happens very often and is not an error.
-    LOG(LS_INFO) << "Dropping packet: no external connection";
-  }
-}
-
-void RelayServer::OnExternalPacket(
-    talk_base::AsyncPacketSocket* socket, const char* bytes, size_t size,
-    const talk_base::SocketAddress& remote_addr) {
-
-  // Get the address of the connection we just received on.
-  talk_base::SocketAddressPair ap(remote_addr, socket->GetLocalAddress());
-  ASSERT(!ap.destination().IsAny());
-
-  // If this connection already exists, then forward the traffic.
-  ConnectionMap::iterator piter = connections_.find(ap);
-  if (piter != connections_.end()) {
-    // TODO: Check the HMAC.
-    RelayServerConnection* ext_conn = piter->second;
-    RelayServerConnection* int_conn =
-        ext_conn->binding()->GetInternalConnection(
-            ext_conn->addr_pair().source());
-    ASSERT(int_conn != NULL);
-    int_conn->Send(bytes, size, ext_conn->addr_pair().source());
-    ext_conn->Lock();  // allow outgoing packets
-    return;
-  }
-
-  // The first packet should always be a STUN / TURN packet.  If it isn't, then
-  // we should just ignore this packet.
-  StunMessage msg;
-  talk_base::ByteBuffer buf(bytes, size);
-  if (!msg.Read(&buf)) {
-    LOG(LS_WARNING) << "Dropping packet: first packet not STUN";
-    return;
-  }
-
-  // The initial packet should have a username (which identifies the binding).
-  const StunByteStringAttribute* username_attr =
-      msg.GetByteString(STUN_ATTR_USERNAME);
-  if (!username_attr) {
-    LOG(LS_WARNING) << "Dropping packet: no username";
-    return;
-  }
-
-  uint32 length = talk_base::_min(static_cast<uint32>(username_attr->length()),
-                                  USERNAME_LENGTH);
-  std::string username(username_attr->bytes(), length);
-  // TODO: Check the HMAC.
-
-  // The binding should already be present.
-  BindingMap::iterator biter = bindings_.find(username);
-  if (biter == bindings_.end()) {
-    LOG(LS_WARNING) << "Dropping packet: no binding with username";
-    return;
-  }
-
-  // Add this authenticted connection to the binding.
-  RelayServerConnection* ext_conn =
-      new RelayServerConnection(biter->second, ap, socket);
-  ext_conn->binding()->AddExternalConnection(ext_conn);
-  AddConnection(ext_conn);
-
-  // We always know where external packets should be forwarded, so we can lock
-  // them from the beginning.
-  ext_conn->Lock();
-
-  // Send this message on the appropriate internal connection.
-  RelayServerConnection* int_conn = ext_conn->binding()->GetInternalConnection(
-      ext_conn->addr_pair().source());
-  ASSERT(int_conn != NULL);
-  int_conn->Send(bytes, size, ext_conn->addr_pair().source());
-}
-
-bool RelayServer::HandleStun(
-    const char* bytes, size_t size, const talk_base::SocketAddress& remote_addr,
-    talk_base::AsyncPacketSocket* socket, std::string* username,
-    StunMessage* msg) {
-
-  // Parse this into a stun message.
-  talk_base::ByteBuffer buf(bytes, size);
-  if (!msg->Read(&buf)) {
-    SendStunError(*msg, socket, remote_addr, 400, "Bad Request", "");
-    return false;
-  }
-
-  // The initial packet should have a username (which identifies the binding).
-  const StunByteStringAttribute* username_attr =
-      msg->GetByteString(STUN_ATTR_USERNAME);
-  if (!username_attr) {
-    SendStunError(*msg, socket, remote_addr, 432, "Missing Username", "");
-    return false;
-  }
-
-  // Record the username if requested.
-  if (username)
-    username->append(username_attr->bytes(), username_attr->length());
-
-  // TODO: Check for unknown attributes (<= 0x7fff)
-
-  return true;
-}
-
-void RelayServer::HandleStunAllocate(
-    const char* bytes, size_t size, const talk_base::SocketAddressPair& ap,
-    talk_base::AsyncPacketSocket* socket) {
-
-  // Make sure this is a valid STUN request.
-  StunMessage request;
-  std::string username;
-  if (!HandleStun(bytes, size, ap.source(), socket, &username, &request))
-    return;
-
-  // Make sure this is a an allocate request.
-  if (request.type() != STUN_ALLOCATE_REQUEST) {
-    SendStunError(request,
-                  socket,
-                  ap.source(),
-                  600,
-                  "Operation Not Supported",
-                  "");
-    return;
-  }
-
-  // TODO: Check the HMAC.
-
-  // Find or create the binding for this username.
-
-  RelayServerBinding* binding;
-
-  BindingMap::iterator biter = bindings_.find(username);
-  if (biter != bindings_.end()) {
-    binding = biter->second;
-  } else {
-    // NOTE: In the future, bindings will be created by the bot only.  This
-    //       else-branch will then disappear.
-
-    // Compute the appropriate lifetime for this binding.
-    uint32 lifetime = MAX_LIFETIME;
-    const StunUInt32Attribute* lifetime_attr =
-        request.GetUInt32(STUN_ATTR_LIFETIME);
-    if (lifetime_attr)
-      lifetime = talk_base::_min(lifetime, lifetime_attr->value() * 1000);
-
-    binding = new RelayServerBinding(this, username, "0", lifetime);
-    binding->SignalTimeout.connect(this, &RelayServer::OnTimeout);
-    bindings_[username] = binding;
-
-    if (log_bindings_) {
-      LOG(LS_INFO) << "Added new binding " << username << ", "
-                   << bindings_.size() << " total";
-    }
-  }
-
-  // Add this connection to the binding.  It starts out unlocked.
-  RelayServerConnection* int_conn =
-      new RelayServerConnection(binding, ap, socket);
-  binding->AddInternalConnection(int_conn);
-  AddConnection(int_conn);
-
-  // Now that we have a connection, this other method takes over.
-  HandleStunAllocate(int_conn, request);
-}
-
-void RelayServer::HandleStun(
-    RelayServerConnection* int_conn, const char* bytes, size_t size) {
-
-  // Make sure this is a valid STUN request.
-  StunMessage request;
-  std::string username;
-  if (!HandleStun(bytes, size, int_conn->addr_pair().source(),
-                  int_conn->socket(), &username, &request))
-    return;
-
-  // Make sure the username is the one were were expecting.
-  if (username != int_conn->binding()->username()) {
-    int_conn->SendStunError(request, 430, "Stale Credentials");
-    return;
-  }
-
-  // TODO: Check the HMAC.
-
-  // Send this request to the appropriate handler.
-  if (request.type() == STUN_SEND_REQUEST)
-    HandleStunSend(int_conn, request);
-  else if (request.type() == STUN_ALLOCATE_REQUEST)
-    HandleStunAllocate(int_conn, request);
-  else
-    int_conn->SendStunError(request, 600, "Operation Not Supported");
-}
-
-void RelayServer::HandleStunAllocate(
-    RelayServerConnection* int_conn, const StunMessage& request) {
-
-  // Create a response message that includes an address with which external
-  // clients can communicate.
-
-  StunMessage response;
-  response.SetType(STUN_ALLOCATE_RESPONSE);
-  response.SetTransactionID(request.transaction_id());
-
-  StunByteStringAttribute* magic_cookie_attr =
-      StunAttribute::CreateByteString(cricket::STUN_ATTR_MAGIC_COOKIE);
-  magic_cookie_attr->CopyBytes(int_conn->binding()->magic_cookie().c_str(),
-                               int_conn->binding()->magic_cookie().size());
-  response.AddAttribute(magic_cookie_attr);
-
-  size_t index = rand() % external_sockets_.size();
-  talk_base::SocketAddress ext_addr =
-      external_sockets_[index]->GetLocalAddress();
-
-  StunAddressAttribute* addr_attr =
-      StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
-  addr_attr->SetIP(ext_addr.ipaddr());
-  addr_attr->SetPort(ext_addr.port());
-  response.AddAttribute(addr_attr);
-
-  StunUInt32Attribute* res_lifetime_attr =
-      StunAttribute::CreateUInt32(STUN_ATTR_LIFETIME);
-  res_lifetime_attr->SetValue(int_conn->binding()->lifetime() / 1000);
-  response.AddAttribute(res_lifetime_attr);
-
-  // TODO: Support transport-prefs (preallocate RTCP port).
-  // TODO: Support bandwidth restrictions.
-  // TODO: Add message integrity check.
-
-  // Send a response to the caller.
-  int_conn->SendStun(response);
-}
-
-void RelayServer::HandleStunSend(
-    RelayServerConnection* int_conn, const StunMessage& request) {
-
-  const StunAddressAttribute* addr_attr =
-      request.GetAddress(STUN_ATTR_DESTINATION_ADDRESS);
-  if (!addr_attr) {
-    int_conn->SendStunError(request, 400, "Bad Request");
-    return;
-  }
-
-  const StunByteStringAttribute* data_attr =
-      request.GetByteString(STUN_ATTR_DATA);
-  if (!data_attr) {
-    int_conn->SendStunError(request, 400, "Bad Request");
-    return;
-  }
-
-  talk_base::SocketAddress ext_addr(addr_attr->ipaddr(), addr_attr->port());
-  RelayServerConnection* ext_conn =
-      int_conn->binding()->GetExternalConnection(ext_addr);
-  if (!ext_conn) {
-    // Create a new connection to establish the relationship with this binding.
-    ASSERT(external_sockets_.size() == 1);
-    talk_base::AsyncPacketSocket* socket = external_sockets_[0];
-    talk_base::SocketAddressPair ap(ext_addr, socket->GetLocalAddress());
-    ext_conn = new RelayServerConnection(int_conn->binding(), ap, socket);
-    ext_conn->binding()->AddExternalConnection(ext_conn);
-    AddConnection(ext_conn);
-  }
-
-  // If this connection has pinged us, then allow outgoing traffic.
-  if (ext_conn->locked())
-    ext_conn->Send(data_attr->bytes(), data_attr->length());
-
-  const StunUInt32Attribute* options_attr =
-      request.GetUInt32(STUN_ATTR_OPTIONS);
-  if (options_attr && (options_attr->value() & 0x01)) {
-    int_conn->set_default_destination(ext_addr);
-    int_conn->Lock();
-
-    StunMessage response;
-    response.SetType(STUN_SEND_RESPONSE);
-    response.SetTransactionID(request.transaction_id());
-
-    StunByteStringAttribute* magic_cookie_attr =
-        StunAttribute::CreateByteString(cricket::STUN_ATTR_MAGIC_COOKIE);
-    magic_cookie_attr->CopyBytes(int_conn->binding()->magic_cookie().c_str(),
-                                 int_conn->binding()->magic_cookie().size());
-    response.AddAttribute(magic_cookie_attr);
-
-    StunUInt32Attribute* options2_attr =
-      StunAttribute::CreateUInt32(cricket::STUN_ATTR_OPTIONS);
-    options2_attr->SetValue(0x01);
-    response.AddAttribute(options2_attr);
-
-    int_conn->SendStun(response);
-  }
-}
-
-void RelayServer::AddConnection(RelayServerConnection* conn) {
-  ASSERT(connections_.find(conn->addr_pair()) == connections_.end());
-  connections_[conn->addr_pair()] = conn;
-}
-
-void RelayServer::RemoveConnection(RelayServerConnection* conn) {
-  ConnectionMap::iterator iter = connections_.find(conn->addr_pair());
-  ASSERT(iter != connections_.end());
-  connections_.erase(iter);
-}
-
-void RelayServer::RemoveBinding(RelayServerBinding* binding) {
-  BindingMap::iterator iter = bindings_.find(binding->username());
-  ASSERT(iter != bindings_.end());
-  bindings_.erase(iter);
-
-  if (log_bindings_) {
-    LOG(LS_INFO) << "Removed binding " << binding->username() << ", "
-                 << bindings_.size() << " remaining";
-  }
-}
-
-void RelayServer::OnMessage(talk_base::Message *pmsg) {
-  ASSERT(pmsg->message_id == kMessageAcceptConnection);
-  talk_base::MessageData* data = pmsg->pdata;
-  talk_base::AsyncSocket* socket =
-      static_cast <talk_base::TypedMessageData<talk_base::AsyncSocket*>*>
-      (data)->data();
-  AcceptConnection(socket);
-  delete data;
-}
-
-void RelayServer::OnTimeout(RelayServerBinding* binding) {
-  // This call will result in all of the necessary clean-up. We can't call
-  // delete here, because you can't delete an object that is signaling you.
-  thread_->Dispose(binding);
-}
-
-void RelayServer::AcceptConnection(talk_base::AsyncSocket* server_socket) {
-  // Check if someone is trying to connect to us.
-  talk_base::SocketAddress accept_addr;
-  talk_base::AsyncSocket* accepted_socket =
-      server_socket->Accept(&accept_addr);
-  if (accepted_socket != NULL) {
-    // We had someone trying to connect, now check which protocol to
-    // use and create a packet socket.
-    ASSERT(server_sockets_[server_socket] == cricket::PROTO_TCP ||
-           server_sockets_[server_socket] == cricket::PROTO_SSLTCP);
-    if (server_sockets_[server_socket] == cricket::PROTO_SSLTCP) {
-      accepted_socket = new talk_base::AsyncSSLServerSocket(accepted_socket);
-    }
-    talk_base::AsyncTCPSocket* tcp_socket =
-        new talk_base::AsyncTCPSocket(accepted_socket, false);
-
-    // Finally add the socket so it can start communicating with the client.
-    AddInternalSocket(tcp_socket);
-  }
-}
-
-RelayServerConnection::RelayServerConnection(
-    RelayServerBinding* binding, const talk_base::SocketAddressPair& addrs,
-    talk_base::AsyncPacketSocket* socket)
-  : binding_(binding), addr_pair_(addrs), socket_(socket), locked_(false) {
-  // The creation of a new connection constitutes a use of the binding.
-  binding_->NoteUsed();
-}
-
-RelayServerConnection::~RelayServerConnection() {
-  // Remove this connection from the server's map (if it exists there).
-  binding_->server()->RemoveConnection(this);
-}
-
-void RelayServerConnection::Send(const char* data, size_t size) {
-  // Note that the binding has been used again.
-  binding_->NoteUsed();
-
-  cricket::Send(socket_, data, size, addr_pair_.source());
-}
-
-void RelayServerConnection::Send(
-    const char* data, size_t size, const talk_base::SocketAddress& from_addr) {
-  // If the from address is known to the client, we don't need to send it.
-  if (locked() && (from_addr == default_dest_)) {
-    Send(data, size);
-    return;
-  }
-
-  // Wrap the given data in a data-indication packet.
-
-  StunMessage msg;
-  msg.SetType(STUN_DATA_INDICATION);
-
-  StunByteStringAttribute* magic_cookie_attr =
-      StunAttribute::CreateByteString(cricket::STUN_ATTR_MAGIC_COOKIE);
-  magic_cookie_attr->CopyBytes(binding_->magic_cookie().c_str(),
-                               binding_->magic_cookie().size());
-  msg.AddAttribute(magic_cookie_attr);
-
-  StunAddressAttribute* addr_attr =
-      StunAttribute::CreateAddress(STUN_ATTR_SOURCE_ADDRESS2);
-  addr_attr->SetIP(from_addr.ipaddr());
-  addr_attr->SetPort(from_addr.port());
-  msg.AddAttribute(addr_attr);
-
-  StunByteStringAttribute* data_attr =
-      StunAttribute::CreateByteString(STUN_ATTR_DATA);
-  ASSERT(size <= 65536);
-  data_attr->CopyBytes(data, uint16(size));
-  msg.AddAttribute(data_attr);
-
-  SendStun(msg);
-}
-
-void RelayServerConnection::SendStun(const StunMessage& msg) {
-  // Note that the binding has been used again.
-  binding_->NoteUsed();
-
-  cricket::SendStun(msg, socket_, addr_pair_.source());
-}
-
-void RelayServerConnection::SendStunError(
-      const StunMessage& request, int error_code, const char* error_desc) {
-  // An error does not indicate use.  If no legitimate use off the binding
-  // occurs, we want it to be cleaned up even if errors are still occuring.
-
-  cricket::SendStunError(
-      request, socket_, addr_pair_.source(), error_code, error_desc,
-      binding_->magic_cookie());
-}
-
-void RelayServerConnection::Lock() {
-  locked_ = true;
-}
-
-void RelayServerConnection::Unlock() {
-  locked_ = false;
-}
-
-// IDs used for posted messages:
-const uint32 MSG_LIFETIME_TIMER = 1;
-
-RelayServerBinding::RelayServerBinding(
-    RelayServer* server, const std::string& username,
-    const std::string& password, uint32 lifetime)
-  : server_(server), username_(username), password_(password),
-    lifetime_(lifetime) {
-  // For now, every connection uses the standard magic cookie value.
-  magic_cookie_.append(
-      reinterpret_cast<const char*>(TURN_MAGIC_COOKIE_VALUE),
-      sizeof(TURN_MAGIC_COOKIE_VALUE));
-
-  // Initialize the last-used time to now.
-  NoteUsed();
-
-  // Set the first timeout check.
-  server_->thread()->PostDelayed(lifetime_, this, MSG_LIFETIME_TIMER);
-}
-
-RelayServerBinding::~RelayServerBinding() {
-  // Clear the outstanding timeout check.
-  server_->thread()->Clear(this);
-
-  // Clean up all of the connections.
-  for (size_t i = 0; i < internal_connections_.size(); ++i)
-    delete internal_connections_[i];
-  for (size_t i = 0; i < external_connections_.size(); ++i)
-    delete external_connections_[i];
-
-  // Remove this binding from the server's map.
-  server_->RemoveBinding(this);
-}
-
-void RelayServerBinding::AddInternalConnection(RelayServerConnection* conn) {
-  internal_connections_.push_back(conn);
-}
-
-void RelayServerBinding::AddExternalConnection(RelayServerConnection* conn) {
-  external_connections_.push_back(conn);
-}
-
-void RelayServerBinding::NoteUsed() {
-  last_used_ = talk_base::Time();
-}
-
-bool RelayServerBinding::HasMagicCookie(const char* bytes, size_t size) const {
-  if (size < 24 + magic_cookie_.size()) {
-    return false;
-  } else {
-    return 0 == std::memcmp(
-        bytes + 24, magic_cookie_.c_str(), magic_cookie_.size());
-  }
-}
-
-RelayServerConnection* RelayServerBinding::GetInternalConnection(
-    const talk_base::SocketAddress& ext_addr) {
-
-  // Look for an internal connection that is locked to this address.
-  for (size_t i = 0; i < internal_connections_.size(); ++i) {
-    if (internal_connections_[i]->locked() &&
-        (ext_addr == internal_connections_[i]->default_destination()))
-      return internal_connections_[i];
-  }
-
-  // If one was not found, we send to the first connection.
-  ASSERT(internal_connections_.size() > 0);
-  return internal_connections_[0];
-}
-
-RelayServerConnection* RelayServerBinding::GetExternalConnection(
-    const talk_base::SocketAddress& ext_addr) {
-  for (size_t i = 0; i < external_connections_.size(); ++i) {
-    if (ext_addr == external_connections_[i]->addr_pair().source())
-      return external_connections_[i];
-  }
-  return 0;
-}
-
-void RelayServerBinding::OnMessage(talk_base::Message *pmsg) {
-  if (pmsg->message_id == MSG_LIFETIME_TIMER) {
-    ASSERT(!pmsg->pdata);
-
-    // If the lifetime timeout has been exceeded, then send a signal.
-    // Otherwise, just keep waiting.
-    if (talk_base::Time() >= last_used_ + lifetime_) {
-      LOG(LS_INFO) << "Expiring binding " << username_;
-      SignalTimeout(this);
-    } else {
-      server_->thread()->PostDelayed(lifetime_, this, MSG_LIFETIME_TIMER);
-    }
-
-  } else {
-    ASSERT(false);
-  }
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/p2p/base/relayserver.h b/third_party/libjingle/source/talk/p2p/base/relayserver.h
deleted file mode 100644
index a5fcc24..0000000
--- a/third_party/libjingle/source/talk/p2p/base/relayserver.h
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_P2P_BASE_RELAYSERVER_H_
-#define TALK_P2P_BASE_RELAYSERVER_H_
-
-#include <string>
-#include <vector>
-#include <map>
-
-#include "talk/base/asyncudpsocket.h"
-#include "talk/base/socketaddresspair.h"
-#include "talk/base/thread.h"
-#include "talk/base/timeutils.h"
-#include "talk/p2p/base/port.h"
-#include "talk/p2p/base/stun.h"
-
-namespace cricket {
-
-class RelayServerBinding;
-class RelayServerConnection;
-
-// Relays traffic between connections to the server that are "bound" together.
-// All connections created with the same username/password are bound together.
-class RelayServer : public talk_base::MessageHandler,
-                    public sigslot::has_slots<> {
- public:
-  // Creates a server, which will use this thread to post messages to itself.
-  explicit RelayServer(talk_base::Thread* thread);
-  ~RelayServer();
-
-  talk_base::Thread* thread() { return thread_; }
-
-  // Indicates whether we will print updates of the number of bindings.
-  bool log_bindings() const { return log_bindings_; }
-  void set_log_bindings(bool log_bindings) { log_bindings_ = log_bindings; }
-
-  // Updates the set of sockets that the server uses to talk to "internal"
-  // clients.  These are clients that do the "port allocations".
-  void AddInternalSocket(talk_base::AsyncPacketSocket* socket);
-  void RemoveInternalSocket(talk_base::AsyncPacketSocket* socket);
-
-  // Updates the set of sockets that the server uses to talk to "external"
-  // clients.  These are the clients that do not do allocations.  They do not
-  // know that these addresses represent a relay server.
-  void AddExternalSocket(talk_base::AsyncPacketSocket* socket);
-  void RemoveExternalSocket(talk_base::AsyncPacketSocket* socket);
-
-  // Starts listening for connections on this sockets. When someone
-  // tries to connect, the connection will be accepted and a new
-  // internal socket will be added.
-  void AddInternalServerSocket(talk_base::AsyncSocket* socket,
-                               cricket::ProtocolType proto);
-
-  // Removes this server socket from the list.
-  void RemoveInternalServerSocket(talk_base::AsyncSocket* socket);
-
-  // Methods for testing and debuging.
-  int GetConnectionCount() const;
-  talk_base::SocketAddressPair GetConnection(int connection) const;
-  bool HasConnection(const talk_base::SocketAddress& address) const;
-
- private:
-  typedef std::vector<talk_base::AsyncPacketSocket*> SocketList;
-  typedef std::map<talk_base::AsyncSocket*,
-                   cricket::ProtocolType> ServerSocketMap;
-  typedef std::map<std::string, RelayServerBinding*> BindingMap;
-  typedef std::map<talk_base::SocketAddressPair,
-                   RelayServerConnection*> ConnectionMap;
-
-  talk_base::Thread* thread_;
-  bool log_bindings_;
-  SocketList internal_sockets_;
-  SocketList external_sockets_;
-  ServerSocketMap server_sockets_;
-  BindingMap bindings_;
-  ConnectionMap connections_;
-
-  // Called when a packet is received by the server on one of its sockets.
-  void OnInternalPacket(talk_base::AsyncPacketSocket* socket,
-                        const char* bytes, size_t size,
-                        const talk_base::SocketAddress& remote_addr);
-  void OnExternalPacket(talk_base::AsyncPacketSocket* socket,
-                        const char* bytes, size_t size,
-                        const talk_base::SocketAddress& remote_addr);
-
-  void OnReadEvent(talk_base::AsyncSocket* socket);
-
-  // Processes the relevant STUN request types from the client.
-  bool HandleStun(const char* bytes, size_t size,
-                  const talk_base::SocketAddress& remote_addr,
-                  talk_base::AsyncPacketSocket* socket,
-                  std::string* username, StunMessage* msg);
-  void HandleStunAllocate(const char* bytes, size_t size,
-                          const talk_base::SocketAddressPair& ap,
-                          talk_base::AsyncPacketSocket* socket);
-  void HandleStun(RelayServerConnection* int_conn, const char* bytes,
-                  size_t size);
-  void HandleStunAllocate(RelayServerConnection* int_conn,
-                          const StunMessage& msg);
-  void HandleStunSend(RelayServerConnection* int_conn, const StunMessage& msg);
-
-  // Adds/Removes the a connection or binding.
-  void AddConnection(RelayServerConnection* conn);
-  void RemoveConnection(RelayServerConnection* conn);
-  void RemoveBinding(RelayServerBinding* binding);
-
-  // Handle messages in our worker thread.
-  void OnMessage(talk_base::Message *pmsg);
-
-  // Called when the timer for checking lifetime times out.
-  void OnTimeout(RelayServerBinding* binding);
-
-  // Accept connections on this server socket.
-  void AcceptConnection(talk_base::AsyncSocket* server_socket);
-
-  friend class RelayServerConnection;
-  friend class RelayServerBinding;
-};
-
-// Maintains information about a connection to the server.  Each connection is
-// part of one and only one binding.
-class RelayServerConnection {
- public:
-  RelayServerConnection(RelayServerBinding* binding,
-                        const talk_base::SocketAddressPair& addrs,
-                        talk_base::AsyncPacketSocket* socket);
-  ~RelayServerConnection();
-
-  RelayServerBinding* binding() { return binding_; }
-  talk_base::AsyncPacketSocket* socket() { return socket_; }
-
-  // Returns a pair where the source is the remote address and the destination
-  // is the local address.
-  const talk_base::SocketAddressPair& addr_pair() { return addr_pair_; }
-
-  // Sends a packet to the connected client.  If an address is provided, then
-  // we make sure the internal client receives it, wrapping if necessary.
-  void Send(const char* data, size_t size);
-  void Send(const char* data, size_t size,
-            const talk_base::SocketAddress& ext_addr);
-
-  // Sends a STUN message to the connected client with no wrapping.
-  void SendStun(const StunMessage& msg);
-  void SendStunError(const StunMessage& request, int code, const char* desc);
-
-  // A locked connection is one for which we know the intended destination of
-  // any raw packet received.
-  bool locked() const { return locked_; }
-  void Lock();
-  void Unlock();
-
-  // Records the address that raw packets should be forwarded to (for internal
-  // packets only; for external, we already know where they go).
-  const talk_base::SocketAddress& default_destination() const {
-    return default_dest_;
-  }
-  void set_default_destination(const talk_base::SocketAddress& addr) {
-    default_dest_ = addr;
-  }
-
- private:
-  RelayServerBinding* binding_;
-  talk_base::SocketAddressPair addr_pair_;
-  talk_base::AsyncPacketSocket* socket_;
-  bool locked_;
-  talk_base::SocketAddress default_dest_;
-};
-
-// Records a set of internal and external connections that we relay between,
-// or in other words, that are "bound" together.
-class RelayServerBinding : public talk_base::MessageHandler {
- public:
-  RelayServerBinding(
-      RelayServer* server, const std::string& username,
-      const std::string& password, uint32 lifetime);
-  virtual ~RelayServerBinding();
-
-  RelayServer* server() { return server_; }
-  uint32 lifetime() { return lifetime_; }
-  const std::string& username() { return username_; }
-  const std::string& password() { return password_; }
-  const std::string& magic_cookie() { return magic_cookie_; }
-
-  // Adds/Removes a connection into the binding.
-  void AddInternalConnection(RelayServerConnection* conn);
-  void AddExternalConnection(RelayServerConnection* conn);
-
-  // We keep track of the use of each binding.  If we detect that it was not
-  // used for longer than the lifetime, then we send a signal.
-  void NoteUsed();
-  sigslot::signal1<RelayServerBinding*> SignalTimeout;
-
-  // Determines whether the given packet has the magic cookie present (in the
-  // right place).
-  bool HasMagicCookie(const char* bytes, size_t size) const;
-
-  // Determines the connection to use to send packets to or from the given
-  // external address.
-  RelayServerConnection* GetInternalConnection(
-      const talk_base::SocketAddress& ext_addr);
-  RelayServerConnection* GetExternalConnection(
-      const talk_base::SocketAddress& ext_addr);
-
-  // MessageHandler:
-  void OnMessage(talk_base::Message *pmsg);
-
- private:
-  RelayServer* server_;
-
-  std::string username_;
-  std::string password_;
-  std::string magic_cookie_;
-
-  std::vector<RelayServerConnection*> internal_connections_;
-  std::vector<RelayServerConnection*> external_connections_;
-
-  uint32 lifetime_;
-  uint32 last_used_;
-  // TODO: bandwidth
-};
-
-}  // namespace cricket
-
-#endif  // TALK_P2P_BASE_RELAYSERVER_H_
diff --git a/third_party/libjingle/source/talk/p2p/base/relayserver_main.cc b/third_party/libjingle/source/talk/p2p/base/relayserver_main.cc
deleted file mode 100644
index 6cc6415..0000000
--- a/third_party/libjingle/source/talk/p2p/base/relayserver_main.cc
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <iostream>  // NOLINT
-
-#include "talk/base/thread.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/p2p/base/relayserver.h"
-
-int main(int argc, char **argv) {
-  if (argc != 3) {
-    std::cerr << "usage: relayserver internal-address external-address"
-              << std::endl;
-    return 1;
-  }
-
-  talk_base::SocketAddress int_addr;
-  if (!int_addr.FromString(argv[1])) {
-    std::cerr << "Unable to parse IP address: " << argv[1];
-    return 1;
-  }
-
-  talk_base::SocketAddress ext_addr;
-  if (!ext_addr.FromString(argv[2])) {
-    std::cerr << "Unable to parse IP address: " << argv[2];
-    return 1;
-  }
-
-  talk_base::Thread *pthMain = talk_base::Thread::Current();
-
-  talk_base::scoped_ptr<talk_base::AsyncUDPSocket> int_socket(
-      talk_base::AsyncUDPSocket::Create(pthMain->socketserver(), int_addr));
-  if (!int_socket.get()) {
-    std::cerr << "Failed to create a UDP socket bound at"
-              << int_addr.ToString() << std::endl;
-    return 1;
-  }
-
-  talk_base::scoped_ptr<talk_base::AsyncUDPSocket> ext_socket(
-      talk_base::AsyncUDPSocket::Create(pthMain->socketserver(), ext_addr));
-  if (!ext_socket.get()) {
-    std::cerr << "Failed to create a UDP socket bound at"
-              << ext_addr.ToString() << std::endl;
-    return 1;
-  }
-
-  cricket::RelayServer server(pthMain);
-  server.AddInternalSocket(int_socket.get());
-  server.AddExternalSocket(ext_socket.get());
-
-  std::cout << "Listening internally at " << int_addr.ToString() << std::endl;
-  std::cout << "Listening externally at " << ext_addr.ToString() << std::endl;
-
-  pthMain->Run();
-  return 0;
-}
diff --git a/third_party/libjingle/source/talk/p2p/base/relayserver_unittest.cc b/third_party/libjingle/source/talk/p2p/base/relayserver_unittest.cc
deleted file mode 100644
index 0f96e27..0000000
--- a/third_party/libjingle/source/talk/p2p/base/relayserver_unittest.cc
+++ /dev/null
@@ -1,546 +0,0 @@
-/*
- * libjingle
- * Copyright 2004 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string>
-
-#include "talk/base/gunit.h"
-#include "talk/base/helpers.h"
-#include "talk/base/host.h"
-#include "talk/base/logging.h"
-#include "talk/base/physicalsocketserver.h"
-#include "talk/base/socketaddress.h"
-#include "talk/base/testclient.h"
-#include "talk/base/thread.h"
-#include "talk/p2p/base/relayserver.h"
-
-using talk_base::SocketAddress;
-using namespace cricket;
-
-static const uint32 LIFETIME = 4;  // seconds
-static const SocketAddress server_int_addr("127.0.0.1", 5000);
-static const SocketAddress server_ext_addr("127.0.0.1", 5001);
-static const SocketAddress client1_addr("127.0.0.1", 6000 + (rand() % 1000));
-static const SocketAddress client2_addr("127.0.0.1", 7000 + (rand() % 1000));
-static const char* bad = "this is a completely nonsensical message whose only "
-                         "purpose is to make the parser go 'ack'.  it doesn't "
-                         "look anything like a normal stun message";
-static const char* msg1 = "spamspamspamspamspamspamspambakedbeansspam";
-static const char* msg2 = "Lobster Thermidor a Crevette with a mornay sauce...";
-
-class RelayServerTest : public testing::Test {
- public:
-  static void SetUpTestCase() {
-    talk_base::InitRandom(NULL, 0);
-  }
-  RelayServerTest()
-      : main_(talk_base::Thread::Current()), ss_(main_->socketserver()),
-        username_(talk_base::CreateRandomString(12)),
-        password_(talk_base::CreateRandomString(12)) {
-  }
- protected:
-  virtual void SetUp() {
-    server_.reset(new RelayServer(main_));
-
-    server_->AddInternalSocket(
-        talk_base::AsyncUDPSocket::Create(ss_, server_int_addr));
-    server_->AddExternalSocket(
-        talk_base::AsyncUDPSocket::Create(ss_, server_ext_addr));
-
-    client1_.reset(new talk_base::TestClient(
-        talk_base::AsyncUDPSocket::Create(ss_, client1_addr)));
-    client2_.reset(new talk_base::TestClient(
-        talk_base::AsyncUDPSocket::Create(ss_, client2_addr)));
-  }
-
-  void Allocate() {
-    talk_base::scoped_ptr<StunMessage> req(
-        CreateStunMessage(STUN_ALLOCATE_REQUEST));
-    AddUsernameAttr(req.get(), username_);
-    AddLifetimeAttr(req.get(), LIFETIME);
-    Send1(req.get());
-    delete Receive1();
-  }
-  void Bind() {
-    talk_base::scoped_ptr<StunMessage> req(
-        CreateStunMessage(STUN_BINDING_REQUEST));
-    AddUsernameAttr(req.get(), username_);
-    Send2(req.get());
-    delete Receive1();
-  }
-
-  void Send1(const StunMessage* msg) {
-    talk_base::ByteBuffer buf;
-    msg->Write(&buf);
-    SendRaw1(buf.Data(), buf.Length());
-  }
-  void Send2(const StunMessage* msg) {
-    talk_base::ByteBuffer buf;
-    msg->Write(&buf);
-    SendRaw2(buf.Data(), buf.Length());
-  }
-  void SendRaw1(const char* data, int len) {
-    return Send(client1_.get(), data, len, server_int_addr);
-  }
-  void SendRaw2(const char* data, int len) {
-    return Send(client2_.get(), data, len, server_ext_addr);
-  }
-  void Send(talk_base::TestClient* client, const char* data,
-            int len, const SocketAddress& addr) {
-    client->SendTo(data, len, addr);
-  }
-
-  StunMessage* Receive1() {
-    return Receive(client1_.get());
-  }
-  StunMessage* Receive2() {
-    return Receive(client2_.get());
-  }
-  std::string ReceiveRaw1() {
-    return ReceiveRaw(client1_.get());
-  }
-  std::string ReceiveRaw2() {
-    return ReceiveRaw(client2_.get());
-  }
-  StunMessage* Receive(talk_base::TestClient* client) {
-    StunMessage* msg = NULL;
-    talk_base::TestClient::Packet* packet = client->NextPacket();
-    if (packet) {
-      talk_base::ByteBuffer buf(packet->buf, packet->size);
-      msg = new StunMessage();
-      msg->Read(&buf);
-      delete packet;
-    }
-    return msg;
-  }
-  std::string ReceiveRaw(talk_base::TestClient* client) {
-    std::string raw;
-    talk_base::TestClient::Packet* packet = client->NextPacket();
-    if (packet) {
-      raw = std::string(packet->buf, packet->size);
-      delete packet;
-    }
-    return raw;
-  }
-
-  static StunMessage* CreateStunMessage(StunMessageType type) {
-    StunMessage* msg = new StunMessage();
-    msg->SetType(type);
-    msg->SetTransactionID(
-        talk_base::CreateRandomString(kStunTransactionIdLength));
-    return msg;
-  }
-  static void AddMagicCookieAttr(StunMessage* msg) {
-    StunByteStringAttribute* attr =
-        StunAttribute::CreateByteString(STUN_ATTR_MAGIC_COOKIE);
-    attr->CopyBytes(TURN_MAGIC_COOKIE_VALUE, sizeof(TURN_MAGIC_COOKIE_VALUE));
-    msg->AddAttribute(attr);
-  }
-  static void AddUsernameAttr(StunMessage* msg, const std::string& val) {
-    StunByteStringAttribute* attr =
-        StunAttribute::CreateByteString(STUN_ATTR_USERNAME);
-    attr->CopyBytes(val.c_str(), val.size());
-    msg->AddAttribute(attr);
-  }
-  static void AddLifetimeAttr(StunMessage* msg, int val) {
-    StunUInt32Attribute* attr =
-        StunAttribute::CreateUInt32(STUN_ATTR_LIFETIME);
-    attr->SetValue(val);
-    msg->AddAttribute(attr);
-  }
-  static void AddDestinationAttr(StunMessage* msg, const SocketAddress& addr) {
-    StunAddressAttribute* attr =
-        StunAttribute::CreateAddress(STUN_ATTR_DESTINATION_ADDRESS);
-    attr->SetIP(addr.ipaddr());
-    attr->SetPort(addr.port());
-    msg->AddAttribute(attr);
-  }
-
-  talk_base::Thread* main_;
-  talk_base::SocketServer* ss_;
-  talk_base::scoped_ptr<RelayServer> server_;
-  talk_base::scoped_ptr<talk_base::TestClient> client1_;
-  talk_base::scoped_ptr<talk_base::TestClient> client2_;
-  std::string username_;
-  std::string password_;
-};
-
-// Send a complete nonsense message and verify that it is rejected.
-TEST_F(RelayServerTest, TestBadRequest) {
-  talk_base::scoped_ptr<StunMessage> res;
-
-  SendRaw1(bad, std::strlen(bad));
-  res.reset(Receive1());
-
-  ASSERT_TRUE(res.get() != NULL);
-  EXPECT_EQ(STUN_BINDING_ERROR_RESPONSE, res->type());
-
-  const StunErrorCodeAttribute* err = res->GetErrorCode();
-  ASSERT_TRUE(err != NULL);
-  EXPECT_EQ(4, err->error_class());
-  EXPECT_EQ(0, err->number());
-  EXPECT_EQ("Bad Request", err->reason());
-}
-
-// Send an allocate request without a username and verify it is rejected.
-TEST_F(RelayServerTest, TestAllocateNoUsername) {
-  talk_base::scoped_ptr<StunMessage> req(
-      CreateStunMessage(STUN_ALLOCATE_REQUEST)), res;
-
-  Send1(req.get());
-  res.reset(Receive1());
-
-  ASSERT_TRUE(res.get() != NULL);
-  EXPECT_EQ(STUN_ALLOCATE_ERROR_RESPONSE, res->type());
-  EXPECT_EQ(req->transaction_id(), res->transaction_id());
-
-  const StunErrorCodeAttribute* err = res->GetErrorCode();
-  ASSERT_TRUE(err != NULL);
-  EXPECT_EQ(4, err->error_class());
-  EXPECT_EQ(32, err->number());
-  EXPECT_EQ("Missing Username", err->reason());
-}
-
-// Send a binding request and verify that it is rejected.
-TEST_F(RelayServerTest, TestBindingRequest) {
-  talk_base::scoped_ptr<StunMessage> req(
-      CreateStunMessage(STUN_BINDING_REQUEST)), res;
-  AddUsernameAttr(req.get(), username_);
-
-  Send1(req.get());
-  res.reset(Receive1());
-
-  ASSERT_TRUE(res.get() != NULL);
-  EXPECT_EQ(STUN_BINDING_ERROR_RESPONSE, res->type());
-  EXPECT_EQ(req->transaction_id(), res->transaction_id());
-
-  const StunErrorCodeAttribute* err = res->GetErrorCode();
-  ASSERT_TRUE(err != NULL);
-  EXPECT_EQ(6, err->error_class());
-  EXPECT_EQ(0, err->number());
-  EXPECT_EQ("Operation Not Supported", err->reason());
-}
-
-// Send an allocate request and verify that it is accepted.
-TEST_F(RelayServerTest, TestAllocate) {
-  talk_base::scoped_ptr<StunMessage> req(
-      CreateStunMessage(STUN_ALLOCATE_REQUEST)), res;
-  AddUsernameAttr(req.get(), username_);
-  AddLifetimeAttr(req.get(), LIFETIME);
-
-  Send1(req.get());
-  res.reset(Receive1());
-
-  ASSERT_TRUE(res.get() != NULL);
-  EXPECT_EQ(STUN_ALLOCATE_RESPONSE, res->type());
-  EXPECT_EQ(req->transaction_id(), res->transaction_id());
-
-  const StunAddressAttribute* mapped_addr =
-      res->GetAddress(STUN_ATTR_MAPPED_ADDRESS);
-  ASSERT_TRUE(mapped_addr != NULL);
-  EXPECT_EQ(1, mapped_addr->family());
-  EXPECT_EQ(server_ext_addr.port(), mapped_addr->port());
-  EXPECT_EQ(server_ext_addr.ipaddr(), mapped_addr->ipaddr());
-
-  const StunUInt32Attribute* res_lifetime_attr =
-      res->GetUInt32(STUN_ATTR_LIFETIME);
-  ASSERT_TRUE(res_lifetime_attr != NULL);
-  EXPECT_EQ(LIFETIME, res_lifetime_attr->value());
-}
-
-// Send a second allocate request and verify that it is also accepted, though
-// the lifetime should be ignored.
-TEST_F(RelayServerTest, TestReallocate) {
-  Allocate();
-
-  talk_base::scoped_ptr<StunMessage> req(
-      CreateStunMessage(STUN_ALLOCATE_REQUEST)), res;
-  AddMagicCookieAttr(req.get());
-  AddUsernameAttr(req.get(), username_);
-
-  Send1(req.get());
-  res.reset(Receive1());
-
-  ASSERT_TRUE(res.get() != NULL);
-  EXPECT_EQ(STUN_ALLOCATE_RESPONSE, res->type());
-  EXPECT_EQ(req->transaction_id(), res->transaction_id());
-
-  const StunAddressAttribute* mapped_addr =
-      res->GetAddress(STUN_ATTR_MAPPED_ADDRESS);
-  ASSERT_TRUE(mapped_addr != NULL);
-  EXPECT_EQ(1, mapped_addr->family());
-  EXPECT_EQ(server_ext_addr.port(), mapped_addr->port());
-  EXPECT_EQ(server_ext_addr.ipaddr(), mapped_addr->ipaddr());
-
-  const StunUInt32Attribute* lifetime_attr =
-      res->GetUInt32(STUN_ATTR_LIFETIME);
-  ASSERT_TRUE(lifetime_attr != NULL);
-  EXPECT_EQ(LIFETIME, lifetime_attr->value());
-}
-
-// Send a request from another client and see that it arrives at the first
-// client in the binding.
-TEST_F(RelayServerTest, TestRemoteBind) {
-  Allocate();
-
-  talk_base::scoped_ptr<StunMessage> req(
-      CreateStunMessage(STUN_BINDING_REQUEST)), res;
-  AddUsernameAttr(req.get(), username_);
-
-  Send2(req.get());
-  res.reset(Receive1());
-
-  ASSERT_TRUE(res.get() != NULL);
-  EXPECT_EQ(STUN_DATA_INDICATION, res->type());
-
-  const StunByteStringAttribute* recv_data =
-      res->GetByteString(STUN_ATTR_DATA);
-  ASSERT_TRUE(recv_data != NULL);
-
-  talk_base::ByteBuffer buf(recv_data->bytes(), recv_data->length());
-  talk_base::scoped_ptr<StunMessage> res2(new StunMessage());
-  EXPECT_TRUE(res2->Read(&buf));
-  EXPECT_EQ(STUN_BINDING_REQUEST, res2->type());
-  EXPECT_EQ(req->transaction_id(), res2->transaction_id());
-
-  const StunAddressAttribute* src_addr =
-      res->GetAddress(STUN_ATTR_SOURCE_ADDRESS2);
-  ASSERT_TRUE(src_addr != NULL);
-  EXPECT_EQ(1, src_addr->family());
-  EXPECT_EQ(client2_addr.ipaddr(), src_addr->ipaddr());
-  EXPECT_EQ(client2_addr.port(), src_addr->port());
-
-  EXPECT_TRUE(Receive2() == NULL);
-}
-
-// Send a complete nonsense message to the established connection and verify
-// that it is dropped by the server.
-TEST_F(RelayServerTest, TestRemoteBadRequest) {
-  Allocate();
-  Bind();
-
-  SendRaw1(bad, std::strlen(bad));
-  EXPECT_TRUE(Receive1() == NULL);
-  EXPECT_TRUE(Receive2() == NULL);
-}
-
-// Send a send request without a username and verify it is rejected.
-TEST_F(RelayServerTest, TestSendRequestMissingUsername) {
-  Allocate();
-  Bind();
-
-  talk_base::scoped_ptr<StunMessage> req(
-      CreateStunMessage(STUN_SEND_REQUEST)), res;
-  AddMagicCookieAttr(req.get());
-
-  Send1(req.get());
-  res.reset(Receive1());
-
-  ASSERT_TRUE(res.get() != NULL);
-  EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
-  EXPECT_EQ(req->transaction_id(), res->transaction_id());
-
-  const StunErrorCodeAttribute* err = res->GetErrorCode();
-  ASSERT_TRUE(err != NULL);
-  EXPECT_EQ(4, err->error_class());
-  EXPECT_EQ(32, err->number());
-  EXPECT_EQ("Missing Username", err->reason());
-}
-
-// Send a send request with the wrong username and verify it is rejected.
-TEST_F(RelayServerTest, TestSendRequestBadUsername) {
-  Allocate();
-  Bind();
-
-  talk_base::scoped_ptr<StunMessage> req(
-      CreateStunMessage(STUN_SEND_REQUEST)), res;
-  AddMagicCookieAttr(req.get());
-  AddUsernameAttr(req.get(), "foobarbizbaz");
-
-  Send1(req.get());
-  res.reset(Receive1());
-
-  ASSERT_TRUE(res.get() != NULL);
-  EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
-  EXPECT_EQ(req->transaction_id(), res->transaction_id());
-
-  const StunErrorCodeAttribute* err = res->GetErrorCode();
-  ASSERT_TRUE(err != NULL);
-  EXPECT_EQ(4, err->error_class());
-  EXPECT_EQ(30, err->number());
-  EXPECT_EQ("Stale Credentials", err->reason());
-}
-
-// Send a send request without a destination address and verify that it is
-// rejected.
-TEST_F(RelayServerTest, TestSendRequestNoDestinationAddress) {
-  Allocate();
-  Bind();
-
-  talk_base::scoped_ptr<StunMessage> req(
-      CreateStunMessage(STUN_SEND_REQUEST)), res;
-  AddMagicCookieAttr(req.get());
-  AddUsernameAttr(req.get(), username_);
-
-  Send1(req.get());
-  res.reset(Receive1());
-
-  ASSERT_TRUE(res.get() != NULL);
-  EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
-  EXPECT_EQ(req->transaction_id(), res->transaction_id());
-
-  const StunErrorCodeAttribute* err = res->GetErrorCode();
-  ASSERT_TRUE(err != NULL);
-  EXPECT_EQ(4, err->error_class());
-  EXPECT_EQ(0, err->number());
-  EXPECT_EQ("Bad Request", err->reason());
-}
-
-// Send a send request without data and verify that it is rejected.
-TEST_F(RelayServerTest, TestSendRequestNoData) {
-  Allocate();
-  Bind();
-
-  talk_base::scoped_ptr<StunMessage> req(
-      CreateStunMessage(STUN_SEND_REQUEST)), res;
-  AddMagicCookieAttr(req.get());
-  AddUsernameAttr(req.get(), username_);
-  AddDestinationAttr(req.get(), client2_addr);
-
-  Send1(req.get());
-  res.reset(Receive1());
-
-  ASSERT_TRUE(res.get() != NULL);
-  EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
-  EXPECT_EQ(req->transaction_id(), res->transaction_id());
-
-  const StunErrorCodeAttribute* err = res->GetErrorCode();
-  ASSERT_TRUE(err != NULL);
-  EXPECT_EQ(4, err->error_class());
-  EXPECT_EQ(00, err->number());
-  EXPECT_EQ("Bad Request", err->reason());
-}
-
-// Send a binding request after an allocate and verify that it is rejected.
-TEST_F(RelayServerTest, TestSendRequestWrongType) {
-  Allocate();
-  Bind();
-
-  talk_base::scoped_ptr<StunMessage> req(
-      CreateStunMessage(STUN_BINDING_REQUEST)), res;
-  AddMagicCookieAttr(req.get());
-  AddUsernameAttr(req.get(), username_);
-
-  Send1(req.get());
-  res.reset(Receive1());
-
-  ASSERT_TRUE(res.get() != NULL);
-  EXPECT_EQ(STUN_BINDING_ERROR_RESPONSE, res->type());
-  EXPECT_EQ(req->transaction_id(), res->transaction_id());
-
-  const StunErrorCodeAttribute* err = res->GetErrorCode();
-  ASSERT_TRUE(err != NULL);
-  EXPECT_EQ(6, err->error_class());
-  EXPECT_EQ(0, err->number());
-  EXPECT_EQ("Operation Not Supported", err->reason());
-}
-
-// Verify that we can send traffic back and forth between the clients after a
-// successful allocate and bind.
-TEST_F(RelayServerTest, TestSendRaw) {
-  Allocate();
-  Bind();
-
-  for (int i = 0; i < 10; i++) {
-    talk_base::scoped_ptr<StunMessage> req(
-        CreateStunMessage(STUN_SEND_REQUEST)), res;
-    AddMagicCookieAttr(req.get());
-    AddUsernameAttr(req.get(), username_);
-    AddDestinationAttr(req.get(), client2_addr);
-
-    StunByteStringAttribute* send_data =
-        StunAttribute::CreateByteString(STUN_ATTR_DATA);
-    send_data->CopyBytes(msg1);
-    req->AddAttribute(send_data);
-
-    Send1(req.get());
-    EXPECT_EQ(msg1, ReceiveRaw2());
-    SendRaw2(msg2, std::strlen(msg2));
-    res.reset(Receive1());
-
-    ASSERT_TRUE(res.get() != NULL);
-    EXPECT_EQ(STUN_DATA_INDICATION, res->type());
-
-    const StunAddressAttribute* src_addr =
-        res->GetAddress(STUN_ATTR_SOURCE_ADDRESS2);
-    ASSERT_TRUE(src_addr != NULL);
-    EXPECT_EQ(1, src_addr->family());
-    EXPECT_EQ(client2_addr.ipaddr(), src_addr->ipaddr());
-    EXPECT_EQ(client2_addr.port(), src_addr->port());
-
-    const StunByteStringAttribute* recv_data =
-        res->GetByteString(STUN_ATTR_DATA);
-    ASSERT_TRUE(recv_data != NULL);
-    EXPECT_EQ(strlen(msg2), recv_data->length());
-    EXPECT_EQ(0, memcmp(msg2, recv_data->bytes(), recv_data->length()));
-  }
-}
-
-// Verify that a binding expires properly, and rejects send requests.
-TEST_F(RelayServerTest, TestExpiration) {
-  Allocate();
-  Bind();
-
-  // Wait twice the lifetime to make sure the server has expired the binding.
-  talk_base::Thread::Current()->ProcessMessages((LIFETIME * 2) * 1000);
-
-  talk_base::scoped_ptr<StunMessage> req(
-      CreateStunMessage(STUN_SEND_REQUEST)), res;
-  AddMagicCookieAttr(req.get());
-  AddUsernameAttr(req.get(), username_);
-  AddDestinationAttr(req.get(), client2_addr);
-
-  StunByteStringAttribute* data_attr =
-      StunAttribute::CreateByteString(STUN_ATTR_DATA);
-  data_attr->CopyBytes(msg1);
-  req->AddAttribute(data_attr);
-
-  Send1(req.get());
-  res.reset(Receive1());
-
-  ASSERT_TRUE(res.get() != NULL);
-  EXPECT_EQ(STUN_SEND_ERROR_RESPONSE, res->type());
-
-  const StunErrorCodeAttribute* err = res->GetErrorCode();
-  ASSERT_TRUE(err != NULL);
-  EXPECT_EQ(6, err->error_class());
-  EXPECT_EQ(0, err->number());
-  EXPECT_EQ("Operation Not Supported", err->reason());
-
-  // Also verify that traffic from the external client is ignored.
-  SendRaw2(msg2, std::strlen(msg2));
-  EXPECT_TRUE(ReceiveRaw1().empty());
-}
diff --git a/third_party/libjingle/source/talk/p2p/base/session.cc b/third_party/libjingle/source/talk/p2p/base/session.cc
deleted file mode 100644
index 9891ee2..0000000
--- a/third_party/libjingle/source/talk/p2p/base/session.cc
+++ /dev/null
@@ -1,1238 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/p2p/base/session.h"
-#include "talk/base/common.h"
-#include "talk/base/logging.h"
-#include "talk/base/helpers.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/xmpp/constants.h"
-#include "talk/xmpp/jid.h"
-#include "talk/p2p/base/p2ptransport.h"
-#include "talk/p2p/base/p2ptransportchannel.h"
-#include "talk/p2p/base/sessionclient.h"
-#include "talk/p2p/base/transport.h"
-#include "talk/p2p/base/transportchannelproxy.h"
-
-#include "talk/p2p/base/constants.h"
-
-namespace {
-
-const uint32 MSG_TIMEOUT = 1;
-const uint32 MSG_ERROR = 2;
-const uint32 MSG_STATE = 3;
-
-}  // namespace
-
-namespace cricket {
-
-bool BadMessage(const buzz::QName type,
-                const std::string& text,
-                MessageError* err) {
-  err->SetType(type);
-  err->SetText(text);
-  return false;
-}
-
-TransportProxy::~TransportProxy() {
-  for (ChannelMap::iterator iter = channels_.begin();
-       iter != channels_.end(); ++iter) {
-    iter->second->SignalDestroyed(iter->second);
-    delete iter->second;
-  }
-  if (owner_)
-    delete transport_;
-}
-
-std::string TransportProxy::type() const {
-  return transport_->type();
-}
-
-void TransportProxy::SetImplementation(Transport* impl, bool owner) {
-  if (owner_ && transport_)
-     delete transport_;
-  transport_ = impl;
-  owner_ = owner;
-}
-
-TransportChannel* TransportProxy::GetChannel(const std::string& name) {
-  return GetProxy(name);
-}
-
-TransportChannel* TransportProxy::CreateChannel(
-    const std::string& name, const std::string& content_type) {
-  ASSERT(GetChannel(name) == NULL);
-  ASSERT(!transport_->HasChannel(name));
-
-  // We always create a proxy in case we need to change out the transport later.
-  TransportChannelProxy* channel =
-      new TransportChannelProxy(name, content_type);
-  channels_[name] = channel;
-
-  if (state_ == STATE_NEGOTIATED) {
-    SetProxyImpl(name, channel);
-  } else if (state_ == STATE_CONNECTING) {
-    GetOrCreateImpl(name, content_type);
-  }
-  return channel;
-}
-
-void TransportProxy::DestroyChannel(const std::string& name) {
-  TransportChannel* channel = GetChannel(name);
-  if (channel) {
-    channels_.erase(name);
-    channel->SignalDestroyed(channel);
-    delete channel;
-  }
-}
-
-void TransportProxy::SpeculativelyConnectChannels() {
-  ASSERT(state_ == STATE_INIT || state_ == STATE_CONNECTING);
-  state_ = STATE_CONNECTING;
-  for (ChannelMap::iterator iter = channels_.begin();
-       iter != channels_.end(); ++iter) {
-    GetOrCreateImpl(iter->first, iter->second->content_type());
-  }
-  transport_->ConnectChannels();
-}
-
-void TransportProxy::CompleteNegotiation() {
-  if (state_ != STATE_NEGOTIATED) {
-    state_ = STATE_NEGOTIATED;
-    for (ChannelMap::iterator iter = channels_.begin();
-         iter != channels_.end(); ++iter) {
-      SetProxyImpl(iter->first, iter->second);
-    }
-    transport_->ConnectChannels();
-  }
-}
-
-void TransportProxy::AddSentCandidates(const Candidates& candidates) {
-  for (Candidates::const_iterator cand = candidates.begin();
-       cand != candidates.end(); ++cand) {
-    sent_candidates_.push_back(*cand);
-  }
-}
-
-void TransportProxy::AddUnsentCandidates(const Candidates& candidates) {
-  for (Candidates::const_iterator cand = candidates.begin();
-       cand != candidates.end(); ++cand) {
-    unsent_candidates_.push_back(*cand);
-  }
-}
-
-
-TransportChannelProxy* TransportProxy::GetProxy(const std::string& name) {
-  ChannelMap::iterator iter = channels_.find(name);
-  return (iter != channels_.end()) ? iter->second : NULL;
-}
-
-TransportChannelImpl* TransportProxy::GetOrCreateImpl(
-    const std::string& name, const std::string& content_type) {
-  TransportChannelImpl* impl = transport_->GetChannel(name);
-  if (impl == NULL) {
-    impl = transport_->CreateChannel(name, content_type);
-  }
-  return impl;
-}
-
-void TransportProxy::SetProxyImpl(
-    const std::string& name, TransportChannelProxy* proxy) {
-  TransportChannelImpl* impl = GetOrCreateImpl(name, proxy->content_type());
-  ASSERT(impl != NULL);
-  proxy->SetImplementation(impl, true);
-}
-
-// This method will use TransportChannelImpls of and deletes what it owns.
-void TransportProxy::CopyTransportProxyChannels(TransportProxy* proxy) {
-  size_t index = 0;
-  for (ChannelMap::const_iterator iter = proxy->channels().begin();
-       iter != proxy->channels().end(); ++iter, ++index) {
-    ReplaceImpl(iter->second, index);
-  }
-}
-
-void TransportProxy::ReplaceImpl(TransportChannelProxy* channel,
-                                 size_t index) {
-  if (index < channels().size()) {
-    ChannelMap::const_iterator iter = channels().begin();
-    // Get handle the index which needs to be replaced.
-    for (size_t i = 0; i < index; ++i, ++iter);
-
-    TransportChannelProxy* target_channel = iter->second;
-    if (target_channel) {
-      // Deleting TransportChannelImpl before replacing it.
-      transport_->DestroyChannel(iter->first);
-      target_channel->SetImplementation(channel->impl(), false);
-    }
-  } else {
-    LOG(LS_WARNING) << "invalid TransportChannelProxy index to replace";
-  }
-}
-
-BaseSession::BaseSession(talk_base::Thread* signaling_thread,
-                         talk_base::Thread* worker_thread,
-                         PortAllocator* port_allocator,
-                         const std::string& sid,
-                         const std::string& content_type,
-                         bool initiator)
-    : state_(STATE_INIT),
-      error_(ERROR_NONE),
-      signaling_thread_(signaling_thread),
-      worker_thread_(worker_thread),
-      port_allocator_(port_allocator),
-      sid_(sid),
-      content_type_(content_type),
-      transport_type_(NS_GINGLE_P2P),
-      initiator_(initiator),
-      local_description_(NULL),
-      remote_description_(NULL) {
-  ASSERT(signaling_thread->IsCurrent());
-}
-
-BaseSession::~BaseSession() {
-  ASSERT(signaling_thread()->IsCurrent());
-
-  ASSERT(state_ != STATE_DEINIT);
-  state_ = STATE_DEINIT;
-  SignalState(this, state_);
-
-  for (TransportMap::iterator iter = transports_.begin();
-       iter != transports_.end(); ++iter) {
-    delete iter->second;
-  }
-
-  delete remote_description_;
-  delete local_description_;
-}
-
-void BaseSession::set_allow_local_ips(bool allow) {
-  allow_local_ips_ = allow;
-  for (TransportMap::iterator iter = transports_.begin();
-       iter != transports_.end(); ++iter) {
-    iter->second->impl()->set_allow_local_ips(allow);
-  }
-}
-
-TransportChannel* BaseSession::CreateChannel(const std::string& content_name,
-                                             const std::string& channel_name) {
-  // We create the proxy "on demand" here because we need to support
-  // creating channels at any time, even before we send or receive
-  // initiate messages, which is before we create the transports.
-  TransportProxy* transproxy = GetOrCreateTransportProxy(content_name);
-  return transproxy->CreateChannel(channel_name, content_type_);
-}
-
-TransportChannel* BaseSession::GetChannel(const std::string& content_name,
-                                          const std::string& channel_name) {
-  TransportProxy* transproxy = GetTransportProxy(content_name);
-  if (transproxy == NULL)
-    return NULL;
-  else
-    return transproxy->GetChannel(channel_name);
-}
-
-void BaseSession::DestroyChannel(const std::string& content_name,
-                                 const std::string& channel_name) {
-  TransportProxy* transproxy = GetTransportProxy(content_name);
-  ASSERT(transproxy != NULL);
-  transproxy->DestroyChannel(channel_name);
-}
-
-TransportProxy* BaseSession::GetOrCreateTransportProxy(
-    const std::string& content_name) {
-  TransportProxy* transproxy = GetTransportProxy(content_name);
-  if (transproxy)
-    return transproxy;
-
-  Transport* transport = CreateTransport();
-  transport->set_allow_local_ips(allow_local_ips_);
-  transport->SignalConnecting.connect(
-      this, &BaseSession::OnTransportConnecting);
-  transport->SignalWritableState.connect(
-      this, &BaseSession::OnTransportWritable);
-  transport->SignalRequestSignaling.connect(
-      this, &BaseSession::OnTransportRequestSignaling);
-  transport->SignalCandidatesReady.connect(
-      this, &BaseSession::OnTransportCandidatesReady);
-  transport->SignalTransportError.connect(
-      this, &BaseSession::OnTransportSendError);
-  transport->SignalChannelGone.connect(
-      this, &BaseSession::OnTransportChannelGone);
-
-  transproxy = new TransportProxy(content_name, transport);
-  transports_[content_name] = transproxy;
-
-  return transproxy;
-}
-
-Transport* BaseSession::GetTransport(const std::string& content_name) {
-  TransportProxy* transproxy = GetTransportProxy(content_name);
-  if (transproxy == NULL)
-    return NULL;
-  return transproxy->impl();
-}
-
-TransportProxy* BaseSession::GetTransportProxy(
-    const std::string& content_name) {
-  TransportMap::iterator iter = transports_.find(content_name);
-  return (iter != transports_.end()) ? iter->second : NULL;
-}
-
-TransportProxy* BaseSession::GetTransportProxy(const Transport* transport) {
-  for (TransportMap::iterator iter = transports_.begin();
-       iter != transports_.end(); ++iter) {
-    TransportProxy* transproxy = iter->second;
-    if (transproxy->impl() == transport) {
-      return transproxy;
-    }
-  }
-  return NULL;
-}
-
-TransportProxy* BaseSession::GetFirstTransportProxy() {
-  if (transports_.empty())
-    return NULL;
-  return transports_.begin()->second;
-}
-
-cricket::Transport* BaseSession::CreateTransport() {
-  ASSERT(transport_type_ == NS_GINGLE_P2P);
-  return new cricket::P2PTransport(
-      signaling_thread(), worker_thread(), port_allocator());
-}
-
-void BaseSession::SetState(State state) {
-  ASSERT(signaling_thread_->IsCurrent());
-  if (state != state_) {
-    state_ = state;
-    SignalState(this, state_);
-    signaling_thread_->Post(this, MSG_STATE);
-  }
-}
-
-void BaseSession::SetError(Error error) {
-  ASSERT(signaling_thread_->IsCurrent());
-  if (error != error_) {
-    error_ = error;
-    SignalError(this, error);
-  }
-}
-
-void BaseSession::OnSignalingReady() {
-  ASSERT(signaling_thread()->IsCurrent());
-  for (TransportMap::iterator iter = transports_.begin();
-       iter != transports_.end(); ++iter) {
-    iter->second->impl()->OnSignalingReady();
-  }
-}
-
-void BaseSession::SpeculativelyConnectAllTransportChannels() {
-  for (TransportMap::iterator iter = transports_.begin();
-       iter != transports_.end(); ++iter) {
-    iter->second->SpeculativelyConnectChannels();
-  }
-}
-
-bool BaseSession::ContentsGrouped() {
-  // TODO - present implementation checks for groups present
-  // in SDP. It may be necessary to check content_names in groups of both
-  // local and remote descriptions. Assumption here is that when this method
-  // returns true, media contents can be muxed.
-  if (local_description()->HasGroup(GN_TOGETHER) &&
-      remote_description()->HasGroup(GN_TOGETHER)) {
-    return true;
-  }
-  return false;
-}
-
-bool BaseSession::MaybeEnableMuxingSupport() {
-  bool ret = true;
-  if (!ContentsGrouped()) {
-    LOG(LS_INFO) << "Contents are not grouped together cannot be muxed";
-  } else {
-    // Always use first content name from the group for muxing. Hence ordering
-    // of content names in SDP should match to the order in group.
-    const ContentGroup* muxed_content_group =
-        local_description()->GetGroupByName(GN_TOGETHER);
-    const std::string* content_name =
-        muxed_content_group->FirstContentName();
-    if (content_name) {
-      const ContentInfo* content =
-          local_description_->GetContentByName(*content_name);
-      ASSERT(content != NULL);
-      SetSelectedProxy(content->name, muxed_content_group);
-    }
-  }
-  return ret;
-}
-
-void BaseSession::SetSelectedProxy(const std::string& content_name,
-                                   const ContentGroup* muxed_group) {
-  TransportProxy* selected_proxy = GetTransportProxy(content_name);
-  if (selected_proxy) {
-    ASSERT(selected_proxy->negotiated());
-    for (TransportMap::iterator iter = transports_.begin();
-         iter != transports_.end(); ++iter) {
-      // If content is part of group, then try to replace the Proxy with
-      // the selected.
-      if (iter->first != content_name &&
-          muxed_group->HasContentName(iter->first)) {
-        TransportProxy* proxy = iter->second;
-        proxy->CopyTransportProxyChannels(selected_proxy);
-        // After replacing the TransportChannels, replace Transport
-        proxy->SetImplementation(selected_proxy->impl(), false);
-      }
-    }
-  }
-}
-
-void BaseSession::OnMessage(talk_base::Message *pmsg) {
-  switch (pmsg->message_id) {
-  case MSG_TIMEOUT:
-    // Session timeout has occured.
-    SetError(ERROR_TIME);
-    break;
-
-  case MSG_STATE:
-    switch (state_) {
-    case STATE_SENTACCEPT:
-    case STATE_RECEIVEDACCEPT:
-      SetState(STATE_INPROGRESS);
-      break;
-
-    default:
-      // Explicitly ignoring some states here.
-      break;
-    }
-    break;
-  }
-}
-
-Session::Session(SessionManager* session_manager,
-                 const std::string& local_name,
-                 const std::string& initiator_name,
-                 const std::string& sid,
-                 const std::string& content_type,
-                 SessionClient* client)
-    : BaseSession(session_manager->signaling_thread(),
-                  session_manager->worker_thread(),
-                  session_manager->port_allocator(),
-                  sid, content_type, initiator_name == local_name) {
-  ASSERT(client != NULL);
-  session_manager_ = session_manager;
-  local_name_ = local_name;
-  initiator_name_ = initiator_name;
-  transport_parser_ = new P2PTransportParser();
-  client_ = client;
-  initiate_acked_ = false;
-  current_protocol_ = PROTOCOL_HYBRID;
-}
-
-Session::~Session() {
-  delete transport_parser_;
-}
-
-bool Session::Initiate(const std::string &to,
-                       const SessionDescription* sdesc) {
-  ASSERT(signaling_thread()->IsCurrent());
-  SessionError error;
-
-  // Only from STATE_INIT
-  if (state() != STATE_INIT)
-    return false;
-
-  // Setup for signaling.
-  set_remote_name(to);
-  set_local_description(sdesc);
-  if (!CreateTransportProxies(GetEmptyTransportInfos(sdesc->contents()),
-                              &error)) {
-    LOG(LS_ERROR) << "Could not create transports: " << error.text;
-    return false;
-  }
-
-  if (!SendInitiateMessage(sdesc, &error)) {
-    LOG(LS_ERROR) << "Could not send initiate message: " << error.text;
-    return false;
-  }
-
-  SetState(Session::STATE_SENTINITIATE);
-
-  SpeculativelyConnectAllTransportChannels();
-  return true;
-}
-
-bool Session::Accept(const SessionDescription* sdesc) {
-  ASSERT(signaling_thread()->IsCurrent());
-
-  // Only if just received initiate
-  if (state() != STATE_RECEIVEDINITIATE)
-    return false;
-
-  // Setup for signaling.
-  set_local_description(sdesc);
-
-  SessionError error;
-  if (!SendAcceptMessage(sdesc, &error)) {
-    LOG(LS_ERROR) << "Could not send accept message: " << error.text;
-    return false;
-  }
-
-  MaybeEnableMuxingSupport();  // Enable transport channel mux if supported.
-  SetState(Session::STATE_SENTACCEPT);
-  return true;
-}
-
-bool Session::Reject(const std::string& reason) {
-  ASSERT(signaling_thread()->IsCurrent());
-
-  // Reject is sent in response to an initiate or modify, to reject the
-  // request
-  if (state() != STATE_RECEIVEDINITIATE && state() != STATE_RECEIVEDMODIFY)
-    return false;
-
-  SessionError error;
-  if (!SendRejectMessage(reason, &error)) {
-    LOG(LS_ERROR) << "Could not send reject message: " << error.text;
-    return false;
-  }
-
-  SetState(STATE_SENTREJECT);
-  return true;
-}
-
-bool Session::TerminateWithReason(const std::string& reason) {
-  ASSERT(signaling_thread()->IsCurrent());
-
-  // Either side can terminate, at any time.
-  switch (state()) {
-    case STATE_SENTTERMINATE:
-    case STATE_RECEIVEDTERMINATE:
-      return false;
-
-    case STATE_SENTREJECT:
-    case STATE_RECEIVEDREJECT:
-      // We don't need to send terminate if we sent or received a reject...
-      // it's implicit.
-      break;
-
-    default:
-      SessionError error;
-      if (!SendTerminateMessage(reason, &error)) {
-        LOG(LS_ERROR) << "Could not send terminate message: " << error.text;
-        return false;
-      }
-      break;
-  }
-
-  SetState(STATE_SENTTERMINATE);
-  return true;
-}
-
-bool Session::SendInfoMessage(const XmlElements& elems) {
-  ASSERT(signaling_thread()->IsCurrent());
-  SessionError error;
-  if (!SendMessage(ACTION_SESSION_INFO, elems, &error)) {
-    LOG(LS_ERROR) << "Could not send info message " << error.text;
-    return false;
-  }
-  return true;
-}
-
-TransportInfos Session::GetEmptyTransportInfos(
-    const ContentInfos& contents) const {
-  TransportInfos tinfos;
-  for (ContentInfos::const_iterator content = contents.begin();
-       content != contents.end(); ++content) {
-    tinfos.push_back(
-        TransportInfo(content->name, transport_type(), Candidates()));
-  }
-  return tinfos;
-}
-
-bool Session::OnRemoteCandidates(
-    const TransportInfos& tinfos, ParseError* error) {
-  for (TransportInfos::const_iterator tinfo = tinfos.begin();
-       tinfo != tinfos.end(); ++tinfo) {
-    TransportProxy* transproxy = GetTransportProxy(tinfo->content_name);
-    if (transproxy == NULL) {
-      return BadParse("Unknown content name: " + tinfo->content_name, error);
-    }
-
-    // Must complete negotiation before sending remote candidates, or
-    // there won't be any channel impls.
-    transproxy->CompleteNegotiation();
-    for (Candidates::const_iterator cand = tinfo->candidates.begin();
-         cand != tinfo->candidates.end(); ++cand) {
-      if (!transproxy->impl()->VerifyCandidate(*cand, error))
-        return false;
-
-      if (!transproxy->impl()->HasChannel(cand->name())) {
-        buzz::XmlElement* extra_info =
-            new buzz::XmlElement(QN_GINGLE_P2P_UNKNOWN_CHANNEL_NAME);
-        extra_info->AddAttr(buzz::QN_NAME, cand->name());
-        error->extra = extra_info;
-
-        return BadParse("channel named in candidate does not exist: " +
-                        cand->name() + " for content: "+ tinfo->content_name,
-                        error);
-      }
-    }
-    transproxy->impl()->OnRemoteCandidates(tinfo->candidates);
-  }
-
-  return true;
-}
-
-bool Session::CreateTransportProxies(const TransportInfos& tinfos,
-                                     SessionError* error) {
-  for (TransportInfos::const_iterator tinfo = tinfos.begin();
-       tinfo != tinfos.end(); ++tinfo) {
-    if (tinfo->transport_type != transport_type()) {
-      error->SetText("No supported transport in offer.");
-      return false;
-    }
-
-    GetOrCreateTransportProxy(tinfo->content_name);
-  }
-  return true;
-}
-
-TransportParserMap Session::GetTransportParsers() {
-  TransportParserMap parsers;
-  parsers[transport_type()] = transport_parser_;
-  return parsers;
-}
-
-ContentParserMap Session::GetContentParsers() {
-  ContentParserMap parsers;
-  parsers[content_type()] = client_;
-  return parsers;
-}
-
-void Session::OnTransportRequestSignaling(Transport* transport) {
-  ASSERT(signaling_thread()->IsCurrent());
-  SignalRequestSignaling(this);
-}
-
-void Session::OnTransportConnecting(Transport* transport) {
-  // This is an indication that we should begin watching the writability
-  // state of the transport.
-  OnTransportWritable(transport);
-}
-
-void Session::OnTransportWritable(Transport* transport) {
-  ASSERT(signaling_thread()->IsCurrent());
-
-  // If the transport is not writable, start a timer to make sure that it
-  // becomes writable within a reasonable amount of time.  If it does not, we
-  // terminate since we can't actually send data.  If the transport is writable,
-  // cancel the timer.  Note that writability transitions may occur repeatedly
-  // during the lifetime of the session.
-  signaling_thread()->Clear(this, MSG_TIMEOUT);
-  if (transport->HasChannels() && !transport->writable()) {
-    signaling_thread()->PostDelayed(
-        session_manager_->session_timeout() * 1000, this, MSG_TIMEOUT);
-  }
-}
-
-void Session::OnTransportCandidatesReady(Transport* transport,
-                                         const Candidates& candidates) {
-  ASSERT(signaling_thread()->IsCurrent());
-  TransportProxy* transproxy = GetTransportProxy(transport);
-  if (transproxy != NULL) {
-    if (initiator() && !initiate_acked_) {
-      // TODO: This is to work around server re-ordering
-      // messages.  We send the candidates once the session-initiate
-      // is acked.  Once we have fixed the server to guarantee message
-      // order, we can remove this case.
-      transproxy->AddUnsentCandidates(candidates);
-    } else {
-      if (!transproxy->negotiated()) {
-        transproxy->AddSentCandidates(candidates);
-      }
-      SessionError error;
-      if (!SendTransportInfoMessage(transproxy, candidates, &error)) {
-        LOG(LS_ERROR) << "Could not send transport info message: "
-                      << error.text;
-        return;
-      }
-    }
-  }
-}
-
-void Session::OnTransportSendError(Transport* transport,
-                                   const buzz::XmlElement* stanza,
-                                   const buzz::QName& name,
-                                   const std::string& type,
-                                   const std::string& text,
-                                   const buzz::XmlElement* extra_info) {
-  ASSERT(signaling_thread()->IsCurrent());
-  SignalErrorMessage(this, stanza, name, type, text, extra_info);
-}
-
-void Session::OnTransportChannelGone(Transport* transport,
-                                     const std::string& name) {
-  ASSERT(signaling_thread()->IsCurrent());
-  SignalChannelGone(this, name);
-}
-
-void Session::OnIncomingMessage(const SessionMessage& msg) {
-  ASSERT(signaling_thread()->IsCurrent());
-  ASSERT(state() == STATE_INIT || msg.from == remote_name());
-
-  if (current_protocol_== PROTOCOL_HYBRID) {
-    if (msg.protocol == PROTOCOL_GINGLE) {
-      current_protocol_ = PROTOCOL_GINGLE;
-    } else {
-      current_protocol_ = PROTOCOL_JINGLE;
-    }
-  }
-
-  bool valid = false;
-  MessageError error;
-  switch (msg.type) {
-    case ACTION_SESSION_INITIATE:
-      valid = OnInitiateMessage(msg, &error);
-      break;
-    case ACTION_SESSION_INFO:
-      valid = OnInfoMessage(msg);
-      break;
-    case ACTION_SESSION_ACCEPT:
-      valid = OnAcceptMessage(msg, &error);
-      break;
-    case ACTION_SESSION_REJECT:
-      valid = OnRejectMessage(msg, &error);
-      break;
-    case ACTION_SESSION_TERMINATE:
-      valid = OnTerminateMessage(msg, &error);
-      break;
-    case ACTION_TRANSPORT_INFO:
-      valid = OnTransportInfoMessage(msg, &error);
-      break;
-    case ACTION_TRANSPORT_ACCEPT:
-      valid = OnTransportAcceptMessage(msg, &error);
-      break;
-    case ACTION_DESCRIPTION_INFO:
-      valid = OnDescriptionInfoMessage(msg, &error);
-      break;
-    default:
-      valid = BadMessage(buzz::QN_STANZA_BAD_REQUEST,
-                         "unknown session message type",
-                         &error);
-  }
-
-  if (valid) {
-    SendAcknowledgementMessage(msg.stanza);
-  } else {
-    SignalErrorMessage(this, msg.stanza, error.type,
-                       "modify", error.text, NULL);
-  }
-}
-
-void Session::OnIncomingResponse(const buzz::XmlElement* orig_stanza,
-                                 const buzz::XmlElement* response_stanza,
-                                 const SessionMessage& msg) {
-  ASSERT(signaling_thread()->IsCurrent());
-
-  if (msg.type == ACTION_SESSION_INITIATE) {
-    OnInitiateAcked();
-  }
-}
-
-void Session::OnInitiateAcked() {
-    // TODO: This is to work around server re-ordering
-    // messages.  We send the candidates once the session-initiate
-    // is acked.  Once we have fixed the server to guarantee message
-    // order, we can remove this case.
-  if (!initiate_acked_) {
-    initiate_acked_ = true;
-    SessionError error;
-    SendAllUnsentTransportInfoMessages(&error);
-  }
-}
-
-void Session::OnFailedSend(const buzz::XmlElement* orig_stanza,
-                           const buzz::XmlElement* error_stanza) {
-  ASSERT(signaling_thread()->IsCurrent());
-
-  SessionMessage msg;
-  ParseError parse_error;
-  if (!ParseSessionMessage(orig_stanza, &msg, &parse_error)) {
-    LOG(LS_ERROR) << "Error parsing failed send: " << parse_error.text
-                  << ":" << orig_stanza;
-    return;
-  }
-
-  // If the error is a session redirect, call OnRedirectError, which will
-  // continue the session with a new remote JID.
-  SessionRedirect redirect;
-  if (FindSessionRedirect(error_stanza, &redirect)) {
-    SessionError error;
-    if (!OnRedirectError(redirect, &error)) {
-      // TODO: Should we send a message back?  The standard
-      // says nothing about it.
-      LOG(LS_ERROR) << "Failed to redirect: " << error.text;
-      SetError(ERROR_RESPONSE);
-    }
-    return;
-  }
-
-  std::string error_type = "cancel";
-
-  const buzz::XmlElement* error = error_stanza->FirstNamed(buzz::QN_ERROR);
-  if (error) {
-    error_type = error->Attr(buzz::QN_TYPE);
-
-    LOG(LS_ERROR) << "Session error:\n" << error->Str() << "\n"
-                  << "in response to:\n" << orig_stanza->Str();
-  } else {
-    // don't crash if <error> is missing
-    LOG(LS_ERROR) << "Session error without <error/> element, ignoring";
-    return;
-  }
-
-  if (msg.type == ACTION_TRANSPORT_INFO) {
-    // Transport messages frequently generate errors because they are sent right
-    // when we detect a network failure.  For that reason, we ignore such
-    // errors, because if we do not establish writability again, we will
-    // terminate anyway.  The exceptions are transport-specific error tags,
-    // which we pass on to the respective transport.
-
-    // TODO: This is only used for unknown channel name.
-    // For Jingle, find a standard-compliant way of doing this.  For
-    // Gingle, guess the content name based on the channel name.
-    for (const buzz::XmlElement* elem = error->FirstElement();
-         NULL != elem; elem = elem->NextElement()) {
-      TransportProxy* transproxy = GetFirstTransportProxy();
-      if (transproxy && transproxy->type() == error->Name().Namespace()) {
-        transproxy->impl()->OnTransportError(elem);
-      }
-    }
-  } else if ((error_type != "continue") && (error_type != "wait")) {
-    // We do not set an error if the other side said it is okay to continue
-    // (possibly after waiting).  These errors can be ignored.
-    SetError(ERROR_RESPONSE);
-  }
-}
-
-bool Session::OnInitiateMessage(const SessionMessage& msg,
-                                MessageError* error) {
-  if (!CheckState(STATE_INIT, error))
-    return false;
-
-  SessionInitiate init;
-  if (!ParseSessionInitiate(msg.protocol, msg.action_elem,
-                            GetContentParsers(), GetTransportParsers(),
-                            &init, error))
-    return false;
-
-  SessionError session_error;
-  if (!CreateTransportProxies(init.transports, &session_error)) {
-    return BadMessage(buzz::QN_STANZA_NOT_ACCEPTABLE,
-                      session_error.text, error);
-  }
-
-  set_remote_name(msg.from);
-  set_remote_description(new SessionDescription(init.ClearContents()));
-  SetState(STATE_RECEIVEDINITIATE);
-
-  // Users of Session may listen to state change and call Reject().
-  if (state() != STATE_SENTREJECT) {
-    if (!OnRemoteCandidates(init.transports, error))
-      return false;
-  }
-  return true;
-}
-
-bool Session::OnAcceptMessage(const SessionMessage& msg, MessageError* error) {
-  if (!CheckState(STATE_SENTINITIATE, error))
-    return false;
-
-  SessionAccept accept;
-  if (!ParseSessionAccept(msg.protocol, msg.action_elem,
-                          GetContentParsers(), GetTransportParsers(),
-                          &accept, error)) {
-    return false;
-  }
-
-  // If we get an accept, we can assume the initiate has been
-  // received, even if we haven't gotten an IQ response.
-  OnInitiateAcked();
-
-  set_remote_description(new SessionDescription(accept.ClearContents()));
-  MaybeEnableMuxingSupport();  // Enable transport channel mux if supported.
-  SetState(STATE_RECEIVEDACCEPT);
-
-  // Users of Session may listen to state change and call Reject().
-  if (state() != STATE_SENTREJECT) {
-    if (!OnRemoteCandidates(accept.transports, error))
-      return false;
-  }
-
-  return true;
-}
-
-bool Session::OnRejectMessage(const SessionMessage& msg, MessageError* error) {
-  if (!CheckState(STATE_SENTINITIATE, error))
-    return false;
-
-  SetState(STATE_RECEIVEDREJECT);
-  return true;
-}
-
-bool Session::OnInfoMessage(const SessionMessage& msg) {
-  SignalInfoMessage(this, msg.action_elem);
-  return true;
-}
-
-bool Session::OnTerminateMessage(const SessionMessage& msg,
-                                 MessageError* error) {
-  SessionTerminate term;
-  if (!ParseSessionTerminate(msg.protocol, msg.action_elem, &term, error))
-    return false;
-
-  SignalReceivedTerminateReason(this, term.reason);
-  if (term.debug_reason != buzz::STR_EMPTY) {
-    LOG(LS_VERBOSE) << "Received error on call: " << term.debug_reason;
-  }
-
-  SetState(STATE_RECEIVEDTERMINATE);
-  return true;
-}
-
-bool Session::OnTransportInfoMessage(const SessionMessage& msg,
-                                     MessageError* error) {
-  TransportInfos tinfos;
-  if (!ParseTransportInfos(msg.protocol, msg.action_elem,
-                           initiator_description()->contents(),
-                           GetTransportParsers(), &tinfos, error))
-    return false;
-
-  if (!OnRemoteCandidates(tinfos, error))
-    return false;
-
-  return true;
-}
-
-bool Session::OnTransportAcceptMessage(const SessionMessage& msg,
-                                       MessageError* error) {
-  // TODO: Currently here only for compatibility with
-  // Gingle 1.1 clients (notably, Google Voice).
-  return true;
-}
-
-bool Session::OnDescriptionInfoMessage(const SessionMessage& msg,
-                              MessageError* error) {
-  if (!CheckState(STATE_INPROGRESS, error))
-    return false;
-
-  DescriptionInfo description_info;
-  if (!ParseDescriptionInfo(msg.protocol, msg.action_elem,
-                            GetContentParsers(), GetTransportParsers(),
-                            &description_info, error)) {
-    return false;
-  }
-
-  ContentInfos updated_contents = description_info.ClearContents();
-  ContentInfos::iterator it;
-
-  // First, ensure all updates are valid before modifying remote_description_.
-  for (it = updated_contents.begin(); it != updated_contents.end(); ++it) {
-    if (remote_description()->GetContentByName(it->name) == NULL) {
-      return false;
-    }
-
-    // TODO: We should add a check to ensure that the updated
-    // contents are compatible with the original contents.
-  }
-
-  // Merge the updates into the remote description.
-  // TODO: Merge streams instead of overwriting.
-  for (it = updated_contents.begin(); it != updated_contents.end(); ++it) {
-    LOG(LS_INFO) << "Updating content " << it->name;
-    remote_description()->RemoveContentByName(it->name);
-    remote_description()->AddContent(it->name, it->type, it->description);
-  }
-
-  // TODO: Add an argument that shows what streams were changed.
-  SignalRemoteDescriptionUpdate(this);
-
-  return true;
-}
-
-bool BareJidsEqual(const std::string& name1,
-                   const std::string& name2) {
-  buzz::Jid jid1(name1);
-  buzz::Jid jid2(name2);
-
-  return jid1.IsValid() && jid2.IsValid() && jid1.BareEquals(jid2);
-}
-
-bool Session::OnRedirectError(const SessionRedirect& redirect,
-                              SessionError* error) {
-  MessageError message_error;
-  if (!CheckState(STATE_SENTINITIATE, &message_error)) {
-    return BadWrite(message_error.text, error);
-  }
-
-  if (!BareJidsEqual(remote_name(), redirect.target))
-    return BadWrite("Redirection not allowed: must be the same bare jid.",
-                    error);
-
-  // When we receive a redirect, we point the session at the new JID
-  // and resend the candidates.
-  set_remote_name(redirect.target);
-  return (SendInitiateMessage(local_description(), error) &&
-          ResendAllTransportInfoMessages(error));
-}
-
-bool Session::CheckState(State expected, MessageError* error) {
-  ASSERT(state() == expected);
-  if (state() != expected) {
-    return BadMessage(buzz::QN_STANZA_NOT_ALLOWED,
-                      "message not allowed in current state",
-                      error);
-  }
-  return true;
-}
-
-void Session::SetError(Error error) {
-  BaseSession::SetError(error);
-  if (error != ERROR_NONE)
-    signaling_thread()->Post(this, MSG_ERROR);
-}
-
-void Session::OnMessage(talk_base::Message *pmsg) {
-  // preserve this because BaseSession::OnMessage may modify it
-  State orig_state = state();
-
-  BaseSession::OnMessage(pmsg);
-
-  switch (pmsg->message_id) {
-  case MSG_ERROR:
-    TerminateWithReason(STR_TERMINATE_ERROR);
-    break;
-
-  case MSG_STATE:
-    switch (orig_state) {
-    case STATE_SENTREJECT:
-    case STATE_RECEIVEDREJECT:
-      // Assume clean termination.
-      Terminate();
-      break;
-
-    case STATE_SENTTERMINATE:
-    case STATE_RECEIVEDTERMINATE:
-      session_manager_->DestroySession(this);
-      break;
-
-    default:
-      // Explicitly ignoring some states here.
-      break;
-    }
-    break;
-  }
-}
-
-bool Session::SendInitiateMessage(const SessionDescription* sdesc,
-                                  SessionError* error) {
-  SessionInitiate init;
-  init.contents = sdesc->contents();
-  init.transports = GetEmptyTransportInfos(init.contents);
-  return SendMessage(ACTION_SESSION_INITIATE, init, error);
-}
-
-bool Session::WriteSessionAction(
-    SignalingProtocol protocol, const SessionInitiate& init,
-    XmlElements* elems, WriteError* error) {
-  ContentParserMap content_parsers = GetContentParsers();
-  TransportParserMap trans_parsers = GetTransportParsers();
-
-  return WriteSessionInitiate(protocol, init.contents, init.transports,
-                              content_parsers, trans_parsers,
-                              elems, error);
-}
-
-bool Session::SendAcceptMessage(const SessionDescription* sdesc,
-                                SessionError* error) {
-  XmlElements elems;
-  if (!WriteSessionAccept(current_protocol_,
-                          sdesc->contents(),
-                          GetEmptyTransportInfos(sdesc->contents()),
-                          GetContentParsers(), GetTransportParsers(),
-                          &elems, error)) {
-    return false;
-  }
-  return SendMessage(ACTION_SESSION_ACCEPT, elems, error);
-}
-
-bool Session::SendRejectMessage(const std::string& reason,
-                                SessionError* error) {
-  SessionTerminate term(reason);
-  return SendMessage(ACTION_SESSION_REJECT, term, error);
-}
-
-bool Session::SendTerminateMessage(const std::string& reason,
-                                   SessionError* error) {
-  SessionTerminate term(reason);
-  return SendMessage(ACTION_SESSION_TERMINATE, term, error);
-}
-
-bool Session::WriteSessionAction(SignalingProtocol protocol,
-                                 const SessionTerminate& term,
-                                 XmlElements* elems, WriteError* error) {
-  WriteSessionTerminate(protocol, term, elems);
-  return true;
-}
-
-bool Session::SendTransportInfoMessage(const TransportInfo& tinfo,
-                                       SessionError* error) {
-  return SendMessage(ACTION_TRANSPORT_INFO, tinfo, error);
-}
-
-bool Session::SendTransportInfoMessage(const TransportProxy* transproxy,
-                                       const Candidates& candidates,
-                                       SessionError* error) {
-  return SendTransportInfoMessage(TransportInfo(transproxy->content_name(),
-                                                transproxy->type(),
-                                                candidates),
-                                  error);
-}
-
-bool Session::WriteSessionAction(SignalingProtocol protocol,
-                                 const TransportInfo& tinfo,
-                                 XmlElements* elems, WriteError* error) {
-  TransportInfos tinfos;
-  tinfos.push_back(tinfo);
-  TransportParserMap parsers = GetTransportParsers();
-
-  return WriteTransportInfos(protocol, tinfos, parsers,
-                             elems, error);
-}
-
-bool Session::ResendAllTransportInfoMessages(SessionError* error) {
-  for (TransportMap::const_iterator iter = transport_proxies().begin();
-       iter != transport_proxies().end(); ++iter) {
-    TransportProxy* transproxy = iter->second;
-    if (transproxy->sent_candidates().size() > 0) {
-      if (!SendTransportInfoMessage(
-              transproxy, transproxy->sent_candidates(), error)) {
-        LOG(LS_ERROR) << "Could not resend transport info messages: "
-                      << error->text;
-        return false;
-      }
-      transproxy->ClearSentCandidates();
-    }
-  }
-  return true;
-}
-
-bool Session::SendAllUnsentTransportInfoMessages(SessionError* error) {
-  for (TransportMap::const_iterator iter = transport_proxies().begin();
-       iter != transport_proxies().end(); ++iter) {
-    TransportProxy* transproxy = iter->second;
-    if (transproxy->unsent_candidates().size() > 0) {
-      if (!SendTransportInfoMessage(
-              transproxy, transproxy->unsent_candidates(), error)) {
-        LOG(LS_ERROR) << "Could not send unsent transport info messages: "
-                      << error->text;
-        return false;
-      }
-      transproxy->ClearUnsentCandidates();
-    }
-  }
-  return true;
-}
-
-bool Session::SendMessage(ActionType type, const XmlElements& action_elems,
-                          SessionError* error) {
-  talk_base::scoped_ptr<buzz::XmlElement> stanza(
-      new buzz::XmlElement(buzz::QN_IQ));
-
-  SessionMessage msg(current_protocol_, type, id(), initiator_name());
-  msg.to = remote_name();
-  WriteSessionMessage(msg, action_elems, stanza.get());
-
-  SignalOutgoingMessage(this, stanza.get());
-  return true;
-}
-
-template <typename Action>
-bool Session::SendMessage(ActionType type, const Action& action,
-                          SessionError* error) {
-  talk_base::scoped_ptr<buzz::XmlElement> stanza(
-      new buzz::XmlElement(buzz::QN_IQ));
-  if (!WriteActionMessage(type, action, stanza.get(), error))
-    return false;
-
-  SignalOutgoingMessage(this, stanza.get());
-  return true;
-}
-
-template <typename Action>
-bool Session::WriteActionMessage(ActionType type, const Action& action,
-                                 buzz::XmlElement* stanza,
-                                 WriteError* error) {
-  if (current_protocol_ == PROTOCOL_HYBRID) {
-    if (!WriteActionMessage(PROTOCOL_JINGLE, type, action, stanza, error))
-      return false;
-    if (!WriteActionMessage(PROTOCOL_GINGLE, type, action, stanza, error))
-      return false;
-  } else {
-    if (!WriteActionMessage(current_protocol_, type, action, stanza, error))
-      return false;
-  }
-  return true;
-}
-
-template <typename Action>
-bool Session::WriteActionMessage(SignalingProtocol protocol,
-                                 ActionType type, const Action& action,
-                                 buzz::XmlElement* stanza, WriteError* error) {
-  XmlElements action_elems;
-  if (!WriteSessionAction(protocol, action, &action_elems, error))
-    return false;
-
-  SessionMessage msg(protocol, type, id(), initiator_name());
-  msg.to = remote_name();
-
-  WriteSessionMessage(msg, action_elems, stanza);
-  return true;
-}
-
-void Session::SendAcknowledgementMessage(const buzz::XmlElement* stanza) {
-  talk_base::scoped_ptr<buzz::XmlElement> ack(
-      new buzz::XmlElement(buzz::QN_IQ));
-  ack->SetAttr(buzz::QN_TO, remote_name());
-  ack->SetAttr(buzz::QN_ID, stanza->Attr(buzz::QN_ID));
-  ack->SetAttr(buzz::QN_TYPE, "result");
-
-  SignalOutgoingMessage(this, ack.get());
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/p2p/base/session.h b/third_party/libjingle/source/talk/p2p/base/session.h
deleted file mode 100644
index f3b6f25..0000000
--- a/third_party/libjingle/source/talk/p2p/base/session.h
+++ /dev/null
@@ -1,587 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_P2P_BASE_SESSION_H_
-#define TALK_P2P_BASE_SESSION_H_
-
-#include <list>
-#include <map>
-#include <string>
-#include <vector>
-
-#include "talk/p2p/base/sessionmessages.h"
-#include "talk/p2p/base/sessionmanager.h"
-#include "talk/base/socketaddress.h"
-#include "talk/p2p/base/sessionclient.h"
-#include "talk/p2p/base/parsing.h"
-#include "talk/p2p/base/port.h"
-#include "talk/xmllite/xmlelement.h"
-#include "talk/xmpp/constants.h"
-
-namespace cricket {
-
-class P2PTransportChannel;
-class Transport;
-class TransportChannel;
-class TransportChannelProxy;
-class TransportChannelImpl;
-
-// Used for errors that will send back a specific error message to the
-// remote peer.  We add "type" to the errors because it's needed for
-// SignalErrorMessage.
-struct MessageError : ParseError {
-  buzz::QName type;
-
-  // if unset, assume type is a parse error
-  MessageError() : ParseError(), type(buzz::QN_STANZA_BAD_REQUEST) {}
-
-  void SetType(const buzz::QName type) {
-    this->type = type;
-  }
-};
-
-// Used for errors that may be returned by public session methods that
-// can fail.
-// TODO: Use this error in Session::Initiate and
-// Session::Accept.
-struct SessionError : WriteError {
-};
-
-// Bundles a Transport and ChannelMap together. ChannelMap is used to
-// create transport channels before receiving or sending a session
-// initiate, and for speculatively connecting channels.  Previously, a
-// session had one ChannelMap and transport.  Now, with multiple
-// transports per session, we need multiple ChannelMaps as well.
-
-typedef std::map<std::string, TransportChannelProxy*> ChannelMap;
-
-class TransportProxy {
- public:
-  TransportProxy(const std::string& content_name, Transport* transport)
-      : content_name_(content_name),
-        transport_(transport),
-        owner_(true),
-        state_(STATE_INIT),
-        sent_candidates_(false) {}
-  ~TransportProxy();
-
-  std::string content_name() const { return content_name_; }
-  Transport* impl() const { return transport_; }
-  // TransportProxy can contain a pointer to Transport for which it's not the
-  // actual owner. In that case it shouldn't try to delete Transport object.
-  // TODO - Remove this hack when ref count support is available.
-  void SetImplementation(Transport* impl, bool owner);
-  std::string type() const;
-  bool negotiated() const { return state_ == STATE_NEGOTIATED; }
-  const Candidates& sent_candidates() const { return sent_candidates_; }
-  const Candidates& unsent_candidates() const { return unsent_candidates_; }
-
-  TransportChannel* GetChannel(const std::string& name);
-  TransportChannel* CreateChannel(const std::string& name,
-                                  const std::string& content_type);
-  void DestroyChannel(const std::string& name);
-  void AddSentCandidates(const Candidates& candidates);
-  void AddUnsentCandidates(const Candidates& candidates);
-  void ClearSentCandidates() { sent_candidates_.clear(); }
-  void ClearUnsentCandidates() { unsent_candidates_.clear(); }
-  void SpeculativelyConnectChannels();
-  void CompleteNegotiation();
-  void CopyTransportProxyChannels(TransportProxy* proxy);
-  const ChannelMap& channels() { return channels_; }
-
- private:
-  enum TransportState {
-    STATE_INIT,
-    STATE_CONNECTING,
-    STATE_NEGOTIATED
-  };
-
-  TransportChannelProxy* GetProxy(const std::string& name);
-  void ReplaceImpl(TransportChannelProxy* channel_proxy, size_t index);
-  TransportChannelImpl* GetOrCreateImpl(const std::string& name,
-                                        const std::string& content_type);
-  void SetProxyImpl(const std::string& name, TransportChannelProxy* proxy);
-
-  std::string content_name_;
-  Transport* transport_;
-  bool owner_;
-  TransportState state_;
-  ChannelMap channels_;
-  Candidates sent_candidates_;
-  Candidates unsent_candidates_;
-};
-
-typedef std::map<std::string, TransportProxy*> TransportMap;
-
-// A BaseSession manages general session state. This includes negotiation
-// of both the application-level and network-level protocols:  the former
-// defines what will be sent and the latter defines how it will be sent.  Each
-// network-level protocol is represented by a Transport object.  Each Transport
-// participates in the network-level negotiation.  The individual streams of
-// packets are represented by TransportChannels.  The application-level protocol
-// is represented by SessionDecription objects.
-class BaseSession : public sigslot::has_slots<>,
-                    public talk_base::MessageHandler {
- public:
-  enum State {
-    STATE_INIT = 0,
-    STATE_SENTINITIATE,       // sent initiate, waiting for Accept or Reject
-    STATE_RECEIVEDINITIATE,   // received an initiate. Call Accept or Reject
-    STATE_SENTACCEPT,         // sent accept. begin connecting transport
-    STATE_RECEIVEDACCEPT,     // received accept. begin connecting transport
-    STATE_SENTMODIFY,         // sent modify, waiting for Accept or Reject
-    STATE_RECEIVEDMODIFY,     // received modify, call Accept or Reject
-    STATE_SENTREJECT,         // sent reject after receiving initiate
-    STATE_RECEIVEDREJECT,     // received reject after sending initiate
-    STATE_SENTREDIRECT,       // sent direct after receiving initiate
-    STATE_SENTTERMINATE,      // sent terminate (any time / either side)
-    STATE_RECEIVEDTERMINATE,  // received terminate (any time / either side)
-    STATE_INPROGRESS,         // session accepted and in progress
-    STATE_DEINIT,             // session is being destroyed
-  };
-
-  enum Error {
-    ERROR_NONE = 0,      // no error
-    ERROR_TIME = 1,      // no response to signaling
-    ERROR_RESPONSE = 2,  // error during signaling
-    ERROR_NETWORK = 3,   // network error, could not allocate network resources
-    ERROR_CONTENT = 4,   // channel errors in SetLocalContent/SetRemoteContent
-  };
-
-  BaseSession(talk_base::Thread* signaling_thread,
-              talk_base::Thread* worker_thread,
-              PortAllocator* port_allocator,
-              const std::string& sid,
-              const std::string& content_type,
-              bool initiator);
-  virtual ~BaseSession();
-
-  talk_base::Thread* signaling_thread() { return signaling_thread_; }
-  talk_base::Thread* worker_thread() { return worker_thread_; }
-  PortAllocator* port_allocator() { return port_allocator_; }
-
-  // The ID of this session.
-  const std::string& id() const { return sid_; }
-
-  // Returns the XML namespace identifying the type of this session.
-  const std::string& content_type() const { return content_type_; }
-
-  // Returns the XML namespace identifying the transport used for this session.
-  const std::string& transport_type() const { return transport_type_; }
-
-  // Indicates whether we initiated this session.
-  bool initiator() const { return initiator_; }
-
-  // Returns the application-level description given by our client.
-  // If we are the recipient, this will be NULL until we send an accept.
-  const SessionDescription* local_description() const {
-    return local_description_;
-  }
-  // Returns the application-level description given by the other client.
-  // If we are the initiator, this will be NULL until we receive an accept.
-  const SessionDescription* remote_description() const {
-    return remote_description_;
-  }
-  SessionDescription* remote_description() {
-    return remote_description_;
-  }
-
-  // Takes ownership of SessionDescription*
-  bool set_local_description(const SessionDescription* sdesc) {
-    if (sdesc != local_description_) {
-      delete local_description_;
-      local_description_ = sdesc;
-    }
-    return true;
-  }
-
-  // Takes ownership of SessionDescription*
-  bool set_remote_description(SessionDescription* sdesc) {
-    if (sdesc != remote_description_) {
-      delete remote_description_;
-      remote_description_ = sdesc;
-    }
-    return true;
-  }
-
-  const SessionDescription* initiator_description() const {
-    if (initiator_) {
-      return local_description_;
-    } else {
-      return remote_description_;
-    }
-  }
-
-  void set_allow_local_ips(bool allow);
-
-  // Returns the current state of the session.  See the enum above for details.
-  // Each time the state changes, we will fire this signal.
-  State state() const { return state_; }
-  sigslot::signal2<BaseSession *, State> SignalState;
-
-  // Returns the last error in the session.  See the enum above for details.
-  // Each time the an error occurs, we will fire this signal.
-  Error error() const { return error_; }
-  sigslot::signal2<BaseSession *, Error> SignalError;
-
-  // Updates the state, signaling if necessary.
-  virtual void SetState(State state);
-
-  // Updates the error state, signaling if necessary.
-  virtual void SetError(Error error);
-
-  // Fired when the remote description is updated.
-  sigslot::signal1<BaseSession *> SignalRemoteDescriptionUpdate;
-
-  // Returns the transport that has been negotiated or NULL if
-  // negotiation is still in progress.
-  Transport* GetTransport(const std::string& content_name);
-
-  // Creates a new channel with the given names.  This method may be called
-  // immediately after creating the session.  However, the actual
-  // implementation may not be fixed until transport negotiation completes.
-  // This will usually be called from the worker thread, but that
-  // shouldn't be an issue since the main thread will be blocked in
-  // Send when doing so.
-  virtual TransportChannel* CreateChannel(const std::string& content_name,
-                                          const std::string& channel_name);
-
-  // Returns the channel with the given names.
-  virtual TransportChannel* GetChannel(const std::string& content_name,
-                                       const std::string& channel_name);
-
-  // Destroys the channel with the given names.
-  // This will usually be called from the worker thread, but that
-  // shouldn't be an issue since the main thread will be blocked in
-  // Send when doing so.
-  virtual void DestroyChannel(const std::string& content_name,
-                              const std::string& channel_name);
-
- protected:
-  const TransportMap& transport_proxies() const { return transports_; }
-  // Get a TransportProxy by content_name or transport. NULL if not found.
-  TransportProxy* GetTransportProxy(const std::string& content_name);
-  TransportProxy* GetTransportProxy(const Transport* transport);
-  TransportProxy* GetFirstTransportProxy();
-  // TransportProxy is owned by session.  Return proxy just for convenience.
-  TransportProxy* GetOrCreateTransportProxy(const std::string& content_name);
-  // Creates the actual transport object. Overridable for testing.
-  virtual Transport* CreateTransport();
-
-  void OnSignalingReady();
-  void SpeculativelyConnectAllTransportChannels();
-  // This method will mux transport channels by content_name.
-  // First content is used for muxing.
-  bool MaybeEnableMuxingSupport();
-
-  // Called when a transport requests signaling.
-  virtual void OnTransportRequestSignaling(Transport* transport) {
-  }
-
-  // Called when the first channel of a transport begins connecting.  We use
-  // this to start a timer, to make sure that the connection completes in a
-  // reasonable amount of time.
-  virtual void OnTransportConnecting(Transport* transport) {
-  }
-
-  // Called when a transport changes its writable state.  We track this to make
-  // sure that the transport becomes writable within a reasonable amount of
-  // time.  If this does not occur, we signal an error.
-  virtual void OnTransportWritable(Transport* transport) {
-  }
-
-  // Called when a transport signals that it has new candidates.
-  virtual void OnTransportCandidatesReady(Transport* transport,
-                                          const Candidates& candidates) {
-  }
-
-  // Called when a transport signals that it found an error in an incoming
-  // message.
-  virtual void OnTransportSendError(Transport* transport,
-                                    const buzz::XmlElement* stanza,
-                                    const buzz::QName& name,
-                                    const std::string& type,
-                                    const std::string& text,
-                                    const buzz::XmlElement* extra_info) {
-  }
-
-  // Called when we notice that one of our local channels has no peer, so it
-  // should be destroyed.
-  virtual void OnTransportChannelGone(Transport* transport,
-                                      const std::string& name) {
-  }
-
-  // Handles messages posted to us.
-  virtual void OnMessage(talk_base::Message *pmsg);
-
- protected:
-  State state_;
-  Error error_;
-
- private:
-  // This method will check GroupInfo in local and remote SessionDescriptions.
-  bool ContentsGrouped();
-  // This method will delete the Transport and TransportChannelImpl's and
-  // replace those with the selected Transport objects. Selection is done
-  // based on the content_name and in this case first MediaContent information
-  // is used for mux.
-  void SetSelectedProxy(const std::string& content_name,
-                        const ContentGroup* muxed_group);
-
-  talk_base::Thread* signaling_thread_;
-  talk_base::Thread* worker_thread_;
-  PortAllocator* port_allocator_;
-  std::string sid_;
-  std::string content_type_;
-  std::string transport_type_;
-  bool initiator_;
-  const SessionDescription* local_description_;
-  SessionDescription* remote_description_;
-  // This is transport-specific but required so much by unit tests
-  // that it's much easier to put it here.
-  bool allow_local_ips_;
-  TransportMap transports_;
-};
-
-// A specific Session created by the SessionManager, using XMPP for protocol.
-class Session : public BaseSession {
- public:
-  // Returns the manager that created and owns this session.
-  SessionManager* session_manager() const { return session_manager_; }
-
-  // Returns the client that is handling the application data of this session.
-  SessionClient* client() const { return client_; }
-
-    // Returns the JID of this client.
-  const std::string& local_name() const { return local_name_; }
-
-  // Returns the JID of the other peer in this session.
-  const std::string& remote_name() const { return remote_name_; }
-
-  // Set the JID of the other peer in this session.
-  // Typically the remote_name_ is set when the session is initiated.
-  // However, sometimes (e.g when a proxy is used) the peer name is
-  // known after the BaseSession has been initiated and it must be updated
-  // explicitly.
-  void set_remote_name(const std::string& name) { remote_name_ = name; }
-
-  // Indicates the JID of the entity who initiated this session.
-  // In special cases, may be different than both local_name and remote_name.
-  const std::string& initiator_name() const { return initiator_name_; }
-
-  SignalingProtocol current_protocol() const { return current_protocol_; }
-
-  void set_current_protocol(SignalingProtocol protocol) {
-    current_protocol_ = protocol;
-  }
-
-  // Updates the error state, signaling if necessary.
-  virtual void SetError(Error error);
-
-  // When the session needs to send signaling messages, it beings by requesting
-  // signaling.  The client should handle this by calling OnSignalingReady once
-  // it is ready to send the messages.
-  // (These are called only by SessionManager.)
-  sigslot::signal1<Session*> SignalRequestSignaling;
-  void OnSignalingReady() { BaseSession::OnSignalingReady(); }
-
-  // Invoked when we notice that there is no matching channel on our peer.
-  sigslot::signal2<Session*, const std::string&> SignalChannelGone;
-
-  // Takes ownership of session description.
-  // TODO: Add an error argument to pass back to the caller.
-  bool Initiate(const std::string& to,
-                const SessionDescription* sdesc);
-
-  // When we receive an initiate, we create a session in the
-  // RECEIVEDINITIATE state and respond by accepting or rejecting.
-  // Takes ownership of session description.
-  // TODO: Add an error argument to pass back to the caller.
-  bool Accept(const SessionDescription* sdesc);
-  bool Reject(const std::string& reason);
-  bool Terminate() {
-    return TerminateWithReason(STR_TERMINATE_SUCCESS);
-  }
-  bool TerminateWithReason(const std::string& reason);
-  // Fired whenever we receive a terminate message along with a reason
-  sigslot::signal2<Session*, const std::string&> SignalReceivedTerminateReason;
-
-  // The two clients in the session may also send one another
-  // arbitrary XML messages, which are called "info" messages. Sending
-  // takes ownership of the given elements.  The signal does not; the
-  // parent element will be deleted after the signal.
-  bool SendInfoMessage(const XmlElements& elems);
-  sigslot::signal2<Session*, const buzz::XmlElement*> SignalInfoMessage;
-
- private:
-  // Creates or destroys a session.  (These are called only SessionManager.)
-  Session(SessionManager *session_manager,
-          const std::string& local_name, const std::string& initiator_name,
-          const std::string& sid, const std::string& content_type,
-          SessionClient* client);
-  ~Session();
-  // For each transport info, create a transport proxy.  Can fail for
-  // incompatible transport types.
-  bool CreateTransportProxies(const TransportInfos& tinfos,
-                              SessionError* error);
-  bool OnRemoteCandidates(const TransportInfos& tinfos,
-                          ParseError* error);
-  // Returns a TransportInfo without candidates for each content name.
-  // Uses the transport_type_ of the session.
-  TransportInfos GetEmptyTransportInfos(const ContentInfos& contents) const;
-
-    // Maps passed to serialization functions.
-  TransportParserMap GetTransportParsers();
-  ContentParserMap GetContentParsers();
-
-  virtual void OnTransportRequestSignaling(Transport* transport);
-  virtual void OnTransportConnecting(Transport* transport);
-  virtual void OnTransportWritable(Transport* transport);
-  virtual void OnTransportCandidatesReady(Transport* transport,
-                                          const Candidates& candidates);
-  virtual void OnTransportSendError(Transport* transport,
-                                    const buzz::XmlElement* stanza,
-                                    const buzz::QName& name,
-                                    const std::string& type,
-                                    const std::string& text,
-                                    const buzz::XmlElement* extra_info);
-  virtual void OnTransportChannelGone(Transport* transport,
-                                      const std::string& name);
-
-  virtual void OnMessage(talk_base::Message *pmsg);
-
-  // Send various kinds of session messages.
-  bool SendInitiateMessage(const SessionDescription* sdesc,
-                           SessionError* error);
-  bool SendAcceptMessage(const SessionDescription* sdesc, SessionError* error);
-  bool SendRejectMessage(const std::string& reason, SessionError* error);
-  bool SendTerminateMessage(const std::string& reason, SessionError* error);
-  bool SendTransportInfoMessage(const TransportInfo& tinfo,
-                                SessionError* error);
-  bool SendTransportInfoMessage(const TransportProxy* transproxy,
-                                const Candidates& candidates,
-                                SessionError* error);
-
-  bool ResendAllTransportInfoMessages(SessionError* error);
-  bool SendAllUnsentTransportInfoMessages(SessionError* error);
-
-  // Both versions of SendMessage send a message of the given type to
-  // the other client.  Can pass either a set of elements or an
-  // "action", which must have a WriteSessionAction method to go along
-  // with it.  Sending with an action supports sending a "hybrid"
-  // message.  Sending with elements must be sent as Jingle or Gingle.
-
-  // When passing elems, must be either Jingle or Gingle protocol.
-  // Takes ownership of action_elems.
-  bool SendMessage(ActionType type, const XmlElements& action_elems,
-                   SessionError* error);
-  // When passing an action, may be Hybrid protocol.
-  template <typename Action>
-  bool SendMessage(ActionType type, const Action& action,
-                   SessionError* error);
-
-  // Helper methods to write the session message stanza.
-  template <typename Action>
-  bool WriteActionMessage(ActionType type, const Action& action,
-                          buzz::XmlElement* stanza, WriteError* error);
-  template <typename Action>
-  bool WriteActionMessage(SignalingProtocol protocol,
-                          ActionType type, const Action& action,
-                          buzz::XmlElement* stanza, WriteError* error);
-
-  // Sending messages in hybrid form requires being able to write them
-  // on a per-protocol basis with a common method signature, which all
-  // of these have.
-  bool WriteSessionAction(SignalingProtocol protocol,
-                          const SessionInitiate& init,
-                          XmlElements* elems, WriteError* error);
-  bool WriteSessionAction(SignalingProtocol protocol,
-                          const TransportInfo& tinfo,
-                          XmlElements* elems, WriteError* error);
-  bool WriteSessionAction(SignalingProtocol protocol,
-                          const SessionTerminate& term,
-                          XmlElements* elems, WriteError* error);
-
-  // Sends a message back to the other client indicating that we have received
-  // and accepted their message.
-  void SendAcknowledgementMessage(const buzz::XmlElement* stanza);
-
-  // Once signaling is ready, the session will use this signal to request the
-  // sending of each message.  When messages are received by the other client,
-  // they should be handed to OnIncomingMessage.
-  // (These are called only by SessionManager.)
-  sigslot::signal2<Session *, const buzz::XmlElement*> SignalOutgoingMessage;
-  void OnIncomingMessage(const SessionMessage& msg);
-
-  void OnIncomingResponse(const buzz::XmlElement* orig_stanza,
-                          const buzz::XmlElement* response_stanza,
-                          const SessionMessage& msg);
-  void OnInitiateAcked();
-  void OnFailedSend(const buzz::XmlElement* orig_stanza,
-                    const buzz::XmlElement* error_stanza);
-
-  // Invoked when an error is found in an incoming message.  This is translated
-  // into the appropriate XMPP response by SessionManager.
-  sigslot::signal6<BaseSession*,
-                   const buzz::XmlElement*,
-                   const buzz::QName&,
-                   const std::string&,
-                   const std::string&,
-                   const buzz::XmlElement*> SignalErrorMessage;
-
-  // Handlers for the various types of messages.  These functions may take
-  // pointers to the whole stanza or to just the session element.
-  bool OnInitiateMessage(const SessionMessage& msg, MessageError* error);
-  bool OnAcceptMessage(const SessionMessage& msg, MessageError* error);
-  bool OnRejectMessage(const SessionMessage& msg, MessageError* error);
-  bool OnInfoMessage(const SessionMessage& msg);
-  bool OnTerminateMessage(const SessionMessage& msg, MessageError* error);
-  bool OnTransportInfoMessage(const SessionMessage& msg, MessageError* error);
-  bool OnTransportAcceptMessage(const SessionMessage& msg, MessageError* error);
-  bool OnDescriptionInfoMessage(const SessionMessage& msg, MessageError* error);
-  bool OnRedirectError(const SessionRedirect& redirect, SessionError* error);
-
-  // Verifies that we are in the appropriate state to receive this message.
-  bool CheckState(State state, MessageError* error);
-
-  SessionManager* session_manager_;
-  bool initiate_acked_;
-  std::string local_name_;
-  std::string initiator_name_;
-  std::string remote_name_;
-  SessionClient* client_;
-  TransportParser* transport_parser_;
-  // Keeps track of what protocol we are speaking.
-  SignalingProtocol current_protocol_;
-
-  friend class SessionManager;  // For access to constructor, destructor,
-                                // and signaling related methods.
-};
-
-}  // namespace cricket
-
-#endif  // TALK_P2P_BASE_SESSION_H_
diff --git a/third_party/libjingle/source/talk/p2p/base/session_unittest.cc b/third_party/libjingle/source/talk/p2p/base/session_unittest.cc
deleted file mode 100644
index e663113..0000000
--- a/third_party/libjingle/source/talk/p2p/base/session_unittest.cc
+++ /dev/null
@@ -1,2222 +0,0 @@
-/*
- * libjingle
- * Copyright 2004 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <cstring>
-#include <sstream>
-#include <deque>
-#include <map>
-
-#include "talk/base/basicpacketsocketfactory.h"
-#include "talk/base/common.h"
-#include "talk/base/gunit.h"
-#include "talk/base/helpers.h"
-#include "talk/base/host.h"
-#include "talk/base/logging.h"
-#include "talk/base/natserver.h"
-#include "talk/base/natsocketfactory.h"
-#include "talk/base/stringencode.h"
-#include "talk/p2p/base/constants.h"
-#include "talk/p2p/base/parsing.h"
-#include "talk/p2p/base/portallocator.h"
-#include "talk/p2p/base/p2ptransport.h"
-#include "talk/p2p/base/relayport.h"
-#include "talk/p2p/base/relayserver.h"
-#include "talk/p2p/base/session.h"
-#include "talk/p2p/base/sessionclient.h"
-#include "talk/p2p/base/sessionmanager.h"
-#include "talk/p2p/base/stunport.h"
-#include "talk/p2p/base/stunserver.h"
-#include "talk/p2p/base/transportchannel.h"
-#include "talk/p2p/base/transportchannelproxy.h"
-#include "talk/p2p/base/udpport.h"
-#include "talk/xmpp/constants.h"
-
-using cricket::SignalingProtocol;
-using cricket::PROTOCOL_HYBRID;
-using cricket::PROTOCOL_JINGLE;
-using cricket::PROTOCOL_GINGLE;
-
-static const std::string kInitiator = "init@init.com";
-static const std::string kResponder = "resp@resp.com";
-// Expected from test random number generator.
-static const std::string kSessionId = "2154761789";
-// TODO: When we need to test more than one transport type,
-// allow this to be injected like the content types are.
-static const std::string kTransportType = "http://www.google.com/transport/p2p";
-
-// Controls how long we wait for a session to send messages that we
-// expect, in milliseconds.  We put it high to avoid flaky tests.
-static const int kEventTimeout = 5000;
-
-static const int kNumPorts = 2;
-static const int kPort0 = 28653;
-static const int kPortStep = 5;
-
-static const std::string kNotifyNick1 = "derekcheng_google.com^59422C27";
-static const std::string kNotifyNick2 = "someoneelses_google.com^7abd6a7a20";
-static const uint32 kNotifyAudioSsrc1 = 2625839801U;
-static const uint32 kNotifyAudioSsrc2 = 2529430427U;
-static const uint32 kNotifyVideoSsrc1 = 3;
-static const uint32 kNotifyVideoSsrc2 = 2;
-
-static const std::string kViewRequestNick = "param_google.com^16A3CDBE";
-static const uint32 kViewRequestSsrc = 4;
-static const int kViewRequestWidth = 320;
-static const int kViewRequestHeight = 200;
-static const int kViewRequestFrameRate = 15;
-
-int GetPort(int port_index) {
-  return kPort0 + (port_index * kPortStep);
-}
-
-std::string GetPortString(int port_index) {
-  return talk_base::ToString(GetPort(port_index));
-}
-
-// Only works for port_index < 10, which is fine for our purposes.
-std::string GetUsername(int port_index) {
-  return "username" + std::string(8, talk_base::ToString(port_index)[0]);
-}
-
-// Only works for port_index < 10, which is fine for our purposes.
-std::string GetPassword(int port_index) {
-  return "password" + std::string(8, talk_base::ToString(port_index)[0]);
-}
-
-std::string IqAck(const std::string& id,
-                  const std::string& from,
-                  const std::string& to) {
-  return "<cli:iq"
-      " to=\"" + to + "\""
-      " id=\"" + id + "\""
-      " type=\"result\""
-      " from=\"" + from + "\""
-      " xmlns:cli=\"jabber:client\""
-      "/>";
-}
-
-std::string IqSet(const std::string& id,
-                  const std::string& from,
-                  const std::string& to,
-                  const std::string& content) {
-  return "<cli:iq"
-      " to=\"" + to + "\""
-      " type=\"set\""
-      " from=\"" + from + "\""
-      " id=\"" + id + "\""
-      " xmlns:cli=\"jabber:client\""
-      ">"
-      + content +
-      "</cli:iq>";
-}
-
-std::string IqError(const std::string& id,
-                    const std::string& from,
-                    const std::string& to,
-                    const std::string& content) {
-  return "<cli:error"
-      " to=\"" + to + "\""
-      " type=\"error\""
-      " from=\"" + from + "\""
-      " id=\"" + id + "\""
-      " xmlns:cli=\"jabber:client\""
-      ">"
-      + content +
-      "</cli:error>";
-}
-
-std::string GingleSessionXml(const std::string& type,
-                             const std::string& content) {
-  return "<session"
-      " xmlns=\"http://www.google.com/session\""
-      " type=\"" + type + "\""
-      " id=\"" + kSessionId + "\""
-      " initiator=\"" + kInitiator + "\""
-      ">"
-      + content +
-      "</session>";
-}
-
-std::string GingleDescriptionXml(const std::string& content_type) {
-  return "<description"
-      " xmlns=\"" + content_type + "\""
-      "/>";
-}
-
-std::string P2pCandidateXml(const std::string& name, int port_index) {
-  return "<candidate"
-      " name=\"" + name + "\""
-      " address=\"127.0.0.1\""
-      " port=\"" + GetPortString(port_index) + "\""
-      " preference=\"1\""
-      " username=\"" + GetUsername(port_index) + "\""
-      " protocol=\"udp\""
-      " generation=\"0\""
-      " password=\"" + GetPassword(port_index) + "\""
-      " type=\"local\""
-      " network=\"network\""
-      "/>";
-}
-
-std::string JingleActionXml(const std::string& action,
-                            const std::string& content) {
-  return "<jingle"
-      " xmlns=\"urn:xmpp:jingle:1\""
-      " action=\"" + action + "\""
-      " sid=\"" + kSessionId + "\""
-      ">"
-      + content +
-      "</jingle>";
-}
-
-std::string JingleInitiateActionXml(const std::string& content) {
-  return "<jingle"
-      " xmlns=\"urn:xmpp:jingle:1\""
-      " action=\"session-initiate\""
-      " sid=\"" + kSessionId + "\""
-      " initiator=\"" + kInitiator + "\""
-      ">"
-      + content +
-      "</jingle>";
-}
-
-std::string JingleEmptyContentXml(const std::string& content_name,
-                                  const std::string& content_type,
-                                  const std::string& transport_type) {
-  return "<content"
-      " name=\"" + content_name + "\""
-      " creator=\"initiator\""
-      ">"
-      "<description"
-      " xmlns=\"" + content_type + "\""
-      "/>"
-      "<transport"
-      " xmlns=\"" + transport_type + "\""
-      "/>"
-      "</content>";
-}
-
-std::string JingleContentXml(const std::string& content_name,
-                             const std::string& content_type,
-                             const std::string& transport_type,
-                             const std::string& transport_main) {
-  std::string transport = transport_type.empty() ? "" :
-      "<transport"
-      " xmlns=\"" + transport_type + "\""
-      ">"
-      + transport_main +
-      "</transport>";
-
-  return"<content"
-      " name=\"" + content_name + "\""
-      " creator=\"initiator\""
-      ">"
-      "<description"
-      " xmlns=\"" + content_type + "\""
-      "/>"
-      + transport +
-      "</content>";
-}
-
-std::string JingleTransportContentXml(const std::string& content_name,
-                                      const std::string& transport_type,
-                                      const std::string& content) {
-  return "<content"
-      " name=\"" + content_name + "\""
-      " creator=\"initiator\""
-      ">"
-      "<transport"
-      " xmlns=\"" + transport_type + "\""
-      ">"
-      + content +
-      "</transport>"
-      "</content>";
-}
-
-std::string GingleInitiateXml(const std::string& content_type) {
-  return GingleSessionXml(
-      "initiate",
-      GingleDescriptionXml(content_type));
-}
-
-std::string JingleInitiateXml(const std::string& content_name_a,
-                              const std::string& content_type_a,
-                              const std::string& content_name_b,
-                              const std::string& content_type_b) {
-  if (content_name_b.empty()) {
-    return JingleInitiateActionXml(
-        JingleEmptyContentXml(
-            content_name_a, content_type_a, kTransportType));
-  } else {
-    return JingleInitiateActionXml(
-        JingleEmptyContentXml(
-            content_name_a, content_type_a, kTransportType) +
-        JingleEmptyContentXml(
-            content_name_b, content_type_b, kTransportType));
-  }
-}
-
-std::string GingleAcceptXml(const std::string& content_type) {
-  return GingleSessionXml(
-      "accept",
-      GingleDescriptionXml(content_type));
-}
-
-std::string JingleAcceptXml(const std::string& content_name_a,
-                            const std::string& content_type_a,
-                            const std::string& content_name_b,
-                            const std::string& content_type_b) {
-  if (content_name_b.empty()) {
-    return JingleActionXml(
-        "session-accept",
-        JingleEmptyContentXml(
-            content_name_a, content_type_a, kTransportType));
-  } else {
-    return JingleActionXml(
-        "session-accept",
-        JingleEmptyContentXml(
-            content_name_a, content_type_a, kTransportType) +
-        JingleEmptyContentXml(
-            content_name_b, content_type_b, kTransportType));
-  }
-}
-
-std::string Gingle2CandidatesXml(const std::string& channel_name,
-                                 int port_index0,
-                                 int port_index1) {
-  return GingleSessionXml(
-      "candidates",
-      P2pCandidateXml(channel_name, port_index0) +
-      P2pCandidateXml(channel_name, port_index1));
-}
-
-std::string Gingle4CandidatesXml(const std::string& channel_name_a,
-                                 int port_index0,
-                                 int port_index1,
-                                 const std::string& channel_name_b,
-                                 int port_index2,
-                                 int port_index3) {
-  return GingleSessionXml(
-      "candidates",
-      P2pCandidateXml(channel_name_a, port_index0) +
-      P2pCandidateXml(channel_name_a, port_index1) +
-      P2pCandidateXml(channel_name_b, port_index2) +
-      P2pCandidateXml(channel_name_b, port_index3));
-}
-
-std::string Jingle2TransportInfoXml(const std::string& content_name,
-                                    const std::string& channel_name,
-                                    int port_index0,
-                                    int port_index1) {
-  return JingleActionXml(
-      "transport-info",
-      JingleTransportContentXml(
-          content_name, kTransportType,
-          P2pCandidateXml(channel_name, port_index0) +
-          P2pCandidateXml(channel_name, port_index1)));
-}
-
-std::string Jingle4TransportInfoXml(const std::string& content_name,
-                                    const std::string& channel_name_a,
-                                    int port_index0,
-                                    int port_index1,
-                                    const std::string& channel_name_b,
-                                    int port_index2,
-                                    int port_index3) {
-  return JingleActionXml(
-      "transport-info",
-      JingleTransportContentXml(
-          content_name, kTransportType,
-          P2pCandidateXml(channel_name_a, port_index0) +
-          P2pCandidateXml(channel_name_a, port_index1) +
-          P2pCandidateXml(channel_name_b, port_index2) +
-          P2pCandidateXml(channel_name_b, port_index3)));
-}
-
-std::string JingleDescriptionInfoXml(const std::string& content_name,
-                                     const std::string& content_type) {
-  return JingleActionXml(
-      "description-info",
-      JingleContentXml(content_name, content_type, "", ""));
-}
-
-std::string GingleRejectXml(const std::string& reason) {
-  return GingleSessionXml(
-      "reject",
-      "<" + reason + "/>");
-}
-
-std::string JingleTerminateXml(const std::string& reason) {
-    return JingleActionXml(
-        "session-terminate",
-        "<reason><" + reason + "/></reason>");
-}
-
-std::string GingleTerminateXml(const std::string& reason) {
-  return GingleSessionXml(
-      "terminate",
-      "<" + reason + "/>");
-}
-
-std::string GingleRedirectXml(const std::string& intitiate,
-                              const std::string& target) {
-  return intitiate +
-    "<error code=\"302\" type=\"modify\">"
-    "<redirect xmlns=\"http://www.google.com/session\">"
-    "xmpp:" + target +
-    "</redirect>"
-    "</error>";
-}
-
-std::string JingleRedirectXml(const std::string& intitiate,
-                              const std::string& target) {
-  return intitiate +
-    "<error code=\"302\" type=\"modify\">"
-    "<redirect xmlns=\"urn:ietf:params:xml:ns:xmpp-stanzas\">"
-    "xmpp:" + target +
-    "</redirect>"
-    "</error>";
-}
-
-std::string InitiateXml(SignalingProtocol protocol,
-                        const std::string& gingle_content_type,
-                        const std::string& content_name_a,
-                        const std::string& content_type_a,
-                        const std::string& content_name_b,
-                        const std::string& content_type_b) {
-  switch (protocol) {
-    case PROTOCOL_JINGLE:
-      return JingleInitiateXml(content_name_a, content_type_a,
-                               content_name_b, content_type_b);
-    case PROTOCOL_GINGLE:
-      return GingleInitiateXml(gingle_content_type);
-    case PROTOCOL_HYBRID:
-      return JingleInitiateXml(content_name_a, content_type_a,
-                               content_name_b, content_type_b) +
-          GingleInitiateXml(gingle_content_type);
-  }
-  return "";
-}
-
-std::string InitiateXml(SignalingProtocol protocol,
-                        const std::string& content_name,
-                        const std::string& content_type) {
-  return InitiateXml(protocol,
-                     content_type,
-                     content_name, content_type,
-                     "", "");
-}
-
-std::string AcceptXml(SignalingProtocol protocol,
-                      const std::string& gingle_content_type,
-                      const std::string& content_name_a,
-                      const std::string& content_type_a,
-                      const std::string& content_name_b,
-                      const std::string& content_type_b) {
-  switch (protocol) {
-    case PROTOCOL_JINGLE:
-      return JingleAcceptXml(content_name_a, content_type_a,
-                             content_name_b, content_type_b);
-    case PROTOCOL_GINGLE:
-      return GingleAcceptXml(gingle_content_type);
-    case PROTOCOL_HYBRID:
-      return
-          JingleAcceptXml(content_name_a, content_type_a,
-                          content_name_b, content_type_b) +
-          GingleAcceptXml(gingle_content_type);
-  }
-  return "";
-}
-
-
-std::string AcceptXml(SignalingProtocol protocol,
-                      const std::string& content_name,
-                      const std::string& content_type) {
-  return AcceptXml(protocol,
-                   content_type,
-                   content_name, content_type,
-                   "", "");
-}
-
-std::string TransportInfo2Xml(SignalingProtocol protocol,
-                              const std::string& content_name,
-                              const std::string& channel_name,
-                              int port_index0,
-                              int port_index1) {
-  switch (protocol) {
-    case PROTOCOL_JINGLE:
-      return Jingle2TransportInfoXml(
-          content_name,
-          channel_name, port_index0, port_index1);
-    case PROTOCOL_GINGLE:
-      return Gingle2CandidatesXml(
-          channel_name, port_index0, port_index1);
-    case PROTOCOL_HYBRID:
-      return
-          Jingle2TransportInfoXml(
-              content_name,
-              channel_name, port_index0, port_index1) +
-          Gingle2CandidatesXml(
-              channel_name, port_index0, port_index1);
-  }
-  return "";
-}
-
-std::string TransportInfo4Xml(SignalingProtocol protocol,
-                              const std::string& content_name,
-                              const std::string& channel_name_a,
-                              int port_index0,
-                              int port_index1,
-                              const std::string& channel_name_b,
-                              int port_index2,
-                              int port_index3) {
-  switch (protocol) {
-    case PROTOCOL_JINGLE:
-      return Jingle4TransportInfoXml(
-          content_name,
-          channel_name_a, port_index0, port_index1,
-          channel_name_b, port_index2, port_index3);
-    case PROTOCOL_GINGLE:
-      return Gingle4CandidatesXml(
-          channel_name_a, port_index0, port_index1,
-          channel_name_b, port_index2, port_index3);
-    case PROTOCOL_HYBRID:
-      return
-          Jingle4TransportInfoXml(
-              content_name,
-              channel_name_a, port_index0, port_index1,
-              channel_name_b, port_index2, port_index3) +
-          Gingle4CandidatesXml(
-              channel_name_a, port_index0, port_index1,
-              channel_name_b, port_index2, port_index3);
-  }
-  return "";
-}
-
-std::string RejectXml(SignalingProtocol protocol,
-                      const std::string& reason) {
-  switch (protocol) {
-    case PROTOCOL_JINGLE:
-      return JingleTerminateXml(reason);
-    case PROTOCOL_GINGLE:
-      return GingleRejectXml(reason);
-    case PROTOCOL_HYBRID:
-      return JingleTerminateXml(reason) +
-          GingleRejectXml(reason);
-  }
-  return "";
-}
-
-std::string TerminateXml(SignalingProtocol protocol,
-                         const std::string& reason) {
-  switch (protocol) {
-    case PROTOCOL_JINGLE:
-      return JingleTerminateXml(reason);
-    case PROTOCOL_GINGLE:
-      return GingleTerminateXml(reason);
-    case PROTOCOL_HYBRID:
-      return JingleTerminateXml(reason) +
-          GingleTerminateXml(reason);
-  }
-  return "";
-}
-
-std::string RedirectXml(SignalingProtocol protocol,
-                        const std::string& initiate,
-                        const std::string& target) {
-  switch (protocol) {
-    case PROTOCOL_JINGLE:
-      return JingleRedirectXml(initiate, target);
-    case PROTOCOL_GINGLE:
-      return GingleRedirectXml(initiate, target);
-  }
-  return "";
-}
-
-// TODO: Break out and join with fakeportallocator.h
-class TestPortAllocatorSession : public cricket::PortAllocatorSession {
- public:
-  TestPortAllocatorSession(const std::string& name,
-                           const int port_offset)
-      : PortAllocatorSession(0),
-        name_(name),
-        port_offset_(port_offset),
-        ports_(kNumPorts),
-        address_("127.0.0.1", 0),
-        network_("network", "unittest", address_.ipaddr()),
-        socket_factory_(talk_base::Thread::Current()),
-        running_(false),
-        port_(28653) {
-  }
-
-  ~TestPortAllocatorSession() {
-    for (size_t i = 0; i < ports_.size(); i++)
-      delete ports_[i];
-  }
-
-  virtual void GetInitialPorts() {
-    for (int i = 0; i < kNumPorts; i++) {
-      int index = port_offset_ + i;
-      ports_[i] = cricket::UDPPort::Create(
-          talk_base::Thread::Current(), &socket_factory_,
-          &network_, address_.ipaddr(), GetPort(index), GetPort(index));
-      ports_[i]->set_username_fragment(GetUsername(index));
-      ports_[i]->set_password(GetPassword(index));
-      AddPort(ports_[i]);
-    }
-  }
-
-  virtual void StartGetAllPorts() { running_ = true; }
-  virtual void StopGetAllPorts() { running_ = false; }
-  virtual bool IsGettingAllPorts() { return running_; }
-
-  void AddPort(cricket::Port* port) {
-    port->set_name(name_);
-    port->set_preference(1.0);
-    port->set_generation(0);
-    port->SignalDestroyed.connect(
-        this, &TestPortAllocatorSession::OnPortDestroyed);
-    port->SignalAddressReady.connect(
-        this, &TestPortAllocatorSession::OnAddressReady);
-    port->PrepareAddress();
-    SignalPortReady(this, port);
-  }
-
-  void OnPortDestroyed(cricket::Port* port) {
-    for (size_t i = 0; i < ports_.size(); i++) {
-      if (ports_[i] == port)
-        ports_[i] = NULL;
-    }
-  }
-
-  void OnAddressReady(cricket::Port* port) {
-    SignalCandidatesReady(this, port->candidates());
-  }
-
- private:
-  std::string name_;
-  int port_offset_;
-  std::vector<cricket::Port*> ports_;
-  talk_base::SocketAddress address_;
-  talk_base::Network network_;
-  talk_base::BasicPacketSocketFactory socket_factory_;
-  bool running_;
-  int port_;
-};
-
-class TestPortAllocator : public cricket::PortAllocator {
- public:
-  TestPortAllocator() : port_offset_(0) {}
-
-  virtual cricket::PortAllocatorSession*
-  CreateSession(const std::string &name,
-                const std::string &content_type) {
-    port_offset_ += 2;
-    return new TestPortAllocatorSession(name, port_offset_ - 2);
-  }
-
-  int port_offset_;
-};
-
-class TestContentDescription : public cricket::ContentDescription {
- public:
-  explicit TestContentDescription(const std::string& gingle_content_type,
-                                  const std::string& content_type)
-      : gingle_content_type(gingle_content_type),
-        content_type(content_type) {
-  }
-
-  std::string gingle_content_type;
-  std::string content_type;
-};
-
-cricket::SessionDescription* NewTestSessionDescription(
-    const std::string gingle_content_type,
-    const std::string& content_name_a, const std::string& content_type_a,
-    const std::string& content_name_b, const std::string& content_type_b) {
-
-  cricket::SessionDescription* offer = new cricket::SessionDescription();
-  offer->AddContent(content_name_a, content_type_a,
-                    new TestContentDescription(gingle_content_type,
-                                               content_type_a));
-  if (content_name_a != content_name_b) {
-    offer->AddContent(content_name_b, content_type_b,
-                      new TestContentDescription(gingle_content_type,
-                                                 content_type_b));
-  }
-  return offer;
-}
-
-cricket::SessionDescription* NewTestSessionDescription(
-    const std::string& content_name, const std::string& content_type) {
-
-  cricket::SessionDescription* offer = new cricket::SessionDescription();
-  offer->AddContent(content_name, content_type,
-                    new TestContentDescription(content_type,
-                                               content_type));
-  return offer;
-}
-
-struct TestSessionClient: public cricket::SessionClient,
-                          public sigslot::has_slots<> {
- public:
-  TestSessionClient() {
-  }
-
-  ~TestSessionClient() {
-  }
-
-  virtual bool ParseContent(SignalingProtocol protocol,
-                            const buzz::XmlElement* elem,
-                            const cricket::ContentDescription** content,
-                            cricket::ParseError* error) {
-    std::string content_type;
-    std::string gingle_content_type;
-    if (protocol == PROTOCOL_GINGLE) {
-      gingle_content_type = elem->Name().Namespace();
-    } else {
-      content_type = elem->Name().Namespace();
-    }
-
-    *content = new TestContentDescription(gingle_content_type, content_type);
-    return true;
-  }
-
-  virtual bool WriteContent(SignalingProtocol protocol,
-                            const cricket::ContentDescription* untyped_content,
-                            buzz::XmlElement** elem,
-                            cricket::WriteError* error) {
-    const TestContentDescription* content =
-        static_cast<const TestContentDescription*>(untyped_content);
-    std::string content_type = (protocol == PROTOCOL_GINGLE ?
-                                content->gingle_content_type :
-                                content->content_type);
-     *elem = new buzz::XmlElement(
-        buzz::QName(content_type, "description"), true);
-    return true;
-  }
-
-  void OnSessionCreate(cricket::Session* session, bool initiate) {
-  }
-
-  void OnSessionDestroy(cricket::Session* session) {
-  }
-};
-
-struct ChannelHandler : sigslot::has_slots<> {
-  explicit ChannelHandler(cricket::TransportChannel* p)
-    : channel(p), last_readable(false), last_writable(false), data_count(0),
-      last_size(0) {
-    p->SignalReadableState.connect(this, &ChannelHandler::OnReadableState);
-    p->SignalWritableState.connect(this, &ChannelHandler::OnWritableState);
-    p->SignalReadPacket.connect(this, &ChannelHandler::OnReadPacket);
-  }
-
-  bool writable() const {
-    return last_writable && channel->writable();
-  }
-
-  bool readable() const {
-    return last_readable && channel->readable();
-  }
-
-  void OnReadableState(cricket::TransportChannel* p) {
-    EXPECT_EQ(channel, p);
-    last_readable = channel->readable();
-  }
-
-  void OnWritableState(cricket::TransportChannel* p) {
-    EXPECT_EQ(channel, p);
-    last_writable = channel->writable();
-  }
-
-  void OnReadPacket(cricket::TransportChannel* p, const char* buf,
-                    size_t size) {
-    EXPECT_EQ(channel, p);
-    EXPECT_LE(size, sizeof(last_data));
-    data_count += 1;
-    last_size = size;
-    std::memcpy(last_data, buf, size);
-  }
-
-  void Send(const char* data, size_t size) {
-    int result = channel->SendPacket(data, size);
-    EXPECT_EQ(static_cast<int>(size), result);
-  }
-
-  cricket::TransportChannel* channel;
-  bool last_readable, last_writable;
-  int data_count;
-  char last_data[4096];
-  size_t last_size;
-};
-
-void PrintStanza(const std::string& message,
-                 const buzz::XmlElement* stanza) {
-  printf("%s: %s\n", message.c_str(), stanza->Str().c_str());
-}
-
-class TestClient : public sigslot::has_slots<> {
- public:
-  TestClient(cricket::PortAllocator* port_allocator,
-             int* next_message_id,
-             const std::string& local_name,
-             SignalingProtocol start_protocol,
-             const std::string& content_type,
-             const std::string& content_name_a,
-             const std::string& channel_name_a,
-             const std::string& content_name_b,
-             const std::string& channel_name_b) {
-    Construct(port_allocator, next_message_id, local_name, start_protocol,
-              content_type, content_name_a, channel_name_a, std::string(""),
-              content_name_b, channel_name_b, std::string(""));
-  }
-
-  TestClient(cricket::PortAllocator* port_allocator,
-             int* next_message_id,
-             const std::string& local_name,
-             SignalingProtocol start_protocol,
-             const std::string& content_type,
-             const std::string& content_name_a,
-             const std::string& channel_name_a,
-             const std::string& channel_name_aa,
-             const std::string& content_name_b,
-             const std::string& channel_name_b,
-             const std::string& channel_name_bb) {
-    Construct(port_allocator, next_message_id, local_name, start_protocol,
-              content_type, content_name_a, channel_name_a, channel_name_aa,
-              content_name_b, channel_name_b, channel_name_bb);
-  }
-
-  ~TestClient() {
-    if (session) {
-      session_manager->DestroySession(session);
-      EXPECT_EQ(1U, session_destroyed_count);
-    }
-    delete session_manager;
-    delete client;
-  }
-
-  void Construct(cricket::PortAllocator* pa,
-                 int* message_id,
-                 const std::string& lname,
-                 SignalingProtocol protocol,
-                 const std::string& cont_type,
-                 const std::string& cont_name_a,
-                 const std::string& chan_name_a,
-                 const std::string& chan_name_aa,
-                 const std::string& cont_name_b,
-                 const std::string& chan_name_b,
-                 const std::string& chan_name_bb) {
-    port_allocator_ = pa;
-    next_message_id = message_id;
-    local_name = lname;
-    start_protocol = protocol;
-    content_type = cont_type;
-    content_name_a = cont_name_a;
-    channel_name_a = chan_name_a;
-    channel_name_aa = chan_name_aa;
-    content_name_b = cont_name_b;
-    channel_name_b = chan_name_b;
-    channel_name_bb = chan_name_bb;
-    session_created_count = 0;
-    session_destroyed_count = 0;
-    session_remote_description_update_count = 0;
-    last_expected_sent_stanza = NULL;
-    session = NULL;
-    last_session_state = cricket::BaseSession::STATE_INIT;
-    chan_a = NULL;
-    chan_b = NULL;
-    blow_up_on_error = true;
-    error_count = 0;
-    if (!chan_name_aa.empty() || !chan_name_bb.empty()) {
-      chan_aa = NULL;
-      chan_bb = NULL;
-    }
-
-    session_manager = new cricket::SessionManager(port_allocator_);
-    session_manager->SignalSessionCreate.connect(
-        this, &TestClient::OnSessionCreate);
-    session_manager->SignalSessionDestroy.connect(
-        this, &TestClient::OnSessionDestroy);
-    session_manager->SignalOutgoingMessage.connect(
-        this, &TestClient::OnOutgoingMessage);
-
-    client = new TestSessionClient();
-    session_manager->AddClient(content_type, client);
-    EXPECT_EQ(client, session_manager->GetClient(content_type));
-  }
-
-  uint32 sent_stanza_count() const {
-    return sent_stanzas.size();
-  }
-
-  const buzz::XmlElement* stanza() const {
-    return last_expected_sent_stanza;
-  }
-
-  cricket::BaseSession::State session_state() const {
-    EXPECT_EQ(last_session_state, session->state());
-    return session->state();
-  }
-
-  void SetSessionState(cricket::BaseSession::State state) {
-    session->SetState(state);
-    EXPECT_EQ_WAIT(last_session_state, session->state(), kEventTimeout);
-  }
-
-  void CreateSession() {
-    session_manager->CreateSession(local_name, content_type);
-  }
-
-  void DeliverStanza(const buzz::XmlElement* stanza) {
-    session_manager->OnIncomingMessage(stanza);
-  }
-
-  void DeliverStanza(const std::string& str) {
-    buzz::XmlElement* stanza = buzz::XmlElement::ForStr(str);
-    session_manager->OnIncomingMessage(stanza);
-    delete stanza;
-  }
-
-  void DeliverAckToLastStanza() {
-    const buzz::XmlElement* orig_stanza = stanza();
-    const buzz::XmlElement* response_stanza =
-        buzz::XmlElement::ForStr(IqAck(orig_stanza->Attr(buzz::QN_IQ), "", ""));
-    session_manager->OnIncomingResponse(orig_stanza, response_stanza);
-    delete response_stanza;
-  }
-
-  void ExpectSentStanza(const std::string& expected) {
-    EXPECT_TRUE(!sent_stanzas.empty()) <<
-        "Found no stanza when expected " << expected;
-
-    last_expected_sent_stanza = sent_stanzas.front();
-    sent_stanzas.pop_front();
-
-    std::string actual = last_expected_sent_stanza->Str();
-    EXPECT_EQ(expected, actual);
-  }
-
-  void SkipUnsentStanza() {
-    GetNextOutgoingMessageID();
-  }
-
-  bool HasTransport(const std::string& content_name) const {
-    ASSERT(session != NULL);
-    const cricket::Transport* transport = session->GetTransport(content_name);
-    return transport != NULL && (kTransportType == transport->type());
-  }
-
-  bool HasChannel(const std::string& content_name,
-                  const std::string& channel_name) const {
-    ASSERT(session != NULL);
-    const cricket::TransportChannel* channel =
-        session->GetChannel(content_name, channel_name);
-    return channel != NULL && (channel_name == channel->name());
-  }
-
-  cricket::TransportChannel* GetChannel(const std::string& content_name,
-                                        const std::string& channel_name) const {
-    ASSERT(session != NULL);
-    return session->GetChannel(content_name, channel_name);
-  }
-
-  void OnSessionCreate(cricket::Session* created_session, bool initiate) {
-    session_created_count += 1;
-
-    session = created_session;
-    session->set_current_protocol(start_protocol);
-    session->set_allow_local_ips(true);
-    session->SignalState.connect(this, &TestClient::OnSessionState);
-    session->SignalError.connect(this, &TestClient::OnSessionError);
-    session->SignalRemoteDescriptionUpdate.connect(
-        this, &TestClient::OnSessionRemoteDescriptionUpdate);
-
-    CreateChannels();
-  }
-
-  void OnSessionDestroy(cricket::Session *session) {
-    session_destroyed_count += 1;
-  }
-
-  void OnSessionState(cricket::BaseSession* session,
-                      cricket::BaseSession::State state) {
-    // EXPECT_EQ does not allow use of this, hence the tmp variable.
-    cricket::BaseSession* tmp = this->session;
-    EXPECT_EQ(tmp, session);
-    last_session_state = state;
-  }
-
-  void OnSessionError(cricket::BaseSession* session,
-                      cricket::BaseSession::Error error) {
-    // EXPECT_EQ does not allow use of this, hence the tmp variable.
-    cricket::BaseSession* tmp = this->session;
-    EXPECT_EQ(tmp, session);
-    if (blow_up_on_error) {
-      EXPECT_TRUE(false);
-    } else {
-      error_count++;
-    }
-  }
-
-  void OnSessionRemoteDescriptionUpdate(cricket::BaseSession* session) {
-    session_remote_description_update_count++;
-  }
-
-  void PrepareCandidates() {
-    session_manager->OnSignalingReady();
-  }
-
-  void OnOutgoingMessage(cricket::SessionManager* manager,
-                         const buzz::XmlElement* stanza) {
-    buzz::XmlElement* elem = new buzz::XmlElement(*stanza);
-    EXPECT_TRUE(elem->Name() == buzz::QN_IQ);
-    EXPECT_TRUE(elem->HasAttr(buzz::QN_TO));
-    EXPECT_FALSE(elem->HasAttr(buzz::QN_FROM));
-    EXPECT_TRUE(elem->HasAttr(buzz::QN_TYPE));
-    EXPECT_TRUE((elem->Attr(buzz::QN_TYPE) == "set") ||
-                (elem->Attr(buzz::QN_TYPE) == "result") ||
-                (elem->Attr(buzz::QN_TYPE) == "error"));
-
-    elem->SetAttr(buzz::QN_FROM, local_name);
-    if (elem->Attr(buzz::QN_TYPE) == "set") {
-      EXPECT_FALSE(elem->HasAttr(buzz::QN_ID));
-      elem->SetAttr(buzz::QN_ID, GetNextOutgoingMessageID());
-    }
-
-    // Uncommenting this is useful for debugging.
-    // PrintStanza("OutgoingMessage", elem);
-    sent_stanzas.push_back(elem);
-  }
-
-  std::string GetNextOutgoingMessageID() {
-    int message_id = (*next_message_id)++;
-    std::ostringstream ost;
-    ost << message_id;
-    return ost.str();
-  }
-
-  void CreateChannels() {
-    ASSERT(session != NULL);
-    chan_a = new ChannelHandler(
-        session->CreateChannel(content_name_a, channel_name_a));
-    chan_b = new ChannelHandler(
-        session->CreateChannel(content_name_b, channel_name_b));
-    if (!channel_name_aa.empty() && !channel_name_bb.empty()) {
-      chan_aa = new ChannelHandler(
-          session->CreateChannel(content_name_a, channel_name_aa));
-      chan_bb = new ChannelHandler(
-          session->CreateChannel(content_name_b, channel_name_bb));
-    }
-  }
-
-  int* next_message_id;
-  std::string local_name;
-  SignalingProtocol start_protocol;
-  std::string content_type;
-  std::string content_name_a;
-  std::string channel_name_a;
-  std::string channel_name_aa;
-  std::string content_name_b;
-  std::string channel_name_b;
-  std::string channel_name_bb;
-
-  uint32 session_created_count;
-  uint32 session_destroyed_count;
-  uint32 session_remote_description_update_count;
-  std::deque<buzz::XmlElement*> sent_stanzas;
-  buzz::XmlElement* last_expected_sent_stanza;
-
-  cricket::SessionManager* session_manager;
-  TestSessionClient* client;
-  cricket::PortAllocator* port_allocator_;
-  cricket::Session* session;
-  cricket::BaseSession::State last_session_state;
-  ChannelHandler* chan_a;
-  ChannelHandler* chan_aa;
-  ChannelHandler* chan_b;
-  ChannelHandler* chan_bb;
-  bool blow_up_on_error;
-  int error_count;
-};
-
-class SessionTest : public testing::Test {
- protected:
-  virtual void SetUp() {
-    // Seed needed for each test to satisfy expectations.
-    talk_base::SetRandomTestMode(true);
-  }
-
-  virtual void TearDown() {
-    talk_base::SetRandomTestMode(false);
-  }
-
-  // Tests sending data between two clients, over two channels.
-  void TestSendRecv(ChannelHandler* chan1a,
-                    ChannelHandler* chan1b,
-                    ChannelHandler* chan2a,
-                    ChannelHandler* chan2b) {
-    const char* dat1a = "spamspamspamspamspamspamspambakedbeansspam";
-    const char* dat2a = "mapssnaebdekabmapsmapsmapsmapsmapsmapsmaps";
-    const char* dat1b = "Lobster Thermidor a Crevette with a mornay sauce...";
-    const char* dat2b = "...ecuas yanrom a htiw etteverC a rodimrehT retsboL";
-
-    for (int i = 0; i < 20; i++) {
-      chan1a->Send(dat1a, strlen(dat1a));
-      chan1b->Send(dat1b, strlen(dat1b));
-      chan2a->Send(dat2a, strlen(dat2a));
-      chan2b->Send(dat2b, strlen(dat2b));
-
-      EXPECT_EQ_WAIT(i + 1, chan1a->data_count, kEventTimeout);
-      EXPECT_EQ_WAIT(i + 1, chan1b->data_count, kEventTimeout);
-      EXPECT_EQ_WAIT(i + 1, chan2a->data_count, kEventTimeout);
-      EXPECT_EQ_WAIT(i + 1, chan2b->data_count, kEventTimeout);
-
-      EXPECT_EQ(strlen(dat2a), chan1a->last_size);
-      EXPECT_EQ(strlen(dat2b), chan1b->last_size);
-      EXPECT_EQ(strlen(dat1a), chan2a->last_size);
-      EXPECT_EQ(strlen(dat1b), chan2b->last_size);
-
-      EXPECT_EQ(0, std::memcmp(chan1a->last_data, dat2a,
-                               strlen(dat2a)));
-      EXPECT_EQ(0, std::memcmp(chan1b->last_data, dat2b,
-                               strlen(dat2b)));
-      EXPECT_EQ(0, std::memcmp(chan2a->last_data, dat1a,
-                               strlen(dat1a)));
-      EXPECT_EQ(0, std::memcmp(chan2b->last_data, dat1b,
-                               strlen(dat1b)));
-    }
-  }
-
-  // Test an initiate from one client to another, each with
-  // independent initial protocols.  Checks for the correct initiates,
-  // candidates, and accept messages, and tests that working network
-  // channels are established.
-  void TestSession(SignalingProtocol initiator_protocol,
-                   SignalingProtocol responder_protocol,
-                   SignalingProtocol resulting_protocol,
-                   const std::string& gingle_content_type,
-                   const std::string& content_type,
-                   const std::string& content_name_a,
-                   const std::string& channel_name_a,
-                   const std::string& content_name_b,
-                   const std::string& channel_name_b,
-                   const std::string& initiate_xml,
-                   const std::string& transport_info_a_xml,
-                   const std::string& transport_info_b_xml,
-                   const std::string& transport_info_reply_a_xml,
-                   const std::string& transport_info_reply_b_xml,
-                   const std::string& accept_xml) {
-    talk_base::scoped_ptr<cricket::PortAllocator> allocator(
-        new TestPortAllocator());
-    int next_message_id = 0;
-
-    talk_base::scoped_ptr<TestClient> initiator(
-        new TestClient(allocator.get(), &next_message_id,
-                       kInitiator, initiator_protocol,
-                       content_type,
-                       content_name_a,  channel_name_a,
-                       content_name_b,  channel_name_b));
-    talk_base::scoped_ptr<TestClient> responder(
-        new TestClient(allocator.get(), &next_message_id,
-                       kResponder, responder_protocol,
-                       content_type,
-                       content_name_a,  channel_name_a,
-                       content_name_b,  channel_name_b));
-
-    // Create Session and check channels and state.
-    initiator->CreateSession();
-    EXPECT_EQ(1U, initiator->session_created_count);
-    EXPECT_EQ(kSessionId, initiator->session->id());
-    EXPECT_EQ(initiator->session->local_name(), kInitiator);
-    EXPECT_EQ(cricket::BaseSession::STATE_INIT,
-              initiator->session_state());
-
-    EXPECT_TRUE(initiator->HasTransport(content_name_a));
-    EXPECT_TRUE(initiator->HasChannel(content_name_a, channel_name_a));
-    EXPECT_TRUE(initiator->HasTransport(content_name_b));
-    EXPECT_TRUE(initiator->HasChannel(content_name_b, channel_name_b));
-
-    // Initiate and expect initiate message sent.
-    cricket::SessionDescription* offer = NewTestSessionDescription(
-        gingle_content_type,
-        content_name_a, content_type,
-        content_name_b, content_type);
-    EXPECT_TRUE(initiator->session->Initiate(kResponder, offer));
-    EXPECT_EQ(initiator->session->remote_name(), kResponder);
-    EXPECT_EQ(initiator->session->local_description(), offer);
-
-    EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout);
-    EXPECT_EQ(cricket::BaseSession::STATE_SENTINITIATE,
-              initiator->session_state());
-    initiator->ExpectSentStanza(
-        IqSet("0", kInitiator, kResponder, initiate_xml));
-
-    // Deliver the initiate. Expect ack and session created with
-    // transports.
-    responder->DeliverStanza(initiator->stanza());
-    responder->ExpectSentStanza(
-        IqAck("0", kResponder, kInitiator));
-    EXPECT_EQ(0U, responder->sent_stanza_count());
-
-    EXPECT_EQ(1U, responder->session_created_count);
-    EXPECT_EQ(kSessionId, responder->session->id());
-    EXPECT_EQ(responder->session->local_name(), kResponder);
-    EXPECT_EQ(responder->session->remote_name(), kInitiator);
-    EXPECT_EQ(cricket::BaseSession::STATE_RECEIVEDINITIATE,
-              responder->session_state());
-
-    EXPECT_TRUE(responder->HasTransport(content_name_a));
-    EXPECT_TRUE(responder->HasChannel(content_name_a, channel_name_a));
-    EXPECT_TRUE(responder->HasTransport(content_name_b));
-    EXPECT_TRUE(responder->HasChannel(content_name_b, channel_name_b));
-
-    // Expect transport-info message from initiator.
-    // But don't send candidates until initiate ack is received.
-    initiator->PrepareCandidates();
-    WAIT(initiator->sent_stanza_count() > 0, 100);
-    EXPECT_EQ(0U, initiator->sent_stanza_count());
-    initiator->DeliverAckToLastStanza();
-    EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout);
-    initiator->ExpectSentStanza(
-        IqSet("1", kInitiator, kResponder, transport_info_a_xml));
-
-    // Deliver transport-info and expect ack.
-    responder->DeliverStanza(initiator->stanza());
-    responder->ExpectSentStanza(
-        IqAck("1", kResponder, kInitiator));
-
-    if (!transport_info_b_xml.empty()) {
-      // Expect second transport-info message from initiator.
-      EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout);
-      initiator->ExpectSentStanza(
-          IqSet("2", kInitiator, kResponder, transport_info_b_xml));
-      EXPECT_EQ(0U, initiator->sent_stanza_count());
-
-      // Deliver second transport-info message and expect ack.
-      responder->DeliverStanza(initiator->stanza());
-      responder->ExpectSentStanza(
-          IqAck("2", kResponder, kInitiator));
-    } else {
-      EXPECT_EQ(0U, initiator->sent_stanza_count());
-      EXPECT_EQ(0U, responder->sent_stanza_count());
-      initiator->SkipUnsentStanza();
-    }
-
-    // Expect reply transport-info message from responder.
-    responder->PrepareCandidates();
-    EXPECT_TRUE_WAIT(responder->sent_stanza_count() > 0, kEventTimeout);
-    responder->ExpectSentStanza(
-        IqSet("3", kResponder, kInitiator, transport_info_reply_a_xml));
-
-    // Deliver reply transport-info and expect ack.
-    initiator->DeliverStanza(responder->stanza());
-    initiator->ExpectSentStanza(
-        IqAck("3", kInitiator, kResponder));
-
-    if (!transport_info_reply_b_xml.empty()) {
-      // Expect second reply transport-info message from responder.
-      EXPECT_TRUE_WAIT(responder->sent_stanza_count() > 0, kEventTimeout);
-      responder->ExpectSentStanza(
-          IqSet("4", kResponder, kInitiator, transport_info_reply_b_xml));
-      EXPECT_EQ(0U, responder->sent_stanza_count());
-
-      // Deliver second reply transport-info message and expect ack.
-      initiator->DeliverStanza(responder->stanza());
-      initiator->ExpectSentStanza(
-          IqAck("4", kInitiator, kResponder));
-      EXPECT_EQ(0U, initiator->sent_stanza_count());
-    } else {
-      EXPECT_EQ(0U, initiator->sent_stanza_count());
-      EXPECT_EQ(0U, responder->sent_stanza_count());
-      responder->SkipUnsentStanza();
-    }
-
-    // The channels should be able to become writable at this point.  This
-    // requires pinging, so it may take a little while.
-    EXPECT_TRUE_WAIT(initiator->chan_a->writable() &&
-                     initiator->chan_a->readable(), kEventTimeout);
-    EXPECT_TRUE_WAIT(initiator->chan_b->writable() &&
-                     initiator->chan_b->readable(), kEventTimeout);
-    EXPECT_TRUE_WAIT(responder->chan_a->writable() &&
-                     responder->chan_a->readable(), kEventTimeout);
-    EXPECT_TRUE_WAIT(responder->chan_b->writable() &&
-                     responder->chan_b->readable(), kEventTimeout);
-
-    // Accept the session and expect accept stanza.
-    cricket::SessionDescription* answer = NewTestSessionDescription(
-        gingle_content_type,
-        content_name_a, content_type,
-        content_name_b, content_type);
-    EXPECT_TRUE(responder->session->Accept(answer));
-    EXPECT_EQ(responder->session->local_description(), answer);
-
-    responder->ExpectSentStanza(
-        IqSet("5", kResponder, kInitiator, accept_xml));
-    EXPECT_EQ(0U, responder->sent_stanza_count());
-
-    // Deliver the accept message and expect an ack.
-    initiator->DeliverStanza(responder->stanza());
-    EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout);
-    initiator->ExpectSentStanza(
-        IqAck("5", kInitiator, kResponder));
-    EXPECT_EQ(0U, initiator->sent_stanza_count());
-
-    // Both sessions should be in progress and have functioning
-    // channels.
-    EXPECT_EQ(resulting_protocol, initiator->session->current_protocol());
-    EXPECT_EQ(resulting_protocol, responder->session->current_protocol());
-    EXPECT_EQ_WAIT(cricket::BaseSession::STATE_INPROGRESS,
-                   initiator->session_state(), kEventTimeout);
-    EXPECT_EQ_WAIT(cricket::BaseSession::STATE_INPROGRESS,
-                   responder->session_state(), kEventTimeout);
-    TestSendRecv(initiator->chan_a, initiator->chan_b,
-                 responder->chan_a, responder->chan_b);
-
-    if (resulting_protocol == PROTOCOL_JINGLE) {
-      // Deliver a description-info message to the initiator and check if the
-      // content description changes.
-      EXPECT_EQ(0U, initiator->session_remote_description_update_count);
-
-      const cricket::SessionDescription* old_session_desc =
-          initiator->session->remote_description();
-      const cricket::ContentInfo* old_content_a =
-          old_session_desc->GetContentByName(content_name_a);
-      const cricket::ContentDescription* old_content_desc_a =
-          old_content_a->description;
-      const cricket::ContentInfo* old_content_b =
-          old_session_desc->GetContentByName(content_name_b);
-      const cricket::ContentDescription* old_content_desc_b =
-          old_content_b->description;
-      EXPECT_TRUE(old_content_desc_a != NULL);
-      EXPECT_TRUE(old_content_desc_b != NULL);
-
-      LOG(LS_INFO) << "A " << old_content_a->name;
-      LOG(LS_INFO) << "B " << old_content_b->name;
-
-      std::string description_info_xml =
-          JingleDescriptionInfoXml(content_name_a, content_type);
-      initiator->DeliverStanza(
-          IqSet("6", kResponder, kInitiator, description_info_xml));
-      responder->SkipUnsentStanza();
-      EXPECT_EQ(1U, initiator->session_remote_description_update_count);
-
-      const cricket::SessionDescription* new_session_desc =
-          initiator->session->remote_description();
-      const cricket::ContentInfo* new_content_a =
-          new_session_desc->GetContentByName(content_name_a);
-      const cricket::ContentDescription* new_content_desc_a =
-          new_content_a->description;
-      const cricket::ContentInfo* new_content_b =
-          new_session_desc->GetContentByName(content_name_b);
-      const cricket::ContentDescription* new_content_desc_b =
-          new_content_b->description;
-      EXPECT_TRUE(new_content_desc_a != NULL);
-      EXPECT_TRUE(new_content_desc_b != NULL);
-      EXPECT_NE(old_content_desc_a, new_content_desc_a);
-
-      if (content_name_a != content_name_b) {
-        // If content_name_a != content_name_b, then b's content description
-        // should not have changed since the description-info message only
-        // contained an update for content_name_a.
-        EXPECT_EQ(old_content_desc_b, new_content_desc_b);
-      }
-
-      EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout);
-      initiator->ExpectSentStanza(
-          IqAck("6", kInitiator, kResponder));
-      EXPECT_EQ(0U, initiator->sent_stanza_count());
-    } else {
-      responder->SkipUnsentStanza();
-    }
-
-    initiator->session->Terminate();
-    initiator->ExpectSentStanza(
-        IqSet("7", kInitiator, kResponder,
-              TerminateXml(resulting_protocol,
-                           cricket::STR_TERMINATE_SUCCESS)));
-
-    responder->DeliverStanza(initiator->stanza());
-    responder->ExpectSentStanza(
-        IqAck("7", kResponder, kInitiator));
-    EXPECT_EQ(cricket::BaseSession::STATE_SENTTERMINATE,
-              initiator->session_state());
-    EXPECT_EQ(cricket::BaseSession::STATE_RECEIVEDTERMINATE,
-              responder->session_state());
-  }
-
-  // Test an initiate with other content, called "main".
-  void TestOtherContent(SignalingProtocol initiator_protocol,
-                        SignalingProtocol responder_protocol,
-                        SignalingProtocol resulting_protocol) {
-    std::string content_name = "main";
-    std::string content_type = "http://oink.splat/session";
-    std::string content_name_a = content_name;
-    std::string channel_name_a = "rtcp";
-    std::string content_name_b = content_name;
-    std::string channel_name_b = "rtp";
-    std::string initiate_xml = InitiateXml(
-        initiator_protocol,
-        content_name_a, content_type);
-    std::string transport_info_a_xml = TransportInfo4Xml(
-        initiator_protocol, content_name,
-        channel_name_a, 0, 1,
-        channel_name_b, 2, 3);
-    std::string transport_info_b_xml = "";
-    std::string transport_info_reply_a_xml = TransportInfo4Xml(
-        resulting_protocol, content_name,
-        channel_name_a, 4, 5,
-        channel_name_b, 6, 7);
-    std::string transport_info_reply_b_xml = "";
-    std::string accept_xml = AcceptXml(
-        resulting_protocol,
-        content_name_a, content_type);
-
-
-    TestSession(initiator_protocol, responder_protocol, resulting_protocol,
-                content_type,
-                content_type,
-                content_name_a, channel_name_a,
-                content_name_b, channel_name_b,
-                initiate_xml,
-                transport_info_a_xml, transport_info_b_xml,
-                transport_info_reply_a_xml, transport_info_reply_b_xml,
-                accept_xml);
-  }
-
-  // Test an initiate with audio content.
-  void TestAudioContent(SignalingProtocol initiator_protocol,
-                        SignalingProtocol responder_protocol,
-                        SignalingProtocol resulting_protocol) {
-    std::string gingle_content_type = cricket::NS_GINGLE_AUDIO;
-    std::string content_name = cricket::CN_AUDIO;
-    std::string content_type = cricket::NS_JINGLE_RTP;
-    std::string channel_name_a = "rtcp";
-    std::string channel_name_b = "rtp";
-    std::string initiate_xml = InitiateXml(
-        initiator_protocol,
-        gingle_content_type,
-        content_name, content_type,
-        "", "");
-    std::string transport_info_a_xml = TransportInfo4Xml(
-        initiator_protocol, content_name,
-        channel_name_a, 0, 1,
-        channel_name_b, 2, 3);
-    std::string transport_info_b_xml = "";
-    std::string transport_info_reply_a_xml = TransportInfo4Xml(
-        resulting_protocol, content_name,
-        channel_name_a, 4, 5,
-        channel_name_b, 6, 7);
-    std::string transport_info_reply_b_xml = "";
-    std::string accept_xml = AcceptXml(
-        resulting_protocol,
-        gingle_content_type,
-        content_name, content_type,
-        "", "");
-
-
-    TestSession(initiator_protocol, responder_protocol, resulting_protocol,
-                gingle_content_type,
-                content_type,
-                content_name, channel_name_a,
-                content_name, channel_name_b,
-                initiate_xml,
-                transport_info_a_xml, transport_info_b_xml,
-                transport_info_reply_a_xml, transport_info_reply_b_xml,
-                accept_xml);
-  }
-
-  // Since media content is "split" into two contents (audio and
-  // video), we need to treat it special.
-  void TestVideoContents(SignalingProtocol initiator_protocol,
-                         SignalingProtocol responder_protocol,
-                         SignalingProtocol resulting_protocol) {
-    std::string content_type = cricket::NS_JINGLE_RTP;
-    std::string gingle_content_type = cricket::NS_GINGLE_VIDEO;
-    std::string content_name_a = cricket::CN_AUDIO;
-    std::string channel_name_a = "rtcp";
-    std::string content_name_b = cricket::CN_VIDEO;
-    std::string channel_name_b = "video_rtp";
-
-    std::string initiate_xml = InitiateXml(
-        initiator_protocol,
-        gingle_content_type,
-        content_name_a, content_type,
-        content_name_b, content_type);
-    std::string transport_info_a_xml = TransportInfo2Xml(
-        initiator_protocol, content_name_a,
-        channel_name_a, 0, 1);
-    std::string transport_info_b_xml = TransportInfo2Xml(
-        initiator_protocol, content_name_b,
-        channel_name_b, 2, 3);
-    std::string transport_info_reply_a_xml = TransportInfo2Xml(
-        resulting_protocol, content_name_a,
-        channel_name_a, 4, 5);
-    std::string transport_info_reply_b_xml = TransportInfo2Xml(
-        resulting_protocol, content_name_b,
-        channel_name_b, 6, 7);
-    std::string accept_xml = AcceptXml(
-        resulting_protocol,
-        gingle_content_type,
-        content_name_a, content_type,
-        content_name_b, content_type);
-
-    TestSession(initiator_protocol, responder_protocol, resulting_protocol,
-                gingle_content_type,
-                content_type,
-                content_name_a, channel_name_a,
-                content_name_b, channel_name_b,
-                initiate_xml,
-                transport_info_a_xml, transport_info_b_xml,
-                transport_info_reply_a_xml, transport_info_reply_b_xml,
-                accept_xml);
-  }
-
-  void TestBadRedirect(SignalingProtocol protocol) {
-    std::string content_name = "main";
-    std::string content_type = "http://oink.splat/session";
-    std::string channel_name_a = "chana";
-    std::string channel_name_b = "chanb";
-    std::string initiate_xml = InitiateXml(
-        protocol, content_name, content_type);
-    std::string transport_info_xml = TransportInfo4Xml(
-        protocol, content_name,
-        channel_name_a, 0, 1,
-        channel_name_b, 2, 3);
-    std::string transport_info_reply_xml = TransportInfo4Xml(
-        protocol, content_name,
-        channel_name_a, 4, 5,
-        channel_name_b, 6, 7);
-    std::string accept_xml = AcceptXml(
-        protocol, content_name, content_type);
-    std::string responder_full = kResponder + "/full";
-
-    talk_base::scoped_ptr<cricket::PortAllocator> allocator(
-        new TestPortAllocator());
-    int next_message_id = 0;
-
-    talk_base::scoped_ptr<TestClient> initiator(
-        new TestClient(allocator.get(), &next_message_id,
-                       kInitiator, protocol,
-                       content_type,
-                       content_name, channel_name_a,
-                       content_name, channel_name_b));
-
-    talk_base::scoped_ptr<TestClient> responder(
-        new TestClient(allocator.get(), &next_message_id,
-                       responder_full, protocol,
-                       content_type,
-                       content_name,  channel_name_a,
-                       content_name,  channel_name_b));
-
-    // Create Session and check channels and state.
-    initiator->CreateSession();
-    EXPECT_EQ(1U, initiator->session_created_count);
-    EXPECT_EQ(kSessionId, initiator->session->id());
-    EXPECT_EQ(initiator->session->local_name(), kInitiator);
-    EXPECT_EQ(cricket::BaseSession::STATE_INIT,
-              initiator->session_state());
-
-    EXPECT_TRUE(initiator->HasChannel(content_name, channel_name_a));
-    EXPECT_TRUE(initiator->HasChannel(content_name, channel_name_b));
-
-    // Initiate and expect initiate message sent.
-    cricket::SessionDescription* offer = NewTestSessionDescription(
-        content_name, content_type);
-    EXPECT_TRUE(initiator->session->Initiate(kResponder, offer));
-    EXPECT_EQ(initiator->session->remote_name(), kResponder);
-    EXPECT_EQ(initiator->session->local_description(), offer);
-
-    EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout);
-    EXPECT_EQ(cricket::BaseSession::STATE_SENTINITIATE,
-              initiator->session_state());
-    initiator->ExpectSentStanza(
-        IqSet("0", kInitiator, kResponder, initiate_xml));
-
-    // Expect transport-info message from initiator.
-    initiator->DeliverAckToLastStanza();
-    initiator->PrepareCandidates();
-    EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout);
-    initiator->ExpectSentStanza(
-        IqSet("1", kInitiator, kResponder, transport_info_xml));
-
-    // Send an unauthorized redirect to the initiator and expect it be ignored.
-    initiator->blow_up_on_error = false;
-    const buzz::XmlElement* initiate_stanza = initiator->stanza();
-    talk_base::scoped_ptr<buzz::XmlElement> redirect_stanza(
-        buzz::XmlElement::ForStr(
-            IqError("ER", kResponder, kInitiator,
-                    RedirectXml(protocol, initiate_xml, "not@allowed.com"))));
-    initiator->session_manager->OnFailedSend(
-        initiate_stanza, redirect_stanza.get());
-    EXPECT_EQ(initiator->session->remote_name(), kResponder);
-    initiator->blow_up_on_error = true;
-    EXPECT_EQ(initiator->error_count, 1);
-  }
-
-  void TestGoodRedirect(SignalingProtocol protocol) {
-    std::string content_name = "main";
-    std::string content_type = "http://oink.splat/session";
-    std::string channel_name_a = "chana";
-    std::string channel_name_b = "chanb";
-    std::string initiate_xml = InitiateXml(
-        protocol, content_name, content_type);
-    std::string transport_info_xml = TransportInfo4Xml(
-        protocol, content_name,
-        channel_name_a, 0, 1,
-        channel_name_b, 2, 3);
-    std::string transport_info_reply_xml = TransportInfo4Xml(
-        protocol, content_name,
-        channel_name_a, 4, 5,
-        channel_name_b, 6, 7);
-    std::string accept_xml = AcceptXml(
-        protocol, content_name, content_type);
-    std::string responder_full = kResponder + "/full";
-
-    talk_base::scoped_ptr<cricket::PortAllocator> allocator(
-        new TestPortAllocator());
-    int next_message_id = 0;
-
-    talk_base::scoped_ptr<TestClient> initiator(
-        new TestClient(allocator.get(), &next_message_id,
-                       kInitiator, protocol,
-                       content_type,
-                       content_name, channel_name_a,
-                       content_name, channel_name_b));
-
-    talk_base::scoped_ptr<TestClient> responder(
-        new TestClient(allocator.get(), &next_message_id,
-                       responder_full, protocol,
-                       content_type,
-                       content_name,  channel_name_a,
-                       content_name,  channel_name_b));
-
-    // Create Session and check channels and state.
-    initiator->CreateSession();
-    EXPECT_EQ(1U, initiator->session_created_count);
-    EXPECT_EQ(kSessionId, initiator->session->id());
-    EXPECT_EQ(initiator->session->local_name(), kInitiator);
-    EXPECT_EQ(cricket::BaseSession::STATE_INIT,
-              initiator->session_state());
-
-    EXPECT_TRUE(initiator->HasChannel(content_name, channel_name_a));
-    EXPECT_TRUE(initiator->HasChannel(content_name, channel_name_b));
-
-    // Initiate and expect initiate message sent.
-    cricket::SessionDescription* offer = NewTestSessionDescription(
-        content_name, content_type);
-    EXPECT_TRUE(initiator->session->Initiate(kResponder, offer));
-    EXPECT_EQ(initiator->session->remote_name(), kResponder);
-    EXPECT_EQ(initiator->session->local_description(), offer);
-
-    EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout);
-    EXPECT_EQ(cricket::BaseSession::STATE_SENTINITIATE,
-              initiator->session_state());
-    initiator->ExpectSentStanza(
-        IqSet("0", kInitiator, kResponder, initiate_xml));
-
-    // Expect transport-info message from initiator.
-    initiator->DeliverAckToLastStanza();
-    initiator->PrepareCandidates();
-    EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout);
-    initiator->ExpectSentStanza(
-        IqSet("1", kInitiator, kResponder, transport_info_xml));
-
-    // Send a redirect to the initiator and expect all of the message
-    // to be resent.
-    const buzz::XmlElement* initiate_stanza = initiator->stanza();
-    talk_base::scoped_ptr<buzz::XmlElement> redirect_stanza(
-        buzz::XmlElement::ForStr(
-            IqError("ER2", kResponder, kInitiator,
-                    RedirectXml(protocol, initiate_xml, responder_full))));
-    initiator->session_manager->OnFailedSend(
-        initiate_stanza, redirect_stanza.get());
-    EXPECT_EQ(initiator->session->remote_name(), responder_full);
-
-    EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout);
-    initiator->ExpectSentStanza(
-        IqSet("2", kInitiator, responder_full, initiate_xml));
-    initiator->ExpectSentStanza(
-        IqSet("3", kInitiator, responder_full, transport_info_xml));
-
-    // Deliver the initiate. Expect ack and session created with
-    // transports.
-    responder->DeliverStanza(
-        IqSet("2", kInitiator, responder_full, initiate_xml));
-    responder->ExpectSentStanza(
-        IqAck("2", responder_full, kInitiator));
-    EXPECT_EQ(0U, responder->sent_stanza_count());
-
-    EXPECT_EQ(1U, responder->session_created_count);
-    EXPECT_EQ(kSessionId, responder->session->id());
-    EXPECT_EQ(responder->session->local_name(), responder_full);
-    EXPECT_EQ(responder->session->remote_name(), kInitiator);
-    EXPECT_EQ(cricket::BaseSession::STATE_RECEIVEDINITIATE,
-              responder->session_state());
-
-    EXPECT_TRUE(responder->HasChannel(content_name, channel_name_a));
-    EXPECT_TRUE(responder->HasChannel(content_name, channel_name_b));
-
-    // Deliver transport-info and expect ack.
-    responder->DeliverStanza(
-        IqSet("3", kInitiator, responder_full, transport_info_xml));
-    responder->ExpectSentStanza(
-        IqAck("3", responder_full, kInitiator));
-
-    // Expect reply transport-infos sent to new remote JID
-    responder->PrepareCandidates();
-    EXPECT_TRUE_WAIT(responder->sent_stanza_count() > 0, kEventTimeout);
-    responder->ExpectSentStanza(
-        IqSet("4", responder_full, kInitiator, transport_info_reply_xml));
-
-    initiator->DeliverStanza(responder->stanza());
-    initiator->ExpectSentStanza(
-        IqAck("4", kInitiator, responder_full));
-
-    // The channels should be able to become writable at this point.  This
-    // requires pinging, so it may take a little while.
-    EXPECT_TRUE_WAIT(initiator->chan_a->writable() &&
-                     initiator->chan_a->readable(), kEventTimeout);
-    EXPECT_TRUE_WAIT(initiator->chan_b->writable() &&
-                     initiator->chan_b->readable(), kEventTimeout);
-    EXPECT_TRUE_WAIT(responder->chan_a->writable() &&
-                     responder->chan_a->readable(), kEventTimeout);
-    EXPECT_TRUE_WAIT(responder->chan_b->writable() &&
-                     responder->chan_b->readable(), kEventTimeout);
-
-    // Accept the session and expect accept stanza.
-    cricket::SessionDescription* answer = NewTestSessionDescription(
-        content_name, content_type);
-    EXPECT_TRUE(responder->session->Accept(answer));
-    EXPECT_EQ(responder->session->local_description(), answer);
-
-    responder->ExpectSentStanza(
-        IqSet("5", responder_full, kInitiator, accept_xml));
-    EXPECT_EQ(0U, responder->sent_stanza_count());
-
-    // Deliver the accept message and expect an ack.
-    initiator->DeliverStanza(responder->stanza());
-    EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout);
-    initiator->ExpectSentStanza(
-        IqAck("5", kInitiator, responder_full));
-    EXPECT_EQ(0U, initiator->sent_stanza_count());
-
-    // Both sessions should be in progress and have functioning
-    // channels.
-    EXPECT_EQ_WAIT(cricket::BaseSession::STATE_INPROGRESS,
-                   initiator->session_state(), kEventTimeout);
-    EXPECT_EQ_WAIT(cricket::BaseSession::STATE_INPROGRESS,
-                   responder->session_state(), kEventTimeout);
-    TestSendRecv(initiator->chan_a, initiator->chan_b,
-                 responder->chan_a, responder->chan_b);
-  }
-
-  void TestCandidatesInInitiateAndAccept(const std::string& test_name) {
-    std::string content_name = "main";
-    std::string content_type = "http://oink.splat/session";
-    std::string channel_name_a = "rtcp";
-    std::string channel_name_b = "rtp";
-    cricket::SignalingProtocol protocol = PROTOCOL_JINGLE;
-
-    talk_base::scoped_ptr<cricket::PortAllocator> allocator(
-        new TestPortAllocator());
-    int next_message_id = 0;
-
-    talk_base::scoped_ptr<TestClient> initiator(
-        new TestClient(allocator.get(), &next_message_id,
-                       kInitiator, protocol,
-                       content_type,
-                       content_name,  channel_name_a,
-                       content_name,  channel_name_b));
-
-    talk_base::scoped_ptr<TestClient> responder(
-        new TestClient(allocator.get(), &next_message_id,
-                       kResponder, protocol,
-                       content_type,
-                       content_name,  channel_name_a,
-                       content_name,  channel_name_b));
-
-    // Create Session and check channels and state.
-    initiator->CreateSession();
-    EXPECT_TRUE(initiator->HasTransport(content_name));
-    EXPECT_TRUE(initiator->HasChannel(content_name, channel_name_a));
-    EXPECT_TRUE(initiator->HasTransport(content_name));
-    EXPECT_TRUE(initiator->HasChannel(content_name, channel_name_b));
-
-    // Initiate and expect initiate message sent.
-    cricket::SessionDescription* offer = NewTestSessionDescription(
-        content_name, content_type);
-    EXPECT_TRUE(initiator->session->Initiate(kResponder, offer));
-
-    EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout);
-    EXPECT_EQ(cricket::BaseSession::STATE_SENTINITIATE,
-              initiator->session_state());
-    initiator->ExpectSentStanza(
-        IqSet("0", kInitiator, kResponder,
-              InitiateXml(protocol, content_name, content_type)));
-
-    // Fake the delivery the initiate and candidates together.
-    responder->DeliverStanza(
-        IqSet("A", kInitiator, kResponder,
-            JingleInitiateActionXml(
-                JingleContentXml(
-                    content_name, content_type, kTransportType,
-                    P2pCandidateXml(channel_name_a, 0) +
-                    P2pCandidateXml(channel_name_a, 1) +
-                    P2pCandidateXml(channel_name_b, 2) +
-                    P2pCandidateXml(channel_name_b, 3)))));
-    responder->ExpectSentStanza(
-        IqAck("A", kResponder, kInitiator));
-    EXPECT_EQ(0U, responder->sent_stanza_count());
-
-    EXPECT_EQ(1U, responder->session_created_count);
-    EXPECT_EQ(kSessionId, responder->session->id());
-    EXPECT_EQ(responder->session->local_name(), kResponder);
-    EXPECT_EQ(responder->session->remote_name(), kInitiator);
-    EXPECT_EQ(cricket::BaseSession::STATE_RECEIVEDINITIATE,
-              responder->session_state());
-
-    EXPECT_TRUE(responder->HasTransport(content_name));
-    EXPECT_TRUE(responder->HasChannel(content_name, channel_name_a));
-    EXPECT_TRUE(responder->HasTransport(content_name));
-    EXPECT_TRUE(responder->HasChannel(content_name, channel_name_b));
-
-    // Expect transport-info message from initiator.
-    // But don't send candidates until initiate ack is received.
-    initiator->DeliverAckToLastStanza();
-    initiator->PrepareCandidates();
-    EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout);
-    initiator->ExpectSentStanza(
-        IqSet("1", kInitiator, kResponder,
-              TransportInfo4Xml(protocol, content_name,
-                                channel_name_a, 0, 1,
-                                channel_name_b, 2, 3)));
-
-    responder->PrepareCandidates();
-    EXPECT_TRUE_WAIT(responder->sent_stanza_count() > 0, kEventTimeout);
-    responder->ExpectSentStanza(
-        IqSet("2", kResponder, kInitiator,
-              TransportInfo4Xml(protocol, content_name,
-                                channel_name_a, 4, 5,
-                                channel_name_b, 6, 7)));
-
-    // Accept the session and expect accept stanza.
-    cricket::SessionDescription* answer = NewTestSessionDescription(
-        content_name, content_type);
-    EXPECT_TRUE(responder->session->Accept(answer));
-
-    responder->ExpectSentStanza(
-        IqSet("3", kResponder, kInitiator,
-              AcceptXml(protocol, content_name, content_type)));
-    EXPECT_EQ(0U, responder->sent_stanza_count());
-
-    // Fake the delivery the accept and candidates together.
-    initiator->DeliverStanza(
-        IqSet("B", kResponder, kInitiator,
-            JingleActionXml("session-accept",
-                JingleContentXml(
-                    content_name, content_type, kTransportType,
-                    P2pCandidateXml(channel_name_a, 4) +
-                    P2pCandidateXml(channel_name_a, 5) +
-                    P2pCandidateXml(channel_name_b, 6) +
-                    P2pCandidateXml(channel_name_b, 7)))));
-    EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout);
-    initiator->ExpectSentStanza(
-        IqAck("B", kInitiator, kResponder));
-    EXPECT_EQ(0U, initiator->sent_stanza_count());
-
-    // The channels should be able to become writable at this point.  This
-    // requires pinging, so it may take a little while.
-    EXPECT_TRUE_WAIT(initiator->chan_a->writable() &&
-                     initiator->chan_a->readable(), kEventTimeout);
-    EXPECT_TRUE_WAIT(initiator->chan_b->writable() &&
-                     initiator->chan_b->readable(), kEventTimeout);
-    EXPECT_TRUE_WAIT(responder->chan_a->writable() &&
-                     responder->chan_a->readable(), kEventTimeout);
-    EXPECT_TRUE_WAIT(responder->chan_b->writable() &&
-                     responder->chan_b->readable(), kEventTimeout);
-
-
-    // Both sessions should be in progress and have functioning
-    // channels.
-    EXPECT_EQ(protocol, initiator->session->current_protocol());
-    EXPECT_EQ(protocol, responder->session->current_protocol());
-    EXPECT_EQ_WAIT(cricket::BaseSession::STATE_INPROGRESS,
-                   initiator->session_state(), kEventTimeout);
-    EXPECT_EQ_WAIT(cricket::BaseSession::STATE_INPROGRESS,
-                   responder->session_state(), kEventTimeout);
-    TestSendRecv(initiator->chan_a, initiator->chan_b,
-                 responder->chan_a, responder->chan_b);
-  }
-
-  // Tests that when an initiator terminates right after initiate,
-  // everything behaves correctly.
-  void TestEarlyTerminationFromInitiator(SignalingProtocol protocol) {
-    std::string content_name = "main";
-    std::string content_type = "http://oink.splat/session";
-
-    talk_base::scoped_ptr<cricket::PortAllocator> allocator(
-        new TestPortAllocator());
-    int next_message_id = 0;
-
-    talk_base::scoped_ptr<TestClient> initiator(
-        new TestClient(allocator.get(), &next_message_id,
-                       kInitiator, protocol,
-                       content_type,
-                       content_name, "a",
-                       content_name, "b"));
-
-    talk_base::scoped_ptr<TestClient> responder(
-        new TestClient(allocator.get(), &next_message_id,
-                       kResponder, protocol,
-                       content_type,
-                       content_name,  "a",
-                       content_name,  "b"));
-
-    // Send initiate
-    initiator->CreateSession();
-    EXPECT_TRUE(initiator->session->Initiate(
-        kResponder, NewTestSessionDescription(content_name, content_type)));
-    initiator->ExpectSentStanza(
-        IqSet("0", kInitiator, kResponder,
-              InitiateXml(protocol, content_name, content_type)));
-    EXPECT_EQ(cricket::BaseSession::STATE_SENTINITIATE,
-              initiator->session_state());
-
-    responder->DeliverStanza(initiator->stanza());
-    responder->ExpectSentStanza(
-        IqAck("0", kResponder, kInitiator));
-    EXPECT_EQ(cricket::BaseSession::STATE_RECEIVEDINITIATE,
-              responder->session_state());
-
-    initiator->session->TerminateWithReason(cricket::STR_TERMINATE_ERROR);
-    initiator->ExpectSentStanza(
-        IqSet("1", kInitiator, kResponder,
-              TerminateXml(protocol, cricket::STR_TERMINATE_ERROR)));
-    EXPECT_EQ(cricket::BaseSession::STATE_SENTTERMINATE,
-              initiator->session_state());
-
-    responder->DeliverStanza(initiator->stanza());
-    responder->ExpectSentStanza(
-        IqAck("1", kResponder, kInitiator));
-    EXPECT_EQ(cricket::BaseSession::STATE_RECEIVEDTERMINATE,
-              responder->session_state());
-  }
-
-  // Tests that when the responder rejects, everything behaves
-  // correctly.
-  void TestRejection(SignalingProtocol protocol) {
-    std::string content_name = "main";
-    std::string content_type = "http://oink.splat/session";
-
-    talk_base::scoped_ptr<cricket::PortAllocator> allocator(
-        new TestPortAllocator());
-    int next_message_id = 0;
-
-    talk_base::scoped_ptr<TestClient> initiator(
-        new TestClient(allocator.get(), &next_message_id,
-                       kInitiator, protocol,
-                       content_type,
-                       content_name, "a",
-                       content_name, "b"));
-
-    // Send initiate
-    initiator->CreateSession();
-    EXPECT_TRUE(initiator->session->Initiate(
-        kResponder, NewTestSessionDescription(content_name, content_type)));
-    initiator->ExpectSentStanza(
-        IqSet("0", kInitiator, kResponder,
-              InitiateXml(protocol, content_name, content_type)));
-    EXPECT_EQ(cricket::BaseSession::STATE_SENTINITIATE,
-              initiator->session_state());
-
-    initiator->DeliverStanza(
-        IqSet("1", kResponder, kInitiator,
-              RejectXml(protocol, cricket::STR_TERMINATE_ERROR)));
-    initiator->ExpectSentStanza(
-        IqAck("1", kInitiator, kResponder));
-    if (protocol == PROTOCOL_JINGLE) {
-      EXPECT_EQ(cricket::BaseSession::STATE_RECEIVEDTERMINATE,
-                initiator->session_state());
-    } else {
-      EXPECT_EQ(cricket::BaseSession::STATE_RECEIVEDREJECT,
-                initiator->session_state());
-    }
-  }
-
-  void TestTransportMux() {
-    std::string content_type = cricket::NS_JINGLE_RTP;
-    std::string gingle_content_type = cricket::NS_GINGLE_VIDEO;
-    std::string content_name_a = cricket::CN_AUDIO;
-    std::string channel_name_a = "rtp";
-    std::string channel_name_aa = "rtcp";
-    std::string content_name_b = cricket::CN_VIDEO;
-    std::string channel_name_b = "video_rtp";
-    std::string channel_name_bb = "video_rtcp";
-    cricket::SignalingProtocol protocol = PROTOCOL_JINGLE;
-
-    talk_base::scoped_ptr<cricket::PortAllocator> allocator(
-        new TestPortAllocator());
-    int next_message_id = 0;
-
-    talk_base::scoped_ptr<TestClient> initiator(
-        new TestClient(allocator.get(), &next_message_id,
-                       kInitiator, protocol,
-                       content_type,
-                       content_name_a, channel_name_a, channel_name_aa,
-                       content_name_b, channel_name_b, channel_name_bb));
-
-    // First creating the offer and answer session descriptions required for
-    // testing.
-    cricket::SessionDescription* offer = NewTestSessionDescription(
-        gingle_content_type,
-        content_name_a, content_type,
-        content_name_b, content_type);
-    // Add group information to the offer
-    cricket::ContentGroup group(cricket::GN_TOGETHER);
-    group.AddContentName(content_name_a);
-    group.AddContentName(content_name_b);
-    EXPECT_TRUE(group.HasContentName(content_name_a));
-    EXPECT_TRUE(group.HasContentName(content_name_b));
-    offer->AddGroup(group);
-
-    // Creating answer for the offer.
-    cricket::SessionDescription* answer = NewTestSessionDescription(
-        gingle_content_type,
-        content_name_a, content_type,
-        content_name_b, content_type);
-    // Check if group "TOGETHER" exists in the offer. If it's present then
-    // remote supports muxing.
-    EXPECT_TRUE(offer->HasGroup(cricket::GN_TOGETHER));
-    const cricket::ContentGroup* group_offer =
-        offer->GetGroupByName(cricket::GN_TOGETHER);
-    // Not creating new copy in answer, for test we can use this for test.
-    answer->AddGroup(*group_offer);
-    EXPECT_TRUE(answer->HasGroup(cricket::GN_TOGETHER));
-
-    initiator->CreateSession();
-    EXPECT_TRUE(initiator->session->Initiate(
-        kResponder, offer));
-
-    EXPECT_TRUE(initiator->HasTransport(content_name_a));
-    EXPECT_TRUE(initiator->HasChannel(content_name_a, channel_name_a));
-    EXPECT_TRUE(initiator->HasChannel(content_name_a, channel_name_aa));
-    EXPECT_TRUE(initiator->HasTransport(content_name_b));
-    EXPECT_TRUE(initiator->HasChannel(content_name_b, channel_name_b));
-    EXPECT_TRUE(initiator->HasChannel(content_name_b, channel_name_bb));
-    // This test will not create initiator and responder. Manually change
-    // session state and invoke methods.
-    initiator->PrepareCandidates();
-    EXPECT_EQ(cricket::BaseSession::STATE_SENTINITIATE,
-              initiator->session_state());
-    // Now apply answer to the session and move session state to
-    // STATE_RECEIVEDACCEPT
-    initiator->session->set_remote_description(answer);
-    initiator->session->SetState(cricket::BaseSession::STATE_RECEIVEDACCEPT);
-    cricket::TransportChannel* chan_a =
-        initiator->GetChannel(content_name_a, channel_name_a);
-    cricket::TransportChannel* chan_b =
-            initiator->GetChannel(content_name_b, channel_name_b);
-    // Since we know these are TransportChannelProxy, type cast it.
-    cricket::TransportChannelProxy* proxy_chan_a =
-        static_cast<cricket::TransportChannelProxy*>(chan_a);
-    cricket::TransportChannelProxy* proxy_chan_b =
-            static_cast<cricket::TransportChannelProxy*>(chan_b);
-    EXPECT_EQ(proxy_chan_a->impl(), proxy_chan_b->impl());
-    cricket::TransportChannel* chan_aa =
-            initiator->GetChannel(content_name_a, channel_name_aa);
-        cricket::TransportChannel* chan_bb =
-                initiator->GetChannel(content_name_b, channel_name_bb);
-    cricket::TransportChannelProxy* proxy_chan_aa =
-        static_cast<cricket::TransportChannelProxy*>(chan_aa);
-    cricket::TransportChannelProxy* proxy_chan_bb =
-            static_cast<cricket::TransportChannelProxy*>(chan_bb);
-    EXPECT_EQ(proxy_chan_aa->impl(), proxy_chan_bb->impl());
-    // TODO - Add test code to send data after mux is enabled.
-  }
-};
-
-// For each of these, "X => Y = Z" means "if a client with protocol X
-// initiates to a client with protocol Y, they end up speaking protocol Z.
-
-// Gingle => Gingle = Gingle (with other content)
-TEST_F(SessionTest, GingleToGingleOtherContent) {
-  TestOtherContent(PROTOCOL_GINGLE, PROTOCOL_GINGLE, PROTOCOL_GINGLE);
-}
-
-// Gingle => Gingle = Gingle (with audio content)
-TEST_F(SessionTest, GingleToGingleAudioContent) {
-  TestAudioContent(PROTOCOL_GINGLE, PROTOCOL_GINGLE, PROTOCOL_GINGLE);
-}
-
-// Gingle => Gingle = Gingle (with video contents)
-TEST_F(SessionTest, GingleToGingleVideoContents) {
-  TestVideoContents(PROTOCOL_GINGLE, PROTOCOL_GINGLE, PROTOCOL_GINGLE);
-}
-
-
-// Jingle => Jingle = Jingle (with other content)
-TEST_F(SessionTest, JingleToJingleOtherContent) {
-  TestOtherContent(PROTOCOL_JINGLE, PROTOCOL_JINGLE, PROTOCOL_JINGLE);
-}
-
-// Jingle => Jingle = Jingle (with audio content)
-TEST_F(SessionTest, JingleToJingleAudioContent) {
-  TestAudioContent(PROTOCOL_JINGLE, PROTOCOL_JINGLE, PROTOCOL_JINGLE);
-}
-
-// Jingle => Jingle = Jingle (with video contents)
-TEST_F(SessionTest, JingleToJingleVideoContents) {
-  TestVideoContents(PROTOCOL_JINGLE, PROTOCOL_JINGLE, PROTOCOL_JINGLE);
-}
-
-
-// Hybrid => Hybrid = Jingle (with other content)
-TEST_F(SessionTest, HybridToHybridOtherContent) {
-  TestOtherContent(PROTOCOL_HYBRID, PROTOCOL_HYBRID, PROTOCOL_JINGLE);
-}
-
-// Hybrid => Hybrid = Jingle (with audio content)
-TEST_F(SessionTest, HybridToHybridAudioContent) {
-  TestAudioContent(PROTOCOL_HYBRID, PROTOCOL_HYBRID, PROTOCOL_JINGLE);
-}
-
-// Hybrid => Hybrid = Jingle (with video contents)
-TEST_F(SessionTest, HybridToHybridVideoContents) {
-  TestVideoContents(PROTOCOL_HYBRID, PROTOCOL_HYBRID, PROTOCOL_JINGLE);
-}
-
-
-// Gingle => Hybrid = Gingle (with other content)
-TEST_F(SessionTest, GingleToHybridOtherContent) {
-  TestOtherContent(PROTOCOL_GINGLE, PROTOCOL_HYBRID, PROTOCOL_GINGLE);
-}
-
-// Gingle => Hybrid = Gingle (with audio content)
-TEST_F(SessionTest, GingleToHybridAudioContent) {
-  TestAudioContent(PROTOCOL_GINGLE, PROTOCOL_HYBRID, PROTOCOL_GINGLE);
-}
-
-// Gingle => Hybrid = Gingle (with video contents)
-TEST_F(SessionTest, GingleToHybridVideoContents) {
-  TestVideoContents(PROTOCOL_GINGLE, PROTOCOL_HYBRID, PROTOCOL_GINGLE);
-}
-
-
-// Jingle => Hybrid = Jingle (with other content)
-TEST_F(SessionTest, JingleToHybridOtherContent) {
-  TestOtherContent(PROTOCOL_JINGLE, PROTOCOL_HYBRID, PROTOCOL_JINGLE);
-}
-
-// Jingle => Hybrid = Jingle (with audio content)
-TEST_F(SessionTest, JingleToHybridAudioContent) {
-  TestAudioContent(PROTOCOL_JINGLE, PROTOCOL_HYBRID, PROTOCOL_JINGLE);
-}
-
-// Jingle => Hybrid = Jingle (with video contents)
-TEST_F(SessionTest, JingleToHybridVideoContents) {
-  TestVideoContents(PROTOCOL_JINGLE, PROTOCOL_HYBRID, PROTOCOL_JINGLE);
-}
-
-
-// Hybrid => Gingle = Gingle (with other content)
-TEST_F(SessionTest, HybridToGingleOtherContent) {
-  TestOtherContent(PROTOCOL_HYBRID, PROTOCOL_GINGLE, PROTOCOL_GINGLE);
-}
-
-// Hybrid => Gingle = Gingle (with audio content)
-TEST_F(SessionTest, HybridToGingleAudioContent) {
-  TestAudioContent(PROTOCOL_HYBRID, PROTOCOL_GINGLE, PROTOCOL_GINGLE);
-}
-
-// Hybrid => Gingle = Gingle (with video contents)
-TEST_F(SessionTest, HybridToGingleVideoContents) {
-  TestVideoContents(PROTOCOL_HYBRID, PROTOCOL_GINGLE, PROTOCOL_GINGLE);
-}
-
-
-// Hybrid => Jingle = Jingle (with other content)
-TEST_F(SessionTest, HybridToJingleOtherContent) {
-  TestOtherContent(PROTOCOL_HYBRID, PROTOCOL_JINGLE, PROTOCOL_JINGLE);
-}
-
-// Hybrid => Jingle = Jingle (with audio content)
-TEST_F(SessionTest, HybridToJingleAudioContent) {
-  TestAudioContent(PROTOCOL_HYBRID, PROTOCOL_JINGLE, PROTOCOL_JINGLE);
-}
-
-// Hybrid => Jingle = Jingle (with video contents)
-TEST_F(SessionTest, HybridToJingleVideoContents) {
-  TestVideoContents(PROTOCOL_HYBRID, PROTOCOL_JINGLE, PROTOCOL_JINGLE);
-}
-
-
-TEST_F(SessionTest, GingleEarlyTerminationFromInitiator) {
-  TestEarlyTerminationFromInitiator(PROTOCOL_GINGLE);
-}
-
-TEST_F(SessionTest, JingleEarlyTerminationFromInitiator) {
-  TestEarlyTerminationFromInitiator(PROTOCOL_JINGLE);
-}
-
-TEST_F(SessionTest, HybridEarlyTerminationFromInitiator) {
-  TestEarlyTerminationFromInitiator(PROTOCOL_HYBRID);
-}
-
-
-TEST_F(SessionTest, GingleRejection) {
-  TestRejection(PROTOCOL_GINGLE);
-}
-
-TEST_F(SessionTest, JingleRejection) {
-  TestRejection(PROTOCOL_JINGLE);
-}
-
-TEST_F(SessionTest, GingleGoodRedirect) {
-  TestGoodRedirect(PROTOCOL_GINGLE);
-}
-
-TEST_F(SessionTest, JingleGoodRedirect) {
-  TestGoodRedirect(PROTOCOL_JINGLE);
-}
-
-TEST_F(SessionTest, GingleBadRedirect) {
-  TestBadRedirect(PROTOCOL_GINGLE);
-}
-
-TEST_F(SessionTest, JingleBadRedirect) {
-  TestBadRedirect(PROTOCOL_JINGLE);
-}
-
-TEST_F(SessionTest, TestCandidatesInInitiateAndAccept) {
-  TestCandidatesInInitiateAndAccept("Candidates in initiate/accept");
-}
-
-TEST_F(SessionTest, TestTransportMux) {
-  TestTransportMux();
-}
diff --git a/third_party/libjingle/source/talk/p2p/base/sessionclient.h b/third_party/libjingle/source/talk/p2p/base/sessionclient.h
deleted file mode 100644
index d6604a9..0000000
--- a/third_party/libjingle/source/talk/p2p/base/sessionclient.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_P2P_BASE_SESSIONCLIENT_H_
-#define TALK_P2P_BASE_SESSIONCLIENT_H_
-
-namespace buzz {
-class XmlElement;
-}
-
-namespace cricket {
-
-struct ParseError;
-class Session;
-class SessionDescription;
-
-class ContentParser {
- public:
-  virtual bool ParseContent(SignalingProtocol protocol,
-                            const buzz::XmlElement* elem,
-                            const ContentDescription** content,
-                            ParseError* error) = 0;
-  virtual bool WriteContent(SignalingProtocol protocol,
-                            const ContentDescription* content,
-                            buzz::XmlElement** elem,
-                            WriteError* error) = 0;
-  virtual ~ContentParser() {}
-};
-
-// A SessionClient exists in 1-1 relation with each session.  The implementor
-// of this interface is the one that understands *what* the two sides are
-// trying to send to one another.  The lower-level layers only know how to send
-// data; they do not know what is being sent.
-class SessionClient : public ContentParser {
- public:
-  // Notifies the client of the creation / destruction of sessions of this type.
-  //
-  // IMPORTANT: The SessionClient, in its handling of OnSessionCreate, must
-  // create whatever channels are indicate in the description.  This is because
-  // the remote client may already be attempting to connect those channels. If
-  // we do not create our channel right away, then connection may fail or be
-  // delayed.
-  virtual void OnSessionCreate(Session* session, bool received_initiate) = 0;
-  virtual void OnSessionDestroy(Session* session) = 0;
-
-  virtual bool ParseContent(SignalingProtocol protocol,
-                            const buzz::XmlElement* elem,
-                            const ContentDescription** content,
-                            ParseError* error) = 0;
-  virtual bool WriteContent(SignalingProtocol protocol,
-                            const ContentDescription* content,
-                            buzz::XmlElement** elem,
-                            WriteError* error) = 0;
- protected:
-  // The SessionClient interface explicitly does not include destructor
-  virtual ~SessionClient() { }
-};
-
-}  // namespace cricket
-
-#endif  // TALK_P2P_BASE_SESSIONCLIENT_H_
diff --git a/third_party/libjingle/source/talk/p2p/base/sessiondescription.cc b/third_party/libjingle/source/talk/p2p/base/sessiondescription.cc
deleted file mode 100644
index add9236..0000000
--- a/third_party/libjingle/source/talk/p2p/base/sessiondescription.cc
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * libjingle
- * Copyright 2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/p2p/base/sessiondescription.h"
-
-#include "talk/xmllite/xmlelement.h"
-
-namespace cricket {
-
-const ContentInfo* FindContentInfoByName(
-    const ContentInfos& contents, const std::string& name) {
-  for (ContentInfos::const_iterator content = contents.begin();
-       content != contents.end(); content++) {
-    if (content->name == name) {
-      return &(*content);
-    }
-  }
-  return NULL;
-}
-
-const ContentInfo* FindContentInfoByType(
-    const ContentInfos& contents, const std::string& type) {
-  for (ContentInfos::const_iterator content = contents.begin();
-       content != contents.end(); content++) {
-    if (content->type == type) {
-      return &(*content);
-    }
-  }
-  return NULL;
-}
-
-void ContentGroup::AddContentName(const std::string& content_name) {
-  content_types_.insert(content_name);
-}
-
-bool ContentGroup::RemoveContentName(const std::string& content_name) {
-  bool ret = false;
-  std::set<std::string>::iterator iter;
-  iter = content_types_.find(content_name);
-  if (iter != content_types_.end()) {
-    content_types_.erase(iter);
-    ret = true;
-  }
-  return ret;
-}
-
-bool ContentGroup::HasContentName(const std::string& content_name) const {
-  return (content_types_.find(content_name) != content_types_.end());
-}
-
-const std::string* ContentGroup::FirstContentName() const {
-  return (content_types_.begin() != content_types_.end()) ?
-      &(*content_types_.begin()) : NULL;
-}
-const ContentInfo* SessionDescription::GetContentByName(
-    const std::string& name) const {
-  return FindContentInfoByName(contents_, name);
-}
-
-const ContentInfo* SessionDescription::FirstContentByType(
-    const std::string& type) const {
-  return FindContentInfoByType(contents_, type);
-}
-
-const ContentInfo* SessionDescription::FirstContent() const {
-  return (contents_.empty()) ? NULL : &(*contents_.begin());
-}
-
-void SessionDescription::AddContent(const std::string& name,
-                                    const std::string& type,
-                                    const ContentDescription* description) {
-  contents_.push_back(ContentInfo(name, type, description));
-}
-
-bool SessionDescription::RemoveContentByName(const std::string& name) {
-  for (ContentInfos::iterator content = contents_.begin();
-       content != contents_.end(); ++content) {
-    if (content->name == name) {
-      delete content->description;
-      contents_.erase(content);
-      return true;
-    }
-  }
-
-  return false;
-}
-
-void SessionDescription::RemoveGroupByName(const std::string& name) {
-  for (ContentGroups::iterator iter = groups_.begin();
-       iter != groups_.end(); ++iter) {
-    if (iter->semantics() == name) {
-      groups_.erase(iter);
-    }
-  }
-}
-
-bool SessionDescription::HasGroup(const std::string& name) const {
-  for (ContentGroups::const_iterator iter = groups_.begin();
-       iter != groups_.end(); ++iter) {
-    if (iter->semantics() == name) {
-      return true;
-    }
-  }
-  return false;
-}
-
-const ContentGroup* SessionDescription::GetGroupByName(
-    const std::string& name) const {
-  for (ContentGroups::const_iterator iter = groups_.begin();
-       iter != groups_.end(); ++iter) {
-    if (iter->semantics() == name) {
-      return &(*iter);
-    }
-  }
-  return NULL;
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/p2p/base/sessiondescription.h b/third_party/libjingle/source/talk/p2p/base/sessiondescription.h
deleted file mode 100644
index 153fe97..0000000
--- a/third_party/libjingle/source/talk/p2p/base/sessiondescription.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_P2P_BASE_SESSIONDESCRIPTION_H_
-#define TALK_P2P_BASE_SESSIONDESCRIPTION_H_
-
-#include <set>
-#include <string>
-#include <vector>
-
-namespace cricket {
-
-// Describes a session content. Individual content types inherit from
-// this class.  Analagous to a <jingle><content><description> or
-// <session><description>.
-class ContentDescription {
- public:
-  virtual ~ContentDescription() {}
-};
-
-// Analagous to a <jingle><content> or <session><description>.
-// name = name of <content name="...">
-// type = xmlns of <content>
-struct ContentInfo {
-  ContentInfo() : description(NULL) {}
-  ContentInfo(const std::string& name,
-              const std::string& type,
-              const ContentDescription* description) :
-      name(name), type(type), description(description) {}
-  std::string name;
-  std::string type;
-  const ContentDescription* description;
-};
-
-// This class provides a mechanism to aggregate different media contents into a
-// group. This group can also be shared with the peers in a pre-defined format.
-// GroupInfo should be populated only with the |content_name| of the
-// MediaDescription.
-class ContentGroup {
- public:
-  explicit ContentGroup(const std::string& semantics) :
-      semantics_(semantics) {}
-  void AddContentName(const std::string& content_name);
-  bool RemoveContentName(const std::string& content_name);
-  bool HasContentName(const std::string& content_name) const;
-  const std::string* FirstContentName() const;
-  const std::string& semantics() const { return semantics_; }
-
- private:
-  std::string semantics_;
-  std::set<std::string> content_types_;
-};
-
-typedef std::vector<ContentInfo> ContentInfos;
-typedef std::vector<ContentGroup> ContentGroups;
-
-const ContentInfo* FindContentInfoByName(
-    const ContentInfos& contents, const std::string& name);
-const ContentInfo* FindContentInfoByType(
-    const ContentInfos& contents, const std::string& type);
-
-// Describes a collection of contents, each with its own name and
-// type.  Analgous to a <jingle> or <session> stanza.  Assumes that
-// contents are unique be name, but doesn't enforce that.
-class SessionDescription {
- public:
-  SessionDescription() {}
-  explicit SessionDescription(const ContentInfos& contents) :
-      contents_(contents) {}
-  const ContentInfo* GetContentByName(const std::string& name) const;
-  const ContentInfo* FirstContentByType(const std::string& type) const;
-  const ContentInfo* FirstContent() const;
-  // Takes ownership of ContentDescription*.
-  void AddContent(const std::string& name,
-                  const std::string& type,
-                  const ContentDescription* description);
-  bool RemoveContentByName(const std::string& name);
-  const ContentInfos& contents() const { return contents_; }
-
-  ~SessionDescription() {
-    for (ContentInfos::iterator content = contents_.begin();
-         content != contents_.end(); content++) {
-      delete content->description;
-    }
-  }
-  bool HasGroup(const std::string& name) const;
-  void AddGroup(const ContentGroup& group) { groups_.push_back(group); }
-  void RemoveGroupByName(const std::string& name);
-  const ContentGroup* GetGroupByName(const std::string& name) const;
-
- private:
-  ContentInfos contents_;
-  ContentGroups groups_;
-};
-
-// Indicates whether a ContentDescription was an offer or an answer, as
-// described in http://www.ietf.org/rfc/rfc3264.txt. CA_UPDATE
-// indicates a jingle update message which contains a subset of a full
-// session description
-enum ContentAction {
-  CA_OFFER, CA_ANSWER, CA_UPDATE
-};
-
-// Indicates whether a ContentDescription was sent by the local client
-// or received from the remote client.
-enum ContentSource {
-  CS_LOCAL, CS_REMOTE
-};
-
-}  // namespace cricket
-
-#endif  // TALK_P2P_BASE_SESSIONDESCRIPTION_H_
diff --git a/third_party/libjingle/source/talk/p2p/base/sessionid.h b/third_party/libjingle/source/talk/p2p/base/sessionid.h
deleted file mode 100644
index 6942942..0000000
--- a/third_party/libjingle/source/talk/p2p/base/sessionid.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_P2P_BASE_SESSIONID_H_
-#define TALK_P2P_BASE_SESSIONID_H_
-
-// TODO: Remove this file.
-
-namespace cricket {
-
-}  // namespace cricket
-
-#endif  // TALK_P2P_BASE_SESSIONID_H_
diff --git a/third_party/libjingle/source/talk/p2p/base/sessionmanager.cc b/third_party/libjingle/source/talk/p2p/base/sessionmanager.cc
deleted file mode 100644
index 89912b5..0000000
--- a/third_party/libjingle/source/talk/p2p/base/sessionmanager.cc
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/p2p/base/sessionmanager.h"
-
-#include "talk/base/common.h"
-#include "talk/base/helpers.h"
-#include "talk/base/logging.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/base/stringencode.h"
-#include "talk/p2p/base/constants.h"
-#include "talk/p2p/base/session.h"
-#include "talk/p2p/base/sessionmessages.h"
-#include "talk/xmpp/constants.h"
-#include "talk/xmpp/jid.h"
-
-namespace cricket {
-
-SessionManager::SessionManager(PortAllocator *allocator,
-                               talk_base::Thread *worker) {
-  allocator_ = allocator;
-  signaling_thread_ = talk_base::Thread::Current();
-  if (worker == NULL) {
-    worker_thread_ = talk_base::Thread::Current();
-  } else {
-    worker_thread_ = worker;
-  }
-  timeout_ = 50;
-}
-
-SessionManager::~SessionManager() {
-  // Note: Session::Terminate occurs asynchronously, so it's too late to
-  // delete them now.  They better be all gone.
-  ASSERT(session_map_.empty());
-  // TerminateAll();
-  SignalDestroyed();
-}
-
-void SessionManager::AddClient(const std::string& content_type,
-                               SessionClient* client) {
-  ASSERT(client_map_.find(content_type) == client_map_.end());
-  client_map_[content_type] = client;
-}
-
-void SessionManager::RemoveClient(const std::string& content_type) {
-  ClientMap::iterator iter = client_map_.find(content_type);
-  ASSERT(iter != client_map_.end());
-  client_map_.erase(iter);
-}
-
-SessionClient* SessionManager::GetClient(const std::string& content_type) {
-  ClientMap::iterator iter = client_map_.find(content_type);
-  return (iter != client_map_.end()) ? iter->second : NULL;
-}
-
-Session* SessionManager::CreateSession(const std::string& local_name,
-                                       const std::string& content_type) {
-  return CreateSession(local_name, local_name,
-                       talk_base::ToString(talk_base::CreateRandomId()),
-                       content_type, false);
-}
-
-Session* SessionManager::CreateSession(
-    const std::string& local_name, const std::string& initiator_name,
-    const std::string& sid, const std::string& content_type,
-    bool received_initiate) {
-  SessionClient* client = GetClient(content_type);
-  ASSERT(client != NULL);
-
-  Session* session = new Session(this, local_name, initiator_name,
-                                 sid, content_type, client);
-  session_map_[session->id()] = session;
-  session->SignalRequestSignaling.connect(
-      this, &SessionManager::OnRequestSignaling);
-  session->SignalOutgoingMessage.connect(
-      this, &SessionManager::OnOutgoingMessage);
-  session->SignalErrorMessage.connect(this, &SessionManager::OnErrorMessage);
-  SignalSessionCreate(session, received_initiate);
-  session->client()->OnSessionCreate(session, received_initiate);
-  return session;
-}
-
-void SessionManager::DestroySession(Session* session) {
-  if (session != NULL) {
-    SessionMap::iterator it = session_map_.find(session->id());
-    if (it != session_map_.end()) {
-      SignalSessionDestroy(session);
-      session->client()->OnSessionDestroy(session);
-      session_map_.erase(it);
-      delete session;
-    }
-  }
-}
-
-Session* SessionManager::GetSession(const std::string& sid) {
-  SessionMap::iterator it = session_map_.find(sid);
-  if (it != session_map_.end())
-    return it->second;
-  return NULL;
-}
-
-void SessionManager::TerminateAll() {
-  while (session_map_.begin() != session_map_.end()) {
-    Session* session = session_map_.begin()->second;
-    session->Terminate();
-  }
-}
-
-bool SessionManager::IsSessionMessage(const buzz::XmlElement* stanza) {
-  return cricket::IsSessionMessage(stanza);
-}
-
-Session* SessionManager::FindSession(const std::string& sid,
-                                     const std::string& remote_name) {
-  SessionMap::iterator iter = session_map_.find(sid);
-  if (iter == session_map_.end())
-    return NULL;
-
-  Session* session = iter->second;
-  if (buzz::Jid(remote_name) != buzz::Jid(session->remote_name()))
-    return NULL;
-
-  return session;
-}
-
-void SessionManager::OnIncomingMessage(const buzz::XmlElement* stanza) {
-  SessionMessage msg;
-  ParseError error;
-
-  if (!ParseSessionMessage(stanza, &msg, &error)) {
-    SendErrorMessage(stanza, buzz::QN_STANZA_BAD_REQUEST, "modify",
-                     error.text, NULL);
-    return;
-  }
-
-  Session* session = FindSession(msg.sid, msg.from);
-  if (session) {
-    session->OnIncomingMessage(msg);
-    return;
-  }
-  if (msg.type != ACTION_SESSION_INITIATE) {
-    SendErrorMessage(stanza, buzz::QN_STANZA_BAD_REQUEST, "modify",
-                     "unknown session", NULL);
-    return;
-  }
-
-  std::string content_type;
-  if (!ParseContentType(msg.protocol, msg.action_elem,
-                        &content_type, &error)) {
-    SendErrorMessage(stanza, buzz::QN_STANZA_BAD_REQUEST, "modify",
-                     error.text, NULL);
-    return;
-  }
-
-  if (!GetClient(content_type)) {
-    SendErrorMessage(stanza, buzz::QN_STANZA_BAD_REQUEST, "modify",
-                     "unknown content type: " + content_type, NULL);
-    return;
-  }
-
-  session = CreateSession(msg.to, msg.initiator, msg.sid,
-                          content_type, true);
-  session->OnIncomingMessage(msg);
-}
-
-void SessionManager::OnIncomingResponse(const buzz::XmlElement* orig_stanza,
-    const buzz::XmlElement* response_stanza) {
-  if (orig_stanza == NULL || response_stanza == NULL) {
-    return;
-  }
-
-  SessionMessage msg;
-  ParseError error;
-  if (!ParseSessionMessage(orig_stanza, &msg, &error)) {
-    LOG(LS_WARNING) << "Error parsing incoming response: " << error.text
-                    << ":" << orig_stanza;
-    return;
-  }
-
-  Session* session = FindSession(msg.sid, msg.to);
-  if (session) {
-    session->OnIncomingResponse(orig_stanza, response_stanza, msg);
-  }
-}
-
-void SessionManager::OnFailedSend(const buzz::XmlElement* orig_stanza,
-                                  const buzz::XmlElement* error_stanza) {
-  SessionMessage msg;
-  ParseError error;
-  if (!ParseSessionMessage(orig_stanza, &msg, &error)) {
-    return;  // TODO: log somewhere?
-  }
-
-  Session* session = FindSession(msg.sid, msg.to);
-  if (session) {
-    talk_base::scoped_ptr<buzz::XmlElement> synthetic_error;
-    if (!error_stanza) {
-      // A failed send is semantically equivalent to an error response, so we
-      // can just turn the former into the latter.
-      synthetic_error.reset(
-        CreateErrorMessage(orig_stanza, buzz::QN_STANZA_ITEM_NOT_FOUND,
-                           "cancel", "Recipient did not respond", NULL));
-      error_stanza = synthetic_error.get();
-    }
-
-    session->OnFailedSend(orig_stanza, error_stanza);
-  }
-}
-
-void SessionManager::SendErrorMessage(const buzz::XmlElement* stanza,
-                                      const buzz::QName& name,
-                                      const std::string& type,
-                                      const std::string& text,
-                                      const buzz::XmlElement* extra_info) {
-  talk_base::scoped_ptr<buzz::XmlElement> msg(
-      CreateErrorMessage(stanza, name, type, text, extra_info));
-  SignalOutgoingMessage(this, msg.get());
-}
-
-buzz::XmlElement* SessionManager::CreateErrorMessage(
-    const buzz::XmlElement* stanza,
-    const buzz::QName& name,
-    const std::string& type,
-    const std::string& text,
-    const buzz::XmlElement* extra_info) {
-  buzz::XmlElement* iq = new buzz::XmlElement(buzz::QN_IQ);
-  iq->SetAttr(buzz::QN_TO, stanza->Attr(buzz::QN_FROM));
-  iq->SetAttr(buzz::QN_ID, stanza->Attr(buzz::QN_ID));
-  iq->SetAttr(buzz::QN_TYPE, "error");
-
-  CopyXmlChildren(stanza, iq);
-
-  buzz::XmlElement* error = new buzz::XmlElement(buzz::QN_ERROR);
-  error->SetAttr(buzz::QN_TYPE, type);
-  iq->AddElement(error);
-
-  // If the error name is not in the standard namespace, we have to first add
-  // some error from that namespace.
-  if (name.Namespace() != buzz::NS_STANZA) {
-     error->AddElement(
-         new buzz::XmlElement(buzz::QN_STANZA_UNDEFINED_CONDITION));
-  }
-  error->AddElement(new buzz::XmlElement(name));
-
-  if (extra_info)
-    error->AddElement(new buzz::XmlElement(*extra_info));
-
-  if (text.size() > 0) {
-    // It's okay to always use English here.  This text is for debugging
-    // purposes only.
-    buzz::XmlElement* text_elem = new buzz::XmlElement(buzz::QN_STANZA_TEXT);
-    text_elem->SetAttr(buzz::QN_XML_LANG, "en");
-    text_elem->SetBodyText(text);
-    error->AddElement(text_elem);
-  }
-
-  // TODO: Should we include error codes as well for SIP compatibility?
-
-  return iq;
-}
-
-void SessionManager::OnOutgoingMessage(Session* session,
-                                       const buzz::XmlElement* stanza) {
-  SignalOutgoingMessage(this, stanza);
-}
-
-void SessionManager::OnErrorMessage(BaseSession* session,
-                                    const buzz::XmlElement* stanza,
-                                    const buzz::QName& name,
-                                    const std::string& type,
-                                    const std::string& text,
-                                    const buzz::XmlElement* extra_info) {
-  SendErrorMessage(stanza, name, type, text, extra_info);
-}
-
-void SessionManager::OnSignalingReady() {
-  for (SessionMap::iterator it = session_map_.begin();
-      it != session_map_.end();
-      ++it) {
-    it->second->OnSignalingReady();
-  }
-}
-
-void SessionManager::OnRequestSignaling(Session* session) {
-  SignalRequestSignaling();
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/p2p/base/sessionmanager.h b/third_party/libjingle/source/talk/p2p/base/sessionmanager.h
deleted file mode 100644
index ec14f72..0000000
--- a/third_party/libjingle/source/talk/p2p/base/sessionmanager.h
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_P2P_BASE_SESSIONMANAGER_H_
-#define TALK_P2P_BASE_SESSIONMANAGER_H_
-
-#include <map>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "talk/base/sigslot.h"
-#include "talk/base/thread.h"
-#include "talk/p2p/base/portallocator.h"
-
-namespace buzz {
-class QName;
-class XmlElement;
-}
-
-namespace cricket {
-
-class Session;
-class BaseSession;
-class SessionClient;
-
-// SessionManager manages session instances
-
-class SessionManager : public sigslot::has_slots<> {
- public:
-  SessionManager(PortAllocator *allocator,
-                 talk_base::Thread *worker_thread = NULL);
-  virtual ~SessionManager();
-
-  PortAllocator *port_allocator() const { return allocator_; }
-  talk_base::Thread *worker_thread() const { return worker_thread_; }
-  talk_base::Thread *signaling_thread() const { return signaling_thread_; }
-
-  int session_timeout() const { return timeout_; }
-  void set_session_timeout(int timeout) { timeout_ = timeout; }
-
-  // Registers support for the given client.  If we receive an initiate
-  // describing a session of the given type, we will automatically create a
-  // Session object and notify this client.  The client may then accept or
-  // reject the session.
-  void AddClient(const std::string& content_type, SessionClient* client);
-  void RemoveClient(const std::string& content_type);
-  SessionClient* GetClient(const std::string& content_type);
-
-  // Creates a new session.  The given name is the JID of the client on whose
-  // behalf we initiate the session.
-  Session *CreateSession(const std::string& local_name,
-                         const std::string& content_type);
-
-  // Destroys the given session.
-  void DestroySession(Session *session);
-
-  // Returns the session with the given ID or NULL if none exists.
-  Session *GetSession(const std::string& sid);
-
-  // Terminates all of the sessions created by this manager.
-  void TerminateAll();
-
-  // These are signaled whenever the set of existing sessions changes.
-  sigslot::signal2<Session *, bool> SignalSessionCreate;
-  sigslot::signal1<Session *> SignalSessionDestroy;
-
-  // Determines whether the given stanza is intended for some session.
-  bool IsSessionMessage(const buzz::XmlElement* stanza);
-
-  // Given a sid, initiator, and remote_name, this finds the matching Session
-  Session* FindSession(const std::string& sid,
-                       const std::string& remote_name);
-
-  // Called when we receive a stanza for which IsSessionMessage is true.
-  void OnIncomingMessage(const buzz::XmlElement* stanza);
-
-  // Called when we get a response to a message that we sent.
-  void OnIncomingResponse(const buzz::XmlElement* orig_stanza,
-                          const buzz::XmlElement* response_stanza);
-
-  // Called if an attempted to send times out or an error is returned.  In the
-  // timeout case error_stanza will be NULL
-  void OnFailedSend(const buzz::XmlElement* orig_stanza,
-                    const buzz::XmlElement* error_stanza);
-
-  // Signalled each time a session generates a signaling message to send.
-  // Also signalled on errors, but with a NULL session.
-  sigslot::signal2<SessionManager*,
-                   const buzz::XmlElement*> SignalOutgoingMessage;
-
-  // Signaled before sessions try to send certain signaling messages.  The
-  // client should call OnSignalingReady once it is safe to send them.  These
-  // steps are taken so that we don't send signaling messages trying to
-  // re-establish the connectivity of a session when the client cannot send
-  // the messages (and would probably just drop them on the floor).
-  //
-  // Note: you can connect this directly to OnSignalingReady(), if a signalling
-  // check is not supported.
-  sigslot::signal0<> SignalRequestSignaling;
-  void OnSignalingReady();
-
-  // Signaled when this SessionManager is deleted.
-  sigslot::signal0<> SignalDestroyed;
-
- private:
-  typedef std::map<std::string, Session*> SessionMap;
-  typedef std::map<std::string, SessionClient*> ClientMap;
-
-  PortAllocator *allocator_;
-  talk_base::Thread *signaling_thread_;
-  talk_base::Thread *worker_thread_;
-  int timeout_;
-  SessionMap session_map_;
-  ClientMap client_map_;
-
-  // Helper function for CreateSession.  This is also invoked when we receive
-  // a message attempting to initiate a session with this client.
-  Session *CreateSession(const std::string& local_name,
-                         const std::string& initiator,
-                         const std::string& sid,
-                         const std::string& content_type,
-                         bool received_initiate);
-
-  // Attempts to find a registered session type whose description appears as
-  // a child of the session element.  Such a child should be present indicating
-  // the application they hope to initiate.
-  std::string FindClient(const buzz::XmlElement* session);
-
-  // Sends a message back to the other client indicating that we found an error
-  // in the stanza they sent.  name identifies the error, type is one of the
-  // standard XMPP types (cancel, continue, modify, auth, wait), and text is a
-  // description for debugging purposes.
-  void SendErrorMessage(const buzz::XmlElement* stanza,
-                        const buzz::QName& name,
-                        const std::string& type,
-                        const std::string& text,
-                        const buzz::XmlElement* extra_info);
-
-  // Creates and returns an error message from the given components.  The
-  // caller is responsible for deleting this.
-  buzz::XmlElement* CreateErrorMessage(
-      const buzz::XmlElement* stanza,
-      const buzz::QName& name,
-      const std::string& type,
-      const std::string& text,
-      const buzz::XmlElement* extra_info);
-
-  // Called each time a session requests signaling.
-  void OnRequestSignaling(Session* session);
-
-  // Called each time a session has an outgoing message.
-  void OnOutgoingMessage(Session* session, const buzz::XmlElement* stanza);
-
-  // Called each time a session has an error to send.
-  void OnErrorMessage(BaseSession* session,
-                      const buzz::XmlElement* stanza,
-                      const buzz::QName& name,
-                      const std::string& type,
-                      const std::string& text,
-                      const buzz::XmlElement* extra_info);
-};
-
-}  // namespace cricket
-
-#endif  // TALK_P2P_BASE_SESSIONMANAGER_H_
diff --git a/third_party/libjingle/source/talk/p2p/base/sessionmessages.cc b/third_party/libjingle/source/talk/p2p/base/sessionmessages.cc
deleted file mode 100644
index 96f91d1..0000000
--- a/third_party/libjingle/source/talk/p2p/base/sessionmessages.cc
+++ /dev/null
@@ -1,897 +0,0 @@
-/*
- * libjingle
- * Copyright 2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdio.h>
-#include <string>
-#include "talk/p2p/base/sessionmessages.h"
-
-#include "talk/base/logging.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/base/stringutils.h"
-#include "talk/p2p/base/constants.h"
-#include "talk/p2p/base/p2ptransport.h"
-#include "talk/p2p/base/parsing.h"
-#include "talk/p2p/base/sessionclient.h"
-#include "talk/p2p/base/sessiondescription.h"
-#include "talk/p2p/base/transport.h"
-#include "talk/xmllite/xmlconstants.h"
-#include "talk/xmpp/constants.h"
-
-namespace cricket {
-
-ActionType ToActionType(const std::string& type) {
-  if (type == GINGLE_ACTION_INITIATE)
-    return ACTION_SESSION_INITIATE;
-  if (type == GINGLE_ACTION_INFO)
-    return ACTION_SESSION_INFO;
-  if (type == GINGLE_ACTION_ACCEPT)
-    return ACTION_SESSION_ACCEPT;
-  if (type == GINGLE_ACTION_REJECT)
-    return ACTION_SESSION_REJECT;
-  if (type == GINGLE_ACTION_TERMINATE)
-    return ACTION_SESSION_TERMINATE;
-  if (type == GINGLE_ACTION_CANDIDATES)
-    return ACTION_TRANSPORT_INFO;
-  if (type == JINGLE_ACTION_SESSION_INITIATE)
-    return ACTION_SESSION_INITIATE;
-  if (type == JINGLE_ACTION_TRANSPORT_INFO)
-    return ACTION_TRANSPORT_INFO;
-  if (type == JINGLE_ACTION_TRANSPORT_ACCEPT)
-    return ACTION_TRANSPORT_ACCEPT;
-  if (type == JINGLE_ACTION_SESSION_INFO)
-    return ACTION_SESSION_INFO;
-  if (type == JINGLE_ACTION_SESSION_ACCEPT)
-    return ACTION_SESSION_ACCEPT;
-  if (type == JINGLE_ACTION_SESSION_TERMINATE)
-    return ACTION_SESSION_TERMINATE;
-  if (type == JINGLE_ACTION_TRANSPORT_INFO)
-    return ACTION_TRANSPORT_INFO;
-  if (type == JINGLE_ACTION_TRANSPORT_ACCEPT)
-    return ACTION_TRANSPORT_ACCEPT;
-  if (type == JINGLE_ACTION_DESCRIPTION_INFO)
-    return ACTION_DESCRIPTION_INFO;
-  if (type == GINGLE_ACTION_UPDATE)
-    return ACTION_DESCRIPTION_INFO;
-
-  return ACTION_UNKNOWN;
-}
-
-std::string ToJingleString(ActionType type) {
-  switch (type) {
-    case ACTION_SESSION_INITIATE:
-      return JINGLE_ACTION_SESSION_INITIATE;
-    case ACTION_SESSION_INFO:
-      return JINGLE_ACTION_SESSION_INFO;
-    case ACTION_SESSION_ACCEPT:
-      return JINGLE_ACTION_SESSION_ACCEPT;
-    // Notice that reject and terminate both go to
-    // "session-terminate", but there is no "session-reject".
-    case ACTION_SESSION_REJECT:
-    case ACTION_SESSION_TERMINATE:
-      return JINGLE_ACTION_SESSION_TERMINATE;
-    case ACTION_TRANSPORT_INFO:
-      return JINGLE_ACTION_TRANSPORT_INFO;
-    case ACTION_TRANSPORT_ACCEPT:
-      return JINGLE_ACTION_TRANSPORT_ACCEPT;
-    default:
-      return "";
-  }
-}
-
-std::string ToGingleString(ActionType type) {
-  switch (type) {
-    case ACTION_SESSION_INITIATE:
-      return GINGLE_ACTION_INITIATE;
-    case ACTION_SESSION_INFO:
-      return GINGLE_ACTION_INFO;
-    case ACTION_SESSION_ACCEPT:
-      return GINGLE_ACTION_ACCEPT;
-    case ACTION_SESSION_REJECT:
-      return GINGLE_ACTION_REJECT;
-    case ACTION_SESSION_TERMINATE:
-      return GINGLE_ACTION_TERMINATE;
-    case ACTION_TRANSPORT_INFO:
-      return GINGLE_ACTION_CANDIDATES;
-    default:
-      return "";
-  }
-}
-
-
-bool IsJingleMessage(const buzz::XmlElement* stanza) {
-  const buzz::XmlElement* jingle = stanza->FirstNamed(QN_JINGLE);
-  if (jingle == NULL)
-    return false;
-
-  return (jingle->HasAttr(buzz::QN_ACTION) && jingle->HasAttr(QN_SID));
-}
-
-bool IsGingleMessage(const buzz::XmlElement* stanza) {
-  const buzz::XmlElement* session = stanza->FirstNamed(QN_GINGLE_SESSION);
-  if (session == NULL)
-    return false;
-
-  return (session->HasAttr(buzz::QN_TYPE) &&
-          session->HasAttr(buzz::QN_ID)   &&
-          session->HasAttr(QN_INITIATOR));
-}
-
-bool IsSessionMessage(const buzz::XmlElement* stanza) {
-  return (stanza->Name() == buzz::QN_IQ &&
-          stanza->Attr(buzz::QN_TYPE) == buzz::STR_SET &&
-          (IsJingleMessage(stanza) ||
-           IsGingleMessage(stanza)));
-}
-
-bool ParseGingleSessionMessage(const buzz::XmlElement* session,
-                               SessionMessage* msg,
-                               ParseError* error) {
-  msg->protocol = PROTOCOL_GINGLE;
-  std::string type_string = session->Attr(buzz::QN_TYPE);
-  msg->type = ToActionType(type_string);
-  msg->sid = session->Attr(buzz::QN_ID);
-  msg->initiator = session->Attr(QN_INITIATOR);
-  msg->action_elem = session;
-
-  if (msg->type == ACTION_UNKNOWN)
-    return BadParse("unknown action: " + type_string, error);
-
-  return true;
-}
-
-bool ParseJingleSessionMessage(const buzz::XmlElement* jingle,
-                               SessionMessage* msg,
-                               ParseError* error) {
-  msg->protocol = PROTOCOL_JINGLE;
-  std::string type_string = jingle->Attr(buzz::QN_ACTION);
-  msg->type = ToActionType(type_string);
-  msg->sid = jingle->Attr(QN_SID);
-  msg->initiator = GetXmlAttr(jingle, QN_INITIATOR, buzz::STR_EMPTY);
-  msg->action_elem = jingle;
-
-  if (msg->type == ACTION_UNKNOWN)
-    return BadParse("unknown action: " + type_string, error);
-
-  return true;
-}
-
-bool ParseHybridSessionMessage(const buzz::XmlElement* jingle,
-                               SessionMessage* msg,
-                               ParseError* error) {
-  if (!ParseJingleSessionMessage(jingle, msg, error))
-    return false;
-  msg->protocol = PROTOCOL_HYBRID;
-
-  return true;
-}
-
-bool ParseSessionMessage(const buzz::XmlElement* stanza,
-                         SessionMessage* msg,
-                         ParseError* error) {
-  msg->id = stanza->Attr(buzz::QN_ID);
-  msg->from = stanza->Attr(buzz::QN_FROM);
-  msg->to = stanza->Attr(buzz::QN_TO);
-  msg->stanza = stanza;
-
-  const buzz::XmlElement* jingle = stanza->FirstNamed(QN_JINGLE);
-  const buzz::XmlElement* session = stanza->FirstNamed(QN_GINGLE_SESSION);
-  if (jingle && session)
-    return ParseHybridSessionMessage(jingle, msg, error);
-  if (jingle != NULL)
-    return ParseJingleSessionMessage(jingle, msg, error);
-  if (session != NULL)
-    return ParseGingleSessionMessage(session, msg, error);
-  return false;
-}
-
-buzz::XmlElement* WriteGingleAction(const SessionMessage& msg,
-                                    const XmlElements& action_elems) {
-  buzz::XmlElement* session = new buzz::XmlElement(QN_GINGLE_SESSION, true);
-  session->AddAttr(buzz::QN_TYPE, ToGingleString(msg.type));
-  session->AddAttr(buzz::QN_ID, msg.sid);
-  session->AddAttr(QN_INITIATOR, msg.initiator);
-  AddXmlChildren(session, action_elems);
-  return session;
-}
-
-buzz::XmlElement* WriteJingleAction(const SessionMessage& msg,
-                                    const XmlElements& action_elems) {
-  buzz::XmlElement* jingle = new buzz::XmlElement(QN_JINGLE, true);
-  jingle->AddAttr(buzz::QN_ACTION, ToJingleString(msg.type));
-  jingle->AddAttr(QN_SID, msg.sid);
-  if (msg.type == ACTION_SESSION_INITIATE) {
-    jingle->AddAttr(QN_INITIATOR, msg.initiator);
-  }
-  AddXmlChildren(jingle, action_elems);
-  return jingle;
-}
-
-void WriteSessionMessage(const SessionMessage& msg,
-                         const XmlElements& action_elems,
-                         buzz::XmlElement* stanza) {
-  stanza->SetAttr(buzz::QN_TO, msg.to);
-  stanza->SetAttr(buzz::QN_TYPE, buzz::STR_SET);
-
-  if (msg.protocol == PROTOCOL_GINGLE) {
-    stanza->AddElement(WriteGingleAction(msg, action_elems));
-  } else {
-    stanza->AddElement(WriteJingleAction(msg, action_elems));
-  }
-}
-
-
-TransportParser* GetTransportParser(const TransportParserMap& trans_parsers,
-                                    const std::string& name) {
-  TransportParserMap::const_iterator map = trans_parsers.find(name);
-  if (map == trans_parsers.end()) {
-    return NULL;
-  } else {
-    return map->second;
-  }
-}
-
-bool ParseCandidates(SignalingProtocol protocol,
-                     const buzz::XmlElement* candidates_elem,
-                     const TransportParserMap& trans_parsers,
-                     const std::string& transport_type,
-                     Candidates* candidates,
-                     ParseError* error) {
-  TransportParser* trans_parser =
-      GetTransportParser(trans_parsers, transport_type);
-  if (trans_parser == NULL)
-    return BadParse("unknown transport type: " + transport_type, error);
-
-  return trans_parser->ParseCandidates(protocol, candidates_elem,
-                                       candidates, error);
-}
-
-bool ParseGingleTransportInfos(const buzz::XmlElement* action_elem,
-                               const ContentInfos& contents,
-                               const TransportParserMap& trans_parsers,
-                               TransportInfos* tinfos,
-                               ParseError* error) {
-  TransportInfo tinfo(CN_OTHER, NS_GINGLE_P2P, Candidates());
-  if (!ParseCandidates(PROTOCOL_GINGLE, action_elem,
-                       trans_parsers, NS_GINGLE_P2P,
-                       &tinfo.candidates, error))
-    return false;
-
-  bool has_audio = FindContentInfoByName(contents, CN_AUDIO) != NULL;
-  bool has_video = FindContentInfoByName(contents, CN_VIDEO) != NULL;
-
-  // If we don't have media, no need to separate the candidates.
-  if (!has_audio && !has_video) {
-    tinfos->push_back(tinfo);
-    return true;
-  }
-
-  // If we have media, separate the candidates.  Create the
-  // TransportInfo here to avoid copying the candidates.
-  TransportInfo audio_tinfo(CN_AUDIO, NS_GINGLE_P2P, Candidates());
-  TransportInfo video_tinfo(CN_VIDEO, NS_GINGLE_P2P, Candidates());
-  for (Candidates::iterator cand = tinfo.candidates.begin();
-       cand != tinfo.candidates.end(); cand++) {
-    if (cand->name() == GINGLE_CANDIDATE_NAME_RTP ||
-        cand->name() == GINGLE_CANDIDATE_NAME_RTCP) {
-      audio_tinfo.candidates.push_back(*cand);
-    } else if (cand->name() == GINGLE_CANDIDATE_NAME_VIDEO_RTP ||
-               cand->name() == GINGLE_CANDIDATE_NAME_VIDEO_RTCP) {
-      video_tinfo.candidates.push_back(*cand);
-    }
-  }
-
-  if (has_audio) {
-    tinfos->push_back(audio_tinfo);
-  }
-
-  if (has_video) {
-    tinfos->push_back(video_tinfo);
-  }
-
-  return true;
-}
-
-bool ParseJingleTransportInfo(const buzz::XmlElement* trans_elem,
-                              const ContentInfo& content,
-                              const TransportParserMap& trans_parsers,
-                              TransportInfos* tinfos,
-                              ParseError* error) {
-  std::string transport_type = trans_elem->Name().Namespace();
-  TransportInfo tinfo(content.name, transport_type, Candidates());
-  if (!ParseCandidates(PROTOCOL_JINGLE, trans_elem,
-                       trans_parsers, transport_type,
-                       &tinfo.candidates, error))
-    return false;
-
-  tinfos->push_back(tinfo);
-  return true;
-}
-
-bool ParseJingleTransportInfos(const buzz::XmlElement* jingle,
-                               const ContentInfos& contents,
-                               const TransportParserMap trans_parsers,
-                               TransportInfos* tinfos,
-                               ParseError* error) {
-  for (const buzz::XmlElement* pair_elem
-           = jingle->FirstNamed(QN_JINGLE_CONTENT);
-       pair_elem != NULL;
-       pair_elem = pair_elem->NextNamed(QN_JINGLE_CONTENT)) {
-    std::string content_name;
-    if (!RequireXmlAttr(pair_elem, QN_JINGLE_CONTENT_NAME,
-                        &content_name, error))
-      return false;
-
-    const ContentInfo* content = FindContentInfoByName(contents, content_name);
-    if (!content)
-      return BadParse("Unknown content name: " + content_name, error);
-
-    const buzz::XmlElement* trans_elem;
-    if (!RequireXmlChild(pair_elem, LN_TRANSPORT, &trans_elem, error))
-      return false;
-
-    if (!ParseJingleTransportInfo(trans_elem, *content, trans_parsers,
-                                  tinfos, error))
-      return false;
-  }
-
-  return true;
-}
-
-buzz::XmlElement* NewTransportElement(const std::string& name) {
-  return new buzz::XmlElement(buzz::QName(name, LN_TRANSPORT), true);
-}
-
-bool WriteCandidates(SignalingProtocol protocol,
-                     const std::string& trans_type,
-                     const Candidates& candidates,
-                     const TransportParserMap& trans_parsers,
-                     XmlElements* elems,
-                     WriteError* error) {
-  TransportParser* trans_parser = GetTransportParser(trans_parsers, trans_type);
-  if (trans_parser == NULL)
-    return BadWrite("unknown transport type: " + trans_type, error);
-
-  return trans_parser->WriteCandidates(protocol, candidates, elems, error);
-}
-
-bool WriteGingleTransportInfos(const TransportInfos& tinfos,
-                               const TransportParserMap& trans_parsers,
-                               XmlElements* elems,
-                               WriteError* error) {
-  for (TransportInfos::const_iterator tinfo = tinfos.begin();
-       tinfo != tinfos.end(); ++tinfo) {
-    if (!WriteCandidates(PROTOCOL_GINGLE,
-                         tinfo->transport_type, tinfo->candidates,
-                         trans_parsers, elems, error))
-      return false;
-  }
-
-  return true;
-}
-
-bool WriteJingleTransportInfo(const TransportInfo& tinfo,
-                              const TransportParserMap& trans_parsers,
-                              XmlElements* elems,
-                              WriteError* error) {
-  XmlElements candidate_elems;
-  if (!WriteCandidates(PROTOCOL_JINGLE,
-                       tinfo.transport_type, tinfo.candidates, trans_parsers,
-                       &candidate_elems, error))
-    return false;
-
-  buzz::XmlElement* trans_elem = NewTransportElement(tinfo.transport_type);
-  AddXmlChildren(trans_elem, candidate_elems);
-  elems->push_back(trans_elem);
-  return true;
-}
-
-void WriteJingleContentPair(const std::string name,
-                            const XmlElements& pair_elems,
-                            XmlElements* elems) {
-  buzz::XmlElement* pair_elem = new buzz::XmlElement(QN_JINGLE_CONTENT);
-  pair_elem->SetAttr(QN_JINGLE_CONTENT_NAME, name);
-  pair_elem->SetAttr(QN_CREATOR, LN_INITIATOR);
-  AddXmlChildren(pair_elem, pair_elems);
-
-  elems->push_back(pair_elem);
-}
-
-bool WriteJingleTransportInfos(const TransportInfos& tinfos,
-                               const TransportParserMap& trans_parsers,
-                               XmlElements* elems,
-                               WriteError* error) {
-  for (TransportInfos::const_iterator tinfo = tinfos.begin();
-       tinfo != tinfos.end(); ++tinfo) {
-    XmlElements pair_elems;
-    if (!WriteJingleTransportInfo(*tinfo, trans_parsers,
-                                  &pair_elems, error))
-      return false;
-
-    WriteJingleContentPair(tinfo->content_name, pair_elems, elems);
-  }
-
-  return true;
-}
-
-ContentParser* GetContentParser(const ContentParserMap& content_parsers,
-                                const std::string& type) {
-  ContentParserMap::const_iterator map = content_parsers.find(type);
-  if (map == content_parsers.end()) {
-    return NULL;
-  } else {
-    return map->second;
-  }
-}
-
-bool ParseContentInfo(SignalingProtocol protocol,
-                      const std::string& name,
-                      const std::string& type,
-                      const buzz::XmlElement* elem,
-                      const ContentParserMap& parsers,
-                      ContentInfos* contents,
-                      ParseError* error) {
-  ContentParser* parser = GetContentParser(parsers, type);
-  if (parser == NULL)
-    return BadParse("unknown application content: " + type, error);
-
-  const ContentDescription* desc;
-  if (!parser->ParseContent(protocol, elem, &desc, error))
-    return false;
-
-  contents->push_back(ContentInfo(name, type, desc));
-  return true;
-}
-
-bool ParseContentType(const buzz::XmlElement* parent_elem,
-                      std::string* content_type,
-                      const buzz::XmlElement** content_elem,
-                      ParseError* error) {
-  if (!RequireXmlChild(parent_elem, LN_DESCRIPTION, content_elem, error))
-    return false;
-
-  *content_type = (*content_elem)->Name().Namespace();
-  return true;
-}
-
-bool ParseGingleContentInfos(const buzz::XmlElement* session,
-                             const ContentParserMap& content_parsers,
-                             ContentInfos* contents,
-                             ParseError* error) {
-  std::string content_type;
-  const buzz::XmlElement* content_elem;
-  if (!ParseContentType(session, &content_type, &content_elem, error))
-    return false;
-
-  if (content_type == NS_GINGLE_VIDEO) {
-    // A parser parsing audio or video content should look at the
-    // namespace and only parse the codecs relevant to that namespace.
-    // We use this to control which codecs get parsed: first audio,
-    // then video.
-    talk_base::scoped_ptr<buzz::XmlElement> audio_elem(
-        new buzz::XmlElement(QN_GINGLE_AUDIO_CONTENT));
-    CopyXmlChildren(content_elem, audio_elem.get());
-    if (!ParseContentInfo(PROTOCOL_GINGLE, CN_AUDIO, NS_JINGLE_RTP,
-                          audio_elem.get(), content_parsers,
-                          contents, error))
-      return false;
-
-    if (!ParseContentInfo(PROTOCOL_GINGLE, CN_VIDEO, NS_JINGLE_RTP,
-                          content_elem, content_parsers,
-                          contents, error))
-      return false;
-  } else if (content_type == NS_GINGLE_AUDIO) {
-    if (!ParseContentInfo(PROTOCOL_GINGLE, CN_AUDIO, NS_JINGLE_RTP,
-                          content_elem, content_parsers,
-                          contents, error))
-      return false;
-  } else {
-    if (!ParseContentInfo(PROTOCOL_GINGLE, CN_OTHER, content_type,
-                          content_elem, content_parsers,
-                          contents, error))
-      return false;
-  }
-  return true;
-}
-
-bool ParseJingleContentInfos(const buzz::XmlElement* jingle,
-                             const ContentParserMap& content_parsers,
-                             ContentInfos* contents,
-                             ParseError* error) {
-  for (const buzz::XmlElement* pair_elem
-           = jingle->FirstNamed(QN_JINGLE_CONTENT);
-       pair_elem != NULL;
-       pair_elem = pair_elem->NextNamed(QN_JINGLE_CONTENT)) {
-    std::string content_name;
-    if (!RequireXmlAttr(pair_elem, QN_JINGLE_CONTENT_NAME,
-                        &content_name, error))
-      return false;
-
-    std::string content_type;
-    const buzz::XmlElement* content_elem;
-    if (!ParseContentType(pair_elem, &content_type, &content_elem, error))
-      return false;
-
-    if (!ParseContentInfo(PROTOCOL_JINGLE, content_name, content_type,
-                          content_elem, content_parsers,
-                          contents, error))
-      return false;
-  }
-  return true;
-}
-
-buzz::XmlElement* WriteContentInfo(SignalingProtocol protocol,
-                                   const ContentInfo& content,
-                                   const ContentParserMap& parsers,
-                                   WriteError* error) {
-  ContentParser* parser = GetContentParser(parsers, content.type);
-  if (parser == NULL) {
-    BadWrite("unknown content type: " + content.type, error);
-    return NULL;
-  }
-
-  buzz::XmlElement* elem = NULL;
-  if (!parser->WriteContent(protocol, content.description, &elem, error))
-    return NULL;
-
-  return elem;
-}
-
-bool WriteGingleContentInfos(const ContentInfos& contents,
-                             const ContentParserMap& parsers,
-                             XmlElements* elems,
-                             WriteError* error) {
-  if (contents.size() == 1) {
-    buzz::XmlElement* elem = WriteContentInfo(
-        PROTOCOL_GINGLE, contents.front(), parsers, error);
-    if (!elem)
-      return false;
-
-    elems->push_back(elem);
-  } else if (contents.size() == 2 &&
-             contents.at(0).type == NS_JINGLE_RTP &&
-             contents.at(1).type == NS_JINGLE_RTP) {
-     // Special-case audio + video contents so that they are "merged"
-     // into one "video" content.
-    buzz::XmlElement* audio = WriteContentInfo(
-        PROTOCOL_GINGLE, contents.at(0), parsers, error);
-    if (!audio)
-      return false;
-
-    buzz::XmlElement* video = WriteContentInfo(
-        PROTOCOL_GINGLE, contents.at(1), parsers, error);
-    if (!video) {
-      delete audio;
-      return false;
-    }
-
-    CopyXmlChildren(audio, video);
-    elems->push_back(video);
-    delete audio;
-  } else {
-    return BadWrite("Gingle protocol may only have one content.", error);
-  }
-
-  return true;
-}
-
-const TransportInfo* GetTransportInfoByContentName(
-    const TransportInfos& tinfos, const std::string& content_name) {
-  for (TransportInfos::const_iterator tinfo = tinfos.begin();
-       tinfo != tinfos.end(); ++tinfo) {
-    if (content_name == tinfo->content_name) {
-      return &*tinfo;
-    }
-  }
-  return NULL;
-}
-
-bool WriteJingleContentPairs(const ContentInfos& contents,
-                             const ContentParserMap& content_parsers,
-                             const TransportInfos& tinfos,
-                             const TransportParserMap& trans_parsers,
-                             XmlElements* elems,
-                             WriteError* error) {
-  for (ContentInfos::const_iterator content = contents.begin();
-       content != contents.end(); ++content) {
-    const TransportInfo* tinfo =
-        GetTransportInfoByContentName(tinfos, content->name);
-    if (!tinfo)
-      return BadWrite("No transport for content: " + content->name, error);
-
-    XmlElements pair_elems;
-    buzz::XmlElement* elem = WriteContentInfo(
-        PROTOCOL_JINGLE, *content, content_parsers, error);
-    if (!elem)
-      return false;
-    pair_elems.push_back(elem);
-
-    if (!WriteJingleTransportInfo(*tinfo, trans_parsers,
-                                  &pair_elems, error))
-      return false;
-
-    WriteJingleContentPair(content->name, pair_elems, elems);
-  }
-  return true;
-}
-
-bool ParseContentType(SignalingProtocol protocol,
-                      const buzz::XmlElement* action_elem,
-                      std::string* content_type,
-                      ParseError* error) {
-  const buzz::XmlElement* content_elem;
-  if (protocol == PROTOCOL_GINGLE) {
-    if (!ParseContentType(action_elem, content_type, &content_elem, error))
-      return false;
-
-    // Internally, we only use NS_JINGLE_RTP.
-    if (*content_type == NS_GINGLE_AUDIO ||
-        *content_type == NS_GINGLE_VIDEO)
-      *content_type = NS_JINGLE_RTP;
-  } else {
-    const buzz::XmlElement* pair_elem
-        = action_elem->FirstNamed(QN_JINGLE_CONTENT);
-    if (pair_elem == NULL)
-      return BadParse("No contents found", error);
-
-    if (!ParseContentType(pair_elem, content_type, &content_elem, error))
-      return false;
-
-    // If there is more than one content type, return an error.
-    for (; pair_elem != NULL;
-         pair_elem = pair_elem->NextNamed(QN_JINGLE_CONTENT)) {
-      std::string content_type2;
-      if (!ParseContentType(pair_elem, &content_type2, &content_elem, error))
-        return false;
-
-      if (content_type2 != *content_type)
-        return BadParse("More than one content type found", error);
-    }
-  }
-
-  return true;
-}
-
-static bool ParseContentMessage(
-    SignalingProtocol protocol,
-    const buzz::XmlElement* action_elem,
-    bool expect_transports,
-    const ContentParserMap& content_parsers,
-    const TransportParserMap& trans_parsers,
-    SessionInitiate* init,
-    ParseError* error) {
-  init->owns_contents = true;
-  if (protocol == PROTOCOL_GINGLE) {
-    if (!ParseGingleContentInfos(action_elem, content_parsers,
-                                 &init->contents, error))
-      return false;
-
-    if (expect_transports &&
-        !ParseGingleTransportInfos(action_elem, init->contents, trans_parsers,
-                                   &init->transports, error))
-      return false;
-  } else {
-    if (!ParseJingleContentInfos(action_elem, content_parsers,
-                                 &init->contents, error))
-      return false;
-
-    if (expect_transports &&
-        !ParseJingleTransportInfos(action_elem, init->contents, trans_parsers,
-                                   &init->transports, error))
-      return false;
-  }
-
-  return true;
-}
-
-static bool WriteContentMessage(
-    SignalingProtocol protocol,
-    const ContentInfos& contents,
-    const TransportInfos& tinfos,
-    const ContentParserMap& content_parsers,
-    const TransportParserMap& transport_parsers,
-    XmlElements* elems,
-    WriteError* error) {
-  if (protocol == PROTOCOL_GINGLE) {
-    if (!WriteGingleContentInfos(contents, content_parsers, elems, error))
-      return false;
-
-    if (!WriteGingleTransportInfos(tinfos, transport_parsers,
-                                   elems, error))
-      return false;
-  } else {
-    if (!WriteJingleContentPairs(contents, content_parsers,
-                                 tinfos, transport_parsers,
-                                 elems, error))
-      return false;
-  }
-
-  return true;
-}
-
-bool ParseSessionInitiate(SignalingProtocol protocol,
-                          const buzz::XmlElement* action_elem,
-                          const ContentParserMap& content_parsers,
-                          const TransportParserMap& trans_parsers,
-                          SessionInitiate* init,
-                          ParseError* error) {
-  bool expect_transports = true;
-  return ParseContentMessage(protocol, action_elem, expect_transports,
-                             content_parsers, trans_parsers,
-                             init, error);
-}
-
-
-bool WriteSessionInitiate(SignalingProtocol protocol,
-                          const ContentInfos& contents,
-                          const TransportInfos& tinfos,
-                          const ContentParserMap& content_parsers,
-                          const TransportParserMap& transport_parsers,
-                          XmlElements* elems,
-                          WriteError* error) {
-  return WriteContentMessage(protocol, contents, tinfos,
-                             content_parsers, transport_parsers,
-                             elems, error);
-}
-
-bool ParseSessionAccept(SignalingProtocol protocol,
-                        const buzz::XmlElement* action_elem,
-                        const ContentParserMap& content_parsers,
-                        const TransportParserMap& transport_parsers,
-                        SessionAccept* accept,
-                        ParseError* error) {
-  bool expect_transports = true;
-  return ParseContentMessage(protocol, action_elem, expect_transports,
-                             content_parsers, transport_parsers,
-                             accept, error);
-}
-
-bool WriteSessionAccept(SignalingProtocol protocol,
-                        const ContentInfos& contents,
-                        const TransportInfos& tinfos,
-                        const ContentParserMap& content_parsers,
-                        const TransportParserMap& transport_parsers,
-                        XmlElements* elems,
-                        WriteError* error) {
-  return WriteContentMessage(protocol, contents, tinfos,
-                             content_parsers, transport_parsers,
-                             elems, error);
-}
-
-bool ParseSessionTerminate(SignalingProtocol protocol,
-                           const buzz::XmlElement* action_elem,
-                           SessionTerminate* term,
-                           ParseError* error) {
-  if (protocol == PROTOCOL_GINGLE) {
-    const buzz::XmlElement* reason_elem = action_elem->FirstElement();
-    if (reason_elem != NULL) {
-      term->reason = reason_elem->Name().LocalPart();
-      const buzz::XmlElement *debug_elem = reason_elem->FirstElement();
-      if (debug_elem != NULL) {
-        term->debug_reason = debug_elem->Name().LocalPart();
-      }
-    }
-    return true;
-  } else {
-    const buzz::XmlElement* reason_elem =
-        action_elem->FirstNamed(QN_JINGLE_REASON);
-    if (reason_elem) {
-      reason_elem = reason_elem->FirstElement();
-      if (reason_elem) {
-        term->reason = reason_elem->Name().LocalPart();
-      }
-    }
-    return true;
-  }
-}
-
-void WriteSessionTerminate(SignalingProtocol protocol,
-                           const SessionTerminate& term,
-                           XmlElements* elems) {
-  if (protocol == PROTOCOL_GINGLE) {
-    elems->push_back(new buzz::XmlElement(buzz::QName(NS_GINGLE, term.reason)));
-  } else {
-    if (!term.reason.empty()) {
-      buzz::XmlElement* reason_elem = new buzz::XmlElement(QN_JINGLE_REASON);
-      reason_elem->AddElement(new buzz::XmlElement(
-          buzz::QName(NS_JINGLE, term.reason)));
-      elems->push_back(reason_elem);
-    }
-  }
-}
-
-bool ParseDescriptionInfo(SignalingProtocol protocol,
-                          const buzz::XmlElement* action_elem,
-                          const ContentParserMap& content_parsers,
-                          const TransportParserMap& transport_parsers,
-                          DescriptionInfo* description_info,
-                          ParseError* error) {
-  bool expect_transports = false;
-  return ParseContentMessage(protocol, action_elem, expect_transports,
-                             content_parsers, transport_parsers,
-                             description_info, error);
-}
-
-bool ParseTransportInfos(SignalingProtocol protocol,
-                         const buzz::XmlElement* action_elem,
-                         const ContentInfos& contents,
-                         const TransportParserMap& trans_parsers,
-                         TransportInfos* tinfos,
-                         ParseError* error) {
-  if (protocol == PROTOCOL_GINGLE) {
-    return ParseGingleTransportInfos(
-        action_elem, contents, trans_parsers, tinfos, error);
-  } else {
-    return ParseJingleTransportInfos(
-        action_elem, contents, trans_parsers, tinfos, error);
-  }
-}
-
-bool WriteTransportInfos(SignalingProtocol protocol,
-                         const TransportInfos& tinfos,
-                         const TransportParserMap& trans_parsers,
-                         XmlElements* elems,
-                         WriteError* error) {
-  if (protocol == PROTOCOL_GINGLE) {
-    return WriteGingleTransportInfos(tinfos, trans_parsers,
-                                     elems, error);
-  } else {
-    return WriteJingleTransportInfos(tinfos, trans_parsers,
-                                     elems, error);
-  }
-}
-
-bool GetUriTarget(const std::string& prefix, const std::string& str,
-                  std::string* after) {
-  size_t pos = str.find(prefix);
-  if (pos == std::string::npos)
-    return false;
-
-  *after = str.substr(pos + prefix.size(), std::string::npos);
-  return true;
-}
-
-bool FindSessionRedirect(const buzz::XmlElement* stanza,
-                         SessionRedirect* redirect) {
-  const buzz::XmlElement* error_elem = GetXmlChild(stanza, LN_ERROR);
-  if (error_elem == NULL)
-    return false;
-
-  const buzz::XmlElement* redirect_elem =
-      error_elem->FirstNamed(QN_GINGLE_REDIRECT);
-  if (redirect_elem == NULL)
-    redirect_elem = error_elem->FirstNamed(buzz::QN_STANZA_REDIRECT);
-  if (redirect_elem == NULL)
-    return false;
-
-  if (!GetUriTarget(STR_REDIRECT_PREFIX, redirect_elem->BodyText(),
-                    &redirect->target))
-    return false;
-
-  return true;
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/p2p/base/sessionmessages.h b/third_party/libjingle/source/talk/p2p/base/sessionmessages.h
deleted file mode 100644
index 1486f0c..0000000
--- a/third_party/libjingle/source/talk/p2p/base/sessionmessages.h
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * libjingle
- * Copyright 2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_P2P_BASE_SESSIONMESSAGES_H_
-#define TALK_P2P_BASE_SESSIONMESSAGES_H_
-
-#include <string>
-#include <vector>
-#include <map>
-
-#include "talk/base/basictypes.h"
-#include "talk/p2p/base/constants.h"
-#include "talk/p2p/base/parsing.h"
-#include "talk/p2p/base/sessiondescription.h"  // Needed to delete contents.
-#include "talk/xmllite/xmlelement.h"
-
-namespace cricket {
-
-struct ParseError;
-struct WriteError;
-class Candidate;
-class ContentParser;
-class TransportParser;
-
-typedef std::vector<Candidate> Candidates;
-typedef std::map<std::string, ContentParser*> ContentParserMap;
-typedef std::map<std::string, TransportParser*> TransportParserMap;
-
-enum ActionType {
-  ACTION_UNKNOWN,
-
-  ACTION_SESSION_INITIATE,
-  ACTION_SESSION_INFO,
-  ACTION_SESSION_ACCEPT,
-  ACTION_SESSION_REJECT,
-  ACTION_SESSION_TERMINATE,
-
-  ACTION_TRANSPORT_INFO,
-  ACTION_TRANSPORT_ACCEPT,
-
-  ACTION_DESCRIPTION_INFO,
-};
-
-// Abstraction of a <jingle> element within an <iq> stanza, per XMPP
-// standard XEP-166.  Can be serialized into multiple protocols,
-// including the standard (Jingle) and the draft standard (Gingle).
-// In general, used to communicate actions related to a p2p session,
-// such accept, initiate, terminate, etc.
-
-struct SessionMessage {
-  SessionMessage() : action_elem(NULL), stanza(NULL) {}
-
-  SessionMessage(SignalingProtocol protocol, ActionType type,
-                 const std::string& sid, const std::string& initiator) :
-      protocol(protocol), type(type), sid(sid), initiator(initiator),
-      action_elem(NULL), stanza(NULL) {}
-
-  std::string id;
-  std::string from;
-  std::string to;
-  SignalingProtocol protocol;
-  ActionType type;
-  std::string sid;  // session id
-  std::string initiator;
-
-  // Used for further parsing when necessary.
-  // Represents <session> or <jingle>.
-  const buzz::XmlElement* action_elem;
-  // Mostly used for debugging.
-  const buzz::XmlElement* stanza;
-};
-
-// A TransportInfo is NOT a transport-info message.  It is comparable
-// to a "ContentInfo". A transport-info message is basically just a
-// collection of TransportInfos.
-struct TransportInfo {
-  TransportInfo() {}
-
-  TransportInfo(const std::string& content_name,
-                const std::string& transport_type,
-                const Candidates& candidates)
-      : content_name(content_name),
-        transport_type(transport_type),
-        candidates(candidates) {}
-
-  std::string content_name;
-  std::string transport_type;  // xmlns of <transport>
-  Candidates candidates;
-};
-
-typedef std::vector<TransportInfo> TransportInfos;
-
-// TODO: Break up this class so we don't have to typedef it into
-// different classes.
-struct ContentMessage {
-  ContentMessage() : owns_contents(false) {}
-
-  ~ContentMessage() {
-    if (owns_contents) {
-      for (ContentInfos::iterator content = contents.begin();
-           content != contents.end(); content++) {
-        delete content->description;
-      }
-    }
-  }
-
-  // Caller takes ownership of contents.
-  ContentInfos ClearContents() {
-    ContentInfos out;
-    contents.swap(out);
-    owns_contents = false;
-    return out;
-  }
-
-  bool owns_contents;
-  ContentInfos contents;
-  TransportInfos transports;
-};
-
-typedef ContentMessage SessionInitiate;
-typedef ContentMessage SessionAccept;
-// Note that a DescriptionInfo does not have TransportInfos.
-typedef ContentMessage DescriptionInfo;
-
-struct SessionTerminate {
-  SessionTerminate() {}
-
-  explicit SessionTerminate(const std::string& reason) :
-      reason(reason) {}
-
-  std::string reason;
-  std::string debug_reason;
-};
-
-struct SessionRedirect {
-  std::string target;
-};
-
-
-bool IsSessionMessage(const buzz::XmlElement* stanza);
-bool ParseSessionMessage(const buzz::XmlElement* stanza,
-                         SessionMessage* msg,
-                         ParseError* error);
-// Will return an error if there is more than one content type.
-bool ParseContentType(SignalingProtocol protocol,
-                      const buzz::XmlElement* action_elem,
-                      std::string* content_type,
-                      ParseError* error);
-void WriteSessionMessage(const SessionMessage& msg,
-                         const XmlElements& action_elems,
-                         buzz::XmlElement* stanza);
-bool ParseSessionInitiate(SignalingProtocol protocol,
-                          const buzz::XmlElement* action_elem,
-                          const ContentParserMap& content_parsers,
-                          const TransportParserMap& transport_parsers,
-                          SessionInitiate* init,
-                          ParseError* error);
-bool WriteSessionInitiate(SignalingProtocol protocol,
-                          const ContentInfos& contents,
-                          const TransportInfos& tinfos,
-                          const ContentParserMap& content_parsers,
-                          const TransportParserMap& transport_parsers,
-                          XmlElements* elems,
-                          WriteError* error);
-bool ParseSessionAccept(SignalingProtocol protocol,
-                        const buzz::XmlElement* action_elem,
-                        const ContentParserMap& content_parsers,
-                        const TransportParserMap& transport_parsers,
-                        SessionAccept* accept,
-                        ParseError* error);
-bool WriteSessionAccept(SignalingProtocol protocol,
-                        const ContentInfos& contents,
-                        const TransportInfos& tinfos,
-                        const ContentParserMap& content_parsers,
-                        const TransportParserMap& transport_parsers,
-                        XmlElements* elems,
-                        WriteError* error);
-bool ParseSessionTerminate(SignalingProtocol protocol,
-                           const buzz::XmlElement* action_elem,
-                           SessionTerminate* term,
-                           ParseError* error);
-void WriteSessionTerminate(SignalingProtocol protocol,
-                           const SessionTerminate& term,
-                           XmlElements* elems);
-bool ParseDescriptionInfo(SignalingProtocol protocol,
-                          const buzz::XmlElement* action_elem,
-                          const ContentParserMap& content_parsers,
-                          const TransportParserMap& transport_parsers,
-                          DescriptionInfo* description_info,
-                          ParseError* error);
-// Since a TransportInfo is not a transport-info message, and a
-// transport-info message is just a collection of TransportInfos, we
-// say Parse/Write TransportInfos for transport-info messages.
-bool ParseTransportInfos(SignalingProtocol protocol,
-                         const buzz::XmlElement* action_elem,
-                         const ContentInfos& contents,
-                         const TransportParserMap& trans_parsers,
-                         TransportInfos* tinfos,
-                         ParseError* error);
-bool WriteTransportInfos(SignalingProtocol protocol,
-                         const TransportInfos& tinfos,
-                         const TransportParserMap& trans_parsers,
-                         XmlElements* elems,
-                         WriteError* error);
-// Handles both Gingle and Jingle syntax.
-bool FindSessionRedirect(const buzz::XmlElement* stanza,
-                         SessionRedirect* redirect);
-}  // namespace cricket
-
-#endif  // TALK_P2P_BASE_SESSIONMESSAGES_H_
diff --git a/third_party/libjingle/source/talk/p2p/base/stun.cc b/third_party/libjingle/source/talk/p2p/base/stun.cc
deleted file mode 100644
index 3b3fad4..0000000
--- a/third_party/libjingle/source/talk/p2p/base/stun.cc
+++ /dev/null
@@ -1,578 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/p2p/base/stun.h"
-
-#include <cstring>
-
-#include "talk/base/byteorder.h"
-#include "talk/base/common.h"
-#include "talk/base/logging.h"
-
-using talk_base::ByteBuffer;
-
-namespace cricket {
-
-const char STUN_ERROR_REASON_BAD_REQUEST[] = "BAD REQUEST";
-const char STUN_ERROR_REASON_STALE_CREDENTIALS[] = "STALE CREDENTIALS";
-const char STUN_ERROR_REASON_SERVER_ERROR[] = "SERVER ERROR";
-
-const char TURN_MAGIC_COOKIE_VALUE[] = { '\x72', '\xC6', '\x4B', '\xC6' };
-
-StunMessage::StunMessage()
-    : type_(0), length_(0),
-      transaction_id_("000000000000") {
-  ASSERT(IsValidTransactionId(transaction_id_));
-  attrs_ = new std::vector<StunAttribute*>();
-}
-
-StunMessage::~StunMessage() {
-  for (unsigned i = 0; i < attrs_->size(); i++)
-    delete (*attrs_)[i];
-  delete attrs_;
-}
-
-bool StunMessage::IsLegacy() const {
-  if (transaction_id_.size() == kStunLegacyTransactionIdLength)
-    return true;
-  ASSERT(transaction_id_.size() == kStunTransactionIdLength);
-  return false;
-}
-
-void StunMessage::SetTransactionID(const std::string& str) {
-  ASSERT(IsValidTransactionId(str));
-  transaction_id_ = str;
-}
-
-void StunMessage::AddAttribute(StunAttribute* attr) {
-  attrs_->push_back(attr);
-  length_ += attr->length() + 4;
-}
-
-const StunAddressAttribute*
-StunMessage::GetAddress(StunAttributeType type) const {
-  switch (type) {
-    case STUN_ATTR_MAPPED_ADDRESS: {
-      // Return XOR-MAPPED-ADDRESS when MAPPED-ADDRESS attribute is
-      // missing.
-      const StunAttribute* mapped_address =
-          GetAttribute(STUN_ATTR_MAPPED_ADDRESS);
-      if (!mapped_address)
-        mapped_address = GetAttribute(STUN_ATTR_XOR_MAPPED_ADDRESS);
-      return reinterpret_cast<const StunAddressAttribute*>(mapped_address);
-    }
-
-    case STUN_ATTR_DESTINATION_ADDRESS:
-    case STUN_ATTR_SOURCE_ADDRESS2:
-    case STUN_ATTR_XOR_MAPPED_ADDRESS:
-      return reinterpret_cast<const StunAddressAttribute*>(GetAttribute(type));
-
-    default:
-      ASSERT(0);
-      return NULL;
-  }
-}
-
-const StunUInt32Attribute*
-StunMessage::GetUInt32(StunAttributeType type) const {
-  switch (type) {
-    case STUN_ATTR_LIFETIME:
-    case STUN_ATTR_BANDWIDTH:
-    case STUN_ATTR_OPTIONS:
-      return reinterpret_cast<const StunUInt32Attribute*>(GetAttribute(type));
-
-    default:
-      ASSERT(0);
-      return NULL;
-  }
-}
-
-const StunByteStringAttribute*
-StunMessage::GetByteString(StunAttributeType type) const {
-  switch (type) {
-    case STUN_ATTR_USERNAME:
-    case STUN_ATTR_MESSAGE_INTEGRITY:
-    case STUN_ATTR_DATA:
-    case STUN_ATTR_MAGIC_COOKIE:
-      return reinterpret_cast<const StunByteStringAttribute*>(
-          GetAttribute(type));
-
-    default:
-      ASSERT(0);
-      return NULL;
-  }
-}
-
-const StunErrorCodeAttribute* StunMessage::GetErrorCode() const {
-  return reinterpret_cast<const StunErrorCodeAttribute*>(
-      GetAttribute(STUN_ATTR_ERROR_CODE));
-}
-
-const StunUInt16ListAttribute* StunMessage::GetUnknownAttributes() const {
-  return reinterpret_cast<const StunUInt16ListAttribute*>(
-      GetAttribute(STUN_ATTR_UNKNOWN_ATTRIBUTES));
-}
-
-const StunAttribute* StunMessage::GetAttribute(StunAttributeType type) const {
-  for (unsigned i = 0; i < attrs_->size(); i++) {
-    if ((*attrs_)[i]->type() == type)
-      return (*attrs_)[i];
-  }
-  return NULL;
-}
-
-bool StunMessage::Read(ByteBuffer* buf) {
-  if (!buf->ReadUInt16(&type_))
-    return false;
-
-  if (type_ & 0x8000) {
-    // rtp and rtcp set MSB of first byte, since first two bits are version,
-    // and version is always 2 (10).  If set, this is not a stun packet.
-    return false;
-  }
-
-  if (!buf->ReadUInt16(&length_))
-    return false;
-
-  std::string magic_cookie;
-  if (!buf->ReadString(&magic_cookie, kStunMagicCookieLength))
-    return false;
-
-  std::string transaction_id;
-  if (!buf->ReadString(&transaction_id, kStunTransactionIdLength))
-    return false;
-
-  uint32 magic_cookie_int =
-      *reinterpret_cast<const uint32*>(magic_cookie.data());
-  if (talk_base::NetworkToHost32(magic_cookie_int) != kStunMagicCookie) {
-    // If magic cookie is invalid it means that the peer implements
-    // RFC3489 instead of RFC5389.
-    transaction_id.insert(0, magic_cookie);
-  }
-  ASSERT(IsValidTransactionId(transaction_id));
-  transaction_id_ = transaction_id;
-
-  if (length_ > buf->Length())
-    return false;
-
-  attrs_->resize(0);
-
-  size_t rest = buf->Length() - length_;
-  while (buf->Length() > rest) {
-    uint16 attr_type, attr_length;
-    if (!buf->ReadUInt16(&attr_type))
-      return false;
-    if (!buf->ReadUInt16(&attr_length))
-      return false;
-
-    StunAttribute* attr = StunAttribute::Create(attr_type, attr_length);
-    if (!attr) {
-      // Skip an unknown attribute.
-      if (!buf->Consume(attr_length))
-        return false;
-    } else {
-      if (!attr->Read(buf))
-        return false;
-      attrs_->push_back(attr);
-    }
-  }
-
-  ASSERT(buf->Length() == rest);
-
-  return true;
-}
-
-void StunMessage::Write(ByteBuffer* buf) const {
-  buf->WriteUInt16(type_);
-  buf->WriteUInt16(length_);
-  if (!IsLegacy())
-    buf->WriteUInt32(kStunMagicCookie);
-  buf->WriteString(transaction_id_);
-
-  for (unsigned i = 0; i < attrs_->size(); i++) {
-    buf->WriteUInt16((*attrs_)[i]->type());
-    buf->WriteUInt16((*attrs_)[i]->length());
-    (*attrs_)[i]->Write(buf);
-  }
-}
-
-bool StunMessage::IsValidTransactionId(const std::string& transaction_id) {
-  return transaction_id.size() == kStunTransactionIdLength ||
-      transaction_id.size() == kStunLegacyTransactionIdLength;
-}
-
-StunAttribute::StunAttribute(uint16 type, uint16 length)
-    : type_(type), length_(length) {
-}
-
-StunAttribute* StunAttribute::Create(uint16 type, uint16 length) {
-  switch (type) {
-    case STUN_ATTR_MAPPED_ADDRESS:
-    case STUN_ATTR_DESTINATION_ADDRESS:
-    case STUN_ATTR_SOURCE_ADDRESS2:
-      // TODO: Addresses may be different size for IPv6
-      // addresses, but we don't support IPv6 yet. Fix address parsing
-      // when IPv6 support is implemented.
-      if (length != StunAddressAttribute::SIZE)
-        return NULL;
-      return new StunAddressAttribute(type);
-
-    case STUN_ATTR_LIFETIME:
-    case STUN_ATTR_BANDWIDTH:
-    case STUN_ATTR_OPTIONS:
-      if (length != StunUInt32Attribute::SIZE)
-        return NULL;
-      return new StunUInt32Attribute(type);
-
-    case STUN_ATTR_USERNAME:
-    case STUN_ATTR_MAGIC_COOKIE:
-      return (length % 4 == 0) ? new StunByteStringAttribute(type, length) : 0;
-
-    case STUN_ATTR_MESSAGE_INTEGRITY:
-      return (length == 20) ? new StunByteStringAttribute(type, length) : 0;
-
-    case STUN_ATTR_DATA:
-      return new StunByteStringAttribute(type, length);
-
-    case STUN_ATTR_ERROR_CODE:
-      if (length < StunErrorCodeAttribute::MIN_SIZE)
-        return NULL;
-      return new StunErrorCodeAttribute(type, length);
-
-    case STUN_ATTR_UNKNOWN_ATTRIBUTES:
-      return (length % 2 == 0) ? new StunUInt16ListAttribute(type, length) : 0;
-
-    case STUN_ATTR_XOR_MAPPED_ADDRESS:
-      // TODO: Addresses may be different size for IPv6
-      // addresses, but we don't support IPv6 yet. Fix address parsing
-      // when IPv6 support is implemented.
-      if (length != StunAddressAttribute::SIZE)
-        return NULL;
-      return new StunXorAddressAttribute(type);
-
-    default:
-      return NULL;
-  }
-}
-
-StunAddressAttribute* StunAttribute::CreateAddress(uint16 type) {
-  switch (type) {
-    case STUN_ATTR_MAPPED_ADDRESS:
-    case STUN_ATTR_DESTINATION_ADDRESS:
-    case STUN_ATTR_SOURCE_ADDRESS2:
-      return new StunAddressAttribute(type);
-
-    case STUN_ATTR_XOR_MAPPED_ADDRESS:
-      return new StunXorAddressAttribute(type);
-
-  default:
-    ASSERT(false);
-    return NULL;
-  }
-}
-
-StunUInt32Attribute* StunAttribute::CreateUInt32(uint16 type) {
-  switch (type) {
-  case STUN_ATTR_LIFETIME:
-  case STUN_ATTR_BANDWIDTH:
-  case STUN_ATTR_OPTIONS:
-    return new StunUInt32Attribute(type);
-
-  default:
-    ASSERT(false);
-    return NULL;
-  }
-}
-
-StunByteStringAttribute* StunAttribute::CreateByteString(uint16 type) {
-  switch (type) {
-    case STUN_ATTR_USERNAME:
-    case STUN_ATTR_MESSAGE_INTEGRITY:
-    case STUN_ATTR_DATA:
-    case STUN_ATTR_MAGIC_COOKIE:
-      return new StunByteStringAttribute(type, 0);
-
-    default:
-      ASSERT(false);
-      return NULL;
-  }
-}
-
-StunErrorCodeAttribute* StunAttribute::CreateErrorCode() {
-  return new StunErrorCodeAttribute(
-      STUN_ATTR_ERROR_CODE, StunErrorCodeAttribute::MIN_SIZE);
-}
-
-StunUInt16ListAttribute* StunAttribute::CreateUnknownAttributes() {
-  return new StunUInt16ListAttribute(STUN_ATTR_UNKNOWN_ATTRIBUTES, 0);
-}
-
-StunAddressAttribute::StunAddressAttribute(uint16 type)
-    : StunAttribute(type, SIZE), family_(STUN_ADDRESS_IPV4), port_(0), ip_(0) {
-}
-
-void StunAddressAttribute::SetFamily(StunAddressFamily family) {
-  family_ = family;
-}
-
-bool StunAddressAttribute::Read(ByteBuffer* buf) {
-  uint8 dummy;
-  if (!buf->ReadUInt8(&dummy))
-    return false;
-
-  uint8 family;
-  // We don't expect IPv6 address here because IPv6 addresses would
-  // not pass the attribute size check in StunAttribute::Create().
-  // TODO: Support IPv6 addresses.
-  if (!buf->ReadUInt8(&family) || family != STUN_ADDRESS_IPV4) {
-    return false;
-  }
-  family_ = static_cast<StunAddressFamily>(family);
-
-  if (!buf->ReadUInt16(&port_))
-    return false;
-  uint32 ip;
-  if (!buf->ReadUInt32(&ip))
-    return false;
-  SetIP(talk_base::IPAddress(ip));
-
-  return true;
-}
-
-void StunAddressAttribute::Write(ByteBuffer* buf) const {
-  // Only IPv4 address family is currently supported.
-  ASSERT(family_ == STUN_ADDRESS_IPV4);
-
-  buf->WriteUInt8(0);
-  buf->WriteUInt8(family_);
-  buf->WriteUInt16(port_);
-  buf->WriteUInt32(ip_.v4AddressAsHostOrderInteger());
-}
-
-StunXorAddressAttribute::StunXorAddressAttribute(uint16 type)
-    : StunAddressAttribute(type) {
-}
-
-bool StunXorAddressAttribute::Read(ByteBuffer* buf) {
-  if (!StunAddressAttribute::Read(buf))
-    return false;
-
-  SetPort(port() ^ (kStunMagicCookie >> 16));
-  uint32 ip = ipaddr().v4AddressAsHostOrderInteger();
-  SetIP(talk_base::IPAddress(ip ^ kStunMagicCookie));
-
-  return true;
-}
-
-void StunXorAddressAttribute::Write(ByteBuffer* buf) const {
-  // Only IPv4 address family is currently supported.
-  ASSERT(family() == STUN_ADDRESS_IPV4);
-
-  buf->WriteUInt8(0);
-  buf->WriteUInt8(family());
-  buf->WriteUInt16(port() ^ (kStunMagicCookie >> 16));
-  buf->WriteUInt32(ipaddr().v4AddressAsHostOrderInteger() ^ kStunMagicCookie);
-}
-
-StunUInt32Attribute::StunUInt32Attribute(uint16 type)
-    : StunAttribute(type, SIZE), bits_(0) {
-}
-
-bool StunUInt32Attribute::GetBit(int index) const {
-  ASSERT((0 <= index) && (index < 32));
-  return static_cast<bool>((bits_ >> index) & 0x1);
-}
-
-void StunUInt32Attribute::SetBit(int index, bool value) {
-  ASSERT((0 <= index) && (index < 32));
-  bits_ &= ~(1 << index);
-  bits_ |= value ? (1 << index) : 0;
-}
-
-bool StunUInt32Attribute::Read(ByteBuffer* buf) {
-  if (!buf->ReadUInt32(&bits_))
-    return false;
-  return true;
-}
-
-void StunUInt32Attribute::Write(ByteBuffer* buf) const {
-  buf->WriteUInt32(bits_);
-}
-
-StunByteStringAttribute::StunByteStringAttribute(uint16 type, uint16 length)
-    : StunAttribute(type, length), bytes_(0) {
-}
-
-StunByteStringAttribute::~StunByteStringAttribute() {
-  delete [] bytes_;
-}
-
-void StunByteStringAttribute::SetBytes(char* bytes, uint16 length) {
-  delete [] bytes_;
-  bytes_ = bytes;
-  SetLength(length);
-}
-
-void StunByteStringAttribute::CopyBytes(const char* bytes) {
-  CopyBytes(bytes, static_cast<uint16>(strlen(bytes)));
-}
-
-void StunByteStringAttribute::CopyBytes(const void* bytes, uint16 length) {
-  char* new_bytes = new char[length];
-  std::memcpy(new_bytes, bytes, length);
-  SetBytes(new_bytes, length);
-}
-
-uint8 StunByteStringAttribute::GetByte(int index) const {
-  ASSERT(bytes_ != NULL);
-  ASSERT((0 <= index) && (index < length()));
-  return static_cast<uint8>(bytes_[index]);
-}
-
-void StunByteStringAttribute::SetByte(int index, uint8 value) {
-  ASSERT(bytes_ != NULL);
-  ASSERT((0 <= index) && (index < length()));
-  bytes_[index] = value;
-}
-
-bool StunByteStringAttribute::Read(ByteBuffer* buf) {
-  bytes_ = new char[length()];
-  if (!buf->ReadBytes(bytes_, length()))
-    return false;
-  return true;
-}
-
-void StunByteStringAttribute::Write(ByteBuffer* buf) const {
-  buf->WriteBytes(bytes_, length());
-}
-
-StunErrorCodeAttribute::StunErrorCodeAttribute(uint16 type, uint16 length)
-    : StunAttribute(type, length), class_(0), number_(0) {
-}
-
-StunErrorCodeAttribute::~StunErrorCodeAttribute() {
-}
-
-void StunErrorCodeAttribute::SetErrorCode(uint32 code) {
-  class_ = (uint8)((code >> 8) & 0x7);
-  number_ = (uint8)(code & 0xff);
-}
-
-void StunErrorCodeAttribute::SetReason(const std::string& reason) {
-  SetLength(MIN_SIZE + static_cast<uint16>(reason.size()));
-  reason_ = reason;
-}
-
-bool StunErrorCodeAttribute::Read(ByteBuffer* buf) {
-  uint32 val;
-  if (!buf->ReadUInt32(&val))
-    return false;
-
-  if ((val >> 11) != 0)
-    LOG(LERROR) << "error-code bits not zero";
-
-  SetErrorCode(val);
-
-  if (!buf->ReadString(&reason_, length() - 4))
-    return false;
-
-  return true;
-}
-
-void StunErrorCodeAttribute::Write(ByteBuffer* buf) const {
-  buf->WriteUInt32(error_code());
-  buf->WriteString(reason_);
-}
-
-StunUInt16ListAttribute::StunUInt16ListAttribute(uint16 type, uint16 length)
-    : StunAttribute(type, length) {
-  attr_types_ = new std::vector<uint16>();
-}
-
-StunUInt16ListAttribute::~StunUInt16ListAttribute() {
-  delete attr_types_;
-}
-
-size_t StunUInt16ListAttribute::Size() const {
-  return attr_types_->size();
-}
-
-uint16 StunUInt16ListAttribute::GetType(int index) const {
-  return (*attr_types_)[index];
-}
-
-void StunUInt16ListAttribute::SetType(int index, uint16 value) {
-  (*attr_types_)[index] = value;
-}
-
-void StunUInt16ListAttribute::AddType(uint16 value) {
-  attr_types_->push_back(value);
-  SetLength(static_cast<uint16>(attr_types_->size() * 2));
-}
-
-bool StunUInt16ListAttribute::Read(ByteBuffer* buf) {
-  for (int i = 0; i < length() / 2; i++) {
-    uint16 attr;
-    if (!buf->ReadUInt16(&attr))
-      return false;
-    attr_types_->push_back(attr);
-  }
-  return true;
-}
-
-void StunUInt16ListAttribute::Write(ByteBuffer* buf) const {
-  for (unsigned i = 0; i < attr_types_->size(); i++)
-    buf->WriteUInt16((*attr_types_)[i]);
-}
-
-StunMessageType GetStunResponseType(StunMessageType request_type) {
-  switch (request_type) {
-    case STUN_SHARED_SECRET_REQUEST:
-      return STUN_SHARED_SECRET_RESPONSE;
-    case STUN_ALLOCATE_REQUEST:
-      return STUN_ALLOCATE_RESPONSE;
-    case STUN_SEND_REQUEST:
-      return STUN_SEND_RESPONSE;
-    default:
-      return STUN_BINDING_RESPONSE;
-  }
-}
-
-StunMessageType GetStunErrorResponseType(StunMessageType request_type) {
-  switch (request_type) {
-    case STUN_SHARED_SECRET_REQUEST:
-      return STUN_SHARED_SECRET_ERROR_RESPONSE;
-    case STUN_ALLOCATE_REQUEST:
-      return STUN_ALLOCATE_ERROR_RESPONSE;
-    case STUN_SEND_REQUEST:
-      return STUN_SEND_ERROR_RESPONSE;
-    default:
-      return STUN_BINDING_ERROR_RESPONSE;
-  }
-}
-
-} // namespace cricket
diff --git a/third_party/libjingle/source/talk/p2p/base/stun.h b/third_party/libjingle/source/talk/p2p/base/stun.h
deleted file mode 100644
index 87687b1..0000000
--- a/third_party/libjingle/source/talk/p2p/base/stun.h
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_P2P_BASE_STUN_H_
-#define TALK_P2P_BASE_STUN_H_
-
-// This file contains classes for dealing with the STUN and TURN protocols.
-// Both protocols use the same wire format.
-
-#include <string>
-#include <vector>
-
-#include "talk/base/basictypes.h"
-#include "talk/base/bytebuffer.h"
-#include "talk/base/ipaddress.h"
-
-namespace cricket {
-
-// These are the types of STUN & TURN messages as of last check.
-enum StunMessageType {
-  STUN_BINDING_REQUEST              = 0x0001,
-  STUN_BINDING_RESPONSE             = 0x0101,
-  STUN_BINDING_ERROR_RESPONSE       = 0x0111,
-  STUN_SHARED_SECRET_REQUEST        = 0x0002,
-  STUN_SHARED_SECRET_RESPONSE       = 0x0102,
-  STUN_SHARED_SECRET_ERROR_RESPONSE = 0x0112,
-  STUN_ALLOCATE_REQUEST             = 0x0003,
-  STUN_ALLOCATE_RESPONSE            = 0x0103,
-  STUN_ALLOCATE_ERROR_RESPONSE      = 0x0113,
-  STUN_SEND_REQUEST                 = 0x0004,
-  STUN_SEND_RESPONSE                = 0x0104,
-  STUN_SEND_ERROR_RESPONSE          = 0x0114,
-  STUN_DATA_INDICATION              = 0x0115
-};
-
-// These are the types of attributes defined in STUN & TURN.  Next to each is
-// the name of the class (T is StunTAttribute) that implements that type.
-//
-// TODO: Some attributes defined in RFC5389 are not
-// implemented yet, particularly REALM, NONCE, SOFTWARE,
-// ALTERNATE-SERVE and FINGEPRINT. Implement them.
-enum StunAttributeType {
-  STUN_ATTR_MAPPED_ADDRESS        = 0x0001, // Address
-  STUN_ATTR_USERNAME              = 0x0006, // ByteString, multiple of 4 bytes
-  STUN_ATTR_MESSAGE_INTEGRITY     = 0x0008, // ByteString, 20 bytes
-  STUN_ATTR_ERROR_CODE            = 0x0009, // ErrorCode
-  STUN_ATTR_UNKNOWN_ATTRIBUTES    = 0x000a, // UInt16List
-  STUN_ATTR_LIFETIME              = 0x000d, // UInt32
-  STUN_ATTR_MAGIC_COOKIE          = 0x000f, // ByteString, 4 bytes
-  STUN_ATTR_BANDWIDTH             = 0x0010, // UInt32
-  STUN_ATTR_DESTINATION_ADDRESS   = 0x0011, // Address
-  STUN_ATTR_SOURCE_ADDRESS2       = 0x0012, // Address
-  STUN_ATTR_DATA                  = 0x0013, // ByteString
-  STUN_ATTR_XOR_MAPPED_ADDRESS    = 0x0020, // XorAddress
-  STUN_ATTR_OPTIONS               = 0x8001  // UInt32
-};
-
-enum StunErrorCodes {
-  STUN_ERROR_BAD_REQUEST          = 400,
-  STUN_ERROR_UNAUTHORIZED         = 401,
-  STUN_ERROR_UNKNOWN_ATTRIBUTE    = 420,
-  STUN_ERROR_STALE_CREDENTIALS    = 430,
-  STUN_ERROR_INTEGRITY_CHECK_FAILURE = 431,
-  STUN_ERROR_MISSING_USERNAME     = 432,
-  STUN_ERROR_USE_TLS              = 433,
-  STUN_ERROR_SERVER_ERROR         = 500,
-  STUN_ERROR_GLOBAL_FAILURE       = 600
-};
-
-enum StunAddressFamily {
-  STUN_ADDRESS_IPV4 = 1,
-  STUN_ADDRESS_IPV6 = 2
-};
-
-extern const char STUN_ERROR_REASON_BAD_REQUEST[];
-extern const char STUN_ERROR_REASON_STALE_CREDENTIALS[];
-extern const char STUN_ERROR_REASON_SERVER_ERROR[];
-
-// Following values correspond to RFC5389.
-const size_t kStunTransactionIdOffset = 8;
-const size_t kStunTransactionIdLength = 12;
-const uint32 kStunMagicCookie = 0x2112A442;
-const size_t kStunMagicCookieLength = sizeof(kStunMagicCookie);
-
-// Following value corresponds to an earlier version of STUN from
-// RFC3489.
-const size_t kStunLegacyTransactionIdLength = 16;
-
-class StunAttribute;
-class StunAddressAttribute;
-class StunUInt32Attribute;
-class StunByteStringAttribute;
-class StunErrorCodeAttribute;
-class StunUInt16ListAttribute;
-class StunTransportPrefsAttribute;
-
-// Records a complete STUN/TURN message.  Each message consists of a type and
-// any number of attributes.  Each attribute is parsed into an instance of an
-// appropriate class (see above).  The Get* methods will return instances of
-// that attribute class.
-class StunMessage {
-public:
-  StunMessage();
-  ~StunMessage();
-  StunMessageType type() const { return static_cast<StunMessageType>(type_); }
-  uint16 length() const { return length_; }
-  const std::string& transaction_id() const { return transaction_id_; }
-
-  // Returns true if the message confirms to RFC3489 rather than
-  // RFC5389. The main difference between two version of the STUN
-  // protocol is the presence of the magic cookie and different length
-  // of transaction ID. For outgoing packets version of the protocol
-  // is determined by the lengths of the transaction ID.
-  bool IsLegacy() const;
-
-  void SetType(StunMessageType type) { type_ = type; }
-  void SetTransactionID(const std::string& str);
-
-  const StunAddressAttribute* GetAddress(StunAttributeType type) const;
-  const StunUInt32Attribute* GetUInt32(StunAttributeType type) const;
-  const StunByteStringAttribute* GetByteString(StunAttributeType type) const;
-  const StunErrorCodeAttribute* GetErrorCode() const;
-  const StunUInt16ListAttribute* GetUnknownAttributes() const;
-  const StunTransportPrefsAttribute* GetTransportPrefs() const;
-
-  void AddAttribute(StunAttribute* attr);
-
-  // Parses the STUN/TURN packet in the given buffer and records it here.  The
-  // return value indicates whether this was successful.
-  bool Read(talk_base::ByteBuffer* buf);
-
-  // Writes this object into a STUN/TURN packet. Return value is true if
-  // successful.
-  void Write(talk_base::ByteBuffer* buf) const;
-
-private:
-  uint16 type_;
-  uint16 length_;
-  std::string transaction_id_;
-  std::vector<StunAttribute*>* attrs_;
-
-  const StunAttribute* GetAttribute(StunAttributeType type) const;
-  static bool IsValidTransactionId(const std::string& transaction_id);
-};
-
-// Base class for all STUN/TURN attributes.
-class StunAttribute {
-public:
-  virtual ~StunAttribute() {}
-
-  StunAttributeType type() const {
-    return static_cast<StunAttributeType>(type_);
-  }
-  uint16 length() const { return length_; }
-
-  // Reads the body (not the type or length) for this type of attribute from
-  // the given buffer.  Return value is true if successful.
-  virtual bool Read(talk_base::ByteBuffer* buf) = 0;
-
-  // Writes the body (not the type or length) to the given buffer.  Return
-  // value is true if successful.
-  virtual void Write(talk_base::ByteBuffer* buf) const = 0;
-
-  // Creates an attribute object with the given type and len.
-  static StunAttribute* Create(uint16 type, uint16 length);
-
-  // Creates an attribute object with the given type and smallest length.
-  static StunAddressAttribute* CreateAddress(uint16 type);
-  static StunUInt32Attribute* CreateUInt32(uint16 type);
-  static StunByteStringAttribute* CreateByteString(uint16 type);
-  static StunErrorCodeAttribute* CreateErrorCode();
-  static StunUInt16ListAttribute* CreateUnknownAttributes();
-  static StunTransportPrefsAttribute* CreateTransportPrefs();
-
-protected:
-  StunAttribute(uint16 type, uint16 length);
-
-  void SetLength(uint16 length) { length_ = length; }
-
-private:
-  uint16 type_;
-  uint16 length_;
-};
-
-// Implements STUN/TURN attributes that record an Internet address.
-// TODO: IPv6 support, and use the SocketAddress class.
-class StunAddressAttribute : public StunAttribute {
-public:
-  explicit StunAddressAttribute(uint16 type);
-
-  static const uint16 SIZE = 8;
-
-  StunAddressFamily family() const { return family_; }
-  uint16 port() const { return port_; }
-  talk_base::IPAddress ipaddr() const { return ip_; }
-
-  void SetFamily(StunAddressFamily family);
-  void SetIP(const talk_base::IPAddress& ip) { ip_ = ip; }
-  void SetPort(uint16 port) { port_ = port; }
-
-  virtual bool Read(talk_base::ByteBuffer* buf);
-  virtual void Write(talk_base::ByteBuffer* buf) const;
-
-private:
-  StunAddressFamily family_;
-  uint16 port_;
-  talk_base::IPAddress ip_;
-};
-
-// Implements STUN/TURN attributes that record an Internet address.
-class StunXorAddressAttribute : public StunAddressAttribute {
-public:
-  explicit StunXorAddressAttribute(uint16 type);
-
-  virtual bool Read(talk_base::ByteBuffer* buf);
-  virtual void Write(talk_base::ByteBuffer* buf) const;
-};
-
-// Implements STUN/TURN attributs that record a 32-bit integer.
-class StunUInt32Attribute : public StunAttribute {
-public:
-  explicit StunUInt32Attribute(uint16 type);
-
-  static const uint16 SIZE = 4;
-
-  uint32 value() const { return bits_; }
-
-  void SetValue(uint32 bits) { bits_ = bits; }
-
-  bool GetBit(int index) const;
-  void SetBit(int index, bool value);
-
-  bool Read(talk_base::ByteBuffer* buf);
-  void Write(talk_base::ByteBuffer* buf) const;
-
-private:
-  uint32 bits_;
-};
-
-// Implements STUN/TURN attributs that record an arbitrary byte string
-class StunByteStringAttribute : public StunAttribute {
-public:
-  StunByteStringAttribute(uint16 type, uint16 length);
-  ~StunByteStringAttribute();
-
-  const char* bytes() const { return bytes_; }
-
-  void SetBytes(char* bytes, uint16 length);
-
-  void CopyBytes(const char* bytes); // uses strlen
-  void CopyBytes(const void* bytes, uint16 length);
-
-  uint8 GetByte(int index) const;
-  void SetByte(int index, uint8 value);
-
-  bool Read(talk_base::ByteBuffer* buf);
-  void Write(talk_base::ByteBuffer* buf) const;
-
-private:
-  char* bytes_;
-};
-
-// Implements STUN/TURN attributs that record an error code.
-class StunErrorCodeAttribute : public StunAttribute {
-public:
-  StunErrorCodeAttribute(uint16 type, uint16 length);
-  ~StunErrorCodeAttribute();
-
-  static const uint16 MIN_SIZE = 4;
-
-  uint32 error_code() const { return (class_ << 8) | number_; }
-  uint8 error_class() const { return class_; }
-  uint8 number() const { return number_; }
-  const std::string& reason() const { return reason_; }
-
-  void SetErrorCode(uint32 code);
-  void SetErrorClass(uint8 eclass) { class_ = eclass; }
-  void SetNumber(uint8 number) { number_ = number; }
-  void SetReason(const std::string& reason);
-
-  bool Read(talk_base::ByteBuffer* buf);
-  void Write(talk_base::ByteBuffer* buf) const;
-
-private:
-  uint8 class_;
-  uint8 number_;
-  std::string reason_;
-};
-
-// Implements STUN/TURN attributs that record a list of attribute names.
-class StunUInt16ListAttribute : public StunAttribute {
-public:
-  StunUInt16ListAttribute(uint16 type, uint16 length);
-  ~StunUInt16ListAttribute();
-
-  size_t Size() const;
-  uint16 GetType(int index) const;
-  void SetType(int index, uint16 value);
-  void AddType(uint16 value);
-
-  bool Read(talk_base::ByteBuffer* buf);
-  void Write(talk_base::ByteBuffer* buf) const;
-
-private:
-  std::vector<uint16>* attr_types_;
-};
-
-// The special MAGIC-COOKIE attribute is used to distinguish TURN packets from
-// other kinds of traffic.
-// TODO: This value has nothing to do with STUN. Move it to a
-// separate file.
-extern const char TURN_MAGIC_COOKIE_VALUE[4];
-
-// Returns the (successful) response type for the given request type.
-StunMessageType GetStunResponseType(StunMessageType request_type);
-
-// Returns the error response type for the given request type.
-StunMessageType GetStunErrorResponseType(StunMessageType request_type);
-
-} // namespace cricket
-
-#endif  // TALK_P2P_BASE_STUN_H_
diff --git a/third_party/libjingle/source/talk/p2p/base/stun_unittest.cc b/third_party/libjingle/source/talk/p2p/base/stun_unittest.cc
deleted file mode 100644
index 34b6059..0000000
--- a/third_party/libjingle/source/talk/p2p/base/stun_unittest.cc
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- * libjingle
- * Copyright 2004 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string>
-
-#include "talk/base/bytebuffer.h"
-#include "talk/base/gunit.h"
-#include "talk/base/logging.h"
-#include "talk/p2p/base/stun.h"
-
-using namespace cricket;
-
-static const unsigned char INPUT_STUN[] = {
-  0x00, 0x01, 0x00, 135,   // message header
-  0x21, 0x12, 0xA4, 0x42,  // magic cookie
-  '0', '1', '2', '3',      // transaction id
-  '4', '5', '6', '7',
-  '8', '9', 'a', 'b',
-  0x00, 0x01, 0x00, 8,     // mapped address
-  0x00, 0x01, 0x00, 13,
-  0x00, 0x00, 0x00, 17,
-  0x00, 0x06, 0x00, 12,    // username
-  'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
-  0x00, 0x08, 0x00, 20,    // message integrity
-  'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
-  'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
-  0x00, 0x09, 0x00, 12,    // error code
-  0x00, 0x00, 2, 10,
-  'f', 'o', 'o', ' ', 'b', 'a', 'r', '!',
-  0x00, 0x0a, 0x00, 4,     // unknown attributes
-  0x00, 0x01, 0x00, 0x02,
-  0x00, 0x0d, 0x00, 4,     // lifetime
-  0x00, 0x00, 0x00, 11,
-  0x00, 0x0f, 0x00, 4,     // magic cookie
-  0x72, 0xc6, 0x4b, 0xc6,
-  0x00, 0x10, 0x00, 4,     // bandwidth
-  0x00, 0x00, 0x00, 6,
-  0x00, 0x11, 0x00, 8,     // destination address
-  0x00, 0x01, 0x00, 13,
-  0x00, 0x00, 0x00, 17,
-  0x00, 0x12, 0x00, 8,     // source address 2
-  0x00, 0x01, 0x00, 13,
-  0x00, 0x00, 0x00, 17,
-  0x00, 0x13, 0x00, 7,     // data
-  'a', 'b', 'c', 'd', 'e', 'f', 'g'
-};
-
-
-// RTCP packet, for testing we correctly ignore non stun packet types.
-// V=2, P=false, RC=0, Type=200, Len=6, Sender-SSRC=85, etc
-static const unsigned char INPUT_RTCP[] = {
-  0x80, 0xc8, 0x00, 0x06, 0x00, 0x00, 0x00, 0x55,
-  0xce, 0xa5, 0x18, 0x3a, 0x39, 0xcc, 0x7d, 0x09,
-  0x23, 0xed, 0x19, 0x07, 0x00, 0x00, 0x01, 0x56,
-  0x00, 0x03, 0x73, 0x50,
-};
-
-// STUN packet with a legacy header.
-static const unsigned char INPUT_LEGACY[] = {
-  0x00, 0x01, 0x00, 135,   // message header
-  '0', '1', '2', '3',      // transaction id
-  '4', '5', '6', '7',
-  '8', '9', 'a', 'b',
-  'c', 'd', 'e', 'f',
-  0x00, 0x01, 0x00, 8,     // mapped address
-  0x00, 0x01, 0x00, 13,
-  0x00, 0x00, 0x00, 17,
-  0x00, 0x06, 0x00, 12,    // username
-  'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
-  0x00, 0x08, 0x00, 20,    // message integrity
-  'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
-  'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
-  0x00, 0x09, 0x00, 12,    // error code
-  0x00, 0x00, 2, 10,
-  'f', 'o', 'o', ' ', 'b', 'a', 'r', '!',
-  0x00, 0x0a, 0x00, 4,     // unknown attributes
-  0x00, 0x01, 0x00, 0x02,
-  0x00, 0x0d, 0x00, 4,     // lifetime
-  0x00, 0x00, 0x00, 11,
-  0x00, 0x0f, 0x00, 4,     // magic cookie
-  0x72, 0xc6, 0x4b, 0xc6,
-  0x00, 0x10, 0x00, 4,     // bandwidth
-  0x00, 0x00, 0x00, 6,
-  0x00, 0x11, 0x00, 8,     // destination address
-  0x00, 0x01, 0x00, 13,
-  0x00, 0x00, 0x00, 17,
-  0x00, 0x12, 0x00, 8,     // source address 2
-  0x00, 0x01, 0x00, 13,
-  0x00, 0x00, 0x00, 17,
-  0x00, 0x13, 0x00, 7,     // data
-  'a', 'b', 'c', 'd', 'e', 'f', 'g'
-};
-
-static const unsigned char INPUT_STUN_UNKNOWN_ATTR[] = {
-  0x00, 0x01, 0x00, 0x1F,  // message header
-  0x21, 0x12, 0xA4, 0x42,  // magic cookie
-  '0', '1', '2', '3',      // transaction id
-  '4', '5', '6', '7',
-  '8', '9', 'a', 'b',
-  0x00, 0x01, 0x00, 8,     // mapped address
-  0x00, 0x01, 0x00, 13,
-  0x00, 0x00, 0x00, 17,
-  0x00, 0xaa, 0x00, 7,     // unknown attribute
-  'a', 'b', 'c', 'd', 'e', 'f', 'g',
-  0x00, 0x0d, 0x00, 4,     // lifetime
-  0x00, 0x00, 0x00, 11,
-};
-
-static const unsigned char INPUT_STUN_XOR_MAPPED_ADDRESS[] = {
-  0x00, 0x01, 0x00, 0x0c,  // message header
-  0x21, 0x12, 0xA4, 0x42,  // magic cookie
-  '0', '1', '2', '3',      // transaction id
-  '4', '5', '6', '7',
-  '8', '9', 'a', 'b',
-  0x00, 0x20, 0x00, 0x08,  // xor mapped address
-  0x00, 0x01, 0x21, 0x1F,
-  0x21, 0x12, 0xA4, 0x53,
-};
-
-static void DoTest(const char* input, size_t size, const char* transaction_id) {
-  StunMessage msg, msg2;
-
-  talk_base::ByteBuffer buf(input, size);
-  EXPECT_TRUE(msg.Read(&buf));
-
-  EXPECT_EQ(STUN_BINDING_REQUEST, msg.type());
-  EXPECT_EQ(size - 20, msg.length());
-  EXPECT_EQ(transaction_id, msg.transaction_id());
-
-  msg2.SetType(STUN_BINDING_REQUEST);
-  msg2.SetTransactionID(transaction_id);
-
-  const StunAddressAttribute* addr = msg.GetAddress(STUN_ATTR_MAPPED_ADDRESS);
-  EXPECT_TRUE(addr != NULL);
-  EXPECT_EQ(1, addr->family());
-  EXPECT_EQ(13, addr->port());
-  EXPECT_EQ(talk_base::IPAddress(17U), addr->ipaddr());
-
-  StunAddressAttribute* addr2 =
-      StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
-  addr2->SetPort(13);
-  addr2->SetIP(talk_base::IPAddress(17U));
-  msg2.AddAttribute(addr2);
-
-  const StunByteStringAttribute* bytes = msg.GetByteString(STUN_ATTR_USERNAME);
-  EXPECT_TRUE(bytes != NULL);
-  EXPECT_EQ(12, bytes->length());
-  EXPECT_EQ(0, memcmp(bytes->bytes(), "abcdefghijkl", bytes->length()));
-
-  StunByteStringAttribute* bytes2 =
-      StunAttribute::CreateByteString(STUN_ATTR_USERNAME);
-  bytes2->CopyBytes("abcdefghijkl");
-  msg2.AddAttribute(bytes2);
-
-  bytes = msg.GetByteString(STUN_ATTR_MESSAGE_INTEGRITY);
-  EXPECT_TRUE(bytes != NULL);
-  EXPECT_EQ(20, bytes->length());
-  EXPECT_EQ(0, memcmp(bytes->bytes(), "abcdefghijklmnopqrst", bytes->length()));
-
-  bytes2 = StunAttribute::CreateByteString(STUN_ATTR_MESSAGE_INTEGRITY);
-  bytes2->CopyBytes("abcdefghijklmnopqrst");
-  msg2.AddAttribute(bytes2);
-
-  const StunErrorCodeAttribute* ecode = msg.GetErrorCode();
-  EXPECT_TRUE(ecode != NULL);
-  EXPECT_EQ(2, ecode->error_class());
-  EXPECT_EQ(10, ecode->number());
-  EXPECT_EQ("foo bar!", ecode->reason());
-
-  StunErrorCodeAttribute* ecode2 = StunAttribute::CreateErrorCode();
-  ecode2->SetErrorClass(2);
-  ecode2->SetNumber(10);
-  ecode2->SetReason("foo bar!");
-  msg2.AddAttribute(ecode2);
-
-  const StunUInt16ListAttribute* unknown = msg.GetUnknownAttributes();
-  EXPECT_TRUE(unknown != NULL);
-  EXPECT_EQ(2U, unknown->Size());
-  EXPECT_EQ(1U, unknown->GetType(0));
-  EXPECT_EQ(2U, unknown->GetType(1));
-
-  StunUInt16ListAttribute* unknown2 = StunAttribute::CreateUnknownAttributes();
-  unknown2->AddType(1);
-  unknown2->AddType(2);
-  msg2.AddAttribute(unknown2);
-
-  const StunUInt32Attribute* uval = msg.GetUInt32(STUN_ATTR_LIFETIME);
-  EXPECT_TRUE(uval != NULL);
-  EXPECT_EQ(11U, uval->value());
-
-  StunUInt32Attribute* uval2 = StunAttribute::CreateUInt32(STUN_ATTR_LIFETIME);
-  uval2->SetValue(11);
-  msg2.AddAttribute(uval2);
-
-  bytes = msg.GetByteString(STUN_ATTR_MAGIC_COOKIE);
-  EXPECT_TRUE(bytes != NULL);
-  EXPECT_EQ(4, bytes->length());
-  EXPECT_EQ(0, memcmp(bytes->bytes(), TURN_MAGIC_COOKIE_VALUE,
-                      sizeof(TURN_MAGIC_COOKIE_VALUE)));
-
-  bytes2 = StunAttribute::CreateByteString(STUN_ATTR_MAGIC_COOKIE);
-  bytes2->CopyBytes(reinterpret_cast<const char*>(TURN_MAGIC_COOKIE_VALUE),
-                    sizeof(TURN_MAGIC_COOKIE_VALUE));
-  msg2.AddAttribute(bytes2);
-
-  uval = msg.GetUInt32(STUN_ATTR_BANDWIDTH);
-  EXPECT_TRUE(uval != NULL);
-  EXPECT_EQ(6U, uval->value());
-
-  uval2 = StunAttribute::CreateUInt32(STUN_ATTR_BANDWIDTH);
-  uval2->SetValue(6);
-  msg2.AddAttribute(uval2);
-
-  addr = msg.GetAddress(STUN_ATTR_DESTINATION_ADDRESS);
-  EXPECT_TRUE(addr != NULL);
-  EXPECT_EQ(1, addr->family());
-  EXPECT_EQ(13, addr->port());
-  EXPECT_EQ(talk_base::IPAddress(17U), addr->ipaddr());
-
-  addr2 = StunAttribute::CreateAddress(STUN_ATTR_DESTINATION_ADDRESS);
-  addr2->SetPort(13);
-  addr2->SetIP(talk_base::IPAddress(17U));
-  msg2.AddAttribute(addr2);
-
-  addr = msg.GetAddress(STUN_ATTR_SOURCE_ADDRESS2);
-  EXPECT_TRUE(addr != NULL);
-  EXPECT_EQ(1, addr->family());
-  EXPECT_EQ(13, addr->port());
-  EXPECT_EQ(talk_base::IPAddress(17U), addr->ipaddr());
-
-  addr2 = StunAttribute::CreateAddress(STUN_ATTR_SOURCE_ADDRESS2);
-  addr2->SetPort(13);
-  addr2->SetIP(talk_base::IPAddress(17U));
-  msg2.AddAttribute(addr2);
-
-  bytes = msg.GetByteString(STUN_ATTR_DATA);
-  EXPECT_TRUE(bytes != NULL);
-  EXPECT_EQ(7, bytes->length());
-  EXPECT_EQ(0, memcmp(bytes->bytes(), "abcdefg", bytes->length()));
-
-  bytes2 = StunAttribute::CreateByteString(STUN_ATTR_DATA);
-  bytes2->CopyBytes("abcdefg");
-  msg2.AddAttribute(bytes2);
-
-  talk_base::ByteBuffer out;
-  msg.Write(&out);
-  EXPECT_EQ(size, out.Length());
-  EXPECT_EQ(0, memcmp(out.Data(), input, out.Length()));
-
-  talk_base::ByteBuffer out2;
-  msg2.Write(&out2);
-  EXPECT_EQ(size, out2.Length());
-  EXPECT_EQ(0, memcmp(out2.Data(), input, out2.Length()));
-}
-
-TEST(StunTest, TestStunPacket) {
-  DoTest(reinterpret_cast<const char*>(INPUT_STUN), sizeof(INPUT_STUN),
-         "0123456789ab");
-}
-
-TEST(StunTest, TestRejectsRtcpPacket) {
-  StunMessage msg;
-
-  talk_base::ByteBuffer buf(
-      reinterpret_cast<const char*>(INPUT_RTCP), sizeof(INPUT_RTCP));
-  EXPECT_FALSE(msg.Read(&buf));
-}
-
-TEST(StunTest, TestLegacyPacket) {
-  DoTest(reinterpret_cast<const char*>(INPUT_LEGACY),
-         sizeof(INPUT_LEGACY), "0123456789abcdef");
-}
-
-TEST(StunTest, TestIgnoreUnknownAttr) {
-  StunMessage msg;
-  talk_base::ByteBuffer buf(
-      reinterpret_cast<const char*>(INPUT_STUN_UNKNOWN_ATTR),
-      sizeof(INPUT_STUN_UNKNOWN_ATTR));
-  EXPECT_TRUE(msg.Read(&buf));
-
-  const StunAddressAttribute* addr = msg.GetAddress(STUN_ATTR_MAPPED_ADDRESS);
-  EXPECT_TRUE(addr != NULL);
-  EXPECT_EQ(1, addr->family());
-  EXPECT_EQ(13, addr->port());
-  EXPECT_EQ(talk_base::IPAddress(17U), addr->ipaddr());
-
-  const StunUInt32Attribute* uval = msg.GetUInt32(STUN_ATTR_LIFETIME);
-  EXPECT_TRUE(uval != NULL);
-  EXPECT_EQ(11U, uval->value());
-}
-
-TEST(StunTest, TestXorMappedAddress) {
-  StunMessage msg;
-  talk_base::ByteBuffer buf(
-      reinterpret_cast<const char*>(INPUT_STUN_XOR_MAPPED_ADDRESS),
-      sizeof(INPUT_STUN_XOR_MAPPED_ADDRESS));
-  EXPECT_TRUE(msg.Read(&buf));
-
-  const StunAddressAttribute* addr = msg.GetAddress(STUN_ATTR_MAPPED_ADDRESS);
-  EXPECT_TRUE(addr != NULL);
-  EXPECT_EQ(1, addr->family());
-  EXPECT_EQ(13, addr->port());
-  EXPECT_EQ(talk_base::IPAddress(17U), addr->ipaddr());
-
-  addr = msg.GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
-  EXPECT_TRUE(addr != NULL);
-  EXPECT_EQ(1, addr->family());
-  EXPECT_EQ(13, addr->port());
-  EXPECT_EQ(talk_base::IPAddress(17U), addr->ipaddr());
-}
diff --git a/third_party/libjingle/source/talk/p2p/base/stunport.cc b/third_party/libjingle/source/talk/p2p/base/stunport.cc
deleted file mode 100644
index 7328b99..0000000
--- a/third_party/libjingle/source/talk/p2p/base/stunport.cc
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/p2p/base/stunport.h"
-
-#include "talk/base/common.h"
-#include "talk/base/logging.h"
-#include "talk/base/helpers.h"
-#include "talk/base/nethelpers.h"
-#include "talk/p2p/base/common.h"
-
-namespace cricket {
-
-// TODO: Move these to a common place (used in relayport too)
-const int KEEPALIVE_DELAY = 10 * 1000;  // 10 seconds - sort timeouts
-const int RETRY_DELAY = 50;             // 50ms, from ICE spec
-const int RETRY_TIMEOUT = 50 * 1000;    // ICE says 50 secs
-
-// Handles a binding request sent to the STUN server.
-class StunPortBindingRequest : public StunRequest {
- public:
-  StunPortBindingRequest(StunPort* port, bool keep_alive,
-                         const talk_base::SocketAddress& addr)
-    : port_(port), keep_alive_(keep_alive), server_addr_(addr) {
-    start_time_ = talk_base::Time();
-  }
-
-  virtual ~StunPortBindingRequest() {
-  }
-
-  const talk_base::SocketAddress& server_addr() const { return server_addr_; }
-
-  virtual void Prepare(StunMessage* request) {
-    request->SetType(STUN_BINDING_REQUEST);
-  }
-
-  virtual void OnResponse(StunMessage* response) {
-    const StunAddressAttribute* addr_attr =
-        response->GetAddress(STUN_ATTR_MAPPED_ADDRESS);
-    if (!addr_attr) {
-      LOG(LS_ERROR) << "Binding response missing mapped address.";
-    } else if (addr_attr->family() != 1) {
-      LOG(LS_ERROR) << "Binding address has bad family";
-    } else {
-      talk_base::SocketAddress addr(addr_attr->ipaddr(), addr_attr->port());
-      port_->AddAddress(addr, "udp", true);
-    }
-
-    // We will do a keep-alive regardless of whether this request suceeds.
-    // This should have almost no impact on network usage.
-    if (keep_alive_) {
-      port_->requests_.SendDelayed(
-          new StunPortBindingRequest(port_, true, server_addr_),
-          KEEPALIVE_DELAY);
-    }
-  }
-
-  virtual void OnErrorResponse(StunMessage* response) {
-    const StunErrorCodeAttribute* attr = response->GetErrorCode();
-    if (!attr) {
-      LOG(LS_ERROR) << "Bad allocate response error code";
-    } else {
-      LOG(LS_ERROR) << "Binding error response:"
-                 << " class=" << attr->error_class()
-                 << " number=" << attr->number()
-                 << " reason='" << attr->reason() << "'";
-    }
-
-    port_->SignalAddressError(port_);
-
-    if (keep_alive_
-        && (talk_base::TimeSince(start_time_) <= RETRY_TIMEOUT)) {
-      port_->requests_.SendDelayed(
-          new StunPortBindingRequest(port_, true, server_addr_),
-          KEEPALIVE_DELAY);
-    }
-  }
-
-  virtual void OnTimeout() {
-    LOG(LS_ERROR) << "Binding request timed out from "
-      << port_->GetLocalAddress().ToString()
-      << " (" << port_->network()->name() << ")";
-
-    port_->SignalAddressError(port_);
-
-    if (keep_alive_
-        && (talk_base::TimeSince(start_time_) <= RETRY_TIMEOUT)) {
-      port_->requests_.SendDelayed(
-          new StunPortBindingRequest(port_, true, server_addr_),
-          RETRY_DELAY);
-    }
-  }
-
- private:
-  StunPort* port_;
-  bool keep_alive_;
-  talk_base::SocketAddress server_addr_;
-  uint32 start_time_;
-};
-
-const char STUN_PORT_TYPE[] = "stun";
-
-StunPort::StunPort(talk_base::Thread* thread,
-                   talk_base::PacketSocketFactory* factory,
-                   talk_base::Network* network,
-                   const talk_base::IPAddress& ip, int min_port, int max_port,
-                   const talk_base::SocketAddress& server_addr)
-    : Port(thread, STUN_PORT_TYPE, factory, network, ip, min_port, max_port),
-      server_addr_(server_addr),
-      requests_(thread),
-      socket_(NULL),
-      error_(0),
-      resolver_(NULL) {
-  requests_.SignalSendPacket.connect(this, &StunPort::OnSendPacket);
-}
-
-bool StunPort::Init() {
-  socket_ = factory_->CreateUdpSocket(
-      talk_base::SocketAddress(ip_, 0), min_port_, max_port_);
-  if (!socket_) {
-    LOG_J(LS_WARNING, this) << "UDP socket creation failed";
-    return false;
-  }
-  socket_->SignalReadPacket.connect(this, &StunPort::OnReadPacket);
-  return true;
-}
-
-StunPort::~StunPort() {
-  if (resolver_) {
-    resolver_->Destroy(false);
-  }
-  delete socket_;
-}
-
-void StunPort::PrepareAddress() {
-  // We will keep pinging the stun server to make sure our NAT pin-hole stays
-  // open during the call.
-  if (server_addr_.IsUnresolved()) {
-    ResolveStunAddress();
-  } else {
-    requests_.Send(new StunPortBindingRequest(this, true, server_addr_));
-  }
-}
-
-void StunPort::PrepareSecondaryAddress() {
-  // DNS resolution of the secondary address is not currently supported.
-  ASSERT(!server_addr2_.IsAny());
-  requests_.Send(new StunPortBindingRequest(this, false, server_addr2_));
-}
-
-Connection* StunPort::CreateConnection(const Candidate& address,
-                                       CandidateOrigin origin) {
-  if (address.protocol() != "udp")
-    return NULL;
-
-  Connection* conn = new ProxyConnection(this, 0, address);
-  AddConnection(conn);
-  return conn;
-}
-
-int StunPort::SendTo(const void* data, size_t size,
-                     const talk_base::SocketAddress& addr, bool payload) {
-  int sent = socket_->SendTo(data, size, addr);
-  if (sent < 0) {
-    error_ = socket_->GetError();
-    LOG_J(LS_ERROR, this) << "UDP send of " << size
-                          << " bytes failed with error " << error_;
-  }
-  return sent;
-}
-
-int StunPort::SetOption(talk_base::Socket::Option opt, int value) {
-  return socket_->SetOption(opt, value);
-}
-
-int StunPort::GetError() {
-  return error_;
-}
-
-void StunPort::OnReadPacket(talk_base::AsyncPacketSocket* socket,
-                            const char* data, size_t size,
-                            const talk_base::SocketAddress& remote_addr) {
-  ASSERT(socket == socket_);
-
-  // Look for a response from the STUN server.
-  // Even if the response doesn't match one of our outstanding requests, we
-  // will eat it because it might be a response to a retransmitted packet, and
-  // we already cleared the request when we got the first response.
-  ASSERT(!server_addr_.IsUnresolved());
-  if (remote_addr == server_addr_ || remote_addr == server_addr2_) {
-    requests_.CheckResponse(data, size);
-    return;
-  }
-
-  if (Connection* conn = GetConnection(remote_addr)) {
-    conn->OnReadPacket(data, size);
-  } else {
-    Port::OnReadPacket(data, size, remote_addr);
-  }
-}
-
-void StunPort::ResolveStunAddress() {
-  if (resolver_)
-    return;
-
-  resolver_ = new talk_base::AsyncResolver();
-  resolver_->SignalWorkDone.connect(this, &StunPort::OnResolveResult);
-  resolver_->set_address(server_addr_);
-  resolver_->Start();
-}
-
-void StunPort::OnResolveResult(talk_base::SignalThread* t) {
-  ASSERT(t == resolver_);
-  if (resolver_->error() != 0) {
-    LOG_J(LS_WARNING, this) << "StunPort: stun host lookup received error "
-                            << resolver_->error();
-    SignalAddressError(this);
-  }
-
-  server_addr_ = resolver_->address();
-  PrepareAddress();
-}
-
-// TODO: merge this with SendTo above.
-void StunPort::OnSendPacket(const void* data, size_t size, StunRequest* req) {
-  StunPortBindingRequest* sreq = static_cast<StunPortBindingRequest*>(req);
-  if (socket_->SendTo(data, size, sreq->server_addr()) < 0)
-    PLOG(LERROR, socket_->GetError()) << "sendto";
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/p2p/base/stunport.h b/third_party/libjingle/source/talk/p2p/base/stunport.h
deleted file mode 100644
index c74ad4d..0000000
--- a/third_party/libjingle/source/talk/p2p/base/stunport.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_P2P_BASE_STUNPORT_H_
-#define TALK_P2P_BASE_STUNPORT_H_
-
-#include <string>
-
-#include "talk/base/asyncpacketsocket.h"
-#include "talk/p2p/base/udpport.h"
-#include "talk/p2p/base/stunrequest.h"
-
-namespace talk_base {
-class AsyncResolver;
-class SignalThread;
-}
-
-namespace cricket {
-
-extern const char STUN_PORT_TYPE[];
-
-// Communicates using the address on the outside of a NAT.
-class StunPort : public Port {
- public:
-  static StunPort* Create(talk_base::Thread* thread,
-                          talk_base::PacketSocketFactory* factory,
-                          talk_base::Network* network,
-                          const talk_base::IPAddress& ip,
-                          int min_port, int max_port,
-                          const talk_base::SocketAddress& server_addr) {
-    StunPort* port = new StunPort(thread, factory, network,
-                                  ip, min_port, max_port, server_addr);
-    if (!port->Init()) {
-      delete port;
-      port = NULL;
-    }
-    return port;
-  }
-  virtual ~StunPort();
-
-  talk_base::SocketAddress GetLocalAddress() const {
-    return socket_->GetLocalAddress();
-  }
-
-  const talk_base::SocketAddress& server_addr() const { return server_addr_; }
-  void set_server_addr(const talk_base::SocketAddress& addr) {
-    server_addr_ = addr;
-  }
-
-  const talk_base::SocketAddress& server_addr2() const { return server_addr2_; }
-  void set_server_addr2(const talk_base::SocketAddress& addr) {
-    server_addr2_ = addr;
-  }
-
-  virtual void PrepareAddress();
-
-  // This will contact the secondary server and signal another candidate
-  // address for this port (which may be the same as the first address).
-  void PrepareSecondaryAddress();
-
-  virtual Connection* CreateConnection(const Candidate& address,
-                                       CandidateOrigin origin);
-  virtual int SetOption(talk_base::Socket::Option opt, int value);
-  virtual int GetError();
-
- protected:
-  StunPort(talk_base::Thread* thread, talk_base::PacketSocketFactory* factory,
-           talk_base::Network* network, const talk_base::IPAddress& ip,
-           int min_port, int max_port,
-           const talk_base::SocketAddress& server_addr);
-  bool Init();
-
-  virtual int SendTo(const void* data, size_t size,
-                     const talk_base::SocketAddress& addr, bool payload);
-
-  void OnReadPacket(talk_base::AsyncPacketSocket* socket,
-                    const char* data, size_t size,
-                    const talk_base::SocketAddress& remote_addr);
-
- private:
-  // DNS resolution of the STUN server.
-  void ResolveStunAddress();
-  void OnResolveResult(talk_base::SignalThread* thread);
-  // Sends STUN requests to the server.
-  void OnSendPacket(const void* data, size_t size, StunRequest* req);
-
-  talk_base::SocketAddress server_addr_;
-  talk_base::SocketAddress server_addr2_;
-  StunRequestManager requests_;
-  talk_base::AsyncPacketSocket* socket_;
-  int error_;
-  talk_base::AsyncResolver* resolver_;
-
-  friend class StunPortBindingRequest;
-};
-
-}  // namespace cricket
-
-#endif  // TALK_P2P_BASE_STUNPORT_H_
diff --git a/third_party/libjingle/source/talk/p2p/base/stunport_unittest.cc b/third_party/libjingle/source/talk/p2p/base/stunport_unittest.cc
deleted file mode 100644
index 3d830ba..0000000
--- a/third_party/libjingle/source/talk/p2p/base/stunport_unittest.cc
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * libjingle
- * Copyright 2009 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/basicpacketsocketfactory.h"
-#include "talk/base/gunit.h"
-#include "talk/base/helpers.h"
-#include "talk/base/socketaddress.h"
-#include "talk/p2p/base/stunport.h"
-#include "talk/p2p/base/teststunserver.h"
-
-using talk_base::SocketAddress;
-
-static const SocketAddress kLocalAddr("127.0.0.1", 0);
-static const SocketAddress kStunAddr("127.0.0.1", 5000);
-static const SocketAddress kBadAddr("0.0.0.1", 5000);
-static const SocketAddress kStunHostnameAddr("localhost", 5000);
-static const SocketAddress kBadHostnameAddr("not-a-real-hostname", 5000);
-static const int kTimeoutMs = 10000;
-
-// Tests connecting a StunPort to a fake STUN server (cricket::StunServer)
-// TODO: Use a VirtualSocketServer here. We have to use a
-// PhysicalSocketServer right now since DNS is not part of SocketServer yet.
-class StunPortTest : public testing::Test,
-                     public sigslot::has_slots<> {
- public:
-  StunPortTest()
-      : network_("unittest", "unittest", talk_base::IPAddress(INADDR_ANY)),
-        socket_factory_(talk_base::Thread::Current()),
-        stun_server_(new cricket::TestStunServer(
-          talk_base::Thread::Current(), kStunAddr)),
-        done_(false), error_(false) {
-  }
-
-  const cricket::Port* port() const { return stun_port_.get(); }
-  bool done() const { return done_; }
-  bool error() const { return error_; }
-
-  void CreateStunPort(const talk_base::SocketAddress& server_addr) {
-    stun_port_.reset(cricket::StunPort::Create(
-        talk_base::Thread::Current(), &socket_factory_, &network_,
-        kLocalAddr.ipaddr(), 0, 0, server_addr));
-    stun_port_->SignalAddressReady.connect(this,
-        &StunPortTest::OnAddressReady);
-    stun_port_->SignalAddressError.connect(this,
-        &StunPortTest::OnAddressError);
-  }
-
-  void PrepareAddress() {
-    stun_port_->PrepareAddress();
-  }
-
- protected:
-  static void SetUpTestCase() {
-    // Ensure the RNG is inited.
-    talk_base::InitRandom(NULL, 0);
-  }
-
-  void OnAddressReady(cricket::Port* port) {
-    done_ = true;
-    error_ = false;
-  }
-  void OnAddressError(cricket::Port* port) {
-    done_ = true;
-    error_ = true;
-  }
-
- private:
-  talk_base::Network network_;
-  talk_base::BasicPacketSocketFactory socket_factory_;
-  talk_base::scoped_ptr<cricket::StunPort> stun_port_;
-  talk_base::scoped_ptr<cricket::TestStunServer> stun_server_;
-  bool done_;
-  bool error_;
-};
-
-// Test that we can create a STUN port
-TEST_F(StunPortTest, TestBasic) {
-  CreateStunPort(kStunAddr);
-  EXPECT_EQ("stun", port()->type());
-  EXPECT_EQ(0U, port()->candidates().size());
-}
-
-// Test that we can get an address from a STUN server.
-TEST_F(StunPortTest, TestPrepareAddress) {
-  CreateStunPort(kStunAddr);
-  PrepareAddress();
-  EXPECT_TRUE_WAIT(done(), kTimeoutMs);
-  ASSERT_EQ(1U, port()->candidates().size());
-  EXPECT_TRUE(kLocalAddr.EqualIPs(port()->candidates()[0].address()));
-}
-
-// Test that we fail properly if we can't get an address.
-TEST_F(StunPortTest, TestPrepareAddressFail) {
-  CreateStunPort(kBadAddr);
-  PrepareAddress();
-  EXPECT_TRUE_WAIT(done(), kTimeoutMs);
-  EXPECT_TRUE(error());
-  EXPECT_EQ(0U, port()->candidates().size());
-}
-
-// Test that we can get an address from a STUN server specified by a hostname.
-TEST_F(StunPortTest, TestPrepareAddressHostname) {
-  CreateStunPort(kStunHostnameAddr);
-  PrepareAddress();
-  EXPECT_TRUE_WAIT(done(), kTimeoutMs);
-  ASSERT_EQ(1U, port()->candidates().size());
-  EXPECT_TRUE(kLocalAddr.EqualIPs(port()->candidates()[0].address()));
-}
-
-// Test that we handle hostname lookup failures properly.
-TEST_F(StunPortTest, TestPrepareAddressHostnameFail) {
-  CreateStunPort(kBadHostnameAddr);
-  PrepareAddress();
-  EXPECT_TRUE_WAIT(done(), kTimeoutMs);
-  EXPECT_TRUE(error());
-  EXPECT_EQ(0U, port()->candidates().size());
-}
diff --git a/third_party/libjingle/source/talk/p2p/base/stunrequest.cc b/third_party/libjingle/source/talk/p2p/base/stunrequest.cc
deleted file mode 100644
index f1fd2ac..0000000
--- a/third_party/libjingle/source/talk/p2p/base/stunrequest.cc
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/p2p/base/stunrequest.h"
-
-#include "talk/base/common.h"
-#include "talk/base/helpers.h"
-#include "talk/base/logging.h"
-
-namespace cricket {
-
-const uint32 MSG_STUN_SEND = 1;
-
-const int MAX_SENDS = 9;
-const int DELAY_UNIT = 100;  // 100 milliseconds
-const int DELAY_MAX_FACTOR = 16;
-
-StunRequestManager::StunRequestManager(talk_base::Thread* thread)
-    : thread_(thread) {
-}
-
-StunRequestManager::~StunRequestManager() {
-  while (requests_.begin() != requests_.end()) {
-    StunRequest *request = requests_.begin()->second;
-    requests_.erase(requests_.begin());
-    delete request;
-  }
-}
-
-void StunRequestManager::Send(StunRequest* request) {
-  SendDelayed(request, 0);
-}
-
-void StunRequestManager::SendDelayed(StunRequest* request, int delay) {
-  request->set_manager(this);
-  ASSERT(requests_.find(request->id()) == requests_.end());
-  request->Construct();
-  requests_[request->id()] = request;
-  thread_->PostDelayed(delay, request, MSG_STUN_SEND, NULL);
-}
-
-void StunRequestManager::Remove(StunRequest* request) {
-  ASSERT(request->manager() == this);
-  RequestMap::iterator iter = requests_.find(request->id());
-  if (iter != requests_.end()) {
-    ASSERT(iter->second == request);
-    requests_.erase(iter);
-    thread_->Clear(request);
-  }
-}
-
-void StunRequestManager::Clear() {
-  std::vector<StunRequest*> requests;
-  for (RequestMap::iterator i = requests_.begin(); i != requests_.end(); ++i)
-    requests.push_back(i->second);
-
-  for (uint32 i = 0; i < requests.size(); ++i) {
-    // StunRequest destructor calls Remove() which deletes requests
-    // from |requests_|.
-    delete requests[i];
-  }
-}
-
-bool StunRequestManager::CheckResponse(StunMessage* msg) {
-  RequestMap::iterator iter = requests_.find(msg->transaction_id());
-  if (iter == requests_.end())
-    return false;
-
-  StunRequest* request = iter->second;
-  if (msg->type() == GetStunResponseType(request->type())) {
-    request->OnResponse(msg);
-  } else if (msg->type() == GetStunErrorResponseType(request->type())) {
-    request->OnErrorResponse(msg);
-  } else {
-    LOG(LERROR) << "Received response with wrong type: " << msg->type()
-               << " (expecting " << GetStunResponseType(request->type()) << ")";
-    return false;
-  }
-
-  delete request;
-  return true;
-}
-
-bool StunRequestManager::CheckResponse(const char* data, size_t size) {
-  // Check the appropriate bytes of the stream to see if they match the
-  // transaction ID of a response we are expecting.
-
-  if (size < 20)
-    return false;
-
-  std::string id;
-  id.append(data + kStunTransactionIdOffset, kStunTransactionIdLength);
-
-  RequestMap::iterator iter = requests_.find(id);
-  if (iter == requests_.end())
-    return false;
-
-  // Parse the STUN message and continue processing as usual.
-
-  talk_base::ByteBuffer buf(data, size);
-  StunMessage msg;
-  if (!msg.Read(&buf))
-    return false;
-
-  return CheckResponse(&msg);
-}
-
-StunRequest::StunRequest()
-    : count_(0), timeout_(false), manager_(0),
-      id_(talk_base::CreateRandomString(kStunTransactionIdLength)),
-      msg_(new StunMessage()),
-      tstamp_(0) {
-  msg_->SetTransactionID(id_);
-}
-
-StunRequest::StunRequest(StunMessage* request)
-  : count_(0), timeout_(false), manager_(0),
-    id_(request->transaction_id()), msg_(request) {
-}
-
-StunRequest::~StunRequest() {
-  ASSERT(manager_ != NULL);
-  if (manager_) {
-    manager_->Remove(this);
-    manager_->thread_->Clear(this);
-  }
-  delete msg_;
-}
-
-void StunRequest::Construct() {
-  if (msg_->type() == 0) {
-    Prepare(msg_);
-    ASSERT(msg_->transaction_id() == id_);
-    ASSERT(msg_->type() != 0);
-  }
-}
-
-StunMessageType StunRequest::type() {
-  ASSERT(msg_ != NULL);
-  return msg_->type();
-}
-
-void StunRequest::set_manager(StunRequestManager* manager) {
-  ASSERT(!manager_);
-  manager_ = manager;
-}
-
-void StunRequest::OnMessage(talk_base::Message* pmsg) {
-  ASSERT(manager_ != NULL);
-  ASSERT(pmsg->message_id == MSG_STUN_SEND);
-
-  if (timeout_) {
-    OnTimeout();
-    delete this;
-    return;
-  }
-
-  tstamp_ = talk_base::Time();
-
-  talk_base::ByteBuffer buf;
-  msg_->Write(&buf);
-  manager_->SignalSendPacket(buf.Data(), buf.Length(), this);
-
-  int delay = GetNextDelay();
-  manager_->thread_->PostDelayed(delay, this, MSG_STUN_SEND, NULL);
-}
-
-uint32 StunRequest::Elapsed() const {
-  return talk_base::TimeSince(tstamp_);
-}
-
-int StunRequest::GetNextDelay() {
-  int delay = DELAY_UNIT * talk_base::_min(1 << count_, DELAY_MAX_FACTOR);
-  count_ += 1;
-  if (count_ == MAX_SENDS)
-    timeout_ = true;
-  return delay;
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/p2p/base/stunrequest.h b/third_party/libjingle/source/talk/p2p/base/stunrequest.h
deleted file mode 100644
index fea2c99..0000000
--- a/third_party/libjingle/source/talk/p2p/base/stunrequest.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_P2P_BASE_STUNREQUEST_H_
-#define TALK_P2P_BASE_STUNREQUEST_H_
-
-#include "talk/base/sigslot.h"
-#include "talk/base/thread.h"
-#include "talk/p2p/base/stun.h"
-#include <map>
-#include <string>
-
-namespace cricket {
-
-class StunRequest;
-
-// Manages a set of STUN requests, sending and resending until we receive a
-// response or determine that the request has timed out.
-class StunRequestManager {
-public:
-  StunRequestManager(talk_base::Thread* thread);
-  ~StunRequestManager();
-
-  // Starts sending the given request (perhaps after a delay).
-  void Send(StunRequest* request);
-  void SendDelayed(StunRequest* request, int delay);
-
-  // Removes a stun request that was added previously.  This will happen
-  // automatically when a request succeeds, fails, or times out.
-  void Remove(StunRequest* request);
-
-  // Removes all stun requests that were added previously.
-  void Clear();
-
-  // Determines whether the given message is a response to one of the
-  // outstanding requests, and if so, processes it appropriately.
-  bool CheckResponse(StunMessage* msg);
-  bool CheckResponse(const char* data, size_t size);
-
-  // Raised when there are bytes to be sent.
-  sigslot::signal3<const void*, size_t, StunRequest*> SignalSendPacket;
-
-private:
-  typedef std::map<std::string, StunRequest*> RequestMap;
-
-  talk_base::Thread* thread_;
-  RequestMap requests_;
-
-  friend class StunRequest;
-};
-
-// Represents an individual request to be sent.  The STUN message can either be
-// constructed beforehand or built on demand.
-class StunRequest : public talk_base::MessageHandler {
-public:
-  StunRequest();
-  StunRequest(StunMessage* request);
-  virtual ~StunRequest();
-
-  // Causes our wrapped StunMessage to be Prepared
-  void Construct();
-
-  // The manager handling this request (if it has been scheduled for sending).
-  StunRequestManager* manager() { return manager_; }
-
-  // Returns the transaction ID of this request.
-  const std::string& id() { return id_; }
-
-  // Returns the STUN type of the request message.
-  StunMessageType type();
-
-  // Handles messages for sending and timeout.
-  void OnMessage(talk_base::Message* pmsg);
-
-  // Time elapsed since last send (in ms)
-  uint32 Elapsed() const;
-
-protected:
-  int count_;
-  bool timeout_;
-
-  // Fills in a request object to be sent.  Note that request's transaction ID
-  // will already be set and cannot be changed.
-  virtual void Prepare(StunMessage* request) {}
-
-  // Called when the message receives a response or times out.
-  virtual void OnResponse(StunMessage* response) {}
-  virtual void OnErrorResponse(StunMessage* response) {}
-  virtual void OnTimeout() {}
-  virtual int GetNextDelay();
-
-private:
-  StunRequestManager* manager_;
-  std::string id_;
-  StunMessage* msg_;
-  uint32 tstamp_;
-
-  void set_manager(StunRequestManager* manager);
-
-  friend class StunRequestManager;
-};
-
-}  // namespace cricket
-
-#endif  // TALK_P2P_BASE_STUNREQUEST_H_
diff --git a/third_party/libjingle/source/talk/p2p/base/stunrequest_unittest.cc b/third_party/libjingle/source/talk/p2p/base/stunrequest_unittest.cc
deleted file mode 100644
index 524c5e6..0000000
--- a/third_party/libjingle/source/talk/p2p/base/stunrequest_unittest.cc
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * libjingle
- * Copyright 2004 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/gunit.h"
-#include "talk/base/helpers.h"
-#include "talk/base/logging.h"
-#include "talk/base/timeutils.h"
-#include "talk/p2p/base/stunrequest.h"
-
-using namespace cricket;
-
-class StunRequestTest : public testing::Test,
-                        public sigslot::has_slots<> {
- public:
-  static void SetUpTestCase() {
-    talk_base::InitRandom(NULL, 0);
-  }
-  StunRequestTest()
-      : manager_(talk_base::Thread::Current()),
-        request_count_(0), response_(NULL),
-        success_(false), failure_(false), timeout_(false) {
-    manager_.SignalSendPacket.connect(this, &StunRequestTest::OnSendPacket);
-  }
-
-  void OnSendPacket(const void* data, size_t size, StunRequest* req) {
-    request_count_++;
-  }
-
-  void OnResponse(StunMessage* res) {
-    response_ = res;
-    success_ = true;
-  }
-  void OnErrorResponse(StunMessage* res) {
-    response_ = res;
-    failure_ = true;
-  }
-  void OnTimeout() {
-    timeout_ = true;
-  }
-
- protected:
-  static StunMessage* CreateStunMessage(StunMessageType type,
-                                        StunMessage* req) {
-    StunMessage* msg = new StunMessage();
-    msg->SetType(type);
-    if (req) {
-      msg->SetTransactionID(req->transaction_id());
-    } else {
-      msg->SetTransactionID(
-          talk_base::CreateRandomString(kStunTransactionIdLength));
-    }
-    return msg;
-  }
-  static int TotalDelay(int sends) {
-    int total = 0;
-    for (int i = 0; i < sends; i++) {
-      if (i < 4)
-        total += 100 << i;
-      else
-        total += 1600;
-    }
-    return total;
-  }
-
-  StunRequestManager manager_;
-  int request_count_;
-  StunMessage* response_;
-  bool success_;
-  bool failure_;
-  bool timeout_;
-};
-
-// Forwards results to the test class.
-class StunRequestThunker : public StunRequest {
- public:
-  StunRequestThunker(StunMessage* msg, StunRequestTest* test)
-      : StunRequest(msg), test_(test) {}
-  explicit StunRequestThunker(StunRequestTest* test) : test_(test) {}
- private:
-  virtual void OnResponse(StunMessage* res) {
-    test_->OnResponse(res);
-  }
-  virtual void OnErrorResponse(StunMessage* res) {
-    test_->OnErrorResponse(res);
-  }
-  virtual void OnTimeout() {
-    test_->OnTimeout();
-  }
-
-  virtual void Prepare(StunMessage* request) {
-    request->SetType(STUN_BINDING_REQUEST);
-  }
-
-  StunRequestTest* test_;
-};
-
-// Test handling of a normal binding response.
-TEST_F(StunRequestTest, TestSuccess) {
-  StunMessage* req = CreateStunMessage(STUN_BINDING_REQUEST, NULL);
-  StunMessage* res = CreateStunMessage(STUN_BINDING_RESPONSE, req);
-
-  manager_.Send(new StunRequestThunker(req, this));
-  EXPECT_TRUE(manager_.CheckResponse(res));
-
-  EXPECT_TRUE(response_ == res);
-  EXPECT_TRUE(success_);
-  EXPECT_FALSE(failure_);
-  EXPECT_FALSE(timeout_);
-  delete res;
-}
-
-// Test handling of an error binding response.
-TEST_F(StunRequestTest, TestError) {
-  StunMessage* req = CreateStunMessage(STUN_BINDING_REQUEST, NULL);
-  StunMessage* res = CreateStunMessage(STUN_BINDING_ERROR_RESPONSE, req);
-
-  manager_.Send(new StunRequestThunker(req, this));
-  EXPECT_TRUE(manager_.CheckResponse(res));
-
-  EXPECT_TRUE(response_ == res);
-  EXPECT_FALSE(success_);
-  EXPECT_TRUE(failure_);
-  EXPECT_FALSE(timeout_);
-  delete res;
-}
-
-// Test handling of a binding response with the wrong transaction id.
-TEST_F(StunRequestTest, TestUnexpected) {
-  StunMessage* req = CreateStunMessage(STUN_BINDING_REQUEST, NULL);
-  StunMessage* res = CreateStunMessage(STUN_BINDING_RESPONSE, NULL);
-
-  manager_.Send(new StunRequestThunker(req, this));
-  EXPECT_FALSE(manager_.CheckResponse(res));
-
-  EXPECT_TRUE(response_ == NULL);
-  EXPECT_FALSE(success_);
-  EXPECT_FALSE(failure_);
-  EXPECT_FALSE(timeout_);
-  delete res;
-}
-
-// Test that requests are sent at the right times, and that the 9th request
-// (sent at 7900 ms) can be properly replied to.
-TEST_F(StunRequestTest, TestBackoff) {
-  StunMessage* req = CreateStunMessage(STUN_BINDING_REQUEST, NULL);
-  StunMessage* res = CreateStunMessage(STUN_BINDING_RESPONSE, req);
-
-  uint32 start = talk_base::Time();
-  manager_.Send(new StunRequestThunker(req, this));
-  for (int i = 0; i < 9; ++i) {
-    while (request_count_ == i)
-      talk_base::Thread::Current()->ProcessMessages(1);
-    int32 elapsed = talk_base::TimeSince(start);
-    LOG(LS_INFO) << "STUN request #" << (i + 1)
-                 << " sent at " << elapsed << " ms";
-    EXPECT_GE(TotalDelay(i + 1), elapsed);
-  }
-  EXPECT_TRUE(manager_.CheckResponse(res));
-
-  EXPECT_TRUE(response_ == res);
-  EXPECT_TRUE(success_);
-  EXPECT_FALSE(failure_);
-  EXPECT_FALSE(timeout_);
-  delete res;
-}
-
-// Test that we timeout properly if no response is received in 9500 ms.
-TEST_F(StunRequestTest, TestTimeout) {
-  StunMessage* req = CreateStunMessage(STUN_BINDING_REQUEST, NULL);
-  StunMessage* res = CreateStunMessage(STUN_BINDING_RESPONSE, req);
-
-  manager_.Send(new StunRequestThunker(req, this));
-  talk_base::Thread::Current()->ProcessMessages(10000);  // > STUN timeout
-  EXPECT_FALSE(manager_.CheckResponse(res));
-
-  EXPECT_TRUE(response_ == NULL);
-  EXPECT_FALSE(success_);
-  EXPECT_FALSE(failure_);
-  EXPECT_TRUE(timeout_);
-  delete res;
-}
-
-// Regression test for specific crash where we receive a response with the
-// same id as a request that doesn't have an underlying StunMessage yet.
-TEST_F(StunRequestTest, TestNoEmptyRequest) {
-  StunRequestThunker* request = new StunRequestThunker(this);
-
-  manager_.SendDelayed(request, 100);
-
-  StunMessage dummy_req;
-  dummy_req.SetTransactionID(request->id());
-  StunMessage* res = CreateStunMessage(STUN_BINDING_RESPONSE, &dummy_req);
-
-  EXPECT_TRUE(manager_.CheckResponse(res));
-
-  EXPECT_TRUE(response_ == res);
-  EXPECT_TRUE(success_);
-  EXPECT_FALSE(failure_);
-  EXPECT_FALSE(timeout_);
-  delete res;
-}
diff --git a/third_party/libjingle/source/talk/p2p/base/stunserver.cc b/third_party/libjingle/source/talk/p2p/base/stunserver.cc
deleted file mode 100644
index 8a5d447..0000000
--- a/third_party/libjingle/source/talk/p2p/base/stunserver.cc
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifdef POSIX
-#include <errno.h>
-#endif  // POSIX
-
-#include "talk/p2p/base/stunserver.h"
-#include "talk/base/bytebuffer.h"
-#include "talk/base/logging.h"
-
-namespace cricket {
-
-StunServer::StunServer(talk_base::AsyncUDPSocket* socket) : socket_(socket) {
-  socket_->SignalReadPacket.connect(this, &StunServer::OnPacket);
-}
-
-StunServer::~StunServer() {
-  socket_->SignalReadPacket.disconnect(this);
-}
-
-void StunServer::OnPacket(
-    talk_base::AsyncPacketSocket* socket, const char* buf, size_t size,
-    const talk_base::SocketAddress& remote_addr) {
-
-  // TODO: If appropriate, look for the magic cookie before parsing.
-
-  // Parse the STUN message.
-  talk_base::ByteBuffer bbuf(buf, size);
-  StunMessage msg;
-  if (!msg.Read(&bbuf)) {
-    SendErrorResponse(msg, remote_addr, 400, "Bad Request");
-    return;
-  }
-
-  // TODO: If this is UDP, then we shouldn't allow non-fully-parsed messages.
-
-  // TODO: If unknown non-optiional (<= 0x7fff) attributes are found, send a
-  //       420 "Unknown Attribute" response.
-
-  // TODO: Check that a message-integrity attribute was given (or send 401
-  //       "Unauthorized").  Check that a username attribute was given (or send
-  //       432 "Missing Username").  Look up the username and password.  If it
-  //       is missing or the HMAC is wrong, send 431 "Integrity Check Failure".
-
-  // Send the message to the appropriate handler function.
-  switch (msg.type()) {
-  case STUN_BINDING_REQUEST:
-    OnBindingRequest(&msg, remote_addr);
-    return;
-
-  case STUN_ALLOCATE_REQUEST:
-    OnAllocateRequest(&msg, remote_addr);
-    return;
-
-  default:
-    SendErrorResponse(msg, remote_addr, 600, "Operation Not Supported");
-  }
-}
-
-void StunServer::OnBindingRequest(
-    StunMessage* msg, const talk_base::SocketAddress& remote_addr) {
-  StunMessage response;
-  response.SetType(STUN_BINDING_RESPONSE);
-  response.SetTransactionID(msg->transaction_id());
-
-  // Tell the user the address that we received their request from.
-  StunAddressAttribute* mapped_addr;
-  if (!msg->IsLegacy()) {
-    mapped_addr = StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
-  } else {
-    mapped_addr = StunAttribute::CreateAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
-  }
-  mapped_addr->SetPort(remote_addr.port());
-  mapped_addr->SetIP(remote_addr.ipaddr());
-  response.AddAttribute(mapped_addr);
-
-  // TODO: Add username and message-integrity.
-
-  SendResponse(response, remote_addr);
-}
-
-void StunServer::OnAllocateRequest(
-    StunMessage* msg, const talk_base::SocketAddress& addr) {
-  SendErrorResponse(*msg, addr, 600, "Operation Not Supported");
-}
-
-void StunServer::OnSharedSecretRequest(
-    StunMessage* msg, const talk_base::SocketAddress& addr) {
-  SendErrorResponse(*msg, addr, 600, "Operation Not Supported");
-}
-
-void StunServer::OnSendRequest(StunMessage* msg,
-                               const talk_base::SocketAddress& addr) {
-  SendErrorResponse(*msg, addr, 600, "Operation Not Supported");
-}
-
-void StunServer::SendErrorResponse(
-    const StunMessage& msg, const talk_base::SocketAddress& addr,
-    int error_code, const char* error_desc) {
-
-  StunMessage err_msg;
-  err_msg.SetType(GetStunErrorResponseType(msg.type()));
-  err_msg.SetTransactionID(msg.transaction_id());
-
-  StunErrorCodeAttribute* err_code = StunAttribute::CreateErrorCode();
-  err_code->SetErrorClass(error_code / 100);
-  err_code->SetNumber(error_code % 100);
-  err_code->SetReason(error_desc);
-  err_msg.AddAttribute(err_code);
-
-  SendResponse(err_msg, addr);
-}
-
-void StunServer::SendResponse(
-    const StunMessage& msg, const talk_base::SocketAddress& addr) {
-
-  talk_base::ByteBuffer buf;
-  msg.Write(&buf);
-
-  // TODO: Allow response addr attribute if sent from another stun server.
-
-  if (socket_->SendTo(buf.Data(), buf.Length(), addr) < 0)
-    LOG_ERR(LS_ERROR) << "sendto";
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/p2p/base/stunserver.h b/third_party/libjingle/source/talk/p2p/base/stunserver.h
deleted file mode 100644
index 6e51ad1..0000000
--- a/third_party/libjingle/source/talk/p2p/base/stunserver.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_P2P_BASE_STUNSERVER_H_
-#define TALK_P2P_BASE_STUNSERVER_H_
-
-#include "talk/base/asyncudpsocket.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/p2p/base/stun.h"
-
-namespace cricket {
-
-const int STUN_SERVER_PORT = 3478;
-
-class StunServer : public sigslot::has_slots<> {
- public:
-  // Creates a STUN server, which will listen on the given socket.
-  explicit StunServer(talk_base::AsyncUDPSocket* socket);
-  // Removes the STUN server from the socket and deletes the socket.
-  ~StunServer();
-
- protected:
-  // Slot for AsyncSocket.PacketRead:
-  void OnPacket(
-      talk_base::AsyncPacketSocket* socket, const char* buf, size_t size,
-      const talk_base::SocketAddress& remote_addr);
-
-  // Handlers for the different types of STUN/TURN requests:
-  void OnBindingRequest(StunMessage* msg,
-      const talk_base::SocketAddress& addr);
-  void OnAllocateRequest(StunMessage* msg,
-      const talk_base::SocketAddress& addr);
-  void OnSharedSecretRequest(StunMessage* msg,
-      const talk_base::SocketAddress& addr);
-  void OnSendRequest(StunMessage* msg,
-      const talk_base::SocketAddress& addr);
-
-  // Sends an error response to the given message back to the user.
-  void SendErrorResponse(
-      const StunMessage& msg, const talk_base::SocketAddress& addr,
-      int error_code, const char* error_desc);
-
-  // Sends the given message to the appropriate destination.
-  void SendResponse(const StunMessage& msg,
-       const talk_base::SocketAddress& addr);
-
- private:
-  talk_base::scoped_ptr<talk_base::AsyncUDPSocket> socket_;
-};
-
-}  // namespace cricket
-
-#endif  // TALK_P2P_BASE_STUNSERVER_H_
diff --git a/third_party/libjingle/source/talk/p2p/base/stunserver_main.cc b/third_party/libjingle/source/talk/p2p/base/stunserver_main.cc
deleted file mode 100644
index e697728..0000000
--- a/third_party/libjingle/source/talk/p2p/base/stunserver_main.cc
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifdef POSIX
-#include <errno.h>
-#endif  // POSIX
-
-#include <iostream>
-
-#include "talk/base/host.h"
-#include "talk/base/thread.h"
-#include "talk/p2p/base/stunserver.h"
-
-using namespace cricket;
-
-int main(int argc, char* argv[]) {
-  if (argc != 2) {
-    std::cerr << "usage: stunserver address" << std::endl;
-    return 1;
-  }
-
-  talk_base::SocketAddress server_addr;
-  if (!server_addr.FromString(argv[1])) {
-    std::cerr << "Unable to parse IP address: " << argv[1];
-    return 1;
-  }
-
-  talk_base::Thread *pthMain = talk_base::Thread::Current();
-
-  talk_base::AsyncUDPSocket* server_socket =
-      talk_base::AsyncUDPSocket::Create(pthMain->socketserver(), server_addr);
-  if (!server_socket) {
-    std::cerr << "Failed to create a UDP socket" << std::endl;
-    return 1;
-  }
-
-  StunServer* server = new StunServer(server_socket);
-
-  std::cout << "Listening at " << server_addr.ToString() << std::endl;
-
-  pthMain->Run();
-
-  delete server;
-  return 0;
-}
diff --git a/third_party/libjingle/source/talk/p2p/base/stunserver_unittest.cc b/third_party/libjingle/source/talk/p2p/base/stunserver_unittest.cc
deleted file mode 100644
index b7f2f00..0000000
--- a/third_party/libjingle/source/talk/p2p/base/stunserver_unittest.cc
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * libjingle
- * Copyright 2004 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string>
-
-#include "talk/base/gunit.h"
-#include "talk/base/logging.h"
-#include "talk/base/physicalsocketserver.h"
-#include "talk/base/virtualsocketserver.h"
-#include "talk/base/testclient.h"
-#include "talk/base/thread.h"
-#include "talk/p2p/base/stunserver.h"
-
-using namespace cricket;
-
-static const talk_base::SocketAddress server_addr("99.99.99.1", 3478);
-static const talk_base::SocketAddress client_addr("1.2.3.4", 1234);
-
-class StunServerTest : public testing::Test {
- public:
-  StunServerTest()
-    : pss_(new talk_base::PhysicalSocketServer),
-      ss_(new talk_base::VirtualSocketServer(pss_.get())),
-      worker_(ss_.get()) {
-  }
-  virtual void SetUp() {
-    server_.reset(new StunServer(
-        talk_base::AsyncUDPSocket::Create(ss_.get(), server_addr)));
-    client_.reset(new talk_base::TestClient(
-        talk_base::AsyncUDPSocket::Create(ss_.get(), client_addr)));
-
-    worker_.Start();
-  }
-  void Send(const StunMessage& msg) {
-    talk_base::ByteBuffer buf;
-    msg.Write(&buf);
-    Send(buf.Data(), buf.Length());
-  }
-  void Send(const char* buf, int len) {
-    client_->SendTo(buf, len, server_addr);
-  }
-  StunMessage* Receive() {
-    StunMessage* msg = NULL;
-    talk_base::TestClient::Packet* packet = client_->NextPacket();
-    if (packet) {
-      talk_base::ByteBuffer buf(packet->buf, packet->size);
-      msg = new StunMessage();
-      msg->Read(&buf);
-      delete packet;
-    }
-    return msg;
-  }
- private:
-  talk_base::scoped_ptr<talk_base::PhysicalSocketServer> pss_;
-  talk_base::scoped_ptr<talk_base::VirtualSocketServer> ss_;
-  talk_base::Thread worker_;
-  talk_base::scoped_ptr<StunServer> server_;
-  talk_base::scoped_ptr<talk_base::TestClient> client_;
-};
-
-TEST_F(StunServerTest, TestGood) {
-  StunMessage req;
-  std::string transaction_id = "0123456789ab";
-  req.SetType(STUN_BINDING_REQUEST);
-  req.SetTransactionID(transaction_id);
-  Send(req);
-
-  StunMessage* msg = Receive();
-  ASSERT_TRUE(msg != NULL);
-  EXPECT_EQ(STUN_BINDING_RESPONSE, msg->type());
-  EXPECT_EQ(req.transaction_id(), msg->transaction_id());
-
-  const StunAddressAttribute* mapped_addr =
-      msg->GetAddress(STUN_ATTR_MAPPED_ADDRESS);
-  EXPECT_TRUE(mapped_addr != NULL);
-  EXPECT_EQ(1, mapped_addr->family());
-  EXPECT_EQ(client_addr.port(), mapped_addr->port());
-  if (mapped_addr->ipaddr() != client_addr.ipaddr()) {
-    LOG(LS_WARNING) << "Warning: mapped IP ("
-                    << mapped_addr->ipaddr()
-                    << ") != local IP (" << client_addr.ipaddr()
-                    << ")";
-  }
-
-  delete msg;
-}
-
-TEST_F(StunServerTest, TestBad) {
-  const char* bad = "this is a completely nonsensical message whose only "
-                    "purpose is to make the parser go 'ack'.  it doesn't "
-                    "look anything like a normal stun message";
-  Send(bad, std::strlen(bad));
-
-  StunMessage* msg = Receive();
-  ASSERT_TRUE(msg != NULL);
-  EXPECT_EQ(STUN_BINDING_ERROR_RESPONSE, msg->type());
-
-  const StunErrorCodeAttribute* err = msg->GetErrorCode();
-  EXPECT_TRUE(err != NULL);
-  EXPECT_EQ(4, err->error_class());
-  EXPECT_EQ(0, err->number());
-  EXPECT_EQ("Bad Request", err->reason());
-
-  delete msg;
-}
diff --git a/third_party/libjingle/source/talk/p2p/base/tcpport.cc b/third_party/libjingle/source/talk/p2p/base/tcpport.cc
deleted file mode 100644
index 4db4761..0000000
--- a/third_party/libjingle/source/talk/p2p/base/tcpport.cc
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/p2p/base/tcpport.h"
-
-#include "talk/base/common.h"
-#include "talk/base/logging.h"
-#include "talk/p2p/base/common.h"
-
-namespace cricket {
-
-TCPPort::TCPPort(talk_base::Thread* thread,
-                 talk_base::PacketSocketFactory* factory,
-                 talk_base::Network* network, const talk_base::IPAddress& ip,
-                 int min_port, int max_port, bool allow_listen)
-    : Port(thread, LOCAL_PORT_TYPE, factory, network, ip, min_port, max_port),
-      incoming_only_(false),
-      allow_listen_(allow_listen),
-      socket_(NULL),
-      error_(0) {
-}
-
-bool TCPPort::Init() {
-  if (allow_listen_) {
-    // Treat failure to create or bind a TCP socket as fatal.  This
-    // should never happen.
-    socket_ = factory_->CreateServerTcpSocket(
-        talk_base::SocketAddress(ip_, 0), min_port_, max_port_,
-        false /* ssl */);
-    if (!socket_) {
-      LOG_J(LS_ERROR, this) << "TCP socket creation failed.";
-      return false;
-    }
-    socket_->SignalNewConnection.connect(this, &TCPPort::OnNewConnection);
-    socket_->SignalAddressReady.connect(this, &TCPPort::OnAddressReady);
-  }
-  return true;
-}
-
-TCPPort::~TCPPort() {
-  delete socket_;
-}
-
-Connection* TCPPort::CreateConnection(const Candidate& address,
-                                      CandidateOrigin origin) {
-  // We only support TCP protocols
-  if ((address.protocol() != "tcp") && (address.protocol() != "ssltcp"))
-    return NULL;
-
-  // We can't accept TCP connections incoming on other ports
-  if (origin == ORIGIN_OTHER_PORT)
-    return NULL;
-
-  // Check if we are allowed to make outgoing TCP connections
-  if (incoming_only_ && (origin == ORIGIN_MESSAGE))
-    return NULL;
-
-  // We don't know how to act as an ssl server yet
-  if ((address.protocol() == "ssltcp") && (origin == ORIGIN_THIS_PORT))
-    return NULL;
-
-  TCPConnection* conn = NULL;
-  if (talk_base::AsyncPacketSocket* socket =
-      GetIncoming(address.address(), true)) {
-    socket->SignalReadPacket.disconnect(this);
-    conn = new TCPConnection(this, address, socket);
-  } else {
-    conn = new TCPConnection(this, address);
-  }
-  AddConnection(conn);
-  return conn;
-}
-
-void TCPPort::PrepareAddress() {
-  if (socket_) {
-    // If socket isn't bound yet the address will be added in
-    // OnAddressReady(). Socket may be in the CLOSED state if Listed()
-    // failed, we still want ot add the socket address.
-    LOG(LS_ERROR) << socket_->GetState();
-    if (socket_->GetState() == talk_base::AsyncPacketSocket::STATE_BOUND ||
-        socket_->GetState() == talk_base::AsyncPacketSocket::STATE_CLOSED)
-      AddAddress(socket_->GetLocalAddress(), "tcp", true);
-  } else {
-    LOG_J(LS_INFO, this) << "Not listening due to firewall restrictions.";
-    // Note: We still add the address, since otherwise the remote side won't
-    // recognize our incoming TCP connections.
-    AddAddress(talk_base::SocketAddress(ip_, 0), "tcp", true);
-  }
-}
-
-int TCPPort::SendTo(const void* data, size_t size,
-                    const talk_base::SocketAddress& addr, bool payload) {
-  talk_base::AsyncPacketSocket * socket = NULL;
-  if (TCPConnection * conn = static_cast<TCPConnection*>(GetConnection(addr))) {
-    socket = conn->socket();
-  } else {
-    socket = GetIncoming(addr);
-  }
-  if (!socket) {
-    LOG_J(LS_ERROR, this) << "Attempted to send to an unknown destination, "
-                          << addr.ToString();
-    return -1;  // TODO: Set error_
-  }
-
-  int sent = socket->Send(data, size);
-  if (sent < 0) {
-    error_ = socket->GetError();
-    LOG_J(LS_ERROR, this) << "TCP send of " << size
-                          << " bytes failed with error " << error_;
-  }
-  return sent;
-}
-
-int TCPPort::GetOption(talk_base::Socket::Option opt, int* value) {
-  if (socket_) {
-    return socket_->GetOption(opt, value);
-  } else {
-    return SOCKET_ERROR;
-  }
-}
-
-int TCPPort::SetOption(talk_base::Socket::Option opt, int value) {
-  if (socket_) {
-    return socket_->SetOption(opt, value);
-  } else {
-    return SOCKET_ERROR;
-  }
-}
-
-int TCPPort::GetError() {
-  return error_;
-}
-
-void TCPPort::OnNewConnection(talk_base::AsyncPacketSocket* socket,
-                              talk_base::AsyncPacketSocket* new_socket) {
-  ASSERT(socket == socket_);
-
-  Incoming incoming;
-  incoming.addr = new_socket->GetRemoteAddress();
-  incoming.socket = new_socket;
-  incoming.socket->SignalReadPacket.connect(this, &TCPPort::OnReadPacket);
-
-  LOG_J(LS_VERBOSE, this) << "Accepted connection from "
-                          << incoming.addr.ToString();
-  incoming_.push_back(incoming);
-}
-
-talk_base::AsyncPacketSocket* TCPPort::GetIncoming(
-    const talk_base::SocketAddress& addr, bool remove) {
-  talk_base::AsyncPacketSocket* socket = NULL;
-  for (std::list<Incoming>::iterator it = incoming_.begin();
-       it != incoming_.end(); ++it) {
-    if (it->addr == addr) {
-      socket = it->socket;
-      if (remove)
-        incoming_.erase(it);
-      break;
-    }
-  }
-  return socket;
-}
-
-void TCPPort::OnReadPacket(talk_base::AsyncPacketSocket* socket,
-                           const char* data, size_t size,
-                           const talk_base::SocketAddress& remote_addr) {
-  Port::OnReadPacket(data, size, remote_addr);
-}
-
-void TCPPort::OnAddressReady(talk_base::AsyncPacketSocket* socket,
-                             const talk_base::SocketAddress& address) {
-  AddAddress(address, "tcp", true);
-}
-
-TCPConnection::TCPConnection(TCPPort* port, const Candidate& candidate,
-                             talk_base::AsyncPacketSocket* socket)
-    : Connection(port, 0, candidate), socket_(socket), error_(0) {
-  bool outgoing = (socket_ == NULL);
-  if (outgoing) {
-    // TODO: Handle failures here (unlikely since TCP).
-
-    socket_ = port->socket_factory()->CreateClientTcpSocket(
-        talk_base::SocketAddress(port_->network()->ip(), 0),
-        candidate.address(), port->proxy(), port->user_agent(),
-        candidate.protocol() == "ssltcp");
-    if (socket_) {
-      LOG_J(LS_VERBOSE, this) << "Connecting from "
-                              << socket_->GetLocalAddress().ToString() << " to "
-                              << candidate.address().ToString();
-      set_connected(false);
-      socket_->SignalConnect.connect(this, &TCPConnection::OnConnect);
-    } else {
-      LOG_J(LS_WARNING, this) << "Failed to create connection to "
-                              << candidate.address().ToString();
-    }
-  } else {
-    // Incoming connections should match the network address.
-    ASSERT(socket_->GetLocalAddress().ipaddr() == port->ip_);
-  }
-
-  if (socket_) {
-    socket_->SignalReadPacket.connect(this, &TCPConnection::OnReadPacket);
-    socket_->SignalClose.connect(this, &TCPConnection::OnClose);
-  }
-}
-
-TCPConnection::~TCPConnection() {
-  delete socket_;
-}
-
-int TCPConnection::Send(const void* data, size_t size) {
-  if (!socket_) {
-    error_ = ENOTCONN;
-    return SOCKET_ERROR;
-  }
-
-  if (write_state() != STATE_WRITABLE) {
-    // TODO: Should STATE_WRITE_TIMEOUT return a non-blocking error?
-    error_ = EWOULDBLOCK;
-    return SOCKET_ERROR;
-  }
-  int sent = socket_->Send(data, size);
-  if (sent < 0) {
-    error_ = socket_->GetError();
-  } else {
-    send_rate_tracker_.Update(sent);
-  }
-  return sent;
-}
-
-int TCPConnection::GetError() {
-  return error_;
-}
-
-void TCPConnection::OnConnect(talk_base::AsyncPacketSocket* socket) {
-  ASSERT(socket == socket_);
-  LOG_J(LS_VERBOSE, this) << "Connection established to "
-                          << socket->GetRemoteAddress().ToString();
-  set_connected(true);
-}
-
-void TCPConnection::OnClose(talk_base::AsyncPacketSocket* socket, int error) {
-  ASSERT(socket == socket_);
-  LOG_J(LS_VERBOSE, this) << "Connection closed with error " << error;
-  set_connected(false);
-  set_write_state(STATE_WRITE_TIMEOUT);
-}
-
-void TCPConnection::OnReadPacket(talk_base::AsyncPacketSocket* socket,
-                                 const char* data, size_t size,
-                                 const talk_base::SocketAddress& remote_addr) {
-  ASSERT(socket == socket_);
-  Connection::OnReadPacket(data, size);
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/p2p/base/tcpport.h b/third_party/libjingle/source/talk/p2p/base/tcpport.h
deleted file mode 100644
index 5ce917d..0000000
--- a/third_party/libjingle/source/talk/p2p/base/tcpport.h
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_P2P_BASE_TCPPORT_H_
-#define TALK_P2P_BASE_TCPPORT_H_
-
-#include <string>
-#include <list>
-#include "talk/base/asyncpacketsocket.h"
-#include "talk/p2p/base/port.h"
-
-namespace cricket {
-
-class TCPConnection;
-
-extern const char LOCAL_PORT_TYPE[];  // type of TCP ports
-
-// Communicates using a local TCP port.
-//
-// This class is designed to allow subclasses to take advantage of the
-// connection management provided by this class.  A subclass should take of all
-// packet sending and preparation, but when a packet is received, it should
-// call this TCPPort::OnReadPacket (3 arg) to dispatch to a connection.
-class TCPPort : public Port {
- public:
-  static TCPPort* Create(talk_base::Thread* thread,
-                         talk_base::PacketSocketFactory* factory,
-                         talk_base::Network* network,
-                         const talk_base::IPAddress& ip,
-                         int min_port, int max_port,
-                         bool allow_listen) {
-    TCPPort* port = new TCPPort(thread, factory, network,
-                                ip, min_port, max_port, allow_listen);
-    if (!port->Init()) {
-      delete port;
-      port = NULL;
-    }
-    return port;
-  }
-  virtual ~TCPPort();
-
-  virtual Connection* CreateConnection(const Candidate& address,
-                                       CandidateOrigin origin);
-
-  virtual void PrepareAddress();
-
-  virtual int GetOption(talk_base::Socket::Option opt, int* value);
-  virtual int SetOption(talk_base::Socket::Option opt, int value);
-  virtual int GetError();
-
- protected:
-  TCPPort(talk_base::Thread* thread, talk_base::PacketSocketFactory* factory,
-          talk_base::Network* network, const talk_base::IPAddress& ip,
-          int min_port, int max_port, bool allow_listen);
-  bool Init();
-
-  // Handles sending using the local TCP socket.
-  virtual int SendTo(const void* data, size_t size,
-                     const talk_base::SocketAddress& addr, bool payload);
-
-  // Accepts incoming TCP connection.
-  void OnNewConnection(talk_base::AsyncPacketSocket* socket,
-                       talk_base::AsyncPacketSocket* new_socket);
-
- private:
-  struct Incoming {
-    talk_base::SocketAddress addr;
-    talk_base::AsyncPacketSocket* socket;
-  };
-
-  talk_base::AsyncPacketSocket* GetIncoming(
-      const talk_base::SocketAddress& addr, bool remove = false);
-
-  // Receives packet signal from the local TCP Socket.
-  void OnReadPacket(talk_base::AsyncPacketSocket* socket,
-                    const char* data, size_t size,
-                    const talk_base::SocketAddress& remote_addr);
-
-  void OnAddressReady(talk_base::AsyncPacketSocket* socket,
-                      const talk_base::SocketAddress& address);
-
-  // TODO: Is this still needed?
-  bool incoming_only_;
-  bool allow_listen_;
-  talk_base::AsyncPacketSocket* socket_;
-  int error_;
-  std::list<Incoming> incoming_;
-
-  friend class TCPConnection;
-};
-
-class TCPConnection : public Connection {
- public:
-  // Connection is outgoing unless socket is specified
-  TCPConnection(TCPPort* port, const Candidate& candidate,
-                talk_base::AsyncPacketSocket* socket = 0);
-  virtual ~TCPConnection();
-
-  virtual int Send(const void* data, size_t size);
-  virtual int GetError();
-
-  talk_base::AsyncPacketSocket* socket() { return socket_; }
-
- private:
-  void OnConnect(talk_base::AsyncPacketSocket* socket);
-  void OnClose(talk_base::AsyncPacketSocket* socket, int error);
-  void OnReadPacket(talk_base::AsyncPacketSocket* socket,
-                    const char* data, size_t size,
-                    const talk_base::SocketAddress& remote_addr);
-
-  talk_base::AsyncPacketSocket* socket_;
-  int error_;
-
-  friend class TCPPort;
-};
-
-}  // namespace cricket
-
-#endif  // TALK_P2P_BASE_TCPPORT_H_
diff --git a/third_party/libjingle/source/talk/p2p/base/testrelayserver.h b/third_party/libjingle/source/talk/p2p/base/testrelayserver.h
deleted file mode 100644
index 45c2b7c..0000000
--- a/third_party/libjingle/source/talk/p2p/base/testrelayserver.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * libjingle
- * Copyright 2008 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_P2P_BASE_TESTRELAYSERVER_H_
-#define TALK_P2P_BASE_TESTRELAYSERVER_H_
-
-#include "talk/base/asynctcpsocket.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/base/socketadapters.h"
-#include "talk/base/sigslot.h"
-#include "talk/base/thread.h"
-#include "talk/p2p/base/relayserver.h"
-
-namespace cricket {
-
-// A test relay server. Useful for unit tests.
-class TestRelayServer : public sigslot::has_slots<> {
- public:
-  TestRelayServer(talk_base::Thread* thread,
-                  const talk_base::SocketAddress& udp_int_addr,
-                  const talk_base::SocketAddress& udp_ext_addr,
-                  const talk_base::SocketAddress& tcp_int_addr,
-                  const talk_base::SocketAddress& tcp_ext_addr,
-                  const talk_base::SocketAddress& ssl_int_addr,
-                  const talk_base::SocketAddress& ssl_ext_addr)
-      : server_(thread) {
-    server_.AddInternalSocket(talk_base::AsyncUDPSocket::Create(
-        thread->socketserver(), udp_int_addr));
-    server_.AddExternalSocket(talk_base::AsyncUDPSocket::Create(
-        thread->socketserver(), udp_ext_addr));
-
-    tcp_int_socket_.reset(CreateListenSocket(thread, tcp_int_addr));
-    tcp_ext_socket_.reset(CreateListenSocket(thread, tcp_ext_addr));
-    ssl_int_socket_.reset(CreateListenSocket(thread, ssl_int_addr));
-    ssl_ext_socket_.reset(CreateListenSocket(thread, ssl_ext_addr));
-  }
-  int GetConnectionCount() const {
-    return server_.GetConnectionCount();
-  }
-  talk_base::SocketAddressPair GetConnection(int connection) const {
-    return server_.GetConnection(connection);
-  }
-  bool HasConnection(const talk_base::SocketAddress& address) const {
-    return server_.HasConnection(address);
-  }
-
- private:
-  talk_base::AsyncSocket* CreateListenSocket(talk_base::Thread* thread,
-      const talk_base::SocketAddress& addr) {
-    talk_base::AsyncSocket* socket =
-        thread->socketserver()->CreateAsyncSocket(SOCK_STREAM);
-    socket->Bind(addr);
-    socket->Listen(5);
-    socket->SignalReadEvent.connect(this, &TestRelayServer::OnAccept);
-    return socket;
-  }
-  void OnAccept(talk_base::AsyncSocket* socket) {
-    bool external = (socket == tcp_ext_socket_.get() ||
-                     socket == ssl_ext_socket_.get());
-    bool ssl = (socket == ssl_int_socket_.get() ||
-                socket == ssl_ext_socket_.get());
-    talk_base::AsyncSocket* raw_socket = socket->Accept(NULL);
-    if (raw_socket) {
-      talk_base::AsyncTCPSocket* packet_socket = new talk_base::AsyncTCPSocket(
-          (!ssl) ? raw_socket :
-          new talk_base::AsyncSSLServerSocket(raw_socket), false);
-      if (!external) {
-        packet_socket->SignalClose.connect(this,
-            &TestRelayServer::OnInternalClose);
-        server_.AddInternalSocket(packet_socket);
-      } else {
-        packet_socket->SignalClose.connect(this,
-            &TestRelayServer::OnExternalClose);
-        server_.AddExternalSocket(packet_socket);
-      }
-    }
-  }
-  void OnInternalClose(talk_base::AsyncPacketSocket* socket, int error) {
-    server_.RemoveInternalSocket(socket);
-  }
-  void OnExternalClose(talk_base::AsyncPacketSocket* socket, int error) {
-    server_.RemoveExternalSocket(socket);
-  }
- private:
-  cricket::RelayServer server_;
-  talk_base::scoped_ptr<talk_base::AsyncSocket> tcp_int_socket_;
-  talk_base::scoped_ptr<talk_base::AsyncSocket> tcp_ext_socket_;
-  talk_base::scoped_ptr<talk_base::AsyncSocket> ssl_int_socket_;
-  talk_base::scoped_ptr<talk_base::AsyncSocket> ssl_ext_socket_;
-};
-
-}  // namespace cricket
-
-#endif  // TALK_P2P_BASE_TESTRELAYSERVER_H_
diff --git a/third_party/libjingle/source/talk/p2p/base/teststunserver.h b/third_party/libjingle/source/talk/p2p/base/teststunserver.h
deleted file mode 100644
index 4574bf8..0000000
--- a/third_party/libjingle/source/talk/p2p/base/teststunserver.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * libjingle
- * Copyright 2008 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_P2P_BASE_TESTSTUNSERVER_H_
-#define TALK_P2P_BASE_TESTSTUNSERVER_H_
-
-#include "talk/base/socketaddress.h"
-#include "talk/base/thread.h"
-#include "talk/p2p/base/stunserver.h"
-
-namespace cricket {
-
-// A test STUN server. Useful for unit tests.
-class TestStunServer {
- public:
-  TestStunServer(talk_base::Thread* thread,
-                 const talk_base::SocketAddress& addr)
-      : socket_(thread->socketserver()->CreateAsyncSocket(SOCK_DGRAM)),
-        udp_socket_(talk_base::AsyncUDPSocket::Create(socket_, addr)),
-        server_(udp_socket_) {
-  }
- private:
-  talk_base::AsyncSocket* socket_;
-  talk_base::AsyncUDPSocket* udp_socket_;
-  cricket::StunServer server_;
-};
-
-}  // namespace cricket
-
-#endif  // TALK_P2P_BASE_TESTSTUNSERVER_H_
diff --git a/third_party/libjingle/source/talk/p2p/base/transport.cc b/third_party/libjingle/source/talk/p2p/base/transport.cc
deleted file mode 100644
index fdd8520..0000000
--- a/third_party/libjingle/source/talk/p2p/base/transport.cc
+++ /dev/null
@@ -1,489 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/p2p/base/transport.h"
-
-#include "talk/base/common.h"
-#include "talk/base/logging.h"
-#include "talk/p2p/base/candidate.h"
-#include "talk/p2p/base/constants.h"
-#include "talk/p2p/base/sessionmanager.h"
-#include "talk/p2p/base/parsing.h"
-#include "talk/p2p/base/transportchannelimpl.h"
-#include "talk/xmllite/xmlelement.h"
-#include "talk/xmpp/constants.h"
-
-namespace cricket {
-
-struct ChannelParams {
-  ChannelParams() : channel(NULL), candidate(NULL) {}
-  explicit ChannelParams(const std::string& name)
-      : name(name), channel(NULL), candidate(NULL) {}
-  ChannelParams(const std::string& name,
-                const std::string& content_type)
-      : name(name), content_type(content_type),
-        channel(NULL), candidate(NULL) {}
-  explicit ChannelParams(cricket::Candidate* candidate) :
-      channel(NULL), candidate(candidate) {
-    name = candidate->name();
-  }
-
-  ~ChannelParams() {
-    delete candidate;
-  }
-
-  std::string name;
-  std::string content_type;
-  cricket::TransportChannelImpl* channel;
-  cricket::Candidate* candidate;
-};
-// TODO: Merge ChannelParams and ChannelMessage.
-typedef talk_base::ScopedMessageData<ChannelParams> ChannelMessage;
-
-enum {
-  MSG_CREATECHANNEL = 1,
-  MSG_DESTROYCHANNEL = 2,
-  MSG_DESTROYALLCHANNELS = 3,
-  MSG_CONNECTCHANNELS = 4,
-  MSG_RESETCHANNELS = 5,
-  MSG_ONSIGNALINGREADY = 6,
-  MSG_ONREMOTECANDIDATE = 7,
-  MSG_READSTATE = 8,
-  MSG_WRITESTATE = 9,
-  MSG_REQUESTSIGNALING = 10,
-  MSG_CANDIDATEREADY = 11,
-  MSG_ROUTECHANGE = 12,
-  MSG_CONNECTING = 13,
-};
-
-Transport::Transport(talk_base::Thread* signaling_thread,
-                     talk_base::Thread* worker_thread,
-                     const std::string& type,
-                     PortAllocator* allocator)
-  : signaling_thread_(signaling_thread),
-    worker_thread_(worker_thread), type_(type), allocator_(allocator),
-    destroyed_(false), readable_(false), writable_(false),
-    connect_requested_(false), allow_local_ips_(false) {
-}
-
-Transport::~Transport() {
-  ASSERT(signaling_thread_->IsCurrent());
-  ASSERT(destroyed_);
-}
-
-TransportChannelImpl* Transport::CreateChannel(
-    const std::string& name, const std::string& content_type) {
-  ChannelMessage msg(new ChannelParams(name, content_type));
-  worker_thread()->Send(this, MSG_CREATECHANNEL, &msg);
-  return msg.data()->channel;
-}
-
-TransportChannelImpl* Transport::CreateChannel_w(
-    const std::string& name, const std::string& content_type) {
-  ASSERT(worker_thread()->IsCurrent());
-
-  TransportChannelImpl* impl = CreateTransportChannel(name, content_type);
-  impl->SignalReadableState.connect(this, &Transport::OnChannelReadableState);
-  impl->SignalWritableState.connect(this, &Transport::OnChannelWritableState);
-  impl->SignalRequestSignaling.connect(
-      this, &Transport::OnChannelRequestSignaling);
-  impl->SignalCandidateReady.connect(this, &Transport::OnChannelCandidateReady);
-  impl->SignalRouteChange.connect(this, &Transport::OnChannelRouteChange);
-
-  talk_base::CritScope cs(&crit_);
-  ASSERT(channels_.find(name) == channels_.end());
-  channels_[name] = impl;
-  destroyed_ = false;
-  if (connect_requested_) {
-    impl->Connect();
-    if (channels_.size() == 1) {
-      // If this is the first channel, then indicate that we have started
-      // connecting.
-      signaling_thread()->Post(this, MSG_CONNECTING, NULL);
-    }
-  }
-  return impl;
-}
-
-TransportChannelImpl* Transport::GetChannel(const std::string& name) {
-  talk_base::CritScope cs(&crit_);
-  ChannelMap::iterator iter = channels_.find(name);
-  return (iter != channels_.end()) ? iter->second : NULL;
-}
-
-bool Transport::HasChannels() {
-  talk_base::CritScope cs(&crit_);
-  return !channels_.empty();
-}
-
-void Transport::DestroyChannel(const std::string& name) {
-  ChannelMessage msg(new ChannelParams(name));
-  worker_thread()->Send(this, MSG_DESTROYCHANNEL, &msg);
-}
-
-void Transport::DestroyChannel_w(const std::string& name) {
-  ASSERT(worker_thread()->IsCurrent());
-
-  TransportChannelImpl* impl = NULL;
-  {
-    talk_base::CritScope cs(&crit_);
-    ChannelMap::iterator iter = channels_.find(name);
-    if (iter == channels_.end())
-      return;
-    impl = iter->second;
-    channels_.erase(iter);
-  }
-
-  if (connect_requested_ && channels_.empty()) {
-    // We're no longer attempting to connect.
-    signaling_thread()->Post(this, MSG_CONNECTING, NULL);
-  }
-
-  if (impl) {
-    // Check in case the deleted channel was the only non-writable channel.
-    OnChannelWritableState(impl);
-    DestroyTransportChannel(impl);
-  }
-}
-
-void Transport::ConnectChannels() {
-  ASSERT(signaling_thread()->IsCurrent());
-  worker_thread()->Send(this, MSG_CONNECTCHANNELS, NULL);
-}
-
-void Transport::ConnectChannels_w() {
-  ASSERT(worker_thread()->IsCurrent());
-  if (connect_requested_ || channels_.empty())
-    return;
-  connect_requested_ = true;
-  signaling_thread()->Post(
-      this, MSG_CANDIDATEREADY, NULL);
-  CallChannels_w(&TransportChannelImpl::Connect);
-  if (!channels_.empty()) {
-    signaling_thread()->Post(this, MSG_CONNECTING, NULL);
-  }
-}
-
-void Transport::OnConnecting_s() {
-  ASSERT(signaling_thread()->IsCurrent());
-  SignalConnecting(this);
-}
-
-void Transport::DestroyAllChannels() {
-  ASSERT(signaling_thread()->IsCurrent());
-  worker_thread()->Send(this, MSG_DESTROYALLCHANNELS, NULL);
-  worker_thread()->Clear(this);
-  signaling_thread()->Clear(this);
-  destroyed_ = true;
-}
-
-void Transport::DestroyAllChannels_w() {
-  ASSERT(worker_thread()->IsCurrent());
-  std::vector<TransportChannelImpl*> impls;
-  {
-    talk_base::CritScope cs(&crit_);
-    for (ChannelMap::iterator iter = channels_.begin();
-         iter != channels_.end();
-         ++iter) {
-      impls.push_back(iter->second);
-    }
-    channels_.clear();
-  }
-
-  for (size_t i = 0; i < impls.size(); ++i)
-    DestroyTransportChannel(impls[i]);
-}
-
-void Transport::ResetChannels() {
-  ASSERT(signaling_thread()->IsCurrent());
-  worker_thread()->Send(this, MSG_RESETCHANNELS, NULL);
-}
-
-void Transport::ResetChannels_w() {
-  ASSERT(worker_thread()->IsCurrent());
-
-  // We are no longer attempting to connect
-  connect_requested_ = false;
-
-  // Clear out the old messages, they aren't relevant
-  talk_base::CritScope cs(&crit_);
-  ready_candidates_.clear();
-
-  // Reset all of the channels
-  CallChannels_w(&TransportChannelImpl::Reset);
-}
-
-void Transport::OnSignalingReady() {
-  ASSERT(signaling_thread()->IsCurrent());
-  if (destroyed_) return;
-
-  worker_thread()->Post(this, MSG_ONSIGNALINGREADY, NULL);
-
-  // Notify the subclass.
-  OnTransportSignalingReady();
-}
-
-void Transport::CallChannels_w(TransportChannelFunc func) {
-  ASSERT(worker_thread()->IsCurrent());
-  talk_base::CritScope cs(&crit_);
-  for (ChannelMap::iterator iter = channels_.begin();
-       iter != channels_.end();
-       ++iter) {
-    ((iter->second)->*func)();
-  }
-}
-
-bool Transport::VerifyCandidate(const Candidate& cand, ParseError* error) {
-  if (cand.address().IsLocalIP() && !allow_local_ips_)
-    return BadParse("candidate has local IP address", error);
-
-  // No address zero.
-  if (cand.address().IsAny()) {
-    return BadParse("candidate has address of zero", error);
-  }
-
-  // Disallow all ports below 1024, except for 80 and 443 on public addresses.
-  int port = cand.address().port();
-  if (port < 1024) {
-    if ((port != 80) && (port != 443))
-      return BadParse(
-          "candidate has port below 1024, but not 80 or 443", error);
-    if (cand.address().IsPrivateIP()) {
-      return BadParse(
-          "candidate has port of 80 or 443 with private IP address", error);
-    }
-  }
-
-  return true;
-}
-
-void Transport::OnRemoteCandidates(const std::vector<Candidate>& candidates) {
-  for (std::vector<Candidate>::const_iterator iter = candidates.begin();
-       iter != candidates.end();
-       ++iter) {
-    OnRemoteCandidate(*iter);
-  }
-}
-
-void Transport::OnRemoteCandidate(const Candidate& candidate) {
-  ASSERT(signaling_thread()->IsCurrent());
-  if (destroyed_) return;
-  if (!HasChannel(candidate.name())) {
-    LOG(LS_WARNING) << "Ignoring candidate for unknown channel "
-                    << candidate.name();
-    return;
-  }
-
-  ChannelMessage* msg = new ChannelMessage(
-      new ChannelParams(new Candidate(candidate)));
-  worker_thread()->Post(this, MSG_ONREMOTECANDIDATE, msg);
-}
-
-void Transport::OnRemoteCandidate_w(const Candidate& candidate) {
-  ASSERT(worker_thread()->IsCurrent());
-  ChannelMap::iterator iter = channels_.find(candidate.name());
-  // It's ok for a channel to go away while this message is in transit.
-  if (iter != channels_.end()) {
-    iter->second->OnCandidate(candidate);
-  }
-}
-
-void Transport::OnChannelReadableState(TransportChannel* channel) {
-  ASSERT(worker_thread()->IsCurrent());
-  signaling_thread()->Post(this, MSG_READSTATE, NULL);
-}
-
-void Transport::OnChannelReadableState_s() {
-  ASSERT(signaling_thread()->IsCurrent());
-  bool readable = GetTransportState_s(true);
-  if (readable_ != readable) {
-    readable_ = readable;
-    SignalReadableState(this);
-  }
-}
-
-void Transport::OnChannelWritableState(TransportChannel* channel) {
-  ASSERT(worker_thread()->IsCurrent());
-  signaling_thread()->Post(this, MSG_WRITESTATE, NULL);
-}
-
-void Transport::OnChannelWritableState_s() {
-  ASSERT(signaling_thread()->IsCurrent());
-  bool writable = GetTransportState_s(false);
-  if (writable_ != writable) {
-    writable_ = writable;
-    SignalWritableState(this);
-  }
-}
-
-bool Transport::GetTransportState_s(bool read) {
-  ASSERT(signaling_thread()->IsCurrent());
-  bool result = false;
-  talk_base::CritScope cs(&crit_);
-  for (ChannelMap::iterator iter = channels_.begin();
-       iter != channels_.end();
-       ++iter) {
-    bool b = (read ? iter->second->readable() : iter->second->writable());
-    result = result || b;
-  }
-  return result;
-}
-
-void Transport::OnChannelRequestSignaling() {
-  ASSERT(worker_thread()->IsCurrent());
-  signaling_thread()->Post(this, MSG_REQUESTSIGNALING, NULL);
-}
-
-void Transport::OnChannelRequestSignaling_s() {
-  ASSERT(signaling_thread()->IsCurrent());
-  SignalRequestSignaling(this);
-}
-
-void Transport::OnChannelCandidateReady(TransportChannelImpl* channel,
-                                        const Candidate& candidate) {
-  ASSERT(worker_thread()->IsCurrent());
-  talk_base::CritScope cs(&crit_);
-  ready_candidates_.push_back(candidate);
-
-  // We hold any messages until the client lets us connect.
-  if (connect_requested_) {
-    signaling_thread()->Post(
-        this, MSG_CANDIDATEREADY, NULL);
-  }
-}
-
-void Transport::OnChannelCandidateReady_s() {
-  ASSERT(signaling_thread()->IsCurrent());
-  ASSERT(connect_requested_);
-
-  std::vector<Candidate> candidates;
-  {
-    talk_base::CritScope cs(&crit_);
-    candidates.swap(ready_candidates_);
-  }
-
-  // we do the deleting of Candidate* here to keep the new above and
-  // delete below close to each other
-  if (!candidates.empty()) {
-    SignalCandidatesReady(this, candidates);
-  }
-}
-
-void Transport::OnChannelRouteChange(TransportChannel* channel,
-                                     const Candidate& remote_candidate) {
-  ASSERT(worker_thread()->IsCurrent());
-  ChannelParams* params = new ChannelParams(new Candidate(remote_candidate));
-  signaling_thread()->Post(this, MSG_ROUTECHANGE, new ChannelMessage(params));
-}
-
-void Transport::OnChannelRouteChange_s(const std::string& name,
-                                       const Candidate& remote_candidate) {
-  ASSERT(signaling_thread()->IsCurrent());
-  SignalRouteChange(this, name, remote_candidate);
-}
-
-void Transport::OnMessage(talk_base::Message* msg) {
-  switch (msg->message_id) {
-  case MSG_CREATECHANNEL:
-    {
-      ChannelParams* params =
-          static_cast<ChannelMessage*>(msg->pdata)->data().get();
-      params->channel = CreateChannel_w(params->name, params->content_type);
-    }
-    break;
-  case MSG_DESTROYCHANNEL:
-    {
-      ChannelParams* params =
-          static_cast<ChannelMessage*>(msg->pdata)->data().get();
-      DestroyChannel_w(params->name);
-    }
-    break;
-  case MSG_CONNECTCHANNELS:
-    ConnectChannels_w();
-    break;
-  case MSG_RESETCHANNELS:
-    ResetChannels_w();
-    break;
-  case MSG_DESTROYALLCHANNELS:
-    DestroyAllChannels_w();
-    break;
-  case MSG_ONSIGNALINGREADY:
-    CallChannels_w(&TransportChannelImpl::OnSignalingReady);
-    break;
-  case MSG_ONREMOTECANDIDATE:
-    {
-      ChannelMessage* channel_msg = static_cast<ChannelMessage*>(msg->pdata);
-      OnRemoteCandidate_w(*(channel_msg->data()->candidate));
-      delete channel_msg;
-    }
-    break;
-  case MSG_CONNECTING:
-    OnConnecting_s();
-    break;
-  case MSG_READSTATE:
-    OnChannelReadableState_s();
-    break;
-  case MSG_WRITESTATE:
-    OnChannelWritableState_s();
-    break;
-  case MSG_REQUESTSIGNALING:
-    OnChannelRequestSignaling_s();
-    break;
-  case MSG_CANDIDATEREADY:
-    OnChannelCandidateReady_s();
-    break;
-  case MSG_ROUTECHANGE:
-    {
-      ChannelMessage* channel_msg = static_cast<ChannelMessage*>(msg->pdata);
-      ChannelParams* params = channel_msg->data().get();
-      OnChannelRouteChange_s(params->name, *params->candidate);
-      delete channel_msg;
-    }
-    break;
-  }
-}
-
-bool TransportParser::ParseAddress(const buzz::XmlElement* elem,
-                                   const buzz::QName& address_name,
-                                   const buzz::QName& port_name,
-                                   talk_base::SocketAddress* address,
-                                   ParseError* error) {
-  if (!elem->HasAttr(address_name))
-    return BadParse("address does not have " + address_name.LocalPart(), error);
-  if (!elem->HasAttr(port_name))
-    return BadParse("address does not have " + port_name.LocalPart(), error);
-
-  address->SetIP(elem->Attr(address_name));
-  std::istringstream ist(elem->Attr(port_name));
-  int port = 0;
-  ist >> port;
-  address->SetPort(port);
-
-  return true;
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/p2p/base/transport.h b/third_party/libjingle/source/talk/p2p/base/transport.h
deleted file mode 100644
index 1446aa7..0000000
--- a/third_party/libjingle/source/talk/p2p/base/transport.h
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// A Transport manages a set of named channels of the same type.
-//
-// Subclasses choose the appropriate class to instantiate for each channel;
-// however, this base class keeps track of the channels by name, watches their
-// state changes (in order to update the manager's state), and forwards
-// requests to begin connecting or to reset to each of the channels.
-//
-// On Threading:  Transport performs work on both the signaling and worker
-// threads.  For subclasses, the rule is that all signaling related calls will
-// be made on the signaling thread and all channel related calls (including
-// signaling for a channel) will be made on the worker thread.  When
-// information needs to be sent between the two threads, this class should do
-// the work (e.g., OnRemoteCandidate).
-//
-// Note: Subclasses must call DestroyChannels() in their own constructors.
-// It is not possible to do so here because the subclass constructor will
-// already have run.
-
-#ifndef TALK_P2P_BASE_TRANSPORT_H_
-#define TALK_P2P_BASE_TRANSPORT_H_
-
-#include <string>
-#include <map>
-#include <vector>
-#include "talk/base/criticalsection.h"
-#include "talk/base/messagequeue.h"
-#include "talk/base/sigslot.h"
-#include "talk/p2p/base/candidate.h"
-#include "talk/p2p/base/constants.h"
-
-namespace talk_base {
-class Thread;
-}
-
-namespace buzz {
-class QName;
-class XmlElement;
-}
-
-namespace cricket {
-
-struct ParseError;
-struct WriteError;
-class PortAllocator;
-class SessionManager;
-class Session;
-class TransportChannel;
-class TransportChannelImpl;
-
-typedef std::vector<buzz::XmlElement*> XmlElements;
-typedef std::vector<Candidate> Candidates;
-
-// Used to parse and serialize (write) transport candidates.  For
-// convenience of old code, Transports will implement TransportParser.
-// Parse/Write seems better than Serialize/Deserialize or
-// Create/Translate.
-class TransportParser {
- public:
-  virtual bool ParseCandidates(SignalingProtocol protocol,
-                               const buzz::XmlElement* elem,
-                               Candidates* candidates,
-                               ParseError* error) = 0;
-  virtual bool WriteCandidates(SignalingProtocol protocol,
-                               const Candidates& candidates,
-                               XmlElements* candidate_elems,
-                               WriteError* error) = 0;
-
-  // Helper function to parse an element describing an address.  This
-  // retrieves the IP and port from the given element and verifies
-  // that they look like plausible values.
-  bool ParseAddress(const buzz::XmlElement* elem,
-                    const buzz::QName& address_name,
-                    const buzz::QName& port_name,
-                    talk_base::SocketAddress* address,
-                    ParseError* error);
-
-  virtual ~TransportParser() {}
-};
-
-class Transport : public talk_base::MessageHandler,
-                  public sigslot::has_slots<> {
- public:
-  Transport(talk_base::Thread* signaling_thread,
-            talk_base::Thread* worker_thread,
-            const std::string& type,
-            PortAllocator* allocator);
-  virtual ~Transport();
-
-  // Returns the signaling thread. The app talks to Transport on this thread.
-  talk_base::Thread* signaling_thread() { return signaling_thread_; }
-  // Returns the worker thread. The actual networking is done on this thread.
-  talk_base::Thread* worker_thread() { return worker_thread_; }
-
-  // Returns the type of this transport.
-  const std::string& type() const { return type_; }
-
-  // Returns the port allocator object for this transport.
-  PortAllocator* port_allocator() { return allocator_; }
-
-  // Returns the readable and states of this manager.  These bits are the ORs
-  // of the corresponding bits on the managed channels.  Each time one of these
-  // states changes, a signal is raised.
-  bool readable() const { return readable_; }
-  bool writable() const { return writable_; }
-  sigslot::signal1<Transport*> SignalReadableState;
-  sigslot::signal1<Transport*> SignalWritableState;
-
-  // Returns whether the client has requested the channels to connect.
-  bool connect_requested() const { return connect_requested_; }
-
-  // Create, destroy, and lookup the channels of this type by their names.
-  TransportChannelImpl* CreateChannel(const std::string& name,
-                                      const std::string& content_type);
-  // Note: GetChannel may lead to race conditions, since the mutex is not held
-  // after the pointer is returned.
-  TransportChannelImpl* GetChannel(const std::string& name);
-  // Note: HasChannel does not lead to race conditions, unlike GetChannel.
-  bool HasChannel(const std::string& name) {
-    return (NULL != GetChannel(name));
-  }
-  bool HasChannels();
-  void DestroyChannel(const std::string& name);
-
-  // Tells all current and future channels to start connecting.  When the first
-  // channel begins connecting, the following signal is raised.
-  void ConnectChannels();
-  sigslot::signal1<Transport*> SignalConnecting;
-
-  // Resets all of the channels back to their initial state.  They are no
-  // longer connecting.
-  void ResetChannels();
-
-  // Destroys every channel created so far.
-  void DestroyAllChannels();
-
-  // Before any stanza is sent, the manager will request signaling.  Once
-  // signaling is available, the client should call OnSignalingReady.  Once
-  // this occurs, the transport (or its channels) can send any waiting stanzas.
-  // OnSignalingReady invokes OnTransportSignalingReady and then forwards this
-  // signal to each channel.
-  sigslot::signal1<Transport*> SignalRequestSignaling;
-  void OnSignalingReady();
-
-  // Handles sending of ready candidates and receiving of remote candidates.
-  sigslot::signal2<Transport*,
-                   const std::vector<Candidate>&> SignalCandidatesReady;
-  void OnRemoteCandidates(const std::vector<Candidate>& candidates);
-
-  // If candidate is not acceptable, returns false and sets error.
-  // Call this before calling OnRemoteCandidates.
-  virtual bool VerifyCandidate(const Candidate& candidate,
-                               ParseError* error);
-
-  // Signals when the best connection for a channel changes.
-  sigslot::signal3<Transport*, const std::string&,
-                   const Candidate&> SignalRouteChange;
-
-  // A transport message has generated an transport-specific error.  The
-  // stanza that caused the error is available in session_msg.  If false is
-  // returned, the error is considered unrecoverable, and the session is
-  // terminated.
-  // TODO: Make OnTransportError take an abstract data type
-  // rather than an XmlElement.  It isn't needed yet, but it might be
-  // later for Jingle compliance.
-  virtual void OnTransportError(const buzz::XmlElement* error) {}
-  sigslot::signal6<Transport*, const buzz::XmlElement*, const buzz::QName&,
-                   const std::string&, const std::string&,
-                   const buzz::XmlElement*>
-      SignalTransportError;
-
-  sigslot::signal2<Transport*, const std::string&> SignalChannelGone;
-
-  // (For testing purposes only.)  This indicates whether we will allow local
-  // IPs (e.g. 127.*) to be used as addresses for P2P.
-  bool allow_local_ips() const { return allow_local_ips_; }
-  void set_allow_local_ips(bool value) { allow_local_ips_ = value; }
-
- protected:
-  // These are called by Create/DestroyChannel above in order to create or
-  // destroy the appropriate type of channel.
-  virtual TransportChannelImpl* CreateTransportChannel(
-      const std::string& name, const std::string &content_type) = 0;
-  virtual void DestroyTransportChannel(TransportChannelImpl* channel) = 0;
-
-  // Informs the subclass that we received the signaling ready message.
-  virtual void OnTransportSignalingReady() {}
-
- private:
-  typedef std::map<std::string, TransportChannelImpl*> ChannelMap;
-
-  // Called when the state of a channel changes.
-  void OnChannelReadableState(TransportChannel* channel);
-  void OnChannelWritableState(TransportChannel* channel);
-
-  // Called when a channel requests signaling.
-  void OnChannelRequestSignaling();
-
-  // Called when a candidate is ready from remote peer.
-  void OnRemoteCandidate(const Candidate& candidate);
-  // Called when a candidate is ready from channel.
-  void OnChannelCandidateReady(TransportChannelImpl* channel,
-                               const Candidate& candidate);
-  void OnChannelRouteChange(TransportChannel* channel,
-                            const Candidate& remote_candidate);
-
-  // Dispatches messages to the appropriate handler (below).
-  void OnMessage(talk_base::Message* msg);
-
-  // These are versions of the above methods that are called only on a
-  // particular thread (s = signaling, w = worker).  The above methods post or
-  // send a message to invoke this version.
-  TransportChannelImpl* CreateChannel_w(const std::string& name,
-                                        const std::string& content_type);
-  void DestroyChannel_w(const std::string& name);
-  void ConnectChannels_w();
-  void ResetChannels_w();
-  void DestroyAllChannels_w();
-  void OnRemoteCandidate_w(const Candidate& candidate);
-  void OnChannelReadableState_s();
-  void OnChannelWritableState_s();
-  void OnChannelRequestSignaling_s();
-  void OnConnecting_s();
-  void OnChannelRouteChange_s(const std::string& name,
-                              const Candidate& remote_candidate);
-
-  // Helper function that invokes the given function on every channel.
-  typedef void (TransportChannelImpl::* TransportChannelFunc)();
-  void CallChannels_w(TransportChannelFunc func);
-
-  // Computes the OR of the channel's read or write state (argument picks).
-  bool GetTransportState_s(bool read);
-
-  void OnChannelCandidateReady_s();
-
-  talk_base::Thread* signaling_thread_;
-  talk_base::Thread* worker_thread_;
-  std::string type_;
-  PortAllocator* allocator_;
-  bool destroyed_;
-  bool readable_;
-  bool writable_;
-  bool connect_requested_;
-  ChannelMap channels_;
-  // Buffers the ready_candidates so that SignalCanidatesReady can
-  // provide them in multiples.
-  std::vector<Candidate> ready_candidates_;
-  // Protects changes to channels and messages
-  talk_base::CriticalSection crit_;
-  bool allow_local_ips_;
-
-  DISALLOW_EVIL_CONSTRUCTORS(Transport);
-};
-
-}  // namespace cricket
-
-#endif  // TALK_P2P_BASE_TRANSPORT_H_
diff --git a/third_party/libjingle/source/talk/p2p/base/transport_unittest.cc b/third_party/libjingle/source/talk/p2p/base/transport_unittest.cc
deleted file mode 100644
index 7718484..0000000
--- a/third_party/libjingle/source/talk/p2p/base/transport_unittest.cc
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * libjingle
- * Copyright 2011 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/gunit.h"
-#include "talk/base/thread.h"
-#include "talk/p2p/base/p2ptransport.h"
-
-class TransportTest : public testing::Test,
-                      public sigslot::has_slots<> {
- public:
-  TransportTest()
-      : thread_(talk_base::Thread::Current()),
-        transport_(new cricket::P2PTransport(thread_, thread_, NULL)),
-        connecting_signalled_(false) {
-    transport_->SignalConnecting.connect(this, &TransportTest::OnConnecting);
-  }
-
- protected:
-  void OnConnecting(cricket::Transport* transport) {
-    connecting_signalled_ = true;
-  }
-
-  talk_base::Thread* thread_;
-  talk_base::scoped_ptr<cricket::P2PTransport> transport_;
-  bool connecting_signalled_;
-};
-
-TEST_F(TransportTest, TestDestroyAllClearsPosts) {
-  EXPECT_TRUE(transport_->CreateChannel("test", "media") != NULL);
-
-  transport_->ConnectChannels();
-  transport_->DestroyAllChannels();
-
-  thread_->ProcessMessages(0);
-  EXPECT_FALSE(connecting_signalled_);
-}
-
-TEST_F(TransportTest, TestConnectChannelsDoesSignal) {
-  EXPECT_TRUE(transport_->CreateChannel("test", "media") != NULL);
-  transport_->ConnectChannels();
-  EXPECT_FALSE(connecting_signalled_);
-
-  EXPECT_TRUE_WAIT(connecting_signalled_, 100);
-}
-
diff --git a/third_party/libjingle/source/talk/p2p/base/transportchannel.cc b/third_party/libjingle/source/talk/p2p/base/transportchannel.cc
deleted file mode 100644
index ba076ac..0000000
--- a/third_party/libjingle/source/talk/p2p/base/transportchannel.cc
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sstream>
-#include "talk/p2p/base/transportchannel.h"
-
-namespace cricket {
-
-std::string TransportChannel::ToString() const {
-  const char READABLE_ABBREV[2] = { '_', 'R' };
-  const char WRITABLE_ABBREV[2] = { '_', 'W' };
-  std::stringstream ss;
-  ss << "Channel[" << name_ << "|" << READABLE_ABBREV[readable_]
-      << WRITABLE_ABBREV[writable_] << "]";
-  return ss.str();
-}
-
-void TransportChannel::set_readable(bool readable) {
-  if (readable_ != readable) {
-    readable_ = readable;
-    SignalReadableState(this);
-  }
-}
-
-void TransportChannel::set_writable(bool writable) {
-  if (writable_ != writable) {
-    writable_ = writable;
-    SignalWritableState(this);
-  }
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/p2p/base/transportchannel.h b/third_party/libjingle/source/talk/p2p/base/transportchannel.h
deleted file mode 100644
index 2672e80..0000000
--- a/third_party/libjingle/source/talk/p2p/base/transportchannel.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_P2P_BASE_TRANSPORTCHANNEL_H_
-#define TALK_P2P_BASE_TRANSPORTCHANNEL_H_
-
-#include <string>
-#include "talk/base/basictypes.h"
-#include "talk/base/sigslot.h"
-#include "talk/base/socket.h"
-
-namespace cricket {
-
-class Candidate;
-class P2PTransportChannel;
-
-// A TransportChannel represents one logical stream of packets that are sent
-// between the two sides of a session.
-class TransportChannel: public sigslot::has_slots<> {
- public:
-  TransportChannel(const std::string& name, const std::string &content_type)
-      : name_(name), content_type_(content_type),
-        readable_(false), writable_(false) {}
-  virtual ~TransportChannel() {}
-
-  // Returns the name of this channel.
-  const std::string& name() const { return name_; }
-  const std::string& content_type() const { return content_type_; }
-
-  // Returns the readable and states of this channel.  Each time one of these
-  // states changes, a signal is raised.  These states are aggregated by the
-  // TransportManager.
-  bool readable() const { return readable_; }
-  bool writable() const { return writable_; }
-  sigslot::signal1<TransportChannel*> SignalReadableState;
-  sigslot::signal1<TransportChannel*> SignalWritableState;
-
-  // Attempts to send the given packet.  The return value is < 0 on failure.
-  virtual int SendPacket(const char *data, size_t len) = 0;
-
-  // Sets a socket option on this channel.  Note that not all options are
-  // supported by all transport types.
-  virtual int SetOption(talk_base::Socket::Option opt, int value) = 0;
-
-  // Returns the most recent error that occurred on this channel.
-  virtual int GetError() = 0;
-
-  // This hack is here to allow the SocketMonitor to downcast to the
-  // P2PTransportChannel safely.
-  // TODO: Generalize network monitoring.
-  virtual P2PTransportChannel* GetP2PChannel() { return NULL; }
-
-  // Signalled each time a packet is received on this channel.
-  sigslot::signal3<TransportChannel*, const char*, size_t> SignalReadPacket;
-
-  // This signal occurs when there is a change in the way that packets are
-  // being routed, i.e. to a different remote location. The candidate
-  // indicates where and how we are currently sending media.
-  sigslot::signal2<TransportChannel*, const Candidate&> SignalRouteChange;
-
-  // Invoked when the channel is being destroyed.
-  sigslot::signal1<TransportChannel*> SignalDestroyed;
-
-  // Debugging description of this transport channel.
-  std::string ToString() const;
-
- protected:
-  // Sets the readable state, signaling if necessary.
-  void set_readable(bool readable);
-
-  // Sets the writable state, signaling if necessary.
-  void set_writable(bool writable);
-
- private:
-  std::string name_;
-  std::string content_type_;
-  bool readable_;
-  bool writable_;
-
-  DISALLOW_EVIL_CONSTRUCTORS(TransportChannel);
-};
-
-}  // namespace cricket
-
-#endif  // TALK_P2P_BASE_TRANSPORTCHANNEL_H_
diff --git a/third_party/libjingle/source/talk/p2p/base/transportchannelimpl.h b/third_party/libjingle/source/talk/p2p/base/transportchannelimpl.h
deleted file mode 100644
index 39e4288..0000000
--- a/third_party/libjingle/source/talk/p2p/base/transportchannelimpl.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_P2P_BASE_TRANSPORTCHANNELIMPL_H_
-#define TALK_P2P_BASE_TRANSPORTCHANNELIMPL_H_
-
-#include <string>
-#include "talk/p2p/base/transportchannel.h"
-
-namespace buzz { class XmlElement; }
-
-namespace cricket {
-
-class Transport;
-class Candidate;
-
-// Base class for real implementations of TransportChannel.  This includes some
-// methods called only by Transport, which do not need to be exposed to the
-// client.
-class TransportChannelImpl : public TransportChannel {
- public:
-  TransportChannelImpl(const std::string& name, const std::string& content_type)
-    : TransportChannel(name, content_type) {}
-
-  // Returns the transport that created this channel.
-  virtual Transport* GetTransport() = 0;
-
-  // Begins the process of attempting to make a connection to the other client.
-  virtual void Connect() = 0;
-
-  // Resets this channel back to the initial state (i.e., not connecting).
-  virtual void Reset() = 0;
-
-  // Allows an individual channel to request signaling and be notified when it
-  // is ready.  This is useful if the individual named channels have need to
-  // send their own transport-info stanzas.
-  sigslot::signal0<> SignalRequestSignaling;
-  virtual void OnSignalingReady() = 0;
-
-  // Handles sending and receiving of candidates.  The Transport
-  // receives the candidates and may forward them to the relevant
-  // channel.
-  //
-  // Note: Since candidates are delivered asynchronously to the
-  // channel, they cannot return an error if the message is invalid.
-  // It is assumed that the Transport will have checked validity
-  // before forwarding.
-  sigslot::signal2<TransportChannelImpl*,
-                   const Candidate&> SignalCandidateReady;
-  virtual void OnCandidate(const Candidate& candidate) = 0;
- private:
-  DISALLOW_EVIL_CONSTRUCTORS(TransportChannelImpl);
-};
-
-}  // namespace cricket
-
-#endif  // TALK_P2P_BASE_TRANSPORTCHANNELIMPL_H_
diff --git a/third_party/libjingle/source/talk/p2p/base/transportchannelproxy.cc b/third_party/libjingle/source/talk/p2p/base/transportchannelproxy.cc
deleted file mode 100644
index 4e035b1..0000000
--- a/third_party/libjingle/source/talk/p2p/base/transportchannelproxy.cc
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/p2p/base/transportchannelproxy.h"
-#include "talk/base/common.h"
-#include "talk/p2p/base/transport.h"
-#include "talk/p2p/base/transportchannelimpl.h"
-
-namespace cricket {
-
-TransportChannelProxy::TransportChannelProxy(const std::string& name,
-                                             const std::string& content_type)
-    : TransportChannel(name, content_type), impl_(NULL), owner_(false) {
-}
-
-TransportChannelProxy::~TransportChannelProxy() {
-  if (owner_ && impl_)
-    impl_->GetTransport()->DestroyChannel(impl_->name());
-}
-
-void TransportChannelProxy::SetImplementation(TransportChannelImpl* impl,
-                                              bool owner) {
-  impl_ = impl;
-  impl_->SignalReadableState.connect(
-      this, &TransportChannelProxy::OnReadableState);
-  impl_->SignalWritableState.connect(
-      this, &TransportChannelProxy::OnWritableState);
-  impl_->SignalReadPacket.connect(this, &TransportChannelProxy::OnReadPacket);
-  impl_->SignalRouteChange.connect(this, &TransportChannelProxy::OnRouteChange);
-  for (OptionList::iterator it = pending_options_.begin();
-       it != pending_options_.end();
-       ++it) {
-    impl_->SetOption(it->first, it->second);
-  }
-  pending_options_.clear();
-  owner_ = owner;
-}
-
-int TransportChannelProxy::SendPacket(const char* data, size_t len) {
-  // Fail if we don't have an impl yet.
-  return (impl_) ? impl_->SendPacket(data, len) : -1;
-}
-
-int TransportChannelProxy::SetOption(talk_base::Socket::Option opt, int value) {
-  if (impl_)
-    return impl_->SetOption(opt, value);
-  pending_options_.push_back(OptionPair(opt, value));
-  return 0;
-}
-
-int TransportChannelProxy::GetError() {
-  ASSERT(impl_ != NULL);  // should not be used until channel is writable
-  return impl_->GetError();
-}
-
-P2PTransportChannel* TransportChannelProxy::GetP2PChannel() {
-  if (impl_) {
-      return impl_->GetP2PChannel();
-  }
-  return NULL;
-}
-
-void TransportChannelProxy::OnReadableState(TransportChannel* channel) {
-  ASSERT(channel == impl_);
-  set_readable(impl_->readable());
-}
-
-void TransportChannelProxy::OnWritableState(TransportChannel* channel) {
-  ASSERT(channel == impl_);
-  set_writable(impl_->writable());
-}
-
-void TransportChannelProxy::OnReadPacket(TransportChannel* channel,
-                                         const char* data, size_t size) {
-  ASSERT(channel == impl_);
-  SignalReadPacket(this, data, size);
-}
-
-void TransportChannelProxy::OnRouteChange(TransportChannel* channel,
-                                          const Candidate& candidate) {
-  ASSERT(channel == impl_);
-  SignalRouteChange(this, candidate);
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/p2p/base/transportchannelproxy.h b/third_party/libjingle/source/talk/p2p/base/transportchannelproxy.h
deleted file mode 100644
index 6923429..0000000
--- a/third_party/libjingle/source/talk/p2p/base/transportchannelproxy.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_P2P_BASE_TRANSPORTCHANNELPROXY_H_
-#define TALK_P2P_BASE_TRANSPORTCHANNELPROXY_H_
-
-#include <string>
-#include <vector>
-#include "talk/p2p/base/transportchannel.h"
-
-namespace cricket {
-
-class TransportChannelImpl;
-
-// Proxies calls between the client and the transport channel implementation.
-// This is needed because clients are allowed to create channels before the
-// network negotiation is complete.  Hence, we create a proxy up front, and
-// when negotiation completes, connect the proxy to the implementaiton.
-class TransportChannelProxy: public TransportChannel {
- public:
-  TransportChannelProxy(const std::string& name,
-                        const std::string& content_type);
-  virtual ~TransportChannelProxy();
-
-  TransportChannelImpl* impl() { return impl_; }
-
-  // Sets the implementation to which we will proxy.
-  // Impl can be belong to some other TransportChannelProxy,
-  // in that case it should't try to delete. TODO - Remove this hack
-  // when ref count support is available.
-  void SetImplementation(TransportChannelImpl* impl, bool owner);
-
-  // Implementation of the TransportChannel interface.  These simply forward to
-  // the implementation.
-  virtual int SendPacket(const char* data, size_t len);
-  virtual int SetOption(talk_base::Socket::Option opt, int value);
-  virtual int GetError();
-  virtual P2PTransportChannel* GetP2PChannel();
-
- private:
-  typedef std::pair<talk_base::Socket::Option, int> OptionPair;
-  typedef std::vector<OptionPair> OptionList;
-  TransportChannelImpl* impl_;
-  bool owner_;
-  OptionList pending_options_;
-
-  // Catch signals from the implementation channel.  These just forward to the
-  // client (after updating our state to match).
-  void OnReadableState(TransportChannel* channel);
-  void OnWritableState(TransportChannel* channel);
-  void OnReadPacket(TransportChannel* channel, const char* data, size_t size);
-  void OnRouteChange(TransportChannel* channel, const Candidate& candidate);
-
-  DISALLOW_EVIL_CONSTRUCTORS(TransportChannelProxy);
-};
-
-}  // namespace cricket
-
-#endif  // TALK_P2P_BASE_TRANSPORTCHANNELPROXY_H_
diff --git a/third_party/libjingle/source/talk/p2p/base/udpport.cc b/third_party/libjingle/source/talk/p2p/base/udpport.cc
deleted file mode 100644
index 311fb45..0000000
--- a/third_party/libjingle/source/talk/p2p/base/udpport.cc
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/p2p/base/udpport.h"
-
-#include "talk/base/asyncpacketsocket.h"
-#include "talk/base/logging.h"
-#include "talk/p2p/base/common.h"
-
-namespace cricket {
-
-const char LOCAL_PORT_TYPE[] = "local";
-
-UDPPort::UDPPort(talk_base::Thread* thread,
-                 talk_base::PacketSocketFactory* factory,
-                 talk_base::Network* network,
-                 const talk_base::IPAddress& ip, int min_port, int max_port)
-    : Port(thread, LOCAL_PORT_TYPE, factory, network, ip, min_port, max_port),
-      socket_(NULL),
-      error_(0) {
-}
-
-bool UDPPort::Init() {
-  socket_ = factory_->CreateUdpSocket(
-      talk_base::SocketAddress(ip_, 0), min_port_, max_port_);
-  if (!socket_) {
-    LOG_J(LS_WARNING, this) << "UDP socket creation failed";
-    return false;
-  }
-  socket_->SignalAddressReady.connect(this, &UDPPort::OnAddressReady);
-  socket_->SignalReadPacket.connect(this, &UDPPort::OnReadPacket);
-  return true;
-}
-
-UDPPort::~UDPPort() {
-  delete socket_;
-}
-
-void UDPPort::PrepareAddress() {
-  if (socket_->GetState() == talk_base::AsyncPacketSocket::STATE_BOUND)
-    AddAddress(socket_->GetLocalAddress(), "udp", true);
-}
-
-Connection* UDPPort::CreateConnection(const Candidate& address,
-                                      CandidateOrigin origin) {
-  if (address.protocol() != "udp")
-    return NULL;
-
-  Connection* conn = new ProxyConnection(this, 0, address);
-  AddConnection(conn);
-  return conn;
-}
-
-int UDPPort::SendTo(const void* data, size_t size,
-                    const talk_base::SocketAddress& addr, bool payload) {
-  int sent = socket_->SendTo(data, size, addr);
-  if (sent < 0) {
-    error_ = socket_->GetError();
-    LOG_J(LS_ERROR, this) << "UDP send of " << size
-                          << " bytes failed with error " << error_;
-  }
-  return sent;
-}
-
-int UDPPort::SetOption(talk_base::Socket::Option opt, int value) {
-  return socket_->SetOption(opt, value);
-}
-
-int UDPPort::GetError() {
-  return error_;
-}
-
-void UDPPort::OnAddressReady(talk_base::AsyncPacketSocket* socket,
-                             const talk_base::SocketAddress& address) {
-  AddAddress(address, "udp", true);
-}
-
-void UDPPort::OnReadPacket(
-    talk_base::AsyncPacketSocket* socket, const char* data, size_t size,
-    const talk_base::SocketAddress& remote_addr) {
-  ASSERT(socket == socket_);
-  if (Connection* conn = GetConnection(remote_addr)) {
-    conn->OnReadPacket(data, size);
-  } else {
-    Port::OnReadPacket(data, size, remote_addr);
-  }
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/p2p/base/udpport.h b/third_party/libjingle/source/talk/p2p/base/udpport.h
deleted file mode 100644
index 5d767bb..0000000
--- a/third_party/libjingle/source/talk/p2p/base/udpport.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_P2P_BASE_UDPPORT_H_
-#define TALK_P2P_BASE_UDPPORT_H_
-
-#include <string>
-
-#include "talk/p2p/base/port.h"
-
-namespace talk_base {
-class Thread;
-class Network;
-class SocketAddress;
-}
-
-namespace cricket {
-
-extern const char LOCAL_PORT_TYPE[];  // type of UDP ports
-
-// Communicates using a local UDP port.
-class UDPPort : public Port {
- public:
-  static UDPPort* Create(talk_base::Thread* thread,
-                         talk_base::PacketSocketFactory* factory,
-                         talk_base::Network* network,
-                         const talk_base::IPAddress& ip,
-                         int min_port, int max_port) {
-    UDPPort* port = new UDPPort(thread, factory, network,
-                                ip, min_port, max_port);
-    if (!port->Init()) {
-      delete port;
-      port = NULL;
-    }
-    return port;
-  }
-  virtual ~UDPPort();
-
-  virtual void PrepareAddress();
-  virtual Connection* CreateConnection(const Candidate& address,
-                                       CandidateOrigin origin);
-
-  virtual int SetOption(talk_base::Socket::Option opt, int value);
-  virtual int GetError();
-
- protected:
-  UDPPort(talk_base::Thread* thread, talk_base::PacketSocketFactory* factory,
-          talk_base::Network* network, const talk_base::IPAddress& ip,
-          int min_port, int max_port);
-  bool Init();
-
-  // Handles sending using the local UDP socket.
-  virtual int SendTo(const void* data, size_t size,
-                     const talk_base::SocketAddress& remote_addr, bool payload);
-
-  void OnAddressReady(talk_base::AsyncPacketSocket* socket,
-                      const talk_base::SocketAddress& address);
-
-  // Dispatches the given packet to the port or connection as appropriate.
-  void OnReadPacket(talk_base::AsyncPacketSocket* socket,
-                    const char* data, size_t size,
-                    const talk_base::SocketAddress& remote_addr);
-
- private:
-  talk_base::AsyncPacketSocket* socket_;
-  int error_;
-};
-
-}  // namespace cricket
-
-#endif  // TALK_P2P_BASE_UDPPORT_H_
diff --git a/third_party/libjingle/source/talk/p2p/client/basicportallocator.cc b/third_party/libjingle/source/talk/p2p/client/basicportallocator.cc
deleted file mode 100644
index ec13b86..0000000
--- a/third_party/libjingle/source/talk/p2p/client/basicportallocator.cc
+++ /dev/null
@@ -1,830 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string>
-#include <vector>
-
-#include "talk/base/basicpacketsocketfactory.h"
-#include "talk/base/common.h"
-#include "talk/base/helpers.h"
-#include "talk/base/host.h"
-#include "talk/base/logging.h"
-#include "talk/p2p/client/basicportallocator.h"
-#include "talk/p2p/base/common.h"
-#include "talk/p2p/base/port.h"
-#include "talk/p2p/base/relayport.h"
-#include "talk/p2p/base/stunport.h"
-#include "talk/p2p/base/tcpport.h"
-#include "talk/p2p/base/udpport.h"
-
-using talk_base::CreateRandomId;
-using talk_base::CreateRandomString;
-
-namespace {
-
-const uint32 MSG_CONFIG_START = 1;
-const uint32 MSG_CONFIG_READY = 2;
-const uint32 MSG_ALLOCATE = 3;
-const uint32 MSG_ALLOCATION_PHASE = 4;
-const uint32 MSG_SHAKE = 5;
-
-const uint32 ALLOCATE_DELAY = 250;
-const uint32 ALLOCATION_STEP_DELAY = 1 * 1000;
-
-const int PHASE_UDP = 0;
-const int PHASE_RELAY = 1;
-const int PHASE_TCP = 2;
-const int PHASE_SSLTCP = 3;
-const int kNumPhases = 4;
-
-const float PREF_LOCAL_UDP = 1.0f;
-const float PREF_LOCAL_STUN = 0.9f;
-const float PREF_LOCAL_TCP = 0.8f;
-const float PREF_RELAY = 0.5f;
-
-// Modifiers of the above constants
-const float RELAY_PRIMARY_PREF_MODIFIER = 0.0f;
-const float RELAY_BACKUP_PREF_MODIFIER = -0.2f;
-
-// Returns the phase in which a given local candidate (or rather, the port that
-// gave rise to that local candidate) would have been created.
-int LocalCandidateToPhase(const cricket::Candidate& candidate) {
-  cricket::ProtocolType proto;
-  bool result = cricket::StringToProto(candidate.protocol().c_str(), &proto);
-  if (result) {
-    if (candidate.type() == cricket::LOCAL_PORT_TYPE) {
-      switch (proto) {
-      case cricket::PROTO_UDP: return PHASE_UDP;
-      case cricket::PROTO_TCP: return PHASE_TCP;
-      default: ASSERT(false);
-      }
-    } else if (candidate.type() == cricket::STUN_PORT_TYPE) {
-      return PHASE_UDP;
-    } else if (candidate.type() == cricket::RELAY_PORT_TYPE) {
-      switch (proto) {
-      case cricket::PROTO_UDP: return PHASE_RELAY;
-      case cricket::PROTO_TCP: return PHASE_TCP;
-      case cricket::PROTO_SSLTCP: return PHASE_SSLTCP;
-      default: ASSERT(false);
-      }
-    } else {
-      ASSERT(false);
-    }
-  } else {
-    ASSERT(false);
-  }
-  return PHASE_UDP;  // reached only with assert failure
-}
-
-const int SHAKE_MIN_DELAY = 45 * 1000;  // 45 seconds
-const int SHAKE_MAX_DELAY = 90 * 1000;  // 90 seconds
-
-int ShakeDelay() {
-  int range = SHAKE_MAX_DELAY - SHAKE_MIN_DELAY + 1;
-  return SHAKE_MIN_DELAY + CreateRandomId() % range;
-}
-
-}  // namespace
-
-namespace cricket {
-
-const uint32 DISABLE_ALL_PHASES =
-  PORTALLOCATOR_DISABLE_UDP
-  | PORTALLOCATOR_DISABLE_TCP
-  | PORTALLOCATOR_DISABLE_STUN
-  | PORTALLOCATOR_DISABLE_RELAY;
-
-// Performs the allocation of ports, in a sequenced (timed) manner, for a given
-// network and IP address.
-class AllocationSequence : public talk_base::MessageHandler {
- public:
-  AllocationSequence(BasicPortAllocatorSession* session,
-                     talk_base::Network* network,
-                     PortConfiguration* config,
-                     uint32 flags);
-  ~AllocationSequence();
-
-  // Disables the phases for a new sequence that this one already covers for an
-  // equivalent network setup.
-  void DisableEquivalentPhases(talk_base::Network* network,
-      PortConfiguration* config, uint32* flags);
-
-  // Starts and stops the sequence.  When started, it will continue allocating
-  // new ports on its own timed schedule.
-  void Start();
-  void Stop();
-
-  // MessageHandler
-  void OnMessage(talk_base::Message* msg);
-
-  void EnableProtocol(ProtocolType proto);
-  bool ProtocolEnabled(ProtocolType proto) const;
-
- private:
-  typedef std::vector<ProtocolType> ProtocolList;
-
-  void CreateUDPPorts();
-  void CreateTCPPorts();
-  void CreateStunPorts();
-  void CreateRelayPorts();
-
-  BasicPortAllocatorSession* session_;
-  talk_base::Network* network_;
-  talk_base::IPAddress ip_;
-  PortConfiguration* config_;
-  bool running_;
-  int step_;
-  int step_of_phase_[kNumPhases];
-  uint32 flags_;
-  ProtocolList protocols_;
-};
-
-
-// BasicPortAllocator
-BasicPortAllocator::BasicPortAllocator(
-    talk_base::NetworkManager* network_manager,
-    talk_base::PacketSocketFactory* socket_factory)
-    : network_manager_(network_manager),
-      socket_factory_(socket_factory) {
-  ASSERT(socket_factory_ != NULL);
-  Construct();
-}
-
-BasicPortAllocator::BasicPortAllocator(
-    talk_base::NetworkManager* network_manager)
-    : network_manager_(network_manager),
-      socket_factory_(NULL) {
-  Construct();
-}
-
-BasicPortAllocator::BasicPortAllocator(
-    talk_base::NetworkManager* network_manager,
-    const talk_base::SocketAddress& stun_address,
-    const talk_base::SocketAddress& relay_address_udp,
-    const talk_base::SocketAddress& relay_address_tcp,
-    const talk_base::SocketAddress& relay_address_ssl)
-    : network_manager_(network_manager),
-      socket_factory_(NULL),
-      stun_address_(stun_address),
-      relay_address_udp_(relay_address_udp),
-      relay_address_tcp_(relay_address_tcp),
-      relay_address_ssl_(relay_address_ssl) {
-  Construct();
-}
-
-void BasicPortAllocator::Construct() {
-  best_writable_phase_ = -1;
-  allow_tcp_listen_ = true;
-}
-
-BasicPortAllocator::~BasicPortAllocator() {
-}
-
-int BasicPortAllocator::best_writable_phase() const {
-  // If we are configured with an HTTP proxy, the best bet is to use the relay
-  if ((best_writable_phase_ == -1)
-      && ((proxy().type == talk_base::PROXY_HTTPS)
-          || (proxy().type == talk_base::PROXY_UNKNOWN))) {
-    return PHASE_RELAY;
-  }
-  return best_writable_phase_;
-}
-
-PortAllocatorSession *BasicPortAllocator::CreateSession(
-    const std::string &name, const std::string &session_type) {
-  return new BasicPortAllocatorSession(this, name, session_type);
-}
-
-void BasicPortAllocator::AddWritablePhase(int phase) {
-  if ((best_writable_phase_ == -1) || (phase < best_writable_phase_))
-    best_writable_phase_ = phase;
-}
-
-// BasicPortAllocatorSession
-BasicPortAllocatorSession::BasicPortAllocatorSession(
-    BasicPortAllocator *allocator,
-    const std::string &name,
-    const std::string &session_type)
-    : PortAllocatorSession(allocator->flags()), allocator_(allocator),
-      name_(name), session_type_(session_type), network_thread_(NULL),
-      socket_factory_(allocator->socket_factory()), allocation_started_(false),
-      network_manager_started_(false),
-      running_(false) {
-  allocator_->network_manager()->SignalNetworksChanged.connect(
-      this, &BasicPortAllocatorSession::OnNetworksChanged);
-  allocator_->network_manager()->StartUpdating();
-}
-
-BasicPortAllocatorSession::~BasicPortAllocatorSession() {
-  if (network_thread_ != NULL)
-    network_thread_->Clear(this);
-
-  std::vector<PortData>::iterator it;
-  for (it = ports_.begin(); it != ports_.end(); it++)
-    delete it->port;
-
-  for (uint32 i = 0; i < configs_.size(); ++i)
-    delete configs_[i];
-
-  for (uint32 i = 0; i < sequences_.size(); ++i)
-    delete sequences_[i];
-}
-
-void BasicPortAllocatorSession::GetInitialPorts() {
-  network_thread_ = talk_base::Thread::Current();
-  if (!socket_factory_) {
-    owned_socket_factory_.reset(
-        new talk_base::BasicPacketSocketFactory(network_thread_));
-    socket_factory_ = owned_socket_factory_.get();
-  }
-
-  network_thread_->Post(this, MSG_CONFIG_START);
-
-  if (flags() & PORTALLOCATOR_ENABLE_SHAKER)
-    network_thread_->PostDelayed(ShakeDelay(), this, MSG_SHAKE);
-}
-
-void BasicPortAllocatorSession::StartGetAllPorts() {
-  ASSERT(talk_base::Thread::Current() == network_thread_);
-  running_ = true;
-  if (allocation_started_)
-    network_thread_->PostDelayed(ALLOCATE_DELAY, this, MSG_ALLOCATE);
-  for (uint32 i = 0; i < sequences_.size(); ++i)
-    sequences_[i]->Start();
-  for (size_t i = 0; i < ports_.size(); ++i)
-    ports_[i].port->Start();
-}
-
-void BasicPortAllocatorSession::StopGetAllPorts() {
-  ASSERT(talk_base::Thread::Current() == network_thread_);
-  running_ = false;
-  network_thread_->Clear(this, MSG_ALLOCATE);
-  for (uint32 i = 0; i < sequences_.size(); ++i)
-    sequences_[i]->Stop();
-}
-
-void BasicPortAllocatorSession::OnMessage(talk_base::Message *message) {
-  switch (message->message_id) {
-  case MSG_CONFIG_START:
-    ASSERT(talk_base::Thread::Current() == network_thread_);
-    GetPortConfigurations();
-    break;
-
-  case MSG_CONFIG_READY:
-    ASSERT(talk_base::Thread::Current() == network_thread_);
-    OnConfigReady(static_cast<PortConfiguration*>(message->pdata));
-    break;
-
-  case MSG_ALLOCATE:
-    ASSERT(talk_base::Thread::Current() == network_thread_);
-    OnAllocate();
-    break;
-
-  case MSG_SHAKE:
-    ASSERT(talk_base::Thread::Current() == network_thread_);
-    OnShake();
-    break;
-
-  default:
-    ASSERT(false);
-  }
-}
-
-void BasicPortAllocatorSession::GetPortConfigurations() {
-  PortConfiguration* config = new PortConfiguration(allocator_->stun_address(),
-                                                    CreateRandomString(16),
-                                                    CreateRandomString(16),
-                                                    "");
-  PortConfiguration::PortList ports;
-  if (!allocator_->relay_address_udp().IsAny())
-    ports.push_back(ProtocolAddress(
-        allocator_->relay_address_udp(), PROTO_UDP));
-  if (!allocator_->relay_address_tcp().IsAny())
-    ports.push_back(ProtocolAddress(
-        allocator_->relay_address_tcp(), PROTO_TCP));
-  if (!allocator_->relay_address_ssl().IsAny())
-    ports.push_back(ProtocolAddress(
-        allocator_->relay_address_ssl(), PROTO_SSLTCP));
-  config->AddRelay(ports, RELAY_PRIMARY_PREF_MODIFIER);
-
-  ConfigReady(config);
-}
-
-void BasicPortAllocatorSession::ConfigReady(PortConfiguration* config) {
-  network_thread_->Post(this, MSG_CONFIG_READY, config);
-}
-
-// Adds a configuration to the list.
-void BasicPortAllocatorSession::OnConfigReady(PortConfiguration* config) {
-  if (config)
-    configs_.push_back(config);
-
-  AllocatePorts();
-}
-
-void BasicPortAllocatorSession::AllocatePorts() {
-  ASSERT(talk_base::Thread::Current() == network_thread_);
-  network_thread_->Post(this, MSG_ALLOCATE);
-}
-
-void BasicPortAllocatorSession::OnAllocate() {
-  if (network_manager_started_)
-    DoAllocate();
-
-  allocation_started_ = true;
-  if (running_)
-    network_thread_->PostDelayed(ALLOCATE_DELAY, this, MSG_ALLOCATE);
-}
-
-// For each network, see if we have a sequence that covers it already.  If not,
-// create a new sequence to create the appropriate ports.
-void BasicPortAllocatorSession::DoAllocate() {
-  std::vector<talk_base::Network*> networks;
-  allocator_->network_manager()->GetNetworks(&networks);
-  if (networks.empty()) {
-    LOG(LS_WARNING) << "Machine has no networks; no ports will be allocated";
-  } else {
-    for (uint32 i = 0; i < networks.size(); ++i) {
-      PortConfiguration* config = NULL;
-      if (configs_.size() > 0)
-        config = configs_.back();
-
-      uint32 sequence_flags = flags();
-
-      // Disables phases that are not specified in this config.
-      if (!config || config->stun_address.IsNil()) {
-        // No STUN ports specified in this config.
-        sequence_flags |= PORTALLOCATOR_DISABLE_STUN;
-      }
-      if (!config || config->relays.empty()) {
-        // No relay ports specified in this config.
-        sequence_flags |= PORTALLOCATOR_DISABLE_RELAY;
-      }
-
-      // Disable phases that would only create ports equivalent to
-      // ones that we have already made.
-      DisableEquivalentPhases(networks[i], config, &sequence_flags);
-
-      if ((sequence_flags & DISABLE_ALL_PHASES) == DISABLE_ALL_PHASES) {
-        // New AllocationSequence would have nothing to do, so don't make it.
-        continue;
-      }
-
-      AllocationSequence* sequence =
-          new AllocationSequence(this, networks[i], config, sequence_flags);
-      if (running_)
-        sequence->Start();
-
-      sequences_.push_back(sequence);
-    }
-  }
-}
-
-void BasicPortAllocatorSession::OnNetworksChanged() {
-  network_manager_started_ = true;
-  if (allocation_started_)
-    DoAllocate();
-}
-
-void BasicPortAllocatorSession::DisableEquivalentPhases(
-    talk_base::Network* network, PortConfiguration* config, uint32* flags) {
-  for (uint32 i = 0; i < sequences_.size() &&
-      (*flags & DISABLE_ALL_PHASES) != DISABLE_ALL_PHASES; ++i) {
-    sequences_[i]->DisableEquivalentPhases(network, config, flags);
-  }
-}
-
-void BasicPortAllocatorSession::AddAllocatedPort(Port* port,
-                                                 AllocationSequence * seq,
-                                                 float pref,
-                                                 bool prepare_address) {
-  if (!port)
-    return;
-
-  port->set_name(name_);
-  port->set_preference(pref);
-  port->set_generation(generation());
-  if (allocator_->proxy().type != talk_base::PROXY_NONE)
-    port->set_proxy(allocator_->user_agent(), allocator_->proxy());
-
-  PortData data;
-  data.port = port;
-  data.sequence = seq;
-  data.ready = false;
-  ports_.push_back(data);
-
-  port->SignalAddressReady.connect(this,
-      &BasicPortAllocatorSession::OnAddressReady);
-  port->SignalConnectionCreated.connect(this,
-      &BasicPortAllocatorSession::OnConnectionCreated);
-  port->SignalDestroyed.connect(this,
-      &BasicPortAllocatorSession::OnPortDestroyed);
-  LOG_J(LS_INFO, port) << "Added port to allocator";
-
-  if (prepare_address)
-    port->PrepareAddress();
-  if (running_)
-    port->Start();
-}
-
-void BasicPortAllocatorSession::OnAddressReady(Port *port) {
-  ASSERT(talk_base::Thread::Current() == network_thread_);
-  std::vector<PortData>::iterator it
-    = std::find(ports_.begin(), ports_.end(), port);
-  ASSERT(it != ports_.end());
-  if (it->ready)
-    return;
-  it->ready = true;
-  SignalPortReady(this, port);
-
-  // Only accumulate the candidates whose protocol has been enabled
-  std::vector<Candidate> candidates;
-  const std::vector<Candidate>& potentials = port->candidates();
-  for (size_t i = 0; i < potentials.size(); ++i) {
-    ProtocolType pvalue;
-    if (!StringToProto(potentials[i].protocol().c_str(), &pvalue))
-      continue;
-    if (it->sequence->ProtocolEnabled(pvalue)) {
-      candidates.push_back(potentials[i]);
-    }
-  }
-  if (!candidates.empty()) {
-    SignalCandidatesReady(this, candidates);
-  }
-}
-
-void BasicPortAllocatorSession::OnProtocolEnabled(AllocationSequence * seq,
-                                                  ProtocolType proto) {
-  std::vector<Candidate> candidates;
-  for (std::vector<PortData>::iterator it = ports_.begin();
-       it != ports_.end(); ++it) {
-    if (!it->ready || (it->sequence != seq))
-      continue;
-
-    const std::vector<Candidate>& potentials = it->port->candidates();
-    for (size_t i = 0; i < potentials.size(); ++i) {
-      ProtocolType pvalue;
-      if (!StringToProto(potentials[i].protocol().c_str(), &pvalue))
-        continue;
-      if (pvalue == proto) {
-        candidates.push_back(potentials[i]);
-      }
-    }
-  }
-  if (!candidates.empty()) {
-    SignalCandidatesReady(this, candidates);
-  }
-}
-
-void BasicPortAllocatorSession::OnPortDestroyed(Port* port) {
-  ASSERT(talk_base::Thread::Current() == network_thread_);
-  std::vector<PortData>::iterator iter =
-      std::find(ports_.begin(), ports_.end(), port);
-  ASSERT(iter != ports_.end());
-  ports_.erase(iter);
-
-  LOG_J(LS_INFO, port) << "Removed port from allocator ("
-                       << static_cast<int>(ports_.size()) << " remaining)";
-}
-
-void BasicPortAllocatorSession::OnConnectionCreated(Port* port,
-                                                    Connection* conn) {
-  conn->SignalStateChange.connect(this,
-    &BasicPortAllocatorSession::OnConnectionStateChange);
-}
-
-void BasicPortAllocatorSession::OnConnectionStateChange(Connection* conn) {
-  if (conn->write_state() == Connection::STATE_WRITABLE)
-    allocator_->AddWritablePhase(
-      LocalCandidateToPhase(conn->local_candidate()));
-}
-
-void BasicPortAllocatorSession::OnShake() {
-  LOG(INFO) << ">>>>> SHAKE <<<<< >>>>> SHAKE <<<<< >>>>> SHAKE <<<<<";
-
-  std::vector<Port*> ports;
-  std::vector<Connection*> connections;
-
-  for (size_t i = 0; i < ports_.size(); ++i) {
-    if (ports_[i].ready)
-      ports.push_back(ports_[i].port);
-  }
-
-  for (size_t i = 0; i < ports.size(); ++i) {
-    Port::AddressMap::const_iterator iter;
-    for (iter = ports[i]->connections().begin();
-         iter != ports[i]->connections().end();
-         ++iter) {
-      connections.push_back(iter->second);
-    }
-  }
-
-  LOG(INFO) << ">>>>> Destroying " << ports.size() << " ports and "
-            << connections.size() << " connections";
-
-  for (size_t i = 0; i < connections.size(); ++i)
-    connections[i]->Destroy();
-
-  if (running_ || (ports.size() > 0) || (connections.size() > 0))
-    network_thread_->PostDelayed(ShakeDelay(), this, MSG_SHAKE);
-}
-
-// AllocationSequence
-
-AllocationSequence::AllocationSequence(BasicPortAllocatorSession* session,
-                                       talk_base::Network* network,
-                                       PortConfiguration* config,
-                                       uint32 flags)
-  : session_(session), network_(network), ip_(network->ip()), config_(config),
-    running_(false), step_(0), flags_(flags) {
-  // All of the phases up until the best-writable phase so far run in step 0.
-  // The other phases follow sequentially in the steps after that.  If there is
-  // no best-writable so far, then only phase 0 occurs in step 0.
-  int last_phase_in_step_zero =
-      talk_base::_max(0, session->allocator()->best_writable_phase());
-  for (int phase = 0; phase < kNumPhases; ++phase)
-    step_of_phase_[phase] = talk_base::_max(0, phase - last_phase_in_step_zero);
-
-  // Immediately perform phase 0.
-  OnMessage(NULL);
-}
-
-AllocationSequence::~AllocationSequence() {
-  session_->network_thread()->Clear(this);
-}
-
-void AllocationSequence::DisableEquivalentPhases(talk_base::Network* network,
-    PortConfiguration* config, uint32* flags) {
-  if (!((network == network_) && (ip_ == network->ip()))) {
-    // Different network setup; nothing is equivalent.
-    return;
-  }
-
-  // Else turn off the stuff that we've already got covered.
-
-  // Every config implicitly specifies local, so turn that off right away.
-  *flags |= PORTALLOCATOR_DISABLE_UDP;
-  *flags |= PORTALLOCATOR_DISABLE_TCP;
-
-  if (config_ && config) {
-    if (config_->stun_address == config->stun_address) {
-      // Already got this STUN server covered.
-      *flags |= PORTALLOCATOR_DISABLE_STUN;
-    }
-    if (!config_->relays.empty()) {
-      // Already got relays covered.
-      // NOTE: This will even skip a _different_ set of relay servers if we
-      // were to be given one, but that never happens in our codebase. Should
-      // probably get rid of the list in PortConfiguration and just keep a
-      // single relay server in each one.
-      *flags |= PORTALLOCATOR_DISABLE_RELAY;
-    }
-  }
-}
-
-void AllocationSequence::Start() {
-  running_ = true;
-  session_->network_thread()->PostDelayed(ALLOCATION_STEP_DELAY,
-                                          this,
-                                          MSG_ALLOCATION_PHASE);
-}
-
-void AllocationSequence::Stop() {
-  running_ = false;
-  session_->network_thread()->Clear(this, MSG_ALLOCATION_PHASE);
-}
-
-void AllocationSequence::OnMessage(talk_base::Message* msg) {
-  ASSERT(talk_base::Thread::Current() == session_->network_thread());
-  if (msg)
-    ASSERT(msg->message_id == MSG_ALLOCATION_PHASE);
-
-  const char* const PHASE_NAMES[kNumPhases] = {
-    "Udp", "Relay", "Tcp", "SslTcp"
-  };
-
-  // Perform all of the phases in the current step.
-  for (int phase = 0; phase < kNumPhases; phase++) {
-    if (step_of_phase_[phase] != step_)
-      continue;
-
-    LOG_J(LS_INFO, network_) << "Allocation Phase=" << PHASE_NAMES[phase]
-                             << " (Step=" << step_ << ")";
-
-    switch (phase) {
-    case PHASE_UDP:
-      CreateUDPPorts();
-      CreateStunPorts();
-      EnableProtocol(PROTO_UDP);
-      break;
-
-    case PHASE_RELAY:
-      CreateRelayPorts();
-      break;
-
-    case PHASE_TCP:
-      CreateTCPPorts();
-      EnableProtocol(PROTO_TCP);
-      break;
-
-    case PHASE_SSLTCP:
-      EnableProtocol(PROTO_SSLTCP);
-      break;
-
-    default:
-      ASSERT(false);
-    }
-  }
-
-  // TODO: use different delays for each stage
-  step_ += 1;
-  if (running_) {
-    session_->network_thread()->PostDelayed(ALLOCATION_STEP_DELAY,
-                                            this,
-                                            MSG_ALLOCATION_PHASE);
-  }
-}
-
-void AllocationSequence::EnableProtocol(ProtocolType proto) {
-  if (!ProtocolEnabled(proto)) {
-    protocols_.push_back(proto);
-    session_->OnProtocolEnabled(this, proto);
-  }
-}
-
-bool AllocationSequence::ProtocolEnabled(ProtocolType proto) const {
-  for (ProtocolList::const_iterator it = protocols_.begin();
-       it != protocols_.end(); ++it) {
-    if (*it == proto)
-      return true;
-  }
-  return false;
-}
-
-void AllocationSequence::CreateUDPPorts() {
-  if (flags_ & PORTALLOCATOR_DISABLE_UDP) {
-    LOG(LS_VERBOSE) << "AllocationSequence: UDP ports disabled, skipping.";
-    return;
-  }
-
-  Port* port = UDPPort::Create(session_->network_thread(),
-                               session_->socket_factory(),
-                               network_, ip_,
-                               session_->allocator()->min_port(),
-                               session_->allocator()->max_port());
-  if (port)
-    session_->AddAllocatedPort(port, this, PREF_LOCAL_UDP);
-}
-
-void AllocationSequence::CreateTCPPorts() {
-  if (flags_ & PORTALLOCATOR_DISABLE_TCP) {
-    LOG(LS_VERBOSE) << "AllocationSequence: TCP ports disabled, skipping.";
-    return;
-  }
-
-  Port* port = TCPPort::Create(session_->network_thread(),
-                               session_->socket_factory(),
-                               network_, ip_,
-                               session_->allocator()->min_port(),
-                               session_->allocator()->max_port(),
-                               session_->allocator()->allow_tcp_listen());
-  if (port)
-    session_->AddAllocatedPort(port, this, PREF_LOCAL_TCP);
-}
-
-void AllocationSequence::CreateStunPorts() {
-  if (flags_ & PORTALLOCATOR_DISABLE_STUN) {
-    LOG(LS_VERBOSE) << "AllocationSequence: STUN ports disabled, skipping.";
-    return;
-  }
-
-  // If BasicPortAllocatorSession::OnAllocate left STUN ports enabled then we
-  // ought to have an address for them here.
-  ASSERT(config_ && !config_->stun_address.IsNil());
-  if (!(config_ && !config_->stun_address.IsNil())) {
-    LOG(LS_WARNING)
-        << "AllocationSequence: No STUN server configured, skipping.";
-    return;
-  }
-
-  Port* port = StunPort::Create(session_->network_thread(),
-                                session_->socket_factory(),
-                                network_, ip_,
-                                session_->allocator()->min_port(),
-                                session_->allocator()->max_port(),
-                                config_->stun_address);
-  if (port)
-    session_->AddAllocatedPort(port, this, PREF_LOCAL_STUN);
-}
-
-void AllocationSequence::CreateRelayPorts() {
-  if (flags_ & PORTALLOCATOR_DISABLE_RELAY) {
-     LOG(LS_VERBOSE) << "AllocationSequence: Relay ports disabled, skipping.";
-     return;
-  }
-
-  // If BasicPortAllocatorSession::OnAllocate left relay ports enabled then we
-  // ought to have a relay list for them here.
-  ASSERT(config_ && !config_->relays.empty());
-  if (!(config_ && !config_->relays.empty())) {
-    LOG(LS_WARNING)
-        << "AllocationSequence: No relay server configured, skipping.";
-    return;
-  }
-
-  PortConfiguration::RelayList::const_iterator relay;
-  for (relay = config_->relays.begin();
-       relay != config_->relays.end(); ++relay) {
-    RelayPort* port = RelayPort::Create(session_->network_thread(),
-                                        session_->socket_factory(),
-                                        network_, ip_,
-                                        session_->allocator()->min_port(),
-                                        session_->allocator()->max_port(),
-                                        config_->username, config_->password,
-                                        config_->magic_cookie);
-    if (port) {
-      // Note: We must add the allocated port before we add addresses because
-      //       the latter will create candidates that need name and preference
-      //       settings.  However, we also can't prepare the address (normally
-      //       done by AddAllocatedPort) until we have these addresses.  So we
-      //       wait to do that until below.
-      session_->AddAllocatedPort(port, this, PREF_RELAY + relay->pref_modifier,
-                                 false);
-
-      // Add the addresses of this protocol.
-      PortConfiguration::PortList::const_iterator relay_port;
-      for (relay_port = relay->ports.begin();
-            relay_port != relay->ports.end();
-            ++relay_port) {
-        port->AddServerAddress(*relay_port);
-        port->AddExternalAddress(*relay_port);
-      }
-
-      // Start fetching an address for this port.
-      port->PrepareAddress();
-    }
-  }
-}
-
-// PortConfiguration
-PortConfiguration::PortConfiguration(const talk_base::SocketAddress& sa,
-                                     const std::string& un,
-                                     const std::string& pw,
-                                     const std::string& mc)
-    : stun_address(sa), username(un), password(pw), magic_cookie(mc) {
-}
-
-void PortConfiguration::AddRelay(const PortList& ports, float pref_modifier) {
-  RelayServer relay;
-  relay.ports = ports;
-  relay.pref_modifier = pref_modifier;
-  relays.push_back(relay);
-}
-
-bool PortConfiguration::ResolveStunAddress() {
-  int err = 0;
-  if (!stun_address.ResolveIP(true, &err)) {
-    LOG(LS_ERROR) << "Unable to resolve STUN host "
-                  << stun_address.hostname() << ".  Error " << err;
-    return false;
-  }
-  return true;
-}
-
-bool PortConfiguration::SupportsProtocol(
-    const PortConfiguration::RelayServer& relay, ProtocolType type) {
-  PortConfiguration::PortList::const_iterator relay_port;
-  for (relay_port = relay.ports.begin();
-        relay_port != relay.ports.end();
-        ++relay_port) {
-    if (relay_port->proto == type)
-      return true;
-  }
-  return false;
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/p2p/client/basicportallocator.h b/third_party/libjingle/source/talk/p2p/client/basicportallocator.h
deleted file mode 100644
index d5fce7e..0000000
--- a/third_party/libjingle/source/talk/p2p/client/basicportallocator.h
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_P2P_CLIENT_BASICPORTALLOCATOR_H_
-#define TALK_P2P_CLIENT_BASICPORTALLOCATOR_H_
-
-#include <string>
-#include <vector>
-
-#include "talk/base/messagequeue.h"
-#include "talk/base/network.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/base/thread.h"
-#include "talk/p2p/base/portallocator.h"
-
-namespace cricket {
-
-class BasicPortAllocator : public PortAllocator {
- public:
-  BasicPortAllocator(talk_base::NetworkManager* network_manager,
-                     talk_base::PacketSocketFactory* socket_factory);
-  explicit BasicPortAllocator(talk_base::NetworkManager* network_manager);
-  BasicPortAllocator(talk_base::NetworkManager* network_manager,
-                     const talk_base::SocketAddress& stun_server,
-                     const talk_base::SocketAddress& relay_server_udp,
-                     const talk_base::SocketAddress& relay_server_tcp,
-                     const talk_base::SocketAddress& relay_server_ssl);
-  virtual ~BasicPortAllocator();
-
-  talk_base::NetworkManager* network_manager() { return network_manager_; }
-
-  // If socket_factory() is set to NULL each PortAllocatorSession
-  // creates its own socket factory.
-  talk_base::PacketSocketFactory* socket_factory() { return socket_factory_; }
-
-  const talk_base::SocketAddress& stun_address() const {
-    return stun_address_;
-  }
-  const talk_base::SocketAddress& relay_address_udp() const {
-    return relay_address_udp_;
-  }
-  const talk_base::SocketAddress& relay_address_tcp() const {
-    return relay_address_tcp_;
-  }
-  const talk_base::SocketAddress& relay_address_ssl() const {
-    return relay_address_ssl_;
-  }
-
-  // Returns the best (highest preference) phase that has produced a port that
-  // produced a writable connection.  If no writable connections have been
-  // produced, this returns -1.
-  int best_writable_phase() const;
-
-  virtual PortAllocatorSession* CreateSession(const std::string& name,
-                                              const std::string& session_type);
-
-  // Called whenever a connection becomes writable with the argument being the
-  // phase that the corresponding port was created in.
-  void AddWritablePhase(int phase);
-
-  bool allow_tcp_listen() const {
-    return allow_tcp_listen_;
-  }
-  void set_allow_tcp_listen(bool allow_tcp_listen) {
-    allow_tcp_listen_ = allow_tcp_listen;
-  }
-
- private:
-  void Construct();
-
-  talk_base::NetworkManager* network_manager_;
-  talk_base::PacketSocketFactory* socket_factory_;
-  const talk_base::SocketAddress stun_address_;
-  const talk_base::SocketAddress relay_address_udp_;
-  const talk_base::SocketAddress relay_address_tcp_;
-  const talk_base::SocketAddress relay_address_ssl_;
-  int best_writable_phase_;
-  bool allow_tcp_listen_;
-};
-
-struct PortConfiguration;
-class AllocationSequence;
-
-class BasicPortAllocatorSession : public PortAllocatorSession,
-    public talk_base::MessageHandler {
- public:
-  BasicPortAllocatorSession(BasicPortAllocator* allocator,
-                            const std::string& name,
-                            const std::string& session_type);
-  ~BasicPortAllocatorSession();
-
-  virtual BasicPortAllocator* allocator() { return allocator_; }
-  const std::string& name() const { return name_; }
-  const std::string& session_type() const { return session_type_; }
-  talk_base::Thread* network_thread() { return network_thread_; }
-  talk_base::PacketSocketFactory* socket_factory() { return socket_factory_; }
-
-  virtual void GetInitialPorts();
-  virtual void StartGetAllPorts();
-  virtual void StopGetAllPorts();
-  virtual bool IsGettingAllPorts() { return running_; }
-
- protected:
-  // Starts the process of getting the port configurations.
-  virtual void GetPortConfigurations();
-
-  // Adds a port configuration that is now ready.  Once we have one for each
-  // network (or a timeout occurs), we will start allocating ports.
-  virtual void ConfigReady(PortConfiguration* config);
-
-  // MessageHandler.  Can be overriden if message IDs do not conflict.
-  virtual void OnMessage(talk_base::Message *message);
-
- private:
-  void OnConfigReady(PortConfiguration* config);
-  void OnConfigTimeout();
-  void AllocatePorts();
-  void OnAllocate();
-  void DoAllocate();
-  void OnNetworksChanged();
-  void DisableEquivalentPhases(talk_base::Network* network,
-      PortConfiguration* config, uint32* flags);
-  void AddAllocatedPort(Port* port, AllocationSequence* seq, float pref,
-      bool prepare_address = true);
-  void OnAddressReady(Port* port);
-  void OnProtocolEnabled(AllocationSequence* seq, ProtocolType proto);
-  void OnPortDestroyed(Port* port);
-  void OnConnectionCreated(Port* port, Connection* conn);
-  void OnConnectionStateChange(Connection* conn);
-  void OnShake();
-
-  BasicPortAllocator* allocator_;
-  std::string name_;
-  std::string session_type_;
-  talk_base::Thread* network_thread_;
-  talk_base::scoped_ptr<talk_base::PacketSocketFactory> owned_socket_factory_;
-  talk_base::PacketSocketFactory* socket_factory_;
-  bool configuration_done_;
-  bool allocation_started_;
-  bool network_manager_started_;
-  bool running_;  // set when StartGetAllPorts is called
-  std::vector<PortConfiguration*> configs_;
-  std::vector<AllocationSequence*> sequences_;
-
-  struct PortData {
-    Port* port;
-    AllocationSequence* sequence;
-    bool ready;
-
-    bool operator==(Port* rhs) const { return (port == rhs); }
-  };
-  std::vector<PortData> ports_;
-
-  friend class AllocationSequence;
-};
-
-// Records configuration information useful in creating ports.
-struct PortConfiguration : public talk_base::MessageData {
-  talk_base::SocketAddress stun_address;
-  std::string username;
-  std::string password;
-  std::string magic_cookie;
-
-  typedef std::vector<ProtocolAddress> PortList;
-  struct RelayServer {
-    PortList ports;
-    float pref_modifier;  // added to the protocol modifier to get the
-                          // preference for this particular server
-  };
-
-  typedef std::vector<RelayServer> RelayList;
-  RelayList relays;
-
-  PortConfiguration(const talk_base::SocketAddress& stun_address,
-                    const std::string& username,
-                    const std::string& password,
-                    const std::string& magic_cookie);
-
-  // Adds another relay server, with the given ports and modifier, to the list.
-  void AddRelay(const PortList& ports, float pref_modifier);
-
-  bool ResolveStunAddress();
-
-  // Determines whether the given relay server supports the given protocol.
-  static bool SupportsProtocol(const PortConfiguration::RelayServer& relay,
-                               ProtocolType type);
-};
-
-}  // namespace cricket
-
-#endif  // TALK_P2P_CLIENT_BASICPORTALLOCATOR_H_
diff --git a/third_party/libjingle/source/talk/p2p/client/httpportallocator.cc b/third_party/libjingle/source/talk/p2p/client/httpportallocator.cc
deleted file mode 100644
index 0baa07d..0000000
--- a/third_party/libjingle/source/talk/p2p/client/httpportallocator.cc
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2008, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/p2p/client/httpportallocator.h"
-
-#include <algorithm>
-#include <map>
-
-#include "talk/base/asynchttprequest.h"
-#include "talk/base/basicdefs.h"
-#include "talk/base/common.h"
-#include "talk/base/helpers.h"
-#include "talk/base/logging.h"
-#include "talk/base/nethelpers.h"
-#include "talk/base/signalthread.h"
-
-namespace {
-
-const uint32 MSG_TIMEOUT = 100;  // must not conflict
-  // with BasicPortAllocator.cpp
-
-// Helper routine to remove whitespace from the ends of a string.
-void Trim(std::string& str) {
-  size_t first = str.find_first_not_of(" \t\r\n");
-  if (first == std::string::npos) {
-    str.clear();
-    return;
-  }
-
-  ASSERT(str.find_last_not_of(" \t\r\n") != std::string::npos);
-}
-
-// Parses the lines in the result of the HTTP request that are of the form
-// 'a=b' and returns them in a map.
-typedef std::map<std::string, std::string> StringMap;
-void ParseMap(const std::string& string, StringMap& map) {
-  size_t start_of_line = 0;
-  size_t end_of_line = 0;
-
-  for (;;) {  // for each line
-    start_of_line = string.find_first_not_of("\r\n", end_of_line);
-    if (start_of_line == std::string::npos)
-      break;
-
-    end_of_line = string.find_first_of("\r\n", start_of_line);
-    if (end_of_line == std::string::npos) {
-      end_of_line = string.length();
-    }
-
-    size_t equals = string.find('=', start_of_line);
-    if ((equals >= end_of_line) || (equals == std::string::npos))
-      continue;
-
-    std::string key(string, start_of_line, equals - start_of_line);
-    std::string value(string, equals + 1, end_of_line - equals - 1);
-
-    Trim(key);
-    Trim(value);
-
-    if ((key.size() > 0) && (value.size() > 0))
-      map[key] = value;
-  }
-}
-
-}  // namespace
-
-namespace cricket {
-
-// HttpPortAllocatorBase
-
-const int HttpPortAllocatorBase::kNumRetries = 5;
-
-const char HttpPortAllocatorBase::kCreateSessionURL[] = "/create_session";
-
-HttpPortAllocatorBase::HttpPortAllocatorBase(
-    talk_base::NetworkManager* network_manager,
-    talk_base::PacketSocketFactory* socket_factory,
-    const std::string &user_agent)
-    : BasicPortAllocator(network_manager, socket_factory), agent_(user_agent) {
-  relay_hosts_.push_back("relay.google.com");
-  stun_hosts_.push_back(
-      talk_base::SocketAddress("stun.l.google.com", 19302));
-}
-
-HttpPortAllocatorBase::HttpPortAllocatorBase(
-    talk_base::NetworkManager* network_manager,
-    const std::string &user_agent)
-    : BasicPortAllocator(network_manager), agent_(user_agent) {
-  relay_hosts_.push_back("relay.google.com");
-  stun_hosts_.push_back(
-      talk_base::SocketAddress("stun.l.google.com", 19302));
-}
-
-HttpPortAllocatorBase::~HttpPortAllocatorBase() {
-}
-
-// HttpPortAllocatorSessionBase
-
-HttpPortAllocatorSessionBase::HttpPortAllocatorSessionBase(
-    HttpPortAllocatorBase* allocator, const std::string &name,
-    const std::string& session_type,
-    const std::vector<talk_base::SocketAddress>& stun_hosts,
-    const std::vector<std::string>& relay_hosts,
-    const std::string& relay_token,
-    const std::string& user_agent)
-    : BasicPortAllocatorSession(allocator, name, session_type),
-      relay_hosts_(relay_hosts), stun_hosts_(stun_hosts),
-      relay_token_(relay_token), agent_(user_agent), attempts_(0) {
-}
-
-HttpPortAllocatorSessionBase::~HttpPortAllocatorSessionBase() {}
-
-void HttpPortAllocatorSessionBase::GetPortConfigurations() {
-  // Creating relay sessions can take time and is done asynchronously.
-  // Creating stun sessions could also take time and could be done aysnc also,
-  // but for now is done here and added to the initial config.  Note any later
-  // configs will have unresolved stun ips and will be discarded by the
-  // AllocationSequence.
-  PortConfiguration* config = new PortConfiguration(stun_hosts_[0], "", "", "");
-  ConfigReady(config);
-  TryCreateRelaySession();
-}
-
-void HttpPortAllocatorSessionBase::TryCreateRelaySession() {
-  if (allocator()->flags() & PORTALLOCATOR_DISABLE_RELAY) {
-    LOG(LS_VERBOSE) << "HttpPortAllocator: Relay ports disabled, skipping.";
-    return;
-  }
-
-  if (attempts_ == HttpPortAllocator::kNumRetries) {
-    LOG(LS_ERROR) << "HttpPortAllocator: maximum number of requests reached; "
-                  << "giving up on relay.";
-    return;
-  }
-
-  if (relay_hosts_.size() == 0) {
-    LOG(LS_ERROR) << "HttpPortAllocator: no relay hosts configured.";
-    return;
-  }
-
-  // Choose the next host to try.
-  std::string host = relay_hosts_[attempts_ % relay_hosts_.size()];
-  attempts_++;
-  LOG(LS_INFO) << "HTTPPortAllocator: sending to relay host " << host;
-  if (relay_token_.empty()) {
-    LOG(LS_WARNING) << "No relay auth token found.";
-  }
-
-  SendSessionRequest(host, talk_base::HTTP_SECURE_PORT);
-}
-
-void HttpPortAllocatorSessionBase::ReceiveSessionResponse(
-    const std::string& response) {
-
-  StringMap map;
-  ParseMap(response, map);
-
-  std::string username = map["username"];
-  std::string password = map["password"];
-  std::string magic_cookie = map["magic_cookie"];
-
-  std::string relay_ip = map["relay.ip"];
-  std::string relay_udp_port = map["relay.udp_port"];
-  std::string relay_tcp_port = map["relay.tcp_port"];
-  std::string relay_ssltcp_port = map["relay.ssltcp_port"];
-
-  PortConfiguration* config = new PortConfiguration(stun_hosts_[0],
-                                                    username,
-                                                    password,
-                                                    magic_cookie);
-
-  PortConfiguration::PortList ports;
-  if (!relay_udp_port.empty()) {
-    talk_base::SocketAddress address(relay_ip, atoi(relay_udp_port.c_str()));
-    ports.push_back(ProtocolAddress(address, PROTO_UDP));
-  }
-  if (!relay_tcp_port.empty()) {
-    talk_base::SocketAddress address(relay_ip, atoi(relay_tcp_port.c_str()));
-    ports.push_back(ProtocolAddress(address, PROTO_TCP));
-  }
-  if (!relay_ssltcp_port.empty()) {
-    talk_base::SocketAddress address(relay_ip, atoi(relay_ssltcp_port.c_str()));
-    ports.push_back(ProtocolAddress(address, PROTO_SSLTCP));
-  }
-  config->AddRelay(ports, 0.0f);
-  ConfigReady(config);
-}
-
-// HttpPortAllocator
-
-HttpPortAllocator::HttpPortAllocator(
-    talk_base::NetworkManager* network_manager,
-    talk_base::PacketSocketFactory* socket_factory,
-    const std::string &user_agent)
-    : HttpPortAllocatorBase(network_manager, socket_factory, user_agent) {
-}
-
-HttpPortAllocator::HttpPortAllocator(
-    talk_base::NetworkManager* network_manager,
-    const std::string &user_agent)
-    : HttpPortAllocatorBase(network_manager, user_agent) {
-}
-HttpPortAllocator::~HttpPortAllocator() {}
-
-PortAllocatorSession* HttpPortAllocator::CreateSession(
-    const std::string& name, const std::string& session_type) {
-  return new HttpPortAllocatorSession(this, name, session_type, stun_hosts(),
-      relay_hosts(), relay_token(), user_agent());
-}
-
-// HttpPortAllocatorSession
-
-HttpPortAllocatorSession::HttpPortAllocatorSession(
-    HttpPortAllocator* allocator,
-    const std::string& name,
-    const std::string& session_type,
-    const std::vector<talk_base::SocketAddress>& stun_hosts,
-    const std::vector<std::string>& relay_hosts,
-    const std::string& relay,
-    const std::string& agent)
-    : HttpPortAllocatorSessionBase(allocator, name, session_type, stun_hosts,
-                                   relay_hosts, relay, agent) {
-}
-
-HttpPortAllocatorSession::~HttpPortAllocatorSession() {
-  for (std::list<talk_base::AsyncHttpRequest*>::iterator it = requests_.begin();
-       it != requests_.end(); ++it) {
-    (*it)->Destroy(true);
-  }
-}
-
-void HttpPortAllocatorSession::SendSessionRequest(const std::string& host,
-                                                  int port) {
-  // Initiate an HTTP request to create a session through the chosen host.
-  talk_base::AsyncHttpRequest* request =
-      new talk_base::AsyncHttpRequest(user_agent());
-  request->SignalWorkDone.connect(this,
-      &HttpPortAllocatorSession::OnRequestDone);
-
-  request->set_secure(port == talk_base::HTTP_SECURE_PORT);
-  request->set_proxy(allocator()->proxy());
-  request->response().document.reset(new talk_base::MemoryStream);
-  request->request().verb = talk_base::HV_GET;
-  request->request().path = HttpPortAllocator::kCreateSessionURL;
-  request->request().addHeader("X-Talk-Google-Relay-Auth", relay_token(), true);
-  request->request().addHeader("X-Google-Relay-Auth", relay_token(), true);
-  request->request().addHeader("X-Session-Type", session_type(), true);
-  request->request().addHeader("X-Stream-Type", name(), true);
-  request->set_host(host);
-  request->set_port(port);
-  request->Start();
-  request->Release();
-  requests_.push_back(request);
-}
-
-void HttpPortAllocatorSession::OnRequestDone(talk_base::SignalThread* data) {
-  talk_base::AsyncHttpRequest* request =
-      static_cast<talk_base::AsyncHttpRequest*>(data);
-
-  // Remove the request from the list of active requests.
-  std::list<talk_base::AsyncHttpRequest*>::iterator it =
-      std::find(requests_.begin(), requests_.end(), request);
-  if (it != requests_.end()) {
-    requests_.erase(it);
-    return;
-  }
-
-  if (request->response().scode != 200) {
-    LOG(LS_WARNING) << "HTTPPortAllocator: request "
-                    << " received error " << request->response().scode;
-    TryCreateRelaySession();
-    return;
-  }
-  LOG(LS_INFO) << "HTTPPortAllocator: request succeeded";
-
-  talk_base::MemoryStream* stream =
-      static_cast<talk_base::MemoryStream*>(request->response().document.get());
-  stream->Rewind();
-  size_t length;
-  stream->GetSize(&length);
-  std::string resp = std::string(stream->GetBuffer(), length);
-  ReceiveSessionResponse(resp);
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/p2p/client/httpportallocator.h b/third_party/libjingle/source/talk/p2p/client/httpportallocator.h
deleted file mode 100644
index e47a69e..0000000
--- a/third_party/libjingle/source/talk/p2p/client/httpportallocator.h
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2008, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_P2P_CLIENT_HTTPPORTALLOCATOR_H_
-#define TALK_P2P_CLIENT_HTTPPORTALLOCATOR_H_
-
-#include <list>
-#include <string>
-#include <vector>
-#include "talk/p2p/client/basicportallocator.h"
-
-namespace talk_base {
-class AsyncHttpRequest;
-class SignalThread;
-}
-
-namespace cricket {
-
-class HttpPortAllocatorBase : public BasicPortAllocator {
- public:
-  // The number of HTTP requests we should attempt before giving up.
-  static const int kNumRetries;
-
-  // Records the URL that we will GET in order to create a session.
-  static const char kCreateSessionURL[];
-
-  HttpPortAllocatorBase(talk_base::NetworkManager* network_manager,
-                        const std::string& user_agent);
-  HttpPortAllocatorBase(talk_base::NetworkManager* network_manager,
-                        talk_base::PacketSocketFactory* socket_factory,
-                        const std::string& user_agent);
-  virtual ~HttpPortAllocatorBase();
-
-  // CreateSession is defined in BasicPortAllocator but is
-  // redefined here as pure virtual.
-  virtual PortAllocatorSession* CreateSession(
-      const std::string& name,
-      const std::string& session_type) = 0;
-
-  void SetStunHosts(const std::vector<talk_base::SocketAddress>& hosts) {
-    if (!hosts.empty()) {
-      stun_hosts_ = hosts;
-    }
-  }
-  void SetRelayHosts(const std::vector<std::string>& hosts) {
-    if (!hosts.empty()) {
-      relay_hosts_ = hosts;
-    }
-  }
-  void SetRelayToken(const std::string& relay) { relay_token_ = relay; }
-
-  const std::vector<talk_base::SocketAddress>& stun_hosts() const {
-    return stun_hosts_;
-  }
-
-  const std::vector<std::string>& relay_hosts() const {
-    return relay_hosts_;
-  }
-
-  const std::string& relay_token() const {
-    return relay_token_;
-  }
-
-  const std::string& user_agent() const {
-    return agent_;
-  }
-
- private:
-  std::vector<talk_base::SocketAddress> stun_hosts_;
-  std::vector<std::string> relay_hosts_;
-  std::string relay_token_;
-  std::string agent_;
-};
-
-class RequestData;
-
-class HttpPortAllocatorSessionBase : public BasicPortAllocatorSession {
- public:
-  HttpPortAllocatorSessionBase(
-      HttpPortAllocatorBase* allocator,
-      const std::string& name,
-      const std::string& session_type,
-      const std::vector<talk_base::SocketAddress>& stun_hosts,
-      const std::vector<std::string>& relay_hosts,
-      const std::string& relay,
-      const std::string& agent);
-  virtual ~HttpPortAllocatorSessionBase();
-
-  const std::string& relay_token() const {
-    return relay_token_;
-  }
-
-  const std::string& user_agent() const {
-      return agent_;
-  }
-
-  virtual void SendSessionRequest(const std::string& host, int port) = 0;
-  virtual void ReceiveSessionResponse(const std::string& response);
-
- protected:
-  virtual void GetPortConfigurations();
-  void TryCreateRelaySession();
-  virtual HttpPortAllocatorBase* allocator() {
-    return static_cast<HttpPortAllocatorBase*>(
-        BasicPortAllocatorSession::allocator());
-  }
-
- private:
-  std::vector<std::string> relay_hosts_;
-  std::vector<talk_base::SocketAddress> stun_hosts_;
-  std::string relay_token_;
-  std::string agent_;
-  int attempts_;
-};
-
-class HttpPortAllocator : public HttpPortAllocatorBase {
- public:
-  HttpPortAllocator(talk_base::NetworkManager* network_manager,
-                    const std::string& user_agent);
-  HttpPortAllocator(talk_base::NetworkManager* network_manager,
-                    talk_base::PacketSocketFactory* socket_factory,
-                    const std::string& user_agent);
-  virtual ~HttpPortAllocator();
-  virtual PortAllocatorSession* CreateSession(const std::string& name,
-                                              const std::string& session_type);
-};
-
-class HttpPortAllocatorSession : public HttpPortAllocatorSessionBase {
- public:
-  HttpPortAllocatorSession(
-      HttpPortAllocator* allocator,
-      const std::string& name,
-      const std::string& session_type,
-      const std::vector<talk_base::SocketAddress>& stun_hosts,
-      const std::vector<std::string>& relay_hosts,
-      const std::string& relay,
-      const std::string& agent);
-  virtual ~HttpPortAllocatorSession();
-
-  virtual void SendSessionRequest(const std::string& host, int port);
-
- protected:
-  // Protected for diagnostics.
-  virtual void OnRequestDone(talk_base::SignalThread* request);
-
- private:
-  std::list<talk_base::AsyncHttpRequest*> requests_;
-};
-
-}  // namespace cricket
-
-#endif  // TALK_P2P_CLIENT_HTTPPORTALLOCATOR_H_
diff --git a/third_party/libjingle/source/talk/p2p/client/portallocator_unittest.cc b/third_party/libjingle/source/talk/p2p/client/portallocator_unittest.cc
deleted file mode 100644
index be3a4e1..0000000
--- a/third_party/libjingle/source/talk/p2p/client/portallocator_unittest.cc
+++ /dev/null
@@ -1,321 +0,0 @@
-/*
- * libjingle
- * Copyright 2009 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/fakenetwork.h"
-#include "talk/base/firewallsocketserver.h"
-#include "talk/base/gunit.h"
-#include "talk/base/helpers.h"
-#include "talk/base/logging.h"
-#include "talk/base/network.h"
-#include "talk/base/physicalsocketserver.h"
-#include "talk/base/socketaddress.h"
-#include "talk/base/thread.h"
-#include "talk/base/virtualsocketserver.h"
-#include "talk/p2p/base/testrelayserver.h"
-#include "talk/p2p/base/teststunserver.h"
-#include "talk/p2p/client/basicportallocator.h"
-#include "talk/p2p/client/httpportallocator.h"
-
-using talk_base::SocketAddress;
-using talk_base::Thread;
-
-static const SocketAddress kClientAddr("11.11.11.11", 0);
-static const SocketAddress kStunAddr("99.99.99.1", cricket::STUN_SERVER_PORT);
-static const SocketAddress kRelayUdpIntAddr("99.99.99.2", 5000);
-static const SocketAddress kRelayUdpExtAddr("99.99.99.3", 5001);
-static const SocketAddress kRelayTcpIntAddr("99.99.99.2", 5002);
-static const SocketAddress kRelayTcpExtAddr("99.99.99.3", 5003);
-static const SocketAddress kRelaySslTcpIntAddr("99.99.99.2", 5004);
-static const SocketAddress kRelaySslTcpExtAddr("99.99.99.3", 5005);
-
-// Minimum and maximum port for port range tests.
-static const int kMinPort = 10000;
-static const int kMaxPort = 10099;
-
-// Helper for dumping candidates
-std::ostream& operator<<(std::ostream& os, const cricket::Candidate& c) {
-  os << c.ToString();
-  return os;
-}
-
-class PortAllocatorTest : public testing::Test, public sigslot::has_slots<> {
- public:
-  static void SetUpTestCase() {
-    // Ensure the RNG is inited.
-    talk_base::InitRandom(NULL, 0);
-  }
-  PortAllocatorTest()
-      : pss_(new talk_base::PhysicalSocketServer),
-        vss_(new talk_base::VirtualSocketServer(pss_.get())),
-        fss_(new talk_base::FirewallSocketServer(vss_.get())),
-        ss_scope_(fss_.get()),
-        stun_server_(Thread::Current(), kStunAddr),
-        relay_server_(Thread::Current(), kRelayUdpIntAddr, kRelayUdpExtAddr,
-                      kRelayTcpIntAddr, kRelayTcpExtAddr,
-                      kRelaySslTcpIntAddr, kRelaySslTcpExtAddr),
-        allocator_(&network_manager_, kStunAddr,
-                   kRelayUdpIntAddr, kRelayTcpIntAddr, kRelaySslTcpIntAddr) {
-  }
-
-  void AddInterface(const SocketAddress& addr) {
-    network_manager_.AddInterface(addr);
-  }
-  bool SetPortRange(int min_port, int max_port) {
-    return allocator_.SetPortRange(min_port, max_port);
-  }
-  bool CreateSession(const std::string& name, const std::string& type) {
-    session_.reset(allocator_.CreateSession(name, type));
-    if (!session_.get())
-      return false;
-
-    session_->SignalPortReady.connect(this,
-        &PortAllocatorTest::OnPortReady);
-    session_->SignalCandidatesReady.connect(this,
-        &PortAllocatorTest::OnCandidatesReady);
-    return true;
-  }
-
-  static bool CheckCandidate(const cricket::Candidate& c,
-                             const std::string& name, const std::string& type,
-                             const std::string& proto,
-                             const SocketAddress& addr) {
-    return (c.name() == name && c.type() == type &&
-        c.protocol() == proto && c.address().ipaddr() == addr.ipaddr() &&
-        (addr.port() == 0 || (c.address().port() == addr.port())));
-  }
-  static bool CheckPort(const talk_base::SocketAddress& addr,
-                        int min_port, int max_port) {
-    return (addr.port() >= min_port && addr.port() <= max_port);
-  }
-
- protected:
-  cricket::BasicPortAllocator& allocator() { return allocator_; }
-
-  void OnPortReady(cricket::PortAllocatorSession* ses, cricket::Port* port) {
-    LOG(LS_INFO) << "OnPortReady: " << port->ToString();
-    ports_.push_back(port);
-  }
-  void OnCandidatesReady(cricket::PortAllocatorSession* ses,
-                         const std::vector<cricket::Candidate>& candidates) {
-    for (size_t i = 0; i < candidates.size(); ++i) {
-      LOG(LS_INFO) << "OnCandidatesReady: " << candidates[i].ToString();
-      candidates_.push_back(candidates[i]);
-    }
-  }
-
-  talk_base::scoped_ptr<talk_base::PhysicalSocketServer> pss_;
-  talk_base::scoped_ptr<talk_base::VirtualSocketServer> vss_;
-  talk_base::scoped_ptr<talk_base::FirewallSocketServer> fss_;
-  talk_base::SocketServerScope ss_scope_;
-  cricket::TestStunServer stun_server_;
-  cricket::TestRelayServer relay_server_;
-  talk_base::FakeNetworkManager network_manager_;
-  cricket::BasicPortAllocator allocator_;
-  talk_base::scoped_ptr<cricket::PortAllocatorSession> session_;
-  std::vector<cricket::Port*> ports_;
-  std::vector<cricket::Candidate> candidates_;
-};
-
-// Tests that we can init the port allocator and create a session.
-TEST_F(PortAllocatorTest, TestBasic) {
-  EXPECT_EQ(&network_manager_, allocator().network_manager());
-  EXPECT_EQ(kStunAddr, allocator().stun_address());
-  EXPECT_EQ(kRelayUdpIntAddr, allocator().relay_address_udp());
-  EXPECT_EQ(kRelayTcpIntAddr, allocator().relay_address_tcp());
-  EXPECT_EQ(kRelaySslTcpIntAddr, allocator().relay_address_ssl());
-  EXPECT_TRUE(CreateSession("rtp", "unittest"));
-}
-
-// Tests that we can get the local and STUN addresses successfully.
-TEST_F(PortAllocatorTest, TestGetInitialPorts) {
-  AddInterface(kClientAddr);
-  EXPECT_TRUE(CreateSession("rtp", "unittest"));
-  session_->GetInitialPorts();
-  ASSERT_EQ_WAIT(2U, candidates_.size(), 1000);
-  EXPECT_PRED5(CheckCandidate, candidates_[0],
-      "rtp", "local", "udp", kClientAddr);
-  EXPECT_PRED5(CheckCandidate, candidates_[1],
-      "rtp", "stun", "udp", kClientAddr);
-  EXPECT_EQ(2U, ports_.size());
-}
-
-// Tests that we can get all the desired addresses successfully.
-TEST_F(PortAllocatorTest, TestGetAllPorts) {
-  AddInterface(kClientAddr);
-  EXPECT_TRUE(CreateSession("rtp", "unittest"));
-  session_->GetInitialPorts();
-  session_->StartGetAllPorts();
-  ASSERT_EQ_WAIT(2U, candidates_.size(), 1000);
-  EXPECT_EQ(2U, ports_.size());
-  ASSERT_EQ_WAIT(4U, candidates_.size(), 2000);
-  EXPECT_EQ(3U, ports_.size());
-  EXPECT_PRED5(CheckCandidate, candidates_[2],
-      "rtp", "relay", "udp", kRelayUdpIntAddr);
-  EXPECT_PRED5(CheckCandidate, candidates_[3],
-      "rtp", "relay", "udp", kRelayUdpExtAddr);
-  ASSERT_EQ_WAIT(6U, candidates_.size(), 1500);
-  EXPECT_PRED5(CheckCandidate, candidates_[4],
-      "rtp", "relay", "tcp", kRelayTcpIntAddr);
-  EXPECT_PRED5(CheckCandidate, candidates_[5],
-      "rtp", "local", "tcp", kClientAddr);
-  EXPECT_EQ(4U, ports_.size());
-  ASSERT_EQ_WAIT(7U, candidates_.size(), 2000);
-  EXPECT_PRED5(CheckCandidate, candidates_[6],
-      "rtp", "relay", "ssltcp", kRelaySslTcpIntAddr);
-  EXPECT_EQ(4U, ports_.size());
-}
-
-// Test that we restrict client ports appropriately when a port range is set.
-// We check the candidates for udp/stun/tcp ports, and the from address
-// for relay ports.
-TEST_F(PortAllocatorTest, TestGetAllPortsPortRange) {
-  AddInterface(kClientAddr);
-  // Check that an invalid port range fails.
-  EXPECT_FALSE(SetPortRange(kMaxPort, kMinPort));
-  // Check that a null port range succeeds.
-  EXPECT_TRUE(SetPortRange(0, 0));
-  // Check that a valid port range succeeds.
-  EXPECT_TRUE(SetPortRange(kMinPort, kMaxPort));
-  EXPECT_TRUE(CreateSession("rtp", "unittest"));
-  session_->GetInitialPorts();
-  session_->StartGetAllPorts();
-  ASSERT_EQ_WAIT(2U, candidates_.size(), 1000);
-  EXPECT_EQ(2U, ports_.size());
-  // Check the port number for the UDP port object.
-  EXPECT_PRED3(CheckPort, candidates_[0].address(), kMinPort, kMaxPort);
-  // Check the port number for the STUN port object.
-  EXPECT_PRED3(CheckPort, candidates_[1].address(), kMinPort, kMaxPort);
-  ASSERT_EQ_WAIT(4U, candidates_.size(), 2000);
-  EXPECT_EQ(3U, ports_.size());
-  // Check the port number used to connect to the relay server.
-  EXPECT_PRED3(CheckPort, relay_server_.GetConnection(0).source(),
-               kMinPort, kMaxPort);
-  ASSERT_EQ_WAIT(6U, candidates_.size(), 1500);
-  EXPECT_EQ(4U, ports_.size());
-  // Check the port number for the TCP port object.
-  EXPECT_PRED3(CheckPort, candidates_[5].address(), kMinPort, kMaxPort);
-}
-
-// Test that we don't crash or malfunction if we have no network adapters.
-// TODO: Find a way to exit early here.
-TEST_F(PortAllocatorTest, TestGetAllPortsNoAdapters) {
-  EXPECT_TRUE(CreateSession("rtp", "unittest"));
-  session_->GetInitialPorts();
-  session_->StartGetAllPorts();
-  WAIT(candidates_.size() > 0, 2000);
-}
-
-// Test that we don't crash or malfunction if we can't create UDP sockets.
-TEST_F(PortAllocatorTest, TestGetAllPortsNoUdpSockets) {
-  AddInterface(kClientAddr);
-  fss_->set_udp_sockets_enabled(false);
-  EXPECT_TRUE(CreateSession("rtp", "unittest"));
-  session_->GetInitialPorts();
-  session_->StartGetAllPorts();
-  ASSERT_EQ_WAIT(2U, candidates_.size(), 2000);
-  EXPECT_PRED5(CheckCandidate, candidates_[0],
-      "rtp", "relay", "udp", kRelayUdpIntAddr);
-  EXPECT_PRED5(CheckCandidate, candidates_[1],
-      "rtp", "relay", "udp", kRelayUdpExtAddr);
-  ASSERT_EQ_WAIT(4U, candidates_.size(), 2000);
-  EXPECT_PRED5(CheckCandidate, candidates_[2],
-      "rtp", "relay", "tcp", kRelayTcpIntAddr);
-  EXPECT_PRED5(CheckCandidate, candidates_[3],
-      "rtp", "local", "tcp", kClientAddr);
-  EXPECT_EQ(2U, ports_.size());
-  ASSERT_EQ_WAIT(5U, candidates_.size(), 2000);
-  EXPECT_PRED5(CheckCandidate, candidates_[4],
-      "rtp", "relay", "ssltcp", kRelaySslTcpIntAddr);
-  EXPECT_EQ(2U, ports_.size());
-}
-
-// Test that we don't crash or malfunction if we can't create UDP sockets or
-// listen on TCP sockets. We still give out a local TCP address, since
-// apparently this is needed for the remote side to accept our connection.
-TEST_F(PortAllocatorTest, TestGetAllPortsNoUdpSocketsNoTcpListen) {
-  AddInterface(kClientAddr);
-  fss_->set_udp_sockets_enabled(false);
-  fss_->set_tcp_listen_enabled(false);
-  EXPECT_TRUE(CreateSession("rtp", "unittest"));
-  session_->GetInitialPorts();
-  session_->StartGetAllPorts();
-  ASSERT_EQ_WAIT(2U, candidates_.size(), 3000);
-  EXPECT_PRED5(CheckCandidate, candidates_[0],
-      "rtp", "relay", "udp", kRelayUdpIntAddr);
-  EXPECT_PRED5(CheckCandidate, candidates_[1],
-      "rtp", "relay", "udp", kRelayUdpExtAddr);
-  ASSERT_EQ_WAIT(4U, candidates_.size(), 2000);
-  EXPECT_PRED5(CheckCandidate, candidates_[2],
-      "rtp", "relay", "tcp", kRelayTcpIntAddr);
-  EXPECT_PRED5(CheckCandidate, candidates_[3],
-      "rtp", "local", "tcp", kClientAddr);
-  EXPECT_EQ(2U, ports_.size());
-  ASSERT_EQ_WAIT(5U, candidates_.size(), 2000);
-  EXPECT_PRED5(CheckCandidate, candidates_[4],
-      "rtp", "relay", "ssltcp", kRelaySslTcpIntAddr);
-  EXPECT_EQ(2U, ports_.size());
-}
-
-// Test that we don't crash or malfunction if we can't create any sockets.
-// TODO: Find a way to exit early here.
-TEST_F(PortAllocatorTest, TestGetAllPortsNoSockets) {
-  AddInterface(kClientAddr);
-  fss_->set_tcp_sockets_enabled(false);
-  fss_->set_udp_sockets_enabled(false);
-  EXPECT_TRUE(CreateSession("rtp", "unittest"));
-  session_->GetInitialPorts();
-  session_->StartGetAllPorts();
-  WAIT(candidates_.size() > 0, 2000);
-}
-
-// Test that the httpportallocator correctly maintains its lists of stun and
-// relay servers, by never allowing an empty list.
-TEST(HttpPortAllocatorTest, TestHttpPortAllocatorHostLists) {
-  talk_base::FakeNetworkManager network_manager;
-  cricket::HttpPortAllocator alloc(&network_manager, "unit test agent");
-  EXPECT_EQ(1U, alloc.relay_hosts().size());
-  EXPECT_EQ(1U, alloc.stun_hosts().size());
-
-  std::vector<std::string> relay_servers;
-  std::vector<talk_base::SocketAddress> stun_servers;
-
-  alloc.SetRelayHosts(relay_servers);
-  alloc.SetStunHosts(stun_servers);
-  EXPECT_EQ(1U, alloc.relay_hosts().size());
-  EXPECT_EQ(1U, alloc.stun_hosts().size());
-
-  relay_servers.push_back("1.unittest.corp.google.com");
-  relay_servers.push_back("2.unittest.corp.google.com");
-  stun_servers.push_back(
-      talk_base::SocketAddress("1.unittest.corp.google.com", 0));
-  stun_servers.push_back(
-      talk_base::SocketAddress("2.unittest.corp.google.com", 0));
-  alloc.SetRelayHosts(relay_servers);
-  alloc.SetStunHosts(stun_servers);
-  EXPECT_EQ(2U, alloc.relay_hosts().size());
-  EXPECT_EQ(2U, alloc.stun_hosts().size());
-}
diff --git a/third_party/libjingle/source/talk/p2p/client/sessionmanagertask.h b/third_party/libjingle/source/talk/p2p/client/sessionmanagertask.h
deleted file mode 100644
index d7d9733..0000000
--- a/third_party/libjingle/source/talk/p2p/client/sessionmanagertask.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _SESSIONMANAGERTASK_H_
-#define _SESSIONMANAGERTASK_H_
-
-#include "talk/p2p/base/sessionmanager.h"
-#include "talk/p2p/client/sessionsendtask.h"
-#include "talk/xmpp/xmppengine.h"
-#include "talk/xmpp/xmpptask.h"
-
-namespace cricket {
-
-// This class handles sending and receiving XMPP messages on behalf of the
-// SessionManager.  The sending part is handed over to SessionSendTask.
-
-class SessionManagerTask : public buzz::XmppTask {
- public:
-  SessionManagerTask(buzz::XmppTaskParentInterface* parent,
-                     SessionManager* session_manager)
-      : buzz::XmppTask(parent, buzz::XmppEngine::HL_SINGLE),
-        session_manager_(session_manager) {
-  }
-
-  ~SessionManagerTask() {
-  }
-
-  // Turns on simple support for sending messages, using SessionSendTask.
-  void EnableOutgoingMessages() {
-    session_manager_->SignalOutgoingMessage.connect(
-        this, &SessionManagerTask::OnOutgoingMessage);
-    session_manager_->SignalRequestSignaling.connect(
-        session_manager_, &SessionManager::OnSignalingReady);
-  }
-
-  virtual int ProcessStart() {
-    const buzz::XmlElement *stanza = NextStanza();
-    if (stanza == NULL)
-      return STATE_BLOCKED;
-    session_manager_->OnIncomingMessage(stanza);
-    return STATE_START;
-  }
-
- protected:
-  virtual bool HandleStanza(const buzz::XmlElement *stanza) {
-    if (!session_manager_->IsSessionMessage(stanza))
-      return false;
-    // Responses are handled by the SessionSendTask that sent the request.
-    //if (stanza->Attr(buzz::QN_TYPE) != buzz::STR_SET)
-    //  return false;
-    QueueStanza(stanza);
-    return true;
-  }
-
- private:
-  void OnOutgoingMessage(SessionManager* manager,
-                         const buzz::XmlElement* stanza) {
-    cricket::SessionSendTask* sender =
-        new cricket::SessionSendTask(parent_, session_manager_);
-    sender->Send(stanza);
-    sender->Start();
-  }
-
-  SessionManager* session_manager_;
-};
-
-}  // namespace cricket
-
-#endif // _SESSIONMANAGERTASK_H_
diff --git a/third_party/libjingle/source/talk/p2p/client/sessionsendtask.h b/third_party/libjingle/source/talk/p2p/client/sessionsendtask.h
deleted file mode 100644
index c9008d4..0000000
--- a/third_party/libjingle/source/talk/p2p/client/sessionsendtask.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_P2P_CLIENT_SESSIONSENDTASK_H_
-#define TALK_P2P_CLIENT_SESSIONSENDTASK_H_
-
-#include "talk/base/common.h"
-#include "talk/xmpp/constants.h"
-#include "talk/xmpp/xmppclient.h"
-#include "talk/xmpp/xmppengine.h"
-#include "talk/xmpp/xmpptask.h"
-#include "talk/p2p/base/sessionmanager.h"
-
-namespace cricket {
-
-// The job of this task is to send an IQ stanza out (after stamping it with
-// an ID attribute) and then wait for a response.  If not response happens
-// within 5 seconds, it will signal failure on a SessionManager.  If an error
-// happens it will also signal failure.  If, however, the send succeeds this
-// task will quietly go away.
-
-class SessionSendTask : public buzz::XmppTask {
- public:
-  SessionSendTask(buzz::XmppTaskParentInterface* parent,
-                  SessionManager* session_manager)
-    : buzz::XmppTask(parent, buzz::XmppEngine::HL_SINGLE),
-      session_manager_(session_manager) {
-    set_timeout_seconds(15);
-    session_manager_->SignalDestroyed.connect(
-        this, &SessionSendTask::OnSessionManagerDestroyed);
-  }
-
-  virtual ~SessionSendTask() {
-    SignalDone(this);
-  }
-
-  void Send(const buzz::XmlElement* stanza) {
-    ASSERT(stanza_.get() == NULL);
-
-    // This should be an IQ of type set, result, or error.  In the first case,
-    // we supply an ID.  In the others, it should be present.
-    ASSERT(stanza->Name() == buzz::QN_IQ);
-    ASSERT(stanza->HasAttr(buzz::QN_TYPE));
-    if (stanza->Attr(buzz::QN_TYPE) == "set") {
-      ASSERT(!stanza->HasAttr(buzz::QN_ID));
-    } else {
-      ASSERT((stanza->Attr(buzz::QN_TYPE) == "result") ||
-             (stanza->Attr(buzz::QN_TYPE) == "error"));
-      ASSERT(stanza->HasAttr(buzz::QN_ID));
-    }
-
-    stanza_.reset(new buzz::XmlElement(*stanza));
-    if (stanza_->HasAttr(buzz::QN_ID)) {
-      set_task_id(stanza_->Attr(buzz::QN_ID));
-    } else {
-      stanza_->SetAttr(buzz::QN_ID, task_id());
-    }
-  }
-
-  void OnSessionManagerDestroyed() {
-    // If the session manager doesn't exist anymore, we should still try to
-    // send the message, but avoid calling back into the SessionManager.
-    session_manager_ = NULL;
-  }
-
-  sigslot::signal1<SessionSendTask *> SignalDone;
-
- protected:
-  virtual int OnTimeout() {
-    if (session_manager_ != NULL) {
-      session_manager_->OnFailedSend(stanza_.get(), NULL);
-    }
-
-    return XmppTask::OnTimeout();
-  }
-
-  virtual int ProcessStart() {
-    SendStanza(stanza_.get());
-    if (stanza_->Attr(buzz::QN_TYPE) == buzz::STR_SET) {
-      return STATE_RESPONSE;
-    } else {
-      return STATE_DONE;
-    }
-  }
-
-  virtual int ProcessResponse() {
-    const buzz::XmlElement* next = NextStanza();
-    if (next == NULL)
-      return STATE_BLOCKED;
-
-    if (session_manager_ != NULL) {
-      if (next->Attr(buzz::QN_TYPE) == buzz::STR_RESULT) {
-        session_manager_->OnIncomingResponse(stanza_.get(), next);
-      } else {
-        session_manager_->OnFailedSend(stanza_.get(), next);
-      }
-    }
-
-    return STATE_DONE;
-  }
-
-  virtual bool HandleStanza(const buzz::XmlElement *stanza) {
-    if (!MatchResponseIq(stanza,
-                         buzz::Jid(stanza_->Attr(buzz::QN_TO)), task_id()))
-      return false;
-    if (stanza->Attr(buzz::QN_TYPE) == buzz::STR_RESULT ||
-        stanza->Attr(buzz::QN_TYPE) == buzz::STR_ERROR) {
-      QueueStanza(stanza);
-      return true;
-    }
-    return false;
-  }
-
- private:
-  SessionManager *session_manager_;
-  talk_base::scoped_ptr<buzz::XmlElement> stanza_;
-  bool timed_out_;
-};
-
-}
-
-#endif // TALK_P2P_CLIENT_SESSIONSENDTASK_H_
diff --git a/third_party/libjingle/source/talk/p2p/client/socketmonitor.cc b/third_party/libjingle/source/talk/p2p/client/socketmonitor.cc
deleted file mode 100644
index 5fe5304..0000000
--- a/third_party/libjingle/source/talk/p2p/client/socketmonitor.cc
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/p2p/client/socketmonitor.h"
-#include "talk/base/common.h"
-
-namespace cricket {
-
-const uint32 MSG_MONITOR_POLL = 1;
-const uint32 MSG_MONITOR_START = 2;
-const uint32 MSG_MONITOR_STOP = 3;
-const uint32 MSG_MONITOR_SIGNAL = 4;
-
-SocketMonitor::SocketMonitor(TransportChannel* channel,
-                             talk_base::Thread* worker_thread,
-                             talk_base::Thread* monitor_thread) {
-  channel_ = channel;
-  channel_thread_ = worker_thread;
-  monitoring_thread_ = monitor_thread;
-  monitoring_ = false;
-}
-
-SocketMonitor::~SocketMonitor() {
-  channel_thread_->Clear(this);
-  monitoring_thread_->Clear(this);
-}
-
-void SocketMonitor::Start(int milliseconds) {
-  rate_ = milliseconds;
-  if (rate_ < 250)
-    rate_ = 250;
-  channel_thread_->Post(this, MSG_MONITOR_START);
-}
-
-void SocketMonitor::Stop() {
-  channel_thread_->Post(this, MSG_MONITOR_STOP);
-}
-
-void SocketMonitor::OnMessage(talk_base::Message *message) {
-  talk_base::CritScope cs(&crit_);
-
-  switch (message->message_id) {
-  case MSG_MONITOR_START:
-    ASSERT(talk_base::Thread::Current() == channel_thread_);
-    if (!monitoring_) {
-      monitoring_ = true;
-      if (GetP2PChannel() != NULL) {
-        GetP2PChannel()->SignalConnectionMonitor.connect(
-            this, &SocketMonitor::OnConnectionMonitor);
-      }
-      PollSocket(true);
-    }
-    break;
-
-  case MSG_MONITOR_STOP:
-    ASSERT(talk_base::Thread::Current() == channel_thread_);
-    if (monitoring_) {
-      monitoring_ = false;
-      if (GetP2PChannel() != NULL)
-        GetP2PChannel()->SignalConnectionMonitor.disconnect(this);
-      channel_thread_->Clear(this);
-    }
-    break;
-
-  case MSG_MONITOR_POLL:
-    ASSERT(talk_base::Thread::Current() == channel_thread_);
-    PollSocket(true);
-    break;
-
-  case MSG_MONITOR_SIGNAL:
-    {
-      ASSERT(talk_base::Thread::Current() == monitoring_thread_);
-      std::vector<ConnectionInfo> infos = connection_infos_;
-      crit_.Leave();
-      SignalUpdate(this, infos);
-      crit_.Enter();
-    }
-    break;
-  }
-}
-
-void SocketMonitor::OnConnectionMonitor(P2PTransportChannel* channel) {
-  talk_base::CritScope cs(&crit_);
-  if (monitoring_)
-    PollSocket(false);
-}
-
-void SocketMonitor::PollSocket(bool poll) {
-  ASSERT(talk_base::Thread::Current() == channel_thread_);
-  talk_base::CritScope cs(&crit_);
-
-  // Gather connection infos
-  P2PTransportChannel* p2p_channel = GetP2PChannel();
-  if (p2p_channel != NULL) {
-    connection_infos_.clear();
-    const std::vector<Connection *> &connections = p2p_channel->connections();
-    std::vector<Connection *>::const_iterator it;
-    for (it = connections.begin(); it != connections.end(); it++) {
-      Connection *connection = *it;
-      ConnectionInfo info;
-      info.best_connection = p2p_channel->best_connection() == connection;
-      info.readable =
-          (connection->read_state() == Connection::STATE_READABLE);
-      info.writable =
-          (connection->write_state() == Connection::STATE_WRITABLE);
-      info.timeout =
-          (connection->write_state() == Connection::STATE_WRITE_TIMEOUT);
-      info.new_connection = !connection->reported();
-      connection->set_reported(true);
-      info.rtt = connection->rtt();
-      info.sent_total_bytes = connection->sent_total_bytes();
-      info.sent_bytes_second = connection->sent_bytes_second();
-      info.recv_total_bytes = connection->recv_total_bytes();
-      info.recv_bytes_second = connection->recv_bytes_second();
-      info.local_candidate = connection->local_candidate();
-      info.remote_candidate = connection->remote_candidate();
-      info.key = connection;
-      connection_infos_.push_back(info);
-    }
-  }
-
-  // Signal the monitoring thread, start another poll timer
-
-  monitoring_thread_->Post(this, MSG_MONITOR_SIGNAL);
-  if (poll)
-    channel_thread_->PostDelayed(rate_, this, MSG_MONITOR_POLL);
-}
-
-}
diff --git a/third_party/libjingle/source/talk/p2p/client/socketmonitor.h b/third_party/libjingle/source/talk/p2p/client/socketmonitor.h
deleted file mode 100644
index 9facf3f..0000000
--- a/third_party/libjingle/source/talk/p2p/client/socketmonitor.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_P2P_CLIENT_SOCKETMONITOR_H_
-#define TALK_P2P_CLIENT_SOCKETMONITOR_H_
-
-#include <vector>
-
-#include "talk/base/criticalsection.h"
-#include "talk/base/sigslot.h"
-#include "talk/base/thread.h"
-#include "talk/p2p/base/p2ptransportchannel.h"
-#include "talk/p2p/base/port.h"
-
-namespace cricket {
-
-struct ConnectionInfo {
-  bool best_connection;
-  bool writable;
-  bool readable;
-  bool timeout;
-  bool new_connection;
-  size_t rtt;
-  size_t sent_total_bytes;
-  size_t sent_bytes_second;
-  size_t recv_total_bytes;
-  size_t recv_bytes_second;
-  Candidate local_candidate;
-  Candidate remote_candidate;
-  void *key;
-};
-
-class SocketMonitor : public talk_base::MessageHandler,
-    public sigslot::has_slots<> {
- public:
-  SocketMonitor(TransportChannel* channel,
-                talk_base::Thread* worker_thread,
-                talk_base::Thread* monitor_thread);
-  ~SocketMonitor();
-
-  void Start(int cms);
-  void Stop();
-
-  talk_base::Thread *monitor_thread() { return monitoring_thread_; }
-
-  sigslot::signal2<SocketMonitor *,
-                   const std::vector<ConnectionInfo> &> SignalUpdate;
-
- protected:
-  P2PTransportChannel* GetP2PChannel() { return channel_->GetP2PChannel(); }
-  void OnMessage(talk_base::Message *message);
-  void OnConnectionMonitor(P2PTransportChannel* channel);
-  void PollSocket(bool poll);
-
-  std::vector<ConnectionInfo> connection_infos_;
-  TransportChannel* channel_;
-  talk_base::Thread* channel_thread_;
-  talk_base::Thread* monitoring_thread_;
-  talk_base::CriticalSection crit_;
-  uint32 rate_;
-  bool monitoring_;
-};
-
-}  // namespace cricket
-
-#endif  // TALK_P2P_CLIENT_SOCKETMONITOR_H_
diff --git a/third_party/libjingle/source/talk/session/phone/audioframe.h b/third_party/libjingle/source/talk/session/phone/audioframe.h
deleted file mode 100644
index bcd8410..0000000
--- a/third_party/libjingle/source/talk/session/phone/audioframe.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SESSION_PHONE_AUDIOFRAME_H_
-#define TALK_SESSION_PHONE_AUDIOFRAME_H_
-
-namespace cricket {
-
-class AudioFrame {
- public:
-  AudioFrame()
-      : audio10ms_(NULL),
-        length_(0),
-        sampling_frequency_(8000),
-        stereo_(false) {
-  }
-  AudioFrame(int16* audio, size_t audio_length, int sample_freq, bool stereo)
-      : audio10ms_(audio),
-        length_(audio_length),
-        sampling_frequency_(sample_freq),
-        stereo_(stereo) {
-  }
-
-  int16* GetData() { return audio10ms_; }
-  size_t GetSize() const { return length_; }
-  int GetSamplingFrequency() const { return sampling_frequency_; }
-  bool GetStereo() const { return stereo_; }
-
- private:
-  int16* audio10ms_;
-  size_t length_;
-  int sampling_frequency_;
-  bool stereo_;
-};
-
-}  // namespace cricket
-#endif  // TALK_SESSION_PHONE_AUDIOFRAME_H_
diff --git a/third_party/libjingle/source/talk/session/phone/audiomonitor.cc b/third_party/libjingle/source/talk/session/phone/audiomonitor.cc
deleted file mode 100644
index d980ded..0000000
--- a/third_party/libjingle/source/talk/session/phone/audiomonitor.cc
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/session/phone/audiomonitor.h"
-#include "talk/session/phone/voicechannel.h"
-#include <cassert>
-
-namespace cricket {
-
-const uint32 MSG_MONITOR_POLL = 1;
-const uint32 MSG_MONITOR_START = 2;
-const uint32 MSG_MONITOR_STOP = 3;
-const uint32 MSG_MONITOR_SIGNAL = 4;
-
-AudioMonitor::AudioMonitor(VoiceChannel *voice_channel, 
-                           talk_base::Thread *monitor_thread) {
-  voice_channel_ = voice_channel;
-  monitoring_thread_ = monitor_thread;
-  monitoring_ = false;
-}
-
-AudioMonitor::~AudioMonitor() {
-  voice_channel_->worker_thread()->Clear(this);
-  monitoring_thread_->Clear(this);
-}
-
-void AudioMonitor::Start(int milliseconds) {
-  rate_ = milliseconds;
-  if (rate_ < 100)
-    rate_ = 100;
-  voice_channel_->worker_thread()->Post(this, MSG_MONITOR_START);
-}
-
-void AudioMonitor::Stop() {
-  voice_channel_->worker_thread()->Post(this, MSG_MONITOR_STOP);
-}
-
-void AudioMonitor::OnMessage(talk_base::Message *message) {
-  talk_base::CritScope cs(&crit_);
-
-  switch (message->message_id) {
-  case MSG_MONITOR_START:
-    assert(talk_base::Thread::Current() == voice_channel_->worker_thread());
-    if (!monitoring_) {
-      monitoring_ = true;
-      PollVoiceChannel();
-    }
-    break;
-
-  case MSG_MONITOR_STOP:
-    assert(talk_base::Thread::Current() == voice_channel_->worker_thread());
-    if (monitoring_) {
-      monitoring_ = false;
-      voice_channel_->worker_thread()->Clear(this);
-    }
-    break;
-
-  case MSG_MONITOR_POLL:
-    assert(talk_base::Thread::Current() == voice_channel_->worker_thread());
-    PollVoiceChannel();
-    break;
-
-  case MSG_MONITOR_SIGNAL:
-    {
-      assert(talk_base::Thread::Current() == monitoring_thread_);
-      AudioInfo info = audio_info_;
-      crit_.Leave();
-      SignalUpdate(this, info);
-      crit_.Enter();
-    }
-    break;
-  }
-}
-
-void AudioMonitor::PollVoiceChannel() {
-  talk_base::CritScope cs(&crit_);
-  assert(talk_base::Thread::Current() == voice_channel_->worker_thread());
-
-  // Gather connection infos
-  audio_info_.input_level = voice_channel_->GetInputLevel_w();
-  audio_info_.output_level = voice_channel_->GetOutputLevel_w();
-  voice_channel_->GetActiveStreams_w(&audio_info_.active_streams);
-
-  // Signal the monitoring thread, start another poll timer
-  monitoring_thread_->Post(this, MSG_MONITOR_SIGNAL);
-  voice_channel_->worker_thread()->PostDelayed(rate_, this, MSG_MONITOR_POLL);
-}
-
-VoiceChannel *AudioMonitor::voice_channel() {
-  return voice_channel_;
-}
-
-talk_base::Thread *AudioMonitor::monitor_thread() {
-  return monitoring_thread_;
-}
-
-}
diff --git a/third_party/libjingle/source/talk/session/phone/audiomonitor.h b/third_party/libjingle/source/talk/session/phone/audiomonitor.h
deleted file mode 100644
index e94ea68..0000000
--- a/third_party/libjingle/source/talk/session/phone/audiomonitor.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _CRICKET_PHONE_AUDIOMONITOR_H_
-#define _CRICKET_PHONE_AUDIOMONITOR_H_
-
-#include "talk/base/thread.h"
-#include "talk/base/sigslot.h"
-#include "talk/p2p/base/port.h"
-#include <vector>
-
-namespace cricket {
-
-class VoiceChannel;
-
-struct AudioInfo {
-  int input_level;
-  int output_level;
-  typedef std::vector<std::pair<uint32, int> > StreamList;
-  StreamList active_streams; // ssrcs contributing to output_level
-};
-
-class AudioMonitor : public talk_base::MessageHandler, 
-    public sigslot::has_slots<> {
-public:
-  AudioMonitor(VoiceChannel* voice_channel, talk_base::Thread *monitor_thread);
-  ~AudioMonitor();
-
-  void Start(int cms);
-  void Stop();
-
-  VoiceChannel* voice_channel();
-  talk_base::Thread *monitor_thread();
-
-  sigslot::signal2<AudioMonitor*, const AudioInfo&> SignalUpdate;
-
-protected:
-  void OnMessage(talk_base::Message *message);
-  void PollVoiceChannel();
-
-  AudioInfo audio_info_;
-  VoiceChannel* voice_channel_;
-  talk_base::Thread* monitoring_thread_;
-  talk_base::CriticalSection crit_;
-  uint32 rate_;
-  bool monitoring_;
-};
-
-}
-
-#endif // _CRICKET_PHONE_AUDIOMONITOR_H_
diff --git a/third_party/libjingle/source/talk/session/phone/call.cc b/third_party/libjingle/source/talk/session/phone/call.cc
deleted file mode 100644
index 4b2e229..0000000
--- a/third_party/libjingle/source/talk/session/phone/call.cc
+++ /dev/null
@@ -1,689 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2007, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string>
-#include "talk/base/helpers.h"
-#include "talk/base/logging.h"
-#include "talk/base/thread.h"
-#include "talk/session/phone/call.h"
-#include "talk/session/phone/mediasessionclient.h"
-
-namespace cricket {
-
-const uint32 MSG_CHECKAUTODESTROY = 1;
-const uint32 MSG_TERMINATECALL = 2;
-const uint32 MSG_PLAYDTMF = 3;
-
-namespace {
-const int kDTMFDelay = 300;  // msec
-const size_t kMaxDTMFDigits = 30;
-const int kSendToVoicemailTimeout = 1000*20;
-const int kNoVoicemailTimeout = 1000*180;
-const int kMediaMonitorInterval = 1000*15;
-// In order to be the same as the server-side switching, this must be 100.
-const int kAudioMonitorPollPeriodMillis = 100;
-}
-
-Call::Call(MediaSessionClient* session_client)
-    : id_(talk_base::CreateRandomId()),
-      session_client_(session_client),
-      local_renderer_(NULL),
-      video_(false),
-      muted_(false),
-      video_muted_(false),
-      send_to_voicemail_(true),
-      playing_dtmf_(false) {
-}
-
-Call::~Call() {
-  while (sessions_.begin() != sessions_.end()) {
-    Session *session = sessions_[0];
-    RemoveSession(session);
-    session_client_->session_manager()->DestroySession(session);
-  }
-  talk_base::Thread::Current()->Clear(this);
-}
-
-Session *Call::InitiateSession(const buzz::Jid &jid,
-                               const CallOptions& options) {
-  const SessionDescription* offer = session_client_->CreateOffer(options);
-
-  Session *session = session_client_->CreateSession(this);
-  AddSession(session, offer);
-  session->Initiate(jid.Str(), offer);
-
-  // After this timeout, terminate the call because the callee isn't
-  // answering
-  session_client_->session_manager()->signaling_thread()->Clear(this,
-      MSG_TERMINATECALL);
-  session_client_->session_manager()->signaling_thread()->PostDelayed(
-    send_to_voicemail_ ? kSendToVoicemailTimeout : kNoVoicemailTimeout,
-    this, MSG_TERMINATECALL);
-  return session;
-}
-
-void Call::IncomingSession(
-    Session* session, const SessionDescription* offer) {
-  AddSession(session, offer);
-
-  // Missed the first state, the initiate, which is needed by
-  // call_client.
-  SignalSessionState(this, session, Session::STATE_RECEIVEDINITIATE);
-}
-
-void Call::AcceptSession(Session* session,
-                         const cricket::CallOptions& options) {
-  std::vector<Session *>::iterator it;
-  it = std::find(sessions_.begin(), sessions_.end(), session);
-  ASSERT(it != sessions_.end());
-  if (it != sessions_.end()) {
-    session->Accept(
-        session_client_->CreateAnswer(session->remote_description(), options));
-  }
-}
-
-void Call::RejectSession(Session *session) {
-  std::vector<Session *>::iterator it;
-  it = std::find(sessions_.begin(), sessions_.end(), session);
-  ASSERT(it != sessions_.end());
-  // Assume polite decline.
-  if (it != sessions_.end())
-    session->Reject(STR_TERMINATE_DECLINE);
-}
-
-void Call::TerminateSession(Session *session) {
-  ASSERT(std::find(sessions_.begin(), sessions_.end(), session)
-         != sessions_.end());
-  std::vector<Session *>::iterator it;
-  it = std::find(sessions_.begin(), sessions_.end(), session);
-  // Assume polite terminations.
-  if (it != sessions_.end())
-    (*it)->Terminate();
-}
-
-void Call::Terminate() {
-  // Copy the list so that we can iterate over it in a stable way
-  std::vector<Session *> sessions = sessions_;
-
-  // There may be more than one session to terminate
-  std::vector<Session *>::iterator it;
-  for (it = sessions.begin(); it != sessions.end(); it++)
-    TerminateSession(*it);
-}
-
-bool Call::SendViewRequest(Session* session,
-                           const ViewRequest& view_request) {
-  StaticVideoViews::const_iterator it;
-  for (it = view_request.static_video_views.begin();
-       it != view_request.static_video_views.end(); ++it) {
-    NamedSource found_source;
-    bool found = media_sources_.GetVideoSourceBySsrc(it->ssrc, &found_source);
-    if (!found) {
-      LOG(LS_WARNING) <<
-          "Tried sending view request for bad ssrc: " << it->ssrc;
-      return false;
-    }
-  }
-
-  XmlElements elems;
-  WriteError error;
-  if (!WriteJingleViewRequest(CN_VIDEO, view_request, &elems, &error)) {
-    LOG(LS_ERROR) << "Couldn't write out view request: " << error.text;
-    return false;
-  }
-
-  return session->SendInfoMessage(elems);
-}
-
-void Call::SetLocalRenderer(VideoRenderer* renderer) {
-  local_renderer_ = renderer;
-  if (session_client_->GetFocus() == this) {
-    session_client_->channel_manager()->SetLocalRenderer(renderer);
-  }
-}
-
-void Call::SetVideoRenderer(Session *session, uint32 ssrc,
-                            VideoRenderer* renderer) {
-  VideoChannel *video_channel = GetVideoChannel(session);
-  if (video_channel) {
-    video_channel->SetRenderer(ssrc, renderer);
-    LOG(LS_INFO) << "Set renderer of ssrc " << ssrc
-                 << " to " << renderer << ".";
-  } else {
-    LOG(LS_INFO) << "Failed to set renderer of ssrc " << ssrc << ".";
-  }
-}
-
-void Call::AddVoiceStream(Session *session, uint32 voice_ssrc) {
-  VoiceChannel *voice_channel = GetVoiceChannel(session);
-  if (voice_channel && voice_ssrc) {
-    voice_channel->AddStream(voice_ssrc);
-  }
-}
-
-void Call::AddVideoStream(Session *session, uint32 video_ssrc) {
-  VideoChannel *video_channel = GetVideoChannel(session);
-  if (video_channel && video_ssrc) {
-    // TODO: Do we need the audio_ssrc here?
-    // It doesn't seem to be used.
-    video_channel->AddStream(video_ssrc, 0U);
-  }
-}
-
-void Call::RemoveVoiceStream(Session *session, uint32 voice_ssrc) {
-  VoiceChannel *voice_channel = GetVoiceChannel(session);
-  if (voice_channel && voice_ssrc) {
-    voice_channel->RemoveStream(voice_ssrc);
-  }
-}
-
-void Call::RemoveVideoStream(Session *session, uint32 video_ssrc) {
-  VideoChannel *video_channel = GetVideoChannel(session);
-  if (video_channel && video_ssrc) {
-    video_channel->RemoveStream(video_ssrc);
-  }
-}
-
-void Call::OnMessage(talk_base::Message *message) {
-  switch (message->message_id) {
-  case MSG_CHECKAUTODESTROY:
-    // If no more sessions for this call, delete it
-    if (sessions_.size() == 0)
-      session_client_->DestroyCall(this);
-    break;
-  case MSG_TERMINATECALL:
-    // Signal to the user that a timeout has happened and the call should
-    // be sent to voicemail.
-    if (send_to_voicemail_) {
-      SignalSetupToCallVoicemail();
-    }
-
-    // Callee didn't answer - terminate call
-    Terminate();
-    break;
-  case MSG_PLAYDTMF:
-    ContinuePlayDTMF();
-  }
-}
-
-const std::vector<Session *> &Call::sessions() {
-  return sessions_;
-}
-
-bool Call::AddSession(Session *session, const SessionDescription* offer) {
-  bool succeeded = true;
-  VoiceChannel *voice_channel = NULL;
-  VideoChannel *video_channel = NULL;
-
-  // Generate a random string for the RTCP CNAME, as stated in RFC 6222.
-  // This string is only used for synchronization, and therefore is opaque.
-  std::string rtcp_cname;
-  if (!talk_base::CreateRandomString(16, &rtcp_cname)) {
-    return false;
-  }
-
-  const ContentInfo* audio_offer = GetFirstAudioContent(offer);
-  const ContentInfo* video_offer = GetFirstVideoContent(offer);
-  video_ = (video_offer != NULL);
-
-  ASSERT(audio_offer != NULL);
-  // Create voice channel and start a media monitor.
-  voice_channel = session_client_->channel_manager()->CreateVoiceChannel(
-      session, audio_offer->name, video_);
-  // voice_channel can be NULL in case of NullVoiceEngine.
-  if (voice_channel) {
-    voice_channel_map_[session->id()] = voice_channel;
-    voice_channel->SetRtcpCName(rtcp_cname);
-    voice_channel->SignalMediaMonitor.connect(this, &Call::OnMediaMonitor);
-    voice_channel->StartMediaMonitor(kMediaMonitorInterval);
-  } else {
-    succeeded = false;
-  }
-
-  // If desired, create video channel and start a media monitor.
-  if (video_ && succeeded) {
-    video_channel = session_client_->channel_manager()->CreateVideoChannel(
-        session, video_offer->name, true, voice_channel);
-    // video_channel can be NULL in case of NullVideoEngine.
-    if (video_channel) {
-      video_channel_map_[session->id()] = video_channel;
-      video_channel->SetRtcpCName(rtcp_cname);
-      video_channel->SignalMediaMonitor.connect(this, &Call::OnMediaMonitor);
-      video_channel->StartMediaMonitor(kMediaMonitorInterval);
-    } else {
-      succeeded = false;
-    }
-  }
-
-  if (succeeded) {
-    // Add session to list, create channels for this session.
-    sessions_.push_back(session);
-    session->SignalState.connect(this, &Call::OnSessionState);
-    session->SignalError.connect(this, &Call::OnSessionError);
-    session->SignalInfoMessage.connect(this, &Call::OnSessionInfo);
-    session->SignalReceivedTerminateReason
-      .connect(this, &Call::OnReceivedTerminateReason);
-
-    // If this call has the focus, enable this channel.
-    if (session_client_->GetFocus() == this) {
-      voice_channel->Enable(true);
-      if (video_channel) {
-        video_channel->Enable(true);
-      }
-    }
-
-    // Signal client.
-    SignalAddSession(this, session);
-  }
-
-  return succeeded;
-}
-
-void Call::RemoveSession(Session *session) {
-  // Remove session from list
-  std::vector<Session *>::iterator it_session;
-  it_session = std::find(sessions_.begin(), sessions_.end(), session);
-  if (it_session == sessions_.end())
-    return;
-  sessions_.erase(it_session);
-
-  // Destroy video channel
-  std::map<std::string, VideoChannel *>::iterator it_vchannel;
-  it_vchannel = video_channel_map_.find(session->id());
-  if (it_vchannel != video_channel_map_.end()) {
-    VideoChannel *video_channel = it_vchannel->second;
-    video_channel_map_.erase(it_vchannel);
-    session_client_->channel_manager()->DestroyVideoChannel(video_channel);
-  }
-
-  // Destroy voice channel
-  std::map<std::string, VoiceChannel *>::iterator it_channel;
-  it_channel = voice_channel_map_.find(session->id());
-  if (it_channel != voice_channel_map_.end()) {
-    VoiceChannel *voice_channel = it_channel->second;
-    voice_channel_map_.erase(it_channel);
-    session_client_->channel_manager()->DestroyVoiceChannel(voice_channel);
-  }
-
-  // Destroy speaker monitor
-  StopSpeakerMonitor(session);
-
-  // Signal client
-  SignalRemoveSession(this, session);
-
-  // The call auto destroys when the last session is removed
-  talk_base::Thread::Current()->Post(this, MSG_CHECKAUTODESTROY);
-}
-
-VoiceChannel* Call::GetVoiceChannel(Session* session) {
-  std::map<std::string, VoiceChannel *>::iterator it
-    = voice_channel_map_.find(session->id());
-  return (it != voice_channel_map_.end()) ? it->second : NULL;
-}
-
-VideoChannel* Call::GetVideoChannel(Session* session) {
-  std::map<std::string, VideoChannel *>::iterator it
-    = video_channel_map_.find(session->id());
-  return (it != video_channel_map_.end()) ? it->second : NULL;
-}
-
-void Call::EnableChannels(bool enable) {
-  std::vector<Session *>::iterator it;
-  for (it = sessions_.begin(); it != sessions_.end(); it++) {
-    VoiceChannel *voice_channel = GetVoiceChannel(*it);
-    VideoChannel *video_channel = GetVideoChannel(*it);
-    if (voice_channel != NULL)
-      voice_channel->Enable(enable);
-    if (video_channel != NULL)
-      video_channel->Enable(enable);
-  }
-  session_client_->channel_manager()->SetLocalRenderer(
-      (enable) ? local_renderer_ : NULL);
-}
-
-void Call::Mute(bool mute) {
-  muted_ = mute;
-  std::vector<Session *>::iterator it;
-  for (it = sessions_.begin(); it != sessions_.end(); it++) {
-    VoiceChannel *voice_channel = voice_channel_map_[(*it)->id()];
-    if (voice_channel != NULL)
-      voice_channel->Mute(mute);
-  }
-}
-
-void Call::MuteVideo(bool mute) {
-  video_muted_ = mute;
-  std::vector<Session *>::iterator it;
-  for (it = sessions_.begin(); it != sessions_.end(); it++) {
-    VideoChannel *video_channel = video_channel_map_[(*it)->id()];
-    if (video_channel != NULL)
-      video_channel->Mute(mute);
-  }
-}
-
-void Call::PressDTMF(int event) {
-  // Queue up this digit
-  if (queued_dtmf_.size() < kMaxDTMFDigits) {
-    LOG(LS_INFO) << "Call::PressDTMF(" << event << ")";
-
-    queued_dtmf_.push_back(event);
-
-    if (!playing_dtmf_) {
-      ContinuePlayDTMF();
-    }
-  }
-}
-
-void Call::ContinuePlayDTMF() {
-  playing_dtmf_ = false;
-
-  // Check to see if we have a queued tone
-  if (queued_dtmf_.size() > 0) {
-    playing_dtmf_ = true;
-
-    int tone = queued_dtmf_.front();
-    queued_dtmf_.pop_front();
-
-    LOG(LS_INFO) << "Call::ContinuePlayDTMF(" << tone << ")";
-    std::vector<Session *>::iterator it;
-    for (it = sessions_.begin(); it != sessions_.end(); it++) {
-      VoiceChannel *voice_channel = voice_channel_map_[(*it)->id()];
-      if (voice_channel != NULL) {
-        voice_channel->PressDTMF(tone, true);
-      }
-    }
-
-    // Post a message to play the next tone or at least clear the playing_dtmf_
-    // bit.
-    talk_base::Thread::Current()->PostDelayed(kDTMFDelay, this, MSG_PLAYDTMF);
-  }
-}
-
-void Call::Join(Call *call, bool enable) {
-  while (call->sessions_.size() != 0) {
-    // Move session
-    Session *session = call->sessions_[0];
-    call->sessions_.erase(call->sessions_.begin());
-    sessions_.push_back(session);
-    session->SignalState.connect(this, &Call::OnSessionState);
-    session->SignalError.connect(this, &Call::OnSessionError);
-    session->SignalReceivedTerminateReason
-      .connect(this, &Call::OnReceivedTerminateReason);
-
-    // Move voice channel
-    std::map<std::string, VoiceChannel *>::iterator it_channel;
-    it_channel = call->voice_channel_map_.find(session->id());
-    if (it_channel != call->voice_channel_map_.end()) {
-      VoiceChannel *voice_channel = (*it_channel).second;
-      call->voice_channel_map_.erase(it_channel);
-      voice_channel_map_[session->id()] = voice_channel;
-      voice_channel->Enable(enable);
-    }
-
-    // Move video channel
-    std::map<std::string, VideoChannel *>::iterator it_vchannel;
-    it_vchannel = call->video_channel_map_.find(session->id());
-    if (it_vchannel != call->video_channel_map_.end()) {
-      VideoChannel *video_channel = (*it_vchannel).second;
-      call->video_channel_map_.erase(it_vchannel);
-      video_channel_map_[session->id()] = video_channel;
-      video_channel->Enable(enable);
-    }
-  }
-}
-
-void Call::StartConnectionMonitor(Session *session, int cms) {
-  VoiceChannel *voice_channel = GetVoiceChannel(session);
-  if (voice_channel) {
-    voice_channel->SignalConnectionMonitor.connect(this,
-        &Call::OnConnectionMonitor);
-    voice_channel->StartConnectionMonitor(cms);
-  }
-
-  VideoChannel *video_channel = GetVideoChannel(session);
-  if (video_channel) {
-    video_channel->SignalConnectionMonitor.connect(this,
-        &Call::OnConnectionMonitor);
-    video_channel->StartConnectionMonitor(cms);
-  }
-}
-
-void Call::StopConnectionMonitor(Session *session) {
-  VoiceChannel *voice_channel = GetVoiceChannel(session);
-  if (voice_channel) {
-    voice_channel->StopConnectionMonitor();
-    voice_channel->SignalConnectionMonitor.disconnect(this);
-  }
-
-  VideoChannel *video_channel = GetVideoChannel(session);
-  if (video_channel) {
-    video_channel->StopConnectionMonitor();
-    video_channel->SignalConnectionMonitor.disconnect(this);
-  }
-}
-
-void Call::StartAudioMonitor(Session *session, int cms) {
-  VoiceChannel *voice_channel = GetVoiceChannel(session);
-  if (voice_channel) {
-    voice_channel->SignalAudioMonitor.connect(this, &Call::OnAudioMonitor);
-    voice_channel->StartAudioMonitor(cms);
-  }
-}
-
-void Call::StopAudioMonitor(Session *session) {
-  VoiceChannel *voice_channel = GetVoiceChannel(session);
-  if (voice_channel) {
-    voice_channel->StopAudioMonitor();
-    voice_channel->SignalAudioMonitor.disconnect(this);
-  }
-}
-
-bool Call::IsAudioMonitorRunning(Session *session) {
-  VoiceChannel *voice_channel = GetVoiceChannel(session);
-  if (voice_channel) {
-    return voice_channel->IsAudioMonitorRunning();
-  } else {
-    return false;
-  }
-}
-
-void Call::StartSpeakerMonitor(Session *session) {
-  if (speaker_monitor_map_.find(session->id()) == speaker_monitor_map_.end()) {
-    if (!IsAudioMonitorRunning(session)) {
-      StartAudioMonitor(session, kAudioMonitorPollPeriodMillis);
-    }
-    CurrentSpeakerMonitor* speaker_monitor =
-        new cricket::CurrentSpeakerMonitor(this, session);
-    speaker_monitor->SignalUpdate.connect(this, &Call::OnSpeakerMonitor);
-    speaker_monitor->Start();
-    speaker_monitor_map_[session->id()] = speaker_monitor;
-  } else {
-    LOG(LS_WARNING) << "Already started speaker monitor for session "
-                    << session->id() << ".";
-  }
-}
-
-void Call::StopSpeakerMonitor(Session *session) {
-  if (speaker_monitor_map_.find(session->id()) == speaker_monitor_map_.end()) {
-    LOG(LS_WARNING) << "Speaker monitor for session "
-                    << session->id() << " already stopped.";
-  } else {
-    CurrentSpeakerMonitor* monitor = speaker_monitor_map_[session->id()];
-    monitor->Stop();
-    speaker_monitor_map_.erase(session->id());
-    delete monitor;
-  }
-}
-
-void Call::OnConnectionMonitor(VoiceChannel *channel,
-                               const std::vector<ConnectionInfo> &infos) {
-  SignalConnectionMonitor(this, infos);
-}
-
-void Call::OnMediaMonitor(VoiceChannel *channel, const VoiceMediaInfo& info) {
-  SignalMediaMonitor(this, info);
-}
-
-void Call::OnAudioMonitor(VoiceChannel *channel, const AudioInfo& info) {
-  SignalAudioMonitor(this, info);
-}
-
-void Call::OnSpeakerMonitor(CurrentSpeakerMonitor* monitor, uint32 ssrc) {
-  NamedSource source;
-  source.ssrc = ssrc;
-  media_sources_.GetAudioSourceBySsrc(ssrc, &source);
-  SignalSpeakerMonitor(this, static_cast<Session *>(monitor->session()),
-                       source);
-}
-
-void Call::OnConnectionMonitor(VideoChannel *channel,
-                               const std::vector<ConnectionInfo> &infos) {
-  SignalVideoConnectionMonitor(this, infos);
-}
-
-void Call::OnMediaMonitor(VideoChannel *channel, const VideoMediaInfo& info) {
-  SignalVideoMediaMonitor(this, info);
-}
-
-uint32 Call::id() {
-  return id_;
-}
-
-void Call::OnSessionState(BaseSession *session, BaseSession::State state) {
-  switch (state) {
-    case Session::STATE_RECEIVEDACCEPT:
-    case Session::STATE_RECEIVEDREJECT:
-    case Session::STATE_RECEIVEDTERMINATE:
-      session_client_->session_manager()->signaling_thread()->Clear(this,
-          MSG_TERMINATECALL);
-      break;
-    default:
-      break;
-  }
-  SignalSessionState(this, static_cast<Session *>(session), state);
-}
-
-void Call::OnSessionError(BaseSession *session, Session::Error error) {
-  session_client_->session_manager()->signaling_thread()->Clear(this,
-      MSG_TERMINATECALL);
-  SignalSessionError(this, static_cast<Session *>(session), error);
-}
-
-void Call::OnSessionInfo(Session *session,
-                         const buzz::XmlElement* action_elem) {
-  // We have a different list of "updates" because we only want to
-  // signal the sources that were added or removed.  We want to filter
-  // out un-changed sources.
-  cricket::MediaSources updates;
-
-  if (IsSourcesNotify(action_elem)) {
-    MediaSources sources;
-    ParseError error;
-    if (!ParseSourcesNotify(action_elem, session->remote_description(),
-                            &sources, &error)) {
-      // TODO: Is there a way we can signal an IQ error
-      // back to the sender?
-      LOG(LS_WARNING) << "Invalid sources notify message: " << error.text;
-      return;
-    }
-
-    NamedSources::iterator it;
-    for (it = sources.mutable_audio()->begin();
-         it != sources.mutable_audio()->end(); ++it) {
-      bool found = false;
-      NamedSource found_source;
-      if (it->ssrc_set) {
-        found = media_sources_.GetAudioSourceBySsrc(it->ssrc, &found_source);
-      } else {
-        // For backwards compatibility, we remove by nick.
-        // TODO: Remove once all senders use explicit remove by ssrc.
-        found = media_sources_.GetFirstAudioSourceByNick(it->nick,
-                                                         &found_source);
-        if (found) {
-          it->SetSsrc(found_source.ssrc);
-          it->removed = true;
-        } else {
-          continue;  // No ssrc to remove.
-        }
-      }
-      if (it->removed && found) {
-        RemoveVoiceStream(session, found_source.ssrc);
-        media_sources_.RemoveAudioSourceBySsrc(it->ssrc);
-        updates.mutable_audio()->push_back(*it);
-        LOG(LS_INFO) << "Removed voice stream:  " << found_source.ssrc;
-      } else if (!it->removed && !found) {
-        AddVoiceStream(session, it->ssrc);
-        media_sources_.AddAudioSource(*it);
-        updates.mutable_audio()->push_back(*it);
-        LOG(LS_INFO) << "Added voice stream:  " << it->ssrc;
-      }
-    }
-    for (it = sources.mutable_video()->begin();
-         it != sources.mutable_video()->end(); ++it) {
-      bool found = false;
-      NamedSource found_source;
-      if (it->ssrc_set) {
-        found = media_sources_.GetVideoSourceBySsrc(it->ssrc, &found_source);
-      } else {
-        // For backwards compatibility, we remove by nick.
-        // TODO: Remove once all senders use explicit remove by ssrc.
-        found = media_sources_.GetFirstVideoSourceByNick(it->nick,
-                                                         &found_source);
-        if (found) {
-          it->SetSsrc(found_source.ssrc);
-          it->removed = true;
-        } else {
-          continue;  // No ssrc to remove.
-        }
-      }
-      if (it->removed && found) {
-        RemoveVideoStream(session, found_source.ssrc);
-        media_sources_.RemoveVideoSourceBySsrc(it->ssrc);
-        updates.mutable_video()->push_back(*it);
-        LOG(LS_INFO) << "Removed video stream:  " << found_source.ssrc;
-      } else if (!it->removed && !found) {
-        AddVideoStream(session, it->ssrc);
-        media_sources_.AddVideoSource(*it);
-        updates.mutable_video()->push_back(*it);
-        LOG(LS_INFO) << "Added video stream:  " << it->ssrc;
-      }
-    }
-
-    if (!updates.audio().empty() || !updates.video().empty()) {
-      SignalMediaSourcesUpdate(this, session, updates);
-    }
-  }
-}
-
-void Call::OnReceivedTerminateReason(Session *session,
-                                     const std::string &reason) {
-  session_client_->session_manager()->signaling_thread()->Clear(this,
-    MSG_TERMINATECALL);
-  SignalReceivedTerminateReason(this, session, reason);
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/session/phone/call.h b/third_party/libjingle/source/talk/session/phone/call.h
deleted file mode 100644
index 357f884..0000000
--- a/third_party/libjingle/source/talk/session/phone/call.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SESSION_PHONE_CALL_H_
-#define TALK_SESSION_PHONE_CALL_H_
-
-#include <string>
-#include <map>
-#include <vector>
-#include <deque>
-#include "talk/base/messagequeue.h"
-#include "talk/p2p/base/session.h"
-#include "talk/p2p/client/socketmonitor.h"
-#include "talk/xmpp/jid.h"
-#include "talk/session/phone/audiomonitor.h"
-#include "talk/session/phone/currentspeakermonitor.h"
-#include "talk/session/phone/mediamessages.h"
-#include "talk/session/phone/mediasession.h"
-
-namespace cricket {
-
-class MediaSessionClient;
-class VoiceChannel;
-class VideoChannel;
-
-// Can't typedef this easily since it's forward declared as struct elsewhere.
-struct CallOptions : public MediaSessionOptions {
-};
-
-class Call : public talk_base::MessageHandler, public sigslot::has_slots<> {
- public:
-  explicit Call(MediaSessionClient* session_client);
-  ~Call();
-
-  Session *InitiateSession(const buzz::Jid &jid, const CallOptions& options);
-  void AcceptSession(Session *session, const CallOptions& options);
-  void RejectSession(Session *session);
-  void TerminateSession(Session *session);
-  void Terminate();
-  bool SendViewRequest(Session* session,
-                       const ViewRequest& view_request);
-  void SetLocalRenderer(VideoRenderer* renderer);
-  void SetVideoRenderer(Session *session, uint32 ssrc,
-                        VideoRenderer* renderer);
-  void StartConnectionMonitor(Session *session, int cms);
-  void StopConnectionMonitor(Session *session);
-  void StartAudioMonitor(Session *session, int cms);
-  void StopAudioMonitor(Session *session);
-  bool IsAudioMonitorRunning(Session *session);
-  void StartSpeakerMonitor(Session *session);
-  void StopSpeakerMonitor(Session *session);
-  void Mute(bool mute);
-  void MuteVideo(bool mute);
-  void PressDTMF(int event);
-
-  const std::vector<Session *> &sessions();
-  uint32 id();
-  bool video() const { return video_; }
-  bool muted() const { return muted_; }
-  bool video_muted() const { return video_muted_; }
-
-  // Setting this to false will cause the call to have a longer timeout and
-  // for the SignalSetupToCallVoicemail to never fire.
-  void set_send_to_voicemail(bool send_to_voicemail) {
-    send_to_voicemail_ = send_to_voicemail;
-  }
-  bool send_to_voicemail() { return send_to_voicemail_; }
-
-  // Sets a flag on the chatapp that will redirect the call to voicemail once
-  // the call has been terminated
-  sigslot::signal0<> SignalSetupToCallVoicemail;
-  sigslot::signal2<Call *, Session *> SignalAddSession;
-  sigslot::signal2<Call *, Session *> SignalRemoveSession;
-  sigslot::signal3<Call *, Session *, Session::State>
-      SignalSessionState;
-  sigslot::signal3<Call *, Session *, Session::Error>
-      SignalSessionError;
-  sigslot::signal3<Call *, Session *, const std::string &>
-      SignalReceivedTerminateReason;
-  sigslot::signal2<Call *, const std::vector<ConnectionInfo> &>
-      SignalConnectionMonitor;
-  sigslot::signal2<Call *, const VoiceMediaInfo&> SignalMediaMonitor;
-  sigslot::signal2<Call *, const AudioInfo&> SignalAudioMonitor;
-  // Empty nick on NamedSource means "unknown".
-  // Ssrc of 0 on NamedSource means "no current speaker".
-  sigslot::signal3<Call *,
-                   Session *,
-                   const NamedSource&> SignalSpeakerMonitor;
-  sigslot::signal2<Call *, const std::vector<ConnectionInfo> &>
-      SignalVideoConnectionMonitor;
-  sigslot::signal2<Call *, const VideoMediaInfo&> SignalVideoMediaMonitor;
-  sigslot::signal3<Call *,
-                   Session *,
-                   const MediaSources&> SignalMediaSourcesUpdate;
-
- private:
-  void OnMessage(talk_base::Message *message);
-  void OnSessionState(BaseSession *session, BaseSession::State state);
-  void OnSessionError(BaseSession *session, Session::Error error);
-  void OnSessionInfo(Session *session, const buzz::XmlElement* action_elem);
-  void OnReceivedTerminateReason(Session *session, const std::string &reason);
-  void IncomingSession(Session *session, const SessionDescription* offer);
-  // Returns true on success.
-  bool AddSession(Session *session, const SessionDescription* offer);
-  void RemoveSession(Session *session);
-  void EnableChannels(bool enable);
-  void Join(Call *call, bool enable);
-  void OnConnectionMonitor(VoiceChannel *channel,
-                           const std::vector<ConnectionInfo> &infos);
-  void OnMediaMonitor(VoiceChannel *channel, const VoiceMediaInfo& info);
-  void OnAudioMonitor(VoiceChannel *channel, const AudioInfo& info);
-  void OnSpeakerMonitor(CurrentSpeakerMonitor* monitor, uint32 ssrc);
-  void OnConnectionMonitor(VideoChannel *channel,
-                           const std::vector<ConnectionInfo> &infos);
-  void OnMediaMonitor(VideoChannel *channel, const VideoMediaInfo& info);
-  VoiceChannel* GetVoiceChannel(Session* session);
-  VideoChannel* GetVideoChannel(Session* session);
-  void AddVoiceStream(Session *session, uint32 voice_ssrc);
-  void AddVideoStream(Session *session, uint32 video_ssrc);
-  void RemoveVoiceStream(Session *session, uint32 voice_ssrc);
-  void RemoveVideoStream(Session *session, uint32 video_ssrc);
-  void ContinuePlayDTMF();
-
-  uint32 id_;
-  MediaSessionClient *session_client_;
-  std::vector<Session *> sessions_;
-  MediaSources media_sources_;
-  std::map<std::string, VoiceChannel *> voice_channel_map_;
-  std::map<std::string, VideoChannel *> video_channel_map_;
-  std::map<std::string, CurrentSpeakerMonitor *> speaker_monitor_map_;
-  VideoRenderer* local_renderer_;
-  bool video_;
-  bool muted_;
-  bool video_muted_;
-  bool send_to_voicemail_;
-
-  // DTMF tones have to be queued up so that we don't flood the call.  We
-  // keep a deque (doubely ended queue) of them around.  While one is playing we
-  // set the playing_dtmf_ bit and schedule a message in XX msec to clear that
-  // bit or start the next tone playing.
-  std::deque<int> queued_dtmf_;
-  bool playing_dtmf_;
-
-  friend class MediaSessionClient;
-};
-
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_CALL_H_
diff --git a/third_party/libjingle/source/talk/session/phone/carbonvideorenderer.cc b/third_party/libjingle/source/talk/session/phone/carbonvideorenderer.cc
deleted file mode 100644
index f34fce5..0000000
--- a/third_party/libjingle/source/talk/session/phone/carbonvideorenderer.cc
+++ /dev/null
@@ -1,182 +0,0 @@
-// libjingle
-// Copyright 2011 Google Inc. All Rights Reserved
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-//  1. Redistributions of source code must retain the above copyright notice,
-//     this list of conditions and the following disclaimer.
-//  2. Redistributions in binary form must reproduce the above copyright notice,
-//     this list of conditions and the following disclaimer in the documentation
-//     and/or other materials provided with the distribution.
-//  3. The name of the author may not be used to endorse or promote products
-//     derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Implementation of CarbonVideoRenderer
-
-#include "talk/session/phone/carbonvideorenderer.h"
-
-#include "talk/base/logging.h"
-#include "talk/session/phone/videocommon.h"
-#include "talk/session/phone/videoframe.h"
-
-namespace cricket {
-
-CarbonVideoRenderer::CarbonVideoRenderer(int x, int y)
-    : image_width_(0),
-      image_height_(0),
-      x_(x),
-      y_(y),
-      image_ref_(NULL),
-      window_ref_(NULL) {
-}
-
-CarbonVideoRenderer::~CarbonVideoRenderer() {
-  if (window_ref_) {
-    DisposeWindow(window_ref_);
-  }
-}
-
-// Called from the main event loop. All renderering needs to happen on
-// the main thread.
-OSStatus CarbonVideoRenderer::DrawEventHandler(EventHandlerCallRef handler,
-                                               EventRef event,
-                                               void* data) {
-  OSStatus status = noErr;
-  CarbonVideoRenderer* renderer = static_cast<CarbonVideoRenderer*>(data);
-  if (renderer != NULL) {
-    if (!renderer->DrawFrame()) {
-      LOG(LS_ERROR) << "Failed to draw frame.";
-    }
-  }
-  return status;
-}
-
-bool CarbonVideoRenderer::DrawFrame() {
-  // Grab the image lock to make sure it is not changed why we'll draw it.
-  talk_base::CritScope cs(&image_crit_);
-
-  if (image_.get() == NULL) {
-    // Nothing to draw, just return.
-    return true;
-  }
-  int width = image_width_;
-  int height = image_height_;
-  CGDataProviderRef provider =
-      CGDataProviderCreateWithData(NULL, image_.get(), width * height * 4,
-                                   NULL);
-  CGColorSpaceRef color_space_ref = CGColorSpaceCreateDeviceRGB();
-  CGBitmapInfo bitmap_info = kCGBitmapByteOrderDefault;
-  CGColorRenderingIntent rendering_intent = kCGRenderingIntentDefault;
-  CGImageRef image_ref = CGImageCreate(width, height, 8, 32, width * 4,
-                                       color_space_ref, bitmap_info, provider,
-                                       NULL, false, rendering_intent);
-  CGDataProviderRelease(provider);
-
-  if (image_ref == NULL) {
-    return false;
-  }
-  CGContextRef context;
-  SetPortWindowPort(window_ref_);
-  if (QDBeginCGContext(GetWindowPort(window_ref_), &context) != noErr) {
-    CGImageRelease(image_ref);
-    return false;
-  }
-  Rect window_bounds;
-  GetWindowPortBounds(window_ref_, &window_bounds);
-
-  // Anchor the image to the top left corner.
-  int x = 0;
-  int y = window_bounds.bottom - CGImageGetHeight(image_ref);
-  CGRect dst_rect = CGRectMake(x, y, CGImageGetWidth(image_ref),
-                               CGImageGetHeight(image_ref));
-  CGContextDrawImage(context, dst_rect, image_ref);
-  CGContextFlush(context);
-  QDEndCGContext(GetWindowPort(window_ref_), &context);
-  CGImageRelease(image_ref);
-  return true;
-}
-
-bool CarbonVideoRenderer::SetSize(int width, int height, int reserved) {
-  if (width != image_width_ || height != image_height_) {
-    // Grab the image lock while changing its size.
-    talk_base::CritScope cs(&image_crit_);
-    image_width_ = width;
-    image_height_ = height;
-    image_.reset(new uint8[width * height * 4]);
-    memset(image_.get(), 255, width * height * 4);
-  }
-  return true;
-}
-
-bool CarbonVideoRenderer::RenderFrame(const VideoFrame* frame) {
-  if (!frame) {
-    return false;
-  }
-  {
-    // Grab the image lock so we are not trashing up the image being drawn.
-    talk_base::CritScope cs(&image_crit_);
-    frame->ConvertToRgbBuffer(cricket::FOURCC_ABGR,
-                              image_.get(),
-                              frame->GetWidth() * frame->GetHeight() * 4,
-                              frame->GetWidth() * 4);
-  }
-
-  // Trigger a repaint event for the whole window.
-  Rect bounds;
-  InvalWindowRect(window_ref_, GetWindowPortBounds(window_ref_, &bounds));
-  return true;
-}
-
-bool CarbonVideoRenderer::Initialize() {
-  OSStatus err;
-  WindowAttributes attributes =
-      kWindowStandardDocumentAttributes |
-      kWindowLiveResizeAttribute |
-      kWindowFrameworkScaledAttribute |
-      kWindowStandardHandlerAttribute;
-
-  struct Rect bounds;
-  bounds.top = y_;
-  bounds.bottom = 480;
-  bounds.left = x_;
-  bounds.right = 640;
-  err = CreateNewWindow(kDocumentWindowClass, attributes,
-                        &bounds, &window_ref_);
-  if (!window_ref_ || err != noErr) {
-    LOG(LS_ERROR) << "CreateNewWindow failed, error code: " << err;
-    return false;
-  }
-  static const EventTypeSpec event_spec = {
-    kEventClassWindow,
-    kEventWindowDrawContent
-  };
-
-  err = InstallWindowEventHandler(
-      window_ref_,
-      NewEventHandlerUPP(CarbonVideoRenderer::DrawEventHandler),
-      GetEventTypeCount(event_spec),
-      &event_spec,
-      this,
-      NULL);
-  if (err != noErr) {
-    LOG(LS_ERROR) << "Failed to install event handler, error code: " << err;
-    return false;
-  }
-  SelectWindow(window_ref_);
-  ShowWindow(window_ref_);
-  return true;
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/session/phone/carbonvideorenderer.h b/third_party/libjingle/source/talk/session/phone/carbonvideorenderer.h
deleted file mode 100644
index 20cf328..0000000
--- a/third_party/libjingle/source/talk/session/phone/carbonvideorenderer.h
+++ /dev/null
@@ -1,72 +0,0 @@
-// libjingle
-// Copyright 2011 Google Inc. All Rights Reserved
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-//  1. Redistributions of source code must retain the above copyright notice,
-//     this list of conditions and the following disclaimer.
-//  2. Redistributions in binary form must reproduce the above copyright notice,
-//     this list of conditions and the following disclaimer in the documentation
-//     and/or other materials provided with the distribution.
-//  3. The name of the author may not be used to endorse or promote products
-//     derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Definition of class CarbonVideoRenderer that implements the abstract class
-// cricket::VideoRenderer via Carbon.
-
-#ifndef TALK_SESSION_PHONE_CARBONVIDEORENDERER_H_
-#define TALK_SESSION_PHONE_CARBONVIDEORENDERER_H_
-
-#include <Carbon/Carbon.h>
-
-#include "talk/base/criticalsection.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/session/phone/videorenderer.h"
-
-namespace cricket {
-
-class CarbonVideoRenderer : public VideoRenderer {
- public:
-  CarbonVideoRenderer(int x, int y);
-  virtual ~CarbonVideoRenderer();
-
-  // Implementation of pure virtual methods of VideoRenderer.
-  // These two methods may be executed in different threads.
-  // SetSize is called before RenderFrame.
-  virtual bool SetSize(int width, int height, int reserved);
-  virtual bool RenderFrame(const VideoFrame* frame);
-
-  // Needs to be called on the main thread.
-  bool Initialize();
-
- private:
-  bool DrawFrame();
-
-  static OSStatus DrawEventHandler(EventHandlerCallRef handler,
-                                   EventRef event,
-                                   void* data);
-  talk_base::scoped_array<uint8> image_;
-  talk_base::CriticalSection image_crit_;
-  int image_width_;
-  int image_height_;
-  int x_;
-  int y_;
-  CGImageRef image_ref_;
-  WindowRef window_ref_;
-};
-
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_CARBONVIDEORENDERER_H_
diff --git a/third_party/libjingle/source/talk/session/phone/channel.cc b/third_party/libjingle/source/talk/session/phone/channel.cc
deleted file mode 100644
index 90d917d..0000000
--- a/third_party/libjingle/source/talk/session/phone/channel.cc
+++ /dev/null
@@ -1,1418 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2007, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/session/phone/channel.h"
-
-#include "talk/base/buffer.h"
-#include "talk/base/byteorder.h"
-#include "talk/base/common.h"
-#include "talk/base/logging.h"
-#include "talk/p2p/base/transportchannel.h"
-#include "talk/session/phone/channelmanager.h"
-#include "talk/session/phone/mediasessionclient.h"
-#include "talk/session/phone/rtcpmuxfilter.h"
-#include "talk/session/phone/rtputils.h"
-
-namespace cricket {
-
-struct PacketMessageData : public talk_base::MessageData {
-  talk_base::Buffer packet;
-};
-
-struct VoiceChannelErrorMessageData : public talk_base::MessageData {
-  VoiceChannelErrorMessageData(uint32 in_ssrc,
-                               VoiceMediaChannel::Error in_error)
-      : ssrc(in_ssrc),
-        error(in_error) {}
-  uint32 ssrc;
-  VoiceMediaChannel::Error error;
-};
-
-struct VideoChannelErrorMessageData : public talk_base::MessageData {
-  VideoChannelErrorMessageData(uint32 in_ssrc,
-                               VideoMediaChannel::Error in_error)
-      : ssrc(in_ssrc),
-        error(in_error) {}
-  uint32 ssrc;
-  VideoMediaChannel::Error error;
-};
-
-static const char* PacketType(bool rtcp) {
-  return (!rtcp) ? "RTP" : "RTCP";
-}
-
-static bool ValidPacket(bool rtcp, const talk_base::Buffer* packet) {
-  // Check the packet size. We could check the header too if needed.
-  return (packet &&
-      packet->length() >= (!rtcp ? kMinRtpPacketLen : kMinRtcpPacketLen) &&
-      packet->length() <= kMaxRtpPacketLen);
-}
-
-BaseChannel::BaseChannel(talk_base::Thread* thread,
-                         MediaEngineInterface* media_engine,
-                         MediaChannel* media_channel, BaseSession* session,
-                         const std::string& content_name, bool rtcp)
-    : worker_thread_(thread),
-      media_engine_(media_engine),
-      session_(session),
-      media_channel_(media_channel),
-      content_name_(content_name),
-      rtcp_(rtcp),
-      transport_channel_(NULL),
-      rtcp_transport_channel_(NULL),
-      enabled_(false),
-      writable_(false),
-      was_ever_writable_(false),
-      has_local_content_(false),
-      has_remote_content_(false),
-      muted_(false) {
-  ASSERT(worker_thread_ == talk_base::Thread::Current());
-  LOG(LS_INFO) << "Created channel";
-}
-
-BaseChannel::~BaseChannel() {
-  ASSERT(worker_thread_ == talk_base::Thread::Current());
-  StopConnectionMonitor();
-  FlushRtcpMessages();  // Send any outstanding RTCP packets.
-  Clear();  // eats any outstanding messages or packets
-  // We must destroy the media channel before the transport channel, otherwise
-  // the media channel may try to send on the dead transport channel. NULLing
-  // is not an effective strategy since the sends will come on another thread.
-  delete media_channel_;
-  set_rtcp_transport_channel(NULL);
-  if (transport_channel_ != NULL)
-    session_->DestroyChannel(content_name_, transport_channel_->name());
-  LOG(LS_INFO) << "Destroyed channel";
-}
-
-bool BaseChannel::Init(TransportChannel* transport_channel,
-                       TransportChannel* rtcp_transport_channel) {
-  if (transport_channel == NULL) {
-    return false;
-  }
-  if (rtcp() && rtcp_transport_channel == NULL) {
-    return false;
-  }
-  transport_channel_ = transport_channel;
-  media_channel_->SetInterface(this);
-  transport_channel_->SignalWritableState.connect(
-      this, &BaseChannel::OnWritableState);
-  transport_channel_->SignalReadPacket.connect(
-      this, &BaseChannel::OnChannelRead);
-
-  session_->SignalState.connect(this, &BaseChannel::OnSessionState);
-  session_->SignalRemoteDescriptionUpdate.connect(this,
-      &BaseChannel::OnRemoteDescriptionUpdate);
-
-  OnSessionState(session(), session()->state());
-  set_rtcp_transport_channel(rtcp_transport_channel);
-  return true;
-}
-
-// Can be called from thread other than worker thread
-bool BaseChannel::Enable(bool enable) {
-  Send(enable ? MSG_ENABLE : MSG_DISABLE);
-  return true;
-}
-
-// Can be called from thread other than worker thread
-bool BaseChannel::Mute(bool mute) {
-  Clear(MSG_UNMUTE);  // Clear any penging auto-unmutes.
-  Send(mute ? MSG_MUTE : MSG_UNMUTE);
-  return true;
-}
-
-bool BaseChannel::RemoveStream(uint32 ssrc) {
-  StreamMessageData data(ssrc, 0);
-  Send(MSG_REMOVESTREAM, &data);
-  ssrc_filter()->RemoveStream(ssrc);
-  return true;
-}
-
-bool BaseChannel::SetRtcpCName(const std::string& cname) {
-  SetRtcpCNameData data(cname);
-  Send(MSG_SETRTCPCNAME, &data);
-  return data.result;
-}
-
-bool BaseChannel::SetLocalContent(const MediaContentDescription* content,
-                                  ContentAction action) {
-  SetContentData data(content, action);
-  Send(MSG_SETLOCALCONTENT, &data);
-  return data.result;
-}
-
-bool BaseChannel::SetRemoteContent(const MediaContentDescription* content,
-                                   ContentAction action) {
-  SetContentData data(content, action);
-  Send(MSG_SETREMOTECONTENT, &data);
-  return data.result;
-}
-
-bool BaseChannel::SetMaxSendBandwidth(int max_bandwidth) {
-  SetBandwidthData data(max_bandwidth);
-  Send(MSG_SETMAXSENDBANDWIDTH, &data);
-  return data.result;
-}
-
-void BaseChannel::StartConnectionMonitor(int cms) {
-  socket_monitor_.reset(new SocketMonitor(transport_channel_,
-                                          worker_thread(),
-                                          talk_base::Thread::Current()));
-  socket_monitor_->SignalUpdate.connect(
-      this, &BaseChannel::OnConnectionMonitorUpdate);
-  socket_monitor_->Start(cms);
-}
-
-void BaseChannel::StopConnectionMonitor() {
-  if (socket_monitor_.get()) {
-    socket_monitor_->Stop();
-    socket_monitor_.reset();
-  }
-}
-
-void BaseChannel::set_rtcp_transport_channel(TransportChannel* channel) {
-  if (rtcp_transport_channel_ != channel) {
-    if (rtcp_transport_channel_) {
-      session_->DestroyChannel(content_name_, rtcp_transport_channel_->name());
-    }
-    rtcp_transport_channel_ = channel;
-    if (rtcp_transport_channel_) {
-      rtcp_transport_channel_->SignalWritableState.connect(
-          this, &BaseChannel::OnWritableState);
-      rtcp_transport_channel_->SignalReadPacket.connect(
-          this, &BaseChannel::OnChannelRead);
-    }
-  }
-}
-
-bool BaseChannel::SendPacket(talk_base::Buffer* packet) {
-  return SendPacket(false, packet);
-}
-
-bool BaseChannel::SendRtcp(talk_base::Buffer* packet) {
-  return SendPacket(true, packet);
-}
-
-int BaseChannel::SetOption(SocketType type, talk_base::Socket::Option opt,
-                           int value) {
-  switch (type) {
-    case ST_RTP: return transport_channel_->SetOption(opt, value);
-    case ST_RTCP: return rtcp_transport_channel_->SetOption(opt, value);
-    default: return -1;
-  }
-}
-
-void BaseChannel::OnWritableState(TransportChannel* channel) {
-  ASSERT(channel == transport_channel_ || channel == rtcp_transport_channel_);
-  if (transport_channel_->writable()
-      && (!rtcp_transport_channel_ || rtcp_transport_channel_->writable())) {
-    ChannelWritable_w();
-  } else {
-    ChannelNotWritable_w();
-  }
-}
-
-void BaseChannel::OnChannelRead(TransportChannel* channel,
-                                const char* data, size_t len) {
-  // OnChannelRead gets called from P2PSocket; now pass data to MediaEngine
-  ASSERT(worker_thread_ == talk_base::Thread::Current());
-
-  // When using RTCP multiplexing we might get RTCP packets on the RTP
-  // transport. We feed RTP traffic into the demuxer to determine if it is RTCP.
-  bool rtcp = PacketIsRtcp(channel, data, len);
-  talk_base::Buffer packet(data, len);
-  HandlePacket(rtcp, &packet);
-}
-
-bool BaseChannel::PacketIsRtcp(const TransportChannel* channel,
-                               const char* data, size_t len) {
-  return (channel == rtcp_transport_channel_ ||
-          rtcp_mux_filter_.DemuxRtcp(data, len));
-}
-
-bool BaseChannel::SendPacket(bool rtcp, talk_base::Buffer* packet) {
-  // Ensure we have a path capable of sending packets.
-  if (!writable_) {
-    return false;
-  }
-
-  // SendPacket gets called from MediaEngine, typically on an encoder thread.
-  // If the thread is not our worker thread, we will post to our worker
-  // so that the real work happens on our worker. This avoids us having to
-  // synchronize access to all the pieces of the send path, including
-  // SRTP and the inner workings of the transport channels.
-  // The only downside is that we can't return a proper failure code if
-  // needed. Since UDP is unreliable anyway, this should be a non-issue.
-  if (talk_base::Thread::Current() != worker_thread_) {
-    // Avoid a copy by transferring the ownership of the packet data.
-    int message_id = (!rtcp) ? MSG_RTPPACKET : MSG_RTCPPACKET;
-    PacketMessageData* data = new PacketMessageData;
-    packet->TransferTo(&data->packet);
-    worker_thread_->Post(this, message_id, data);
-    return true;
-  }
-
-  // Now that we are on the correct thread, ensure we have a place to send this
-  // packet before doing anything. (We might get RTCP packets that we don't
-  // intend to send.) If we've negotiated RTCP mux, send RTCP over the RTP
-  // transport.
-  TransportChannel* channel = (!rtcp || rtcp_mux_filter_.IsActive()) ?
-      transport_channel_ : rtcp_transport_channel_;
-  if (!channel || !channel->writable()) {
-    return false;
-  }
-
-  // Protect ourselves against crazy data.
-  if (!ValidPacket(rtcp, packet)) {
-    LOG(LS_ERROR) << "Dropping outgoing " << content_name_ << " "
-                  << PacketType(rtcp) << " packet: wrong size="
-                  << packet->length();
-    return false;
-  }
-
-  // Protect if needed.
-  if (srtp_filter_.IsActive()) {
-    bool res;
-    char* data = packet->data();
-    int len = packet->length();
-    if (!rtcp) {
-      res = srtp_filter_.ProtectRtp(data, len, packet->capacity(), &len);
-      if (!res) {
-        int seq_num = -1;
-        uint32 ssrc = 0;
-        GetRtpSeqNum(data, len, &seq_num);
-        GetRtpSsrc(data, len, &ssrc);
-        LOG(LS_ERROR) << "Failed to protect " << content_name_
-                      << " RTP packet: size=" << len
-                      << ", seqnum=" << seq_num << ", SSRC=" << ssrc;
-        return false;
-      }
-    } else {
-      res = srtp_filter_.ProtectRtcp(data, len, packet->capacity(), &len);
-      if (!res) {
-        int type = -1;
-        GetRtcpType(data, len, &type);
-        LOG(LS_ERROR) << "Failed to protect " << content_name_
-                      << " RTCP packet: size=" << len << ", type=" << type;
-        return false;
-      }
-    }
-
-    // Update the length of the packet now that we've added the auth tag.
-    packet->SetLength(len);
-  }
-
-  // Signal to the media sink after protecting the packet. TODO:
-  // Separate APIs to record unprotected media and protected header.
-  {
-    talk_base::CritScope cs(&signal_send_packet_cs_);
-    SignalSendPacket(packet->data(), packet->length(), rtcp);
-  }
-
-  // Bon voyage.
-  return (channel->SendPacket(packet->data(), packet->length())
-      == static_cast<int>(packet->length()));
-}
-
-void BaseChannel::HandlePacket(bool rtcp, talk_base::Buffer* packet) {
-  // Protect ourselvs against crazy data.
-  if (!ValidPacket(rtcp, packet)) {
-    LOG(LS_ERROR) << "Dropping incoming " << content_name_ << " "
-                  << PacketType(rtcp) << " packet: wrong size="
-                  << packet->length();
-    return;
-  }
-
-  // If this channel is suppose to handle RTP data, that is determined by
-  // checking against ssrc filter. This is necessary to do it here to avoid
-  // double decryption.
-  if (ssrc_filter_.IsActive() &&
-      !ssrc_filter_.DemuxPacket(packet->data(), packet->length(), rtcp)) {
-    return;
-  }
-
-  // Signal to the media sink before unprotecting the packet. TODO:
-  // Separate APIs to record unprotected media and protected header.
-  {
-    talk_base::CritScope cs(&signal_recv_packet_cs_);
-    SignalRecvPacket(packet->data(), packet->length(), rtcp);
-  }
-
-  // Unprotect the packet, if needed.
-  if (srtp_filter_.IsActive()) {
-    char* data = packet->data();
-    int len = packet->length();
-    bool res;
-    if (!rtcp) {
-      res = srtp_filter_.UnprotectRtp(data, len, &len);
-      if (!res) {
-        int seq_num = -1;
-        uint32 ssrc = 0;
-        GetRtpSeqNum(data, len, &seq_num);
-        GetRtpSsrc(data, len, &ssrc);
-        LOG(LS_ERROR) << "Failed to unprotect " << content_name_
-                      << " RTP packet: size=" << len
-                      << ", seqnum=" << seq_num << ", SSRC=" << ssrc;
-        return;
-      }
-    } else {
-      res = srtp_filter_.UnprotectRtcp(data, len, &len);
-      if (!res) {
-        int type = -1;
-        GetRtcpType(data, len, &type);
-        LOG(LS_ERROR) << "Failed to unprotect " << content_name_
-                      << " RTCP packet: size=" << len << ", type=" << type;
-        return;
-      }
-    }
-
-    packet->SetLength(len);
-  }
-
-  // Push it down to the media channel.
-  if (!rtcp) {
-    media_channel_->OnPacketReceived(packet);
-  } else {
-    media_channel_->OnRtcpReceived(packet);
-  }
-}
-
-void BaseChannel::OnSessionState(BaseSession* session,
-                                 BaseSession::State state) {
-  const MediaContentDescription* content = NULL;
-  switch (state) {
-    case Session::STATE_SENTINITIATE:
-      content = GetFirstContent(session->local_description());
-      if (content && !SetLocalContent(content, CA_OFFER)) {
-        LOG(LS_ERROR) << "Failure in SetLocalContent with CA_OFFER";
-        session->SetError(BaseSession::ERROR_CONTENT);
-      }
-      break;
-    case Session::STATE_SENTACCEPT:
-      content = GetFirstContent(session->local_description());
-      if (content && !SetLocalContent(content, CA_ANSWER)) {
-        LOG(LS_ERROR) << "Failure in SetLocalContent with CA_ANSWER";
-        session->SetError(BaseSession::ERROR_CONTENT);
-      }
-      break;
-    case Session::STATE_RECEIVEDINITIATE:
-      content = GetFirstContent(session->remote_description());
-      if (content && !SetRemoteContent(content, CA_OFFER)) {
-        LOG(LS_ERROR) << "Failure in SetRemoteContent with CA_OFFER";
-        session->SetError(BaseSession::ERROR_CONTENT);
-      }
-      break;
-    case Session::STATE_RECEIVEDACCEPT:
-      content = GetFirstContent(session->remote_description());
-      if (content && !SetRemoteContent(content, CA_ANSWER)) {
-        LOG(LS_ERROR) << "Failure in SetRemoteContent with CA_ANSWER";
-        session->SetError(BaseSession::ERROR_CONTENT);
-      }
-      break;
-    default:
-      break;
-  }
-}
-
-void BaseChannel::OnRemoteDescriptionUpdate(BaseSession* session) {
-  const MediaContentDescription* content =
-      GetFirstContent(session->remote_description());
-
-  if (content && !SetRemoteContent(content, CA_UPDATE)) {
-    LOG(LS_ERROR) << "Failure in SetRemoteContent with CA_UPDATE";
-    session->SetError(BaseSession::ERROR_CONTENT);
-  }
-}
-
-void BaseChannel::EnableMedia_w() {
-  ASSERT(worker_thread_ == talk_base::Thread::Current());
-  if (enabled_)
-    return;
-
-  LOG(LS_INFO) << "Channel enabled";
-  enabled_ = true;
-  ChangeState();
-}
-
-void BaseChannel::DisableMedia_w() {
-  ASSERT(worker_thread_ == talk_base::Thread::Current());
-  if (!enabled_)
-    return;
-
-  LOG(LS_INFO) << "Channel disabled";
-  enabled_ = false;
-  ChangeState();
-}
-
-void BaseChannel::MuteMedia_w() {
-  ASSERT(worker_thread_ == talk_base::Thread::Current());
-  if (muted_)
-    return;
-
-  if (media_channel()->Mute(true)) {
-    LOG(LS_INFO) << "Channel muted";
-    muted_ = true;
-  }
-}
-
-void BaseChannel::UnmuteMedia_w() {
-  ASSERT(worker_thread_ == talk_base::Thread::Current());
-  if (!muted_)
-    return;
-
-  if (media_channel()->Mute(false)) {
-    LOG(LS_INFO) << "Channel unmuted";
-    muted_ = false;
-  }
-}
-
-void BaseChannel::ChannelWritable_w() {
-  ASSERT(worker_thread_ == talk_base::Thread::Current());
-  if (writable_)
-    return;
-  LOG(LS_INFO) << "Channel socket writable ("
-               << transport_channel_->name().c_str() << ")"
-               << (was_ever_writable_ ? "" : " for the first time");
-  was_ever_writable_ = true;
-  writable_ = true;
-  ChangeState();
-}
-
-void BaseChannel::ChannelNotWritable_w() {
-  ASSERT(worker_thread_ == talk_base::Thread::Current());
-  if (!writable_)
-    return;
-
-  LOG(LS_INFO) << "Channel socket not writable ("
-               << transport_channel_->name().c_str() << ")";
-  writable_ = false;
-  ChangeState();
-}
-
-// Sets the maximum video bandwidth for automatic bandwidth adjustment.
-bool BaseChannel::SetMaxSendBandwidth_w(int max_bandwidth) {
-  return media_channel()->SetSendBandwidth(true, max_bandwidth);
-}
-
-bool BaseChannel::SetRtcpCName_w(const std::string& cname) {
-  return media_channel()->SetRtcpCName(cname);
-}
-
-bool BaseChannel::SetSrtp_w(const std::vector<CryptoParams>& cryptos,
-                            ContentAction action, ContentSource src) {
-  bool ret;
-  if (action == CA_OFFER) {
-    ret = srtp_filter_.SetOffer(cryptos, src);
-  } else if (action == CA_ANSWER) {
-    ret = srtp_filter_.SetAnswer(cryptos, src);
-  } else {
-    // CA_UPDATE, no crypto params.
-    ret = true;
-  }
-  return ret;
-}
-
-bool BaseChannel::SetRtcpMux_w(bool enable, ContentAction action,
-                               ContentSource src) {
-  bool ret;
-  if (action == CA_OFFER) {
-    ret = rtcp_mux_filter_.SetOffer(enable, src);
-  } else if (action == CA_ANSWER) {
-    ret = rtcp_mux_filter_.SetAnswer(enable, src);
-    if (ret && rtcp_mux_filter_.IsActive()) {
-      // We activated RTCP mux, close down the RTCP transport.
-      set_rtcp_transport_channel(NULL);
-      // If the RTP transport is already writable, then so are we.
-      if (transport_channel_->writable()) {
-        ChannelWritable_w();
-      }
-    }
-  } else {
-    // CA_UPDATE, no RTCP mux info.
-    ret = true;
-  }
-  return ret;
-}
-
-// TODO: Check all of the ssrcs in all of the streams in
-// the content, and not just the first one.
-bool BaseChannel::SetSsrcMux_w(bool enable,
-                               const MediaContentDescription* content,
-                               ContentAction action,
-                               ContentSource src) {
-  bool ret = true;
-  if (action == CA_OFFER) {
-    ret = ssrc_filter_.SetOffer(enable, src);
-    if (ret && src == CS_REMOTE) {  // if received offer with ssrc
-      ret = ssrc_filter_.AddStream(content->first_ssrc());
-    }
-  } else if (action == CA_ANSWER) {
-    ret = ssrc_filter_.SetAnswer(enable, src);
-    if (ret && src == CS_REMOTE && ssrc_filter_.IsActive()) {
-      ret = ssrc_filter_.AddStream(content->first_ssrc());
-    }
-  }
-  return ret;
-}
-
-void BaseChannel::OnMessage(talk_base::Message *pmsg) {
-  switch (pmsg->message_id) {
-    case MSG_ENABLE:
-      EnableMedia_w();
-      break;
-    case MSG_DISABLE:
-      DisableMedia_w();
-      break;
-
-    case MSG_MUTE:
-      MuteMedia_w();
-      break;
-    case MSG_UNMUTE:
-      UnmuteMedia_w();
-      break;
-
-    case MSG_SETRTCPCNAME: {
-      SetRtcpCNameData* data = static_cast<SetRtcpCNameData*>(pmsg->pdata);
-      data->result = SetRtcpCName_w(data->cname);
-      break;
-    }
-
-    case MSG_SETLOCALCONTENT: {
-      SetContentData* data = static_cast<SetContentData*>(pmsg->pdata);
-      data->result = SetLocalContent_w(data->content, data->action);
-      break;
-    }
-    case MSG_SETREMOTECONTENT: {
-      SetContentData* data = static_cast<SetContentData*>(pmsg->pdata);
-      data->result = SetRemoteContent_w(data->content, data->action);
-      break;
-    }
-
-    case MSG_REMOVESTREAM: {
-      StreamMessageData* data = static_cast<StreamMessageData*>(pmsg->pdata);
-      RemoveStream_w(data->ssrc1);
-      break;
-    }
-
-    case MSG_SETMAXSENDBANDWIDTH: {
-      SetBandwidthData* data = static_cast<SetBandwidthData*>(pmsg->pdata);
-      data->result = SetMaxSendBandwidth_w(data->value);
-      break;
-    }
-
-    case MSG_RTPPACKET:
-    case MSG_RTCPPACKET: {
-      PacketMessageData* data = static_cast<PacketMessageData*>(pmsg->pdata);
-      SendPacket(pmsg->message_id == MSG_RTCPPACKET, &data->packet);
-      delete data;  // because it is Posted
-      break;
-    }
-  }
-}
-
-void BaseChannel::Send(uint32 id, talk_base::MessageData *pdata) {
-  worker_thread_->Send(this, id, pdata);
-}
-
-void BaseChannel::Post(uint32 id, talk_base::MessageData *pdata) {
-  worker_thread_->Post(this, id, pdata);
-}
-
-void BaseChannel::PostDelayed(int cmsDelay, uint32 id,
-                              talk_base::MessageData *pdata) {
-  worker_thread_->PostDelayed(cmsDelay, this, id, pdata);
-}
-
-void BaseChannel::Clear(uint32 id, talk_base::MessageList* removed) {
-  worker_thread_->Clear(this, id, removed);
-}
-
-void BaseChannel::FlushRtcpMessages() {
-  // Flush all remaining RTCP messages. This should only be called in
-  // destructor.
-  ASSERT(talk_base::Thread::Current() == worker_thread_);
-  talk_base::MessageList rtcp_messages;
-  Clear(MSG_RTCPPACKET, &rtcp_messages);
-  for (talk_base::MessageList::iterator it = rtcp_messages.begin();
-       it != rtcp_messages.end(); ++it) {
-    Send(MSG_RTCPPACKET, it->pdata);
-  }
-}
-
-VoiceChannel::VoiceChannel(talk_base::Thread* thread,
-                           MediaEngineInterface* media_engine,
-                           VoiceMediaChannel* media_channel,
-                           BaseSession* session,
-                           const std::string& content_name,
-                           bool rtcp)
-    : BaseChannel(thread, media_engine, media_channel, session, content_name,
-                  rtcp),
-      received_media_(false),
-      mute_on_type_(false),
-      mute_on_type_timeout_(kTypingBlackoutPeriod) {
-}
-
-VoiceChannel::~VoiceChannel() {
-  StopAudioMonitor();
-  StopMediaMonitor();
-  // this can't be done in the base class, since it calls a virtual
-  DisableMedia_w();
-}
-
-bool VoiceChannel::Init() {
-  TransportChannel* rtcp_channel = rtcp() ?
-      session()->CreateChannel(content_name(), "rtcp") : NULL;
-  if (!BaseChannel::Init(session()->CreateChannel(content_name(), "rtp"),
-                         rtcp_channel)) {
-    return false;
-  }
-  media_channel()->SignalMediaError.connect(
-      this, &VoiceChannel::OnVoiceChannelError);
-  srtp_filter()->SignalSrtpError.connect(
-      this, &VoiceChannel::OnSrtpError);
-  return true;
-}
-
-bool VoiceChannel::AddStream(uint32 ssrc) {
-  StreamMessageData data(ssrc, 0);
-  Send(MSG_ADDSTREAM, &data);
-  ssrc_filter()->AddStream(ssrc);
-  return true;
-}
-
-bool VoiceChannel::SetRingbackTone(const void* buf, int len) {
-  SetRingbackToneMessageData data(buf, len);
-  Send(MSG_SETRINGBACKTONE, &data);
-  return data.result;
-}
-
-// TODO: Handle early media the right way. We should get an explicit
-// ringing message telling us to start playing local ringback, which we cancel
-// if any early media actually arrives. For now, we do the opposite, which is
-// to wait 1 second for early media, and start playing local ringback if none
-// arrives.
-void VoiceChannel::SetEarlyMedia(bool enable) {
-  if (enable) {
-    // Start the early media timeout
-    PostDelayed(kEarlyMediaTimeout, MSG_EARLYMEDIATIMEOUT);
-  } else {
-    // Stop the timeout if currently going.
-    Clear(MSG_EARLYMEDIATIMEOUT);
-  }
-}
-
-bool VoiceChannel::PlayRingbackTone(uint32 ssrc, bool play, bool loop) {
-  PlayRingbackToneMessageData data(ssrc, play, loop);
-  Send(MSG_PLAYRINGBACKTONE, &data);
-  return data.result;
-}
-
-bool VoiceChannel::PressDTMF(int digit, bool playout) {
-  DtmfMessageData data(digit, playout);
-  Send(MSG_PRESSDTMF, &data);
-  return data.result;
-}
-
-bool VoiceChannel::SetOutputScaling(uint32 ssrc, double left, double right) {
-  ScaleVolumeMessageData data(ssrc, left, right);
-  Send(MSG_SCALEVOLUME, &data);
-  return data.result;
-}
-
-void VoiceChannel::StartMediaMonitor(int cms) {
-  media_monitor_.reset(new VoiceMediaMonitor(media_channel(), worker_thread(),
-      talk_base::Thread::Current()));
-  media_monitor_->SignalUpdate.connect(
-      this, &VoiceChannel::OnMediaMonitorUpdate);
-  media_monitor_->Start(cms);
-}
-
-void VoiceChannel::StopMediaMonitor() {
-  if (media_monitor_.get()) {
-    media_monitor_->Stop();
-    media_monitor_->SignalUpdate.disconnect(this);
-    media_monitor_.reset();
-  }
-}
-
-void VoiceChannel::StartAudioMonitor(int cms) {
-  audio_monitor_.reset(new AudioMonitor(this, talk_base::Thread::Current()));
-  audio_monitor_
-    ->SignalUpdate.connect(this, &VoiceChannel::OnAudioMonitorUpdate);
-  audio_monitor_->Start(cms);
-}
-
-void VoiceChannel::StopAudioMonitor() {
-  if (audio_monitor_.get()) {
-    audio_monitor_->Stop();
-    audio_monitor_.reset();
-  }
-}
-
-bool VoiceChannel::IsAudioMonitorRunning() const {
-  return (audio_monitor_.get() != NULL);
-}
-
-int VoiceChannel::GetInputLevel_w() {
-  return media_engine()->GetInputLevel();
-}
-
-int VoiceChannel::GetOutputLevel_w() {
-  return media_channel()->GetOutputLevel();
-}
-
-void VoiceChannel::GetActiveStreams_w(AudioInfo::StreamList* actives) {
-  media_channel()->GetActiveStreams(actives);
-}
-
-void VoiceChannel::OnChannelRead(TransportChannel* channel,
-                                 const char* data, size_t len) {
-  BaseChannel::OnChannelRead(channel, data, len);
-
-  // Set a flag when we've received an RTP packet. If we're waiting for early
-  // media, this will disable the timeout.
-  if (!received_media_ && !PacketIsRtcp(channel, data, len)) {
-    received_media_ = true;
-  }
-}
-
-void VoiceChannel::ChangeState() {
-  // Render incoming data if we're the active call, and we have the local
-  // content. We receive data on the default channel and multiplexed streams.
-  bool recv = enabled() && has_local_content();
-  if (!media_channel()->SetPlayout(recv)) {
-    SendLastMediaError();
-  }
-    
-  // Send outgoing data if we're the active call, we have the remote content,
-  // and we have had some form of connectivity.
-  bool send = enabled() && has_remote_content() && was_ever_writable();
-  SendFlags send_flag = send ? SEND_MICROPHONE : SEND_NOTHING;
-  if (!media_channel()->SetSend(send_flag)) {
-    LOG(LS_ERROR) << "Failed to SetSend " << send_flag << " on voice channel";
-    SendLastMediaError();
-  }
-
-  LOG(LS_INFO) << "Changing voice state, recv=" << recv << " send=" << send;
-}
-
-const MediaContentDescription* VoiceChannel::GetFirstContent(
-    const SessionDescription* sdesc) {
-  const ContentInfo* cinfo = GetFirstAudioContent(sdesc);
-  if (cinfo == NULL)
-    return NULL;
-
-  return static_cast<const MediaContentDescription*>(cinfo->description);
-}
-
-bool VoiceChannel::SetLocalContent_w(const MediaContentDescription* content,
-                                     ContentAction action) {
-  ASSERT(worker_thread() == talk_base::Thread::Current());
-  LOG(LS_INFO) << "Setting local voice description";
-
-  const AudioContentDescription* audio =
-      static_cast<const AudioContentDescription*>(content);
-  ASSERT(audio != NULL);
-
-  bool ret;
-  if (audio->has_ssrcs()) {
-    // TODO: Handle multiple streams and ssrcs here.
-    media_channel()->SetSendSsrc(audio->first_ssrc());
-    LOG(LS_INFO) << "Set send ssrc for audio: " << audio->first_ssrc();
-  }
-  // Set local SRTP parameters (what we will encrypt with).
-  ret = SetSrtp_w(audio->cryptos(), action, CS_LOCAL);
-  // Set local RTCP mux parameters.
-  if (ret) {
-    ret = SetRtcpMux_w(audio->rtcp_mux(), action, CS_LOCAL);
-  }
-  // Set SSRC mux filter
-  if (ret) {
-    ret = SetSsrcMux_w(audio->has_ssrcs(), content, action, CS_LOCAL);
-  }
-  // Set local audio codecs (what we want to receive).
-  if (ret) {
-    ret = media_channel()->SetRecvCodecs(audio->codecs());
-  }
-  // Set local RTP header extensions.
-  if (ret && audio->rtp_header_extensions_set()) {
-    ret = media_channel()->SetRecvRtpHeaderExtensions(
-        audio->rtp_header_extensions());
-  }
-  // If everything worked, see if we can start receiving.
-  if (ret) {
-    set_has_local_content(true);
-    ChangeState();
-  } else {
-    LOG(LS_WARNING) << "Failed to set local voice description";
-  }
-  return ret;
-}
-
-bool VoiceChannel::SetRemoteContent_w(const MediaContentDescription* content,
-                                      ContentAction action) {
-  ASSERT(worker_thread() == talk_base::Thread::Current());
-  LOG(LS_INFO) << "Setting remote voice description";
-
-  const AudioContentDescription* audio =
-      static_cast<const AudioContentDescription*>(content);
-  ASSERT(audio != NULL);
-
-  bool ret;
-  // Set remote SRTP parameters (what the other side will encrypt with).
-  ret = SetSrtp_w(audio->cryptos(), action, CS_REMOTE);
-  // Set remote RTCP mux parameters.
-  if (ret) {
-    ret = SetRtcpMux_w(audio->rtcp_mux(), action, CS_REMOTE);
-  }
-  // Set SSRC mux filter
-  if (ret) {
-    ret = SetSsrcMux_w(audio->has_ssrcs(), content, action, CS_REMOTE);
-  }
-
-  // Set remote video codecs (what the other side wants to receive).
-  if (ret) {
-    ret = media_channel()->SetSendCodecs(audio->codecs());
-  }
-  // Set remote RTP header extensions.
-  if (ret && audio->rtp_header_extensions_set()) {
-    ret = media_channel()->SetSendRtpHeaderExtensions(
-        audio->rtp_header_extensions());
-  }
-
-  // Tweak our audio processing settings, if needed.
-  int audio_options = 0;
-  if (audio->conference_mode()) {
-    audio_options |= OPT_CONFERENCE;
-  }
-  if (audio->agc_minus_10db()) {
-    audio_options |= OPT_AGC_MINUS_10DB;
-  }
-  if (!media_channel()->SetOptions(audio_options)) {
-    // Log an error on failure, but don't abort the call.
-    LOG(LS_ERROR) << "Failed to set voice channel options";
-  }
-
-  // If everything worked, see if we can start sending.
-  if (ret) {
-    set_has_remote_content(true);
-    ChangeState();
-  } else {
-    LOG(LS_WARNING) << "Failed to set remote voice description";
-  }
-  return ret;
-}
-
-void VoiceChannel::AddStream_w(uint32 ssrc) {
-  ASSERT(worker_thread() == talk_base::Thread::Current());
-  media_channel()->AddStream(ssrc);
-}
-
-void VoiceChannel::RemoveStream_w(uint32 ssrc) {
-  media_channel()->RemoveStream(ssrc);
-}
-
-bool VoiceChannel::SetRingbackTone_w(const void* buf, int len) {
-  ASSERT(worker_thread() == talk_base::Thread::Current());
-  return media_channel()->SetRingbackTone(static_cast<const char*>(buf), len);
-}
-
-bool VoiceChannel::PlayRingbackTone_w(uint32 ssrc, bool play, bool loop) {
-  ASSERT(worker_thread() == talk_base::Thread::Current());
-  if (play) {
-    LOG(LS_INFO) << "Playing ringback tone, loop=" << loop;
-  } else {
-    LOG(LS_INFO) << "Stopping ringback tone";
-  }
-  return media_channel()->PlayRingbackTone(ssrc, play, loop);
-}
-
-void VoiceChannel::HandleEarlyMediaTimeout() {
-  // This occurs on the main thread, not the worker thread.
-  if (!received_media_) {
-    LOG(LS_INFO) << "No early media received before timeout";
-    SignalEarlyMediaTimeout(this);
-  }
-}
-
-bool VoiceChannel::PressDTMF_w(int digit, bool playout) {
-  if (!enabled() || !writable()) {
-    return false;
-  }
-
-  return media_channel()->PressDTMF(digit, playout);
-}
-
-bool VoiceChannel::SetOutputScaling_w(uint32 ssrc, double left, double right) {
-  return media_channel()->SetOutputScaling(ssrc, left, right);
-}
-
-void VoiceChannel::OnMessage(talk_base::Message *pmsg) {
-  switch (pmsg->message_id) {
-    case MSG_ADDSTREAM: {
-      StreamMessageData* data = static_cast<StreamMessageData*>(pmsg->pdata);
-      AddStream_w(data->ssrc1);
-      break;
-    }
-    case MSG_SETRINGBACKTONE: {
-      SetRingbackToneMessageData* data =
-          static_cast<SetRingbackToneMessageData*>(pmsg->pdata);
-      data->result = SetRingbackTone_w(data->buf, data->len);
-      break;
-    }
-    case MSG_PLAYRINGBACKTONE: {
-      PlayRingbackToneMessageData* data =
-          static_cast<PlayRingbackToneMessageData*>(pmsg->pdata);
-      data->result = PlayRingbackTone_w(data->ssrc, data->play, data->loop);
-      break;
-    }
-    case MSG_EARLYMEDIATIMEOUT:
-      HandleEarlyMediaTimeout();
-      break;
-    case MSG_PRESSDTMF: {
-      DtmfMessageData* data = static_cast<DtmfMessageData*>(pmsg->pdata);
-      data->result = PressDTMF_w(data->digit, data->playout);
-      break;
-    }
-    case MSG_SCALEVOLUME: {
-      ScaleVolumeMessageData* data =
-          static_cast<ScaleVolumeMessageData*>(pmsg->pdata);
-      data->result = SetOutputScaling_w(data->ssrc, data->left, data->right);
-      break;
-    }
-    case MSG_CHANNEL_ERROR: {
-      VoiceChannelErrorMessageData* data =
-          static_cast<VoiceChannelErrorMessageData*>(pmsg->pdata);
-      SignalMediaError(this, data->ssrc, data->error);
-      delete data;
-      break;
-    }
-    default:
-      BaseChannel::OnMessage(pmsg);
-      break;
-  }
-}
-
-void VoiceChannel::OnConnectionMonitorUpdate(
-    SocketMonitor* monitor, const std::vector<ConnectionInfo>& infos) {
-  SignalConnectionMonitor(this, infos);
-}
-
-void VoiceChannel::OnMediaMonitorUpdate(
-    VoiceMediaChannel* media_channel, const VoiceMediaInfo& info) {
-  ASSERT(media_channel == this->media_channel());
-  SignalMediaMonitor(this, info);
-}
-
-void VoiceChannel::OnAudioMonitorUpdate(AudioMonitor* monitor,
-                                        const AudioInfo& info) {
-  SignalAudioMonitor(this, info);
-}
-
-void VoiceChannel::OnVoiceChannelError(
-    uint32 ssrc, VoiceMediaChannel::Error err) {
-  if (err == VoiceMediaChannel::ERROR_REC_TYPING_NOISE_DETECTED &&
-      mute_on_type_ && !muted()) {
-    Mute(true);
-    PostDelayed(mute_on_type_timeout_, MSG_UNMUTE, NULL);
-  }
-  VoiceChannelErrorMessageData* data = new VoiceChannelErrorMessageData(
-      ssrc, err);
-  signaling_thread()->Post(this, MSG_CHANNEL_ERROR, data);
-}
-
-void VoiceChannel::OnSrtpError(uint32 ssrc, SrtpFilter::Mode mode,
-                               SrtpFilter::Error error) {
-  switch (error) {
-    case SrtpFilter::ERROR_FAIL:
-      OnVoiceChannelError(ssrc, (mode == SrtpFilter::PROTECT) ?
-                          VoiceMediaChannel::ERROR_REC_SRTP_ERROR :
-                          VoiceMediaChannel::ERROR_PLAY_SRTP_ERROR);
-      break;
-    case SrtpFilter::ERROR_AUTH:
-      OnVoiceChannelError(ssrc, (mode == SrtpFilter::PROTECT) ?
-                          VoiceMediaChannel::ERROR_REC_SRTP_AUTH_FAILED :
-                          VoiceMediaChannel::ERROR_PLAY_SRTP_AUTH_FAILED);
-      break;
-    case SrtpFilter::ERROR_REPLAY:
-      // Only receving channel should have this error.
-      ASSERT(mode == SrtpFilter::UNPROTECT);
-      OnVoiceChannelError(ssrc, VoiceMediaChannel::ERROR_PLAY_SRTP_REPLAY);
-      break;
-    default:
-      break;
-  }
-}
-
-VideoChannel::VideoChannel(talk_base::Thread* thread,
-                           MediaEngineInterface* media_engine,
-                           VideoMediaChannel* media_channel,
-                           BaseSession* session,
-                           const std::string& content_name,
-                           bool rtcp,
-                           VoiceChannel* voice_channel)
-    : BaseChannel(thread, media_engine, media_channel, session, content_name,
-                  rtcp),
-      voice_channel_(voice_channel), renderer_(NULL) {
-}
-
-bool VideoChannel::Init() {
-  TransportChannel* rtcp_channel = rtcp() ?
-      session()->CreateChannel(content_name(), "video_rtcp") : NULL;
-  if (!BaseChannel::Init(
-          session()->CreateChannel(content_name(), "video_rtp"),
-          rtcp_channel)) {
-    return false;
-  }
-  media_channel()->SignalScreencastWindowEvent.connect(
-      this, &VideoChannel::OnScreencastWindowEvent);
-  media_channel()->SignalMediaError.connect(
-      this, &VideoChannel::OnVideoChannelError);
-  srtp_filter()->SignalSrtpError.connect(
-      this, &VideoChannel::OnSrtpError);
-  return true;
-}
-
-void VoiceChannel::SendLastMediaError() {
-  uint32 ssrc;
-  VoiceMediaChannel::Error error;
-  media_channel()->GetLastMediaError(&ssrc, &error);
-  SignalMediaError(this, ssrc, error);
-}
-
-VideoChannel::~VideoChannel() {
-  StopMediaMonitor();
-  // this can't be done in the base class, since it calls a virtual
-  DisableMedia_w();
-}
-
-bool VideoChannel::AddStream(uint32 ssrc, uint32 voice_ssrc) {
-  StreamMessageData data(ssrc, voice_ssrc);
-  Send(MSG_ADDSTREAM, &data);
-  ssrc_filter()->AddStream(ssrc);
-  return true;
-}
-
-bool VideoChannel::SetRenderer(uint32 ssrc, VideoRenderer* renderer) {
-  RenderMessageData data(ssrc, renderer);
-  Send(MSG_SETRENDERER, &data);
-  return true;
-}
-
-bool VideoChannel::AddScreencast(uint32 ssrc, talk_base::WindowId id) {
-  ScreencastMessageData data(ssrc, id);
-  Send(MSG_ADDSCREENCAST, &data);
-  return true;
-}
-
-bool VideoChannel::RemoveScreencast(uint32 ssrc) {
-  ScreencastMessageData data(ssrc, 0);
-  Send(MSG_REMOVESCREENCAST, &data);
-  return true;
-}
-
-bool VideoChannel::SendIntraFrame() {
-  Send(MSG_SENDINTRAFRAME);
-  return true;
-}
-
-bool VideoChannel::RequestIntraFrame() {
-  Send(MSG_REQUESTINTRAFRAME);
-  return true;
-}
-
-void VideoChannel::EnableCpuAdaptation(bool enable) {
-  Send(enable ? MSG_ENABLECPUADAPTATION : MSG_DISABLECPUADAPTATION);
-}
-
-void VideoChannel::ChangeState() {
-  // Render incoming data if we're the active call, and we have the local
-  // content. We receive data on the default channel and multiplexed streams.
-  bool recv = enabled() && has_local_content();
-  if (!media_channel()->SetRender(recv)) {
-    LOG(LS_ERROR) << "Failed to SetRender on video channel";
-    // TODO: Report error back to server.
-  }
-
-  // Send outgoing data if we're the active call, we have the remote content,
-  // and we have had some form of connectivity.
-  bool send = enabled() && has_remote_content() && was_ever_writable();
-  if (!media_channel()->SetSend(send)) {
-    LOG(LS_ERROR) << "Failed to SetSend on video channel";
-    // TODO: Report error back to server.
-  }
-
-  LOG(LS_INFO) << "Changing video state, recv=" << recv << " send=" << send;
-}
-
-void VideoChannel::StartMediaMonitor(int cms) {
-  media_monitor_.reset(new VideoMediaMonitor(media_channel(), worker_thread(),
-      talk_base::Thread::Current()));
-  media_monitor_->SignalUpdate.connect(
-      this, &VideoChannel::OnMediaMonitorUpdate);
-  media_monitor_->Start(cms);
-}
-
-void VideoChannel::StopMediaMonitor() {
-  if (media_monitor_.get()) {
-    media_monitor_->Stop();
-    media_monitor_.reset();
-  }
-}
-
-const MediaContentDescription* VideoChannel::GetFirstContent(
-    const SessionDescription* sdesc) {
-  const ContentInfo* cinfo = GetFirstVideoContent(sdesc);
-  if (cinfo == NULL)
-    return NULL;
-
-  return static_cast<const MediaContentDescription*>(cinfo->description);
-}
-
-bool VideoChannel::SetLocalContent_w(const MediaContentDescription* content,
-                                     ContentAction action) {
-  ASSERT(worker_thread() == talk_base::Thread::Current());
-  LOG(LS_INFO) << "Setting local video description";
-
-  const VideoContentDescription* video =
-      static_cast<const VideoContentDescription*>(content);
-  ASSERT(video != NULL);
-
-  bool ret;
-  if (video->has_ssrcs()) {
-    // TODO: Handle multiple streams and ssrcs here.
-    media_channel()->SetSendSsrc(video->first_ssrc());
-    LOG(LS_INFO) << "Set send ssrc for video: " << video->first_ssrc();
-  }
-  // Set local SRTP parameters (what we will encrypt with).
-  ret = SetSrtp_w(video->cryptos(), action, CS_LOCAL);
-  // Set local RTCP mux parameters.
-  if (ret) {
-    ret = SetRtcpMux_w(video->rtcp_mux(), action, CS_LOCAL);
-  }
-  // Set SSRC mux filter
-  if (ret) {
-    ret = SetSsrcMux_w(video->has_ssrcs(), content, action, CS_LOCAL);
-  }
-
-  // Set local video codecs (what we want to receive).
-  if (ret) {
-    ret = media_channel()->SetRecvCodecs(video->codecs());
-  }
-  // Set local RTP header extensions.
-  if (ret && video->rtp_header_extensions_set()) {
-    ret = media_channel()->SetRecvRtpHeaderExtensions(
-        video->rtp_header_extensions());
-  }
-  // If everything worked, see if we can start receiving.
-  if (ret) {
-    set_has_local_content(true);
-    ChangeState();
-  } else {
-    LOG(LS_WARNING) << "Failed to set local video description";
-  }
-  return ret;
-}
-
-bool VideoChannel::SetRemoteContent_w(const MediaContentDescription* content,
-                                      ContentAction action) {
-  ASSERT(worker_thread() == talk_base::Thread::Current());
-  LOG(LS_INFO) << "Setting remote video description";
-
-  const VideoContentDescription* video =
-      static_cast<const VideoContentDescription*>(content);
-  ASSERT(video != NULL);
-
-  bool ret;
-  // Set remote SRTP parameters (what the other side will encrypt with).
-  ret = SetSrtp_w(video->cryptos(), action, CS_REMOTE);
-  // Set remote RTCP mux parameters.
-  if (ret) {
-    ret = SetRtcpMux_w(video->rtcp_mux(), action, CS_REMOTE);
-  }
-  // Set SSRC mux filter
-  if (ret) {
-    ret = SetSsrcMux_w(video->has_ssrcs(), content, action, CS_REMOTE);
-  }
-  // Set remote video codecs (what the other side wants to receive).
-  if (ret) {
-    ret = media_channel()->SetSendCodecs(video->codecs());
-  }
-  // Set remote RTP header extensions.
-  if (ret && video->rtp_header_extensions_set()) {
-    ret = media_channel()->SetSendRtpHeaderExtensions(
-        video->rtp_header_extensions());
-  }
-  // Set bandwidth parameters (what the other side wants to get, default=auto)
-  if (ret) {
-    int bandwidth_bps = video->bandwidth();
-    bool auto_bandwidth = (bandwidth_bps == kAutoBandwidth);
-    ret = media_channel()->SetSendBandwidth(auto_bandwidth, bandwidth_bps);
-  }
-  // If everything worked, see if we can start sending.
-  if (ret) {
-    set_has_remote_content(true);
-    ChangeState();
-  } else {
-    LOG(LS_WARNING) << "Failed to set remote video description";
-  }
-  return ret;
-}
-
-void VideoChannel::AddStream_w(uint32 ssrc, uint32 voice_ssrc) {
-  media_channel()->AddStream(ssrc, voice_ssrc);
-}
-
-void VideoChannel::RemoveStream_w(uint32 ssrc) {
-  media_channel()->RemoveStream(ssrc);
-}
-
-void VideoChannel::SetRenderer_w(uint32 ssrc, VideoRenderer* renderer) {
-  media_channel()->SetRenderer(ssrc, renderer);
-}
-
-void VideoChannel::AddScreencast_w(uint32 ssrc, talk_base::WindowId id) {
-  media_channel()->AddScreencast(ssrc, id);
-}
-
-void VideoChannel::RemoveScreencast_w(uint32 ssrc) {
-  media_channel()->RemoveScreencast(ssrc);
-}
-
-void VideoChannel::OnScreencastWindowEvent_s(uint32 ssrc,
-                                             talk_base::WindowEvent we) {
-  ASSERT(signaling_thread() == talk_base::Thread::Current());
-  SignalScreencastWindowEvent(ssrc, we);
-}
-
-void VideoChannel::OnMessage(talk_base::Message *pmsg) {
-  switch (pmsg->message_id) {
-    case MSG_ADDSTREAM: {
-      StreamMessageData* data = static_cast<StreamMessageData*>(pmsg->pdata);
-      AddStream_w(data->ssrc1, data->ssrc2);
-      break;
-    }
-    case MSG_SETRENDERER: {
-      RenderMessageData* data = static_cast<RenderMessageData*>(pmsg->pdata);
-      SetRenderer_w(data->ssrc, data->renderer);
-      break;
-    }
-    case MSG_ADDSCREENCAST: {
-      ScreencastMessageData* data =
-          static_cast<ScreencastMessageData*>(pmsg->pdata);
-      AddScreencast_w(data->ssrc, data->window_id);
-      break;
-    }
-    case MSG_REMOVESCREENCAST: {
-      ScreencastMessageData* data =
-          static_cast<ScreencastMessageData*>(pmsg->pdata);
-      RemoveScreencast_w(data->ssrc);
-      break;
-    }
-    case MSG_SCREENCASTWINDOWEVENT: {
-      ScreencastEventData* data =
-          static_cast<ScreencastEventData*>(pmsg->pdata);
-      OnScreencastWindowEvent_s(data->ssrc, data->event);
-      delete data;
-      break;
-    }
-    case MSG_SENDINTRAFRAME:
-      SendIntraFrame_w();
-      break;
-    case MSG_REQUESTINTRAFRAME:
-      RequestIntraFrame_w();
-      break;
-    case MSG_ENABLECPUADAPTATION:
-      EnableCpuAdaptation_w(true);
-      break;
-    case MSG_DISABLECPUADAPTATION:
-      EnableCpuAdaptation_w(false);
-      break;
-    case MSG_CHANNEL_ERROR: {
-      const VideoChannelErrorMessageData* data =
-          static_cast<VideoChannelErrorMessageData*>(pmsg->pdata);
-      SignalMediaError(this, data->ssrc, data->error);
-      delete data;
-      break;
-    }
-    default:
-      BaseChannel::OnMessage(pmsg);
-      break;
-  }
-}
-
-void VideoChannel::OnConnectionMonitorUpdate(
-    SocketMonitor *monitor, const std::vector<ConnectionInfo> &infos) {
-  SignalConnectionMonitor(this, infos);
-}
-
-void VideoChannel::OnMediaMonitorUpdate(
-    VideoMediaChannel* media_channel, const VideoMediaInfo &info) {
-  ASSERT(media_channel == this->media_channel());
-  SignalMediaMonitor(this, info);
-}
-
-void VideoChannel::OnScreencastWindowEvent(uint32 ssrc,
-                                           talk_base::WindowEvent event) {
-  ScreencastEventData* pdata = new ScreencastEventData(ssrc, event);
-  signaling_thread()->Post(this, MSG_SCREENCASTWINDOWEVENT, pdata);
-}
-
-void VideoChannel::OnVideoChannelError(uint32 ssrc,
-                                       VideoMediaChannel::Error error) {
-  VideoChannelErrorMessageData* data = new VideoChannelErrorMessageData(
-      ssrc, error);
-  signaling_thread()->Post(this, MSG_CHANNEL_ERROR, data);
-}
-
-void VideoChannel::OnSrtpError(uint32 ssrc, SrtpFilter::Mode mode,
-                               SrtpFilter::Error error) {
-  switch (error) {
-    case SrtpFilter::ERROR_FAIL:
-      OnVideoChannelError(ssrc, (mode == SrtpFilter::PROTECT) ?
-                          VideoMediaChannel::ERROR_REC_SRTP_ERROR :
-                          VideoMediaChannel::ERROR_PLAY_SRTP_ERROR);
-      break;
-    case SrtpFilter::ERROR_AUTH:
-      OnVideoChannelError(ssrc, (mode == SrtpFilter::PROTECT) ?
-                          VideoMediaChannel::ERROR_REC_SRTP_AUTH_FAILED :
-                          VideoMediaChannel::ERROR_PLAY_SRTP_AUTH_FAILED);
-      break;
-    case SrtpFilter::ERROR_REPLAY:
-      // Only receving channel should have this error.
-      ASSERT(mode == SrtpFilter::UNPROTECT);
-      // TODO: Turn on the signaling of replay error once we have
-      // switched to the new mechanism for doing video retransmissions.
-      // OnVideoChannelError(ssrc, VideoMediaChannel::ERROR_PLAY_SRTP_REPLAY);
-      break;
-    default:
-      break;
-  }
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/session/phone/channel.h b/third_party/libjingle/source/talk/session/phone/channel.h
deleted file mode 100644
index cf06f2e..0000000
--- a/third_party/libjingle/source/talk/session/phone/channel.h
+++ /dev/null
@@ -1,551 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2007, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SESSION_PHONE_CHANNEL_H_
-#define TALK_SESSION_PHONE_CHANNEL_H_
-
-#include <string>
-#include <vector>
-
-#include "talk/base/asyncudpsocket.h"
-#include "talk/base/criticalsection.h"
-#include "talk/base/network.h"
-#include "talk/base/sigslot.h"
-#include "talk/base/window.h"
-#include "talk/p2p/client/socketmonitor.h"
-#include "talk/p2p/base/session.h"
-#include "talk/session/phone/audiomonitor.h"
-#include "talk/session/phone/mediachannel.h"
-#include "talk/session/phone/mediaengine.h"
-#include "talk/session/phone/mediamonitor.h"
-#include "talk/session/phone/rtcpmuxfilter.h"
-#include "talk/session/phone/ssrcmuxfilter.h"
-#include "talk/session/phone/srtpfilter.h"
-
-namespace cricket {
-
-class MediaContentDescription;
-struct CryptoParams;
-
-enum {
-  MSG_ENABLE = 1,
-  MSG_DISABLE = 2,
-  MSG_MUTE = 3,
-  MSG_UNMUTE = 4,
-  MSG_SETREMOTECONTENT = 5,
-  MSG_SETLOCALCONTENT = 6,
-  MSG_EARLYMEDIATIMEOUT = 8,
-  MSG_PRESSDTMF = 9,
-  MSG_SETRENDERER = 10,
-  MSG_ADDSTREAM = 11,
-  MSG_REMOVESTREAM = 12,
-  MSG_SETRINGBACKTONE = 13,
-  MSG_PLAYRINGBACKTONE = 14,
-  MSG_SETMAXSENDBANDWIDTH = 15,
-  MSG_ADDSCREENCAST = 16,
-  MSG_REMOVESCREENCAST = 17,
-  MSG_SETRTCPCNAME = 18,
-  MSG_SENDINTRAFRAME = 19,
-  MSG_REQUESTINTRAFRAME = 20,
-  MSG_SCREENCASTWINDOWEVENT = 21,
-  MSG_RTPPACKET = 22,
-  MSG_RTCPPACKET = 23,
-  MSG_CHANNEL_ERROR = 24,
-  MSG_ENABLECPUADAPTATION = 25,
-  MSG_DISABLECPUADAPTATION = 26,
-  MSG_SCALEVOLUME = 27
-};
-
-// BaseChannel contains logic common to voice and video, including
-// enable/mute, marshaling calls to a worker thread, and
-// connection and media monitors.
-class BaseChannel
-    : public talk_base::MessageHandler, public sigslot::has_slots<>,
-      public MediaChannel::NetworkInterface {
- public:
-  BaseChannel(talk_base::Thread* thread, MediaEngineInterface* media_engine,
-              MediaChannel* channel, BaseSession* session,
-              const std::string& content_name, bool rtcp);
-  virtual ~BaseChannel();
-  bool Init(TransportChannel* transport_channel,
-            TransportChannel* rtcp_transport_channel);
-
-  talk_base::Thread* worker_thread() const { return worker_thread_; }
-  BaseSession* session() const { return session_; }
-  const std::string& content_name() { return content_name_; }
-  TransportChannel* transport_channel() const {
-    return transport_channel_;
-  }
-  TransportChannel* rtcp_transport_channel() const {
-    return rtcp_transport_channel_;
-  }
-  bool enabled() const { return enabled_; }
-  bool secure() const { return srtp_filter_.IsActive(); }
-
-  // Channel control
-  bool SetRtcpCName(const std::string& cname);
-  bool SetLocalContent(const MediaContentDescription* content,
-                       ContentAction action);
-  bool SetRemoteContent(const MediaContentDescription* content,
-                        ContentAction action);
-  bool SetMaxSendBandwidth(int max_bandwidth);
-
-  bool Enable(bool enable);
-  bool Mute(bool mute);
-
-  // Multiplexing
-  bool RemoveStream(uint32 ssrc);
-
-  // Monitoring
-  void StartConnectionMonitor(int cms);
-  void StopConnectionMonitor();
-
-  void set_srtp_signal_silent_time(uint32 silent_time) {
-    srtp_filter_.set_signal_silent_time(silent_time);
-  }
-
-  template <class T>
-  void RegisterSendSink(T* sink,
-                        void (T::*OnPacket)(const void*, size_t, bool)) {
-    talk_base::CritScope cs(&signal_send_packet_cs_);
-    SignalSendPacket.disconnect(sink);
-    SignalSendPacket.connect(sink, OnPacket);
-  }
-
-  void UnregisterSendSink(sigslot::has_slots<>* sink) {
-    talk_base::CritScope cs(&signal_send_packet_cs_);
-    SignalSendPacket.disconnect(sink);
-  }
-
-  bool HasSendSinks() {
-    talk_base::CritScope cs(&signal_send_packet_cs_);
-    return !SignalSendPacket.is_empty();
-  }
-
-  template <class T>
-  void RegisterRecvSink(T* sink,
-                        void (T::*OnPacket)(const void*, size_t, bool)) {
-    talk_base::CritScope cs(&signal_recv_packet_cs_);
-    SignalRecvPacket.disconnect(sink);
-    SignalRecvPacket.connect(sink, OnPacket);
-  }
-
-  void UnregisterRecvSink(sigslot::has_slots<>* sink) {
-    talk_base::CritScope cs(&signal_recv_packet_cs_);
-    SignalRecvPacket.disconnect(sink);
-  }
-
-  bool HasRecvSinks() {
-    talk_base::CritScope cs(&signal_recv_packet_cs_);
-    return !SignalRecvPacket.is_empty();
-  }
-
-  SsrcMuxFilter* ssrc_filter() { return &ssrc_filter_; }
-
- protected:
-  MediaEngineInterface* media_engine() const { return media_engine_; }
-  virtual MediaChannel* media_channel() const { return media_channel_; }
-  void set_rtcp_transport_channel(TransportChannel* transport);
-  bool writable() const { return writable_; }
-  bool was_ever_writable() const { return was_ever_writable_; }
-  bool has_local_content() const { return has_local_content_; }
-  bool has_remote_content() const { return has_remote_content_; }
-  void set_has_local_content(bool has) { has_local_content_ = has; }
-  void set_has_remote_content(bool has) { has_remote_content_ = has; }
-  bool muted() const { return muted_; }
-  talk_base::Thread* signaling_thread() { return session_->signaling_thread(); }
-  SrtpFilter* srtp_filter() { return &srtp_filter_; }
-  bool rtcp() const { return rtcp_; }
-
-  void Send(uint32 id, talk_base::MessageData *pdata = NULL);
-  void Post(uint32 id, talk_base::MessageData *pdata = NULL);
-  void PostDelayed(int cmsDelay, uint32 id = 0,
-                   talk_base::MessageData *pdata = NULL);
-  void Clear(uint32 id = talk_base::MQID_ANY,
-             talk_base::MessageList* removed = NULL);
-  void FlushRtcpMessages();
-
-  // NetworkInterface implementation, called by MediaEngine
-  virtual bool SendPacket(talk_base::Buffer* packet);
-  virtual bool SendRtcp(talk_base::Buffer* packet);
-  virtual int SetOption(SocketType type, talk_base::Socket::Option o, int val);
-
-  // From TransportChannel
-  void OnWritableState(TransportChannel* channel);
-  virtual void OnChannelRead(TransportChannel* channel, const char* data,
-                             size_t len);
-
-  bool PacketIsRtcp(const TransportChannel* channel, const char* data,
-                    size_t len);
-  bool SendPacket(bool rtcp, talk_base::Buffer* packet);
-  void HandlePacket(bool rtcp, talk_base::Buffer* packet);
-
-  // Setting the send codec based on the remote description.
-  void OnSessionState(BaseSession* session, BaseSession::State state);
-  void OnRemoteDescriptionUpdate(BaseSession* session);
-
-  void EnableMedia_w();
-  void DisableMedia_w();
-  void MuteMedia_w();
-  void UnmuteMedia_w();
-  void ChannelWritable_w();
-  void ChannelNotWritable_w();
-
-  struct StreamMessageData : public talk_base::MessageData {
-    StreamMessageData(uint32 s1, uint32 s2) : ssrc1(s1), ssrc2(s2) {}
-    uint32 ssrc1;
-    uint32 ssrc2;
-  };
-  virtual void RemoveStream_w(uint32 ssrc) = 0;
-
-  virtual void ChangeState() = 0;
-
-  struct SetRtcpCNameData : public talk_base::MessageData {
-    explicit SetRtcpCNameData(const std::string& cname)
-        : cname(cname), result(false) {}
-    std::string cname;
-    bool result;
-  };
-  bool SetRtcpCName_w(const std::string& cname);
-
-  struct SetContentData : public talk_base::MessageData {
-    SetContentData(const MediaContentDescription* content,
-                   ContentAction action)
-        : content(content), action(action), result(false) {}
-    const MediaContentDescription* content;
-    ContentAction action;
-    bool result;
-  };
-
-  // Gets the content appropriate to the channel (audio or video).
-  virtual const MediaContentDescription* GetFirstContent(
-      const SessionDescription* sdesc) = 0;
-  virtual bool SetLocalContent_w(const MediaContentDescription* content,
-                                 ContentAction action) = 0;
-  virtual bool SetRemoteContent_w(const MediaContentDescription* content,
-                                  ContentAction action) = 0;
-
-  bool SetSrtp_w(const std::vector<CryptoParams>& params, ContentAction action,
-                 ContentSource src);
-  bool SetRtcpMux_w(bool enable, ContentAction action, ContentSource src);
-
-  // SSRC mux handling methods.
-  bool AddSsrcMux_w(const MediaContentDescription* content);
-  bool SetSsrcMux_w(bool enable, const MediaContentDescription* content,
-                    ContentAction action, ContentSource src);
-
-  struct SetBandwidthData : public talk_base::MessageData {
-    explicit SetBandwidthData(int value) : value(value), result(false) {}
-    int value;
-    bool result;
-  };
-  bool SetMaxSendBandwidth_w(int max_bandwidth);
-
-  // From MessageHandler
-  virtual void OnMessage(talk_base::Message *pmsg);
-
-  // Handled in derived classes
-  virtual void OnConnectionMonitorUpdate(SocketMonitor *monitor,
-      const std::vector<ConnectionInfo> &infos) = 0;
-
- private:
-  sigslot::signal3<const void*, size_t, bool> SignalSendPacket;
-  sigslot::signal3<const void*, size_t, bool> SignalRecvPacket;
-  talk_base::CriticalSection signal_send_packet_cs_;
-  talk_base::CriticalSection signal_recv_packet_cs_;
-
-  talk_base::Thread *worker_thread_;
-  MediaEngineInterface *media_engine_;
-  BaseSession *session_;
-  MediaChannel *media_channel_;
-
-  std::string content_name_;
-  bool rtcp_;
-  TransportChannel *transport_channel_;
-  TransportChannel *rtcp_transport_channel_;
-  SrtpFilter srtp_filter_;
-  RtcpMuxFilter rtcp_mux_filter_;
-  SsrcMuxFilter ssrc_filter_;
-  talk_base::scoped_ptr<SocketMonitor> socket_monitor_;
-  bool enabled_;
-  bool writable_;
-  bool was_ever_writable_;
-  bool has_local_content_;
-  bool has_remote_content_;
-  bool muted_;
-};
-
-// VoiceChannel is a specialization that adds support for early media, DTMF,
-// and input/output level monitoring.
-class VoiceChannel : public BaseChannel {
- public:
-  VoiceChannel(talk_base::Thread *thread, MediaEngineInterface *media_engine,
-               VoiceMediaChannel *channel, BaseSession *session,
-               const std::string& content_name, bool rtcp);
-  ~VoiceChannel();
-  bool Init();
-
-  // downcasts a MediaChannel
-  virtual VoiceMediaChannel* media_channel() const {
-    return static_cast<VoiceMediaChannel*>(BaseChannel::media_channel());
-  }
-
-  // Add an incoming stream with the specified SSRC.
-  bool AddStream(uint32 ssrc);
-
-  bool SetRingbackTone(const void* buf, int len);
-  void SetEarlyMedia(bool enable);
-  // This signal is emitted when we have gone a period of time without
-  // receiving early media. When received, a UI should start playing its
-  // own ringing sound
-  sigslot::signal1<VoiceChannel*> SignalEarlyMediaTimeout;
-
-  bool PlayRingbackTone(uint32 ssrc, bool play, bool loop);
-  bool PressDTMF(int digit, bool playout);
-  bool SetOutputScaling(uint32 ssrc, double left, double right);
-  void set_mute_on_type(bool enable, int timeout) {
-    mute_on_type_ = enable;
-    mute_on_type_timeout_ = talk_base::_max(0, timeout);
-  }
-
-  // Monitoring functions
-  sigslot::signal2<VoiceChannel*, const std::vector<ConnectionInfo> &>
-      SignalConnectionMonitor;
-
-  void StartMediaMonitor(int cms);
-  void StopMediaMonitor();
-  sigslot::signal2<VoiceChannel*, const VoiceMediaInfo&> SignalMediaMonitor;
-
-  void StartAudioMonitor(int cms);
-  void StopAudioMonitor();
-  bool IsAudioMonitorRunning() const;
-  sigslot::signal2<VoiceChannel*, const AudioInfo&> SignalAudioMonitor;
-
-  int GetInputLevel_w();
-  int GetOutputLevel_w();
-  void GetActiveStreams_w(AudioInfo::StreamList* actives);
-
-  // Signal errors from VoiceMediaChannel.  Arguments are:
-  //     ssrc(uint32), and error(VoiceMediaChannel::Error).
-  sigslot::signal3<VoiceChannel*, uint32, VoiceMediaChannel::Error>
-      SignalMediaError;
-
-  static const int kTypingBlackoutPeriod = 1500;
-
- private:
-  struct SetRingbackToneMessageData : public talk_base::MessageData {
-    SetRingbackToneMessageData(const void* b, int l)
-        : buf(b),
-          len(l),
-          result(false) {
-    }
-    const void* buf;
-    int len;
-    bool result;
-  };
-  struct PlayRingbackToneMessageData : public talk_base::MessageData {
-    PlayRingbackToneMessageData(uint32 s, bool p, bool l)
-        : ssrc(s),
-          play(p),
-          loop(l),
-          result(false) {
-    }
-    uint32 ssrc;
-    bool play;
-    bool loop;
-    bool result;
-  };
-  struct DtmfMessageData : public talk_base::MessageData {
-    DtmfMessageData(int d, bool p)
-        : digit(d),
-          playout(p),
-          result(false) {
-    }
-    int digit;
-    bool playout;
-    bool result;
-  };
-  struct ScaleVolumeMessageData : public talk_base::MessageData {
-    ScaleVolumeMessageData(uint32 s, double l, double r)
-        : ssrc(s),
-          left(l),
-          right(r),
-          result(false) {
-    }
-    uint32 ssrc;
-    double left;
-    double right;
-    bool result;
-  };
-
-  // overrides from BaseChannel
-  virtual void OnChannelRead(TransportChannel* channel,
-                             const char *data, size_t len);
-  virtual void ChangeState();
-  virtual const MediaContentDescription* GetFirstContent(
-      const SessionDescription* sdesc);
-  virtual bool SetLocalContent_w(const MediaContentDescription* content,
-                                 ContentAction action);
-  virtual bool SetRemoteContent_w(const MediaContentDescription* content,
-                                  ContentAction action);
-
-  void AddStream_w(uint32 ssrc);
-  void RemoveStream_w(uint32 ssrc);
-
-  bool SetRingbackTone_w(const void* buf, int len);
-  bool PlayRingbackTone_w(uint32 ssrc, bool play, bool loop);
-  void HandleEarlyMediaTimeout();
-  bool PressDTMF_w(int digit, bool playout);
-  bool SetOutputScaling_w(uint32 ssrc, double left, double right);
-
-  virtual void OnMessage(talk_base::Message *pmsg);
-  virtual void OnConnectionMonitorUpdate(
-      SocketMonitor *monitor, const std::vector<ConnectionInfo> &infos);
-  virtual void OnMediaMonitorUpdate(
-      VoiceMediaChannel *media_channel, const VoiceMediaInfo& info);
-  void OnAudioMonitorUpdate(AudioMonitor *monitor, const AudioInfo& info);
-  void OnVoiceChannelError(uint32 ssrc, VoiceMediaChannel::Error error);
-  void SendLastMediaError();
-  void OnSrtpError(uint32 ssrc, SrtpFilter::Mode mode, SrtpFilter::Error error);
-
-  static const int kEarlyMediaTimeout = 1000;
-  bool received_media_;
-  talk_base::scoped_ptr<VoiceMediaMonitor> media_monitor_;
-  talk_base::scoped_ptr<AudioMonitor> audio_monitor_;
-  bool mute_on_type_;
-  int  mute_on_type_timeout_;
-};
-
-// VideoChannel is a specialization for video.
-class VideoChannel : public BaseChannel {
- public:
-  VideoChannel(talk_base::Thread *thread, MediaEngineInterface *media_engine,
-               VideoMediaChannel *channel, BaseSession *session,
-               const std::string& content_name, bool rtcp,
-               VoiceChannel *voice_channel);
-  ~VideoChannel();
-  bool Init();
-
-  // downcasts a MediaChannel
-  virtual VideoMediaChannel* media_channel() const {
-    return static_cast<VideoMediaChannel*>(BaseChannel::media_channel());
-  }
-
-  // Add an incoming stream with the specified SSRC.
-  bool AddStream(uint32 ssrc, uint32 voice_ssrc);
-
-  bool SetRenderer(uint32 ssrc, VideoRenderer* renderer);
-
-  bool AddScreencast(uint32 ssrc, talk_base::WindowId id);
-  bool RemoveScreencast(uint32 ssrc);
-
-  sigslot::signal2<VideoChannel*, const std::vector<ConnectionInfo> &>
-      SignalConnectionMonitor;
-
-  void StartMediaMonitor(int cms);
-  void StopMediaMonitor();
-  sigslot::signal2<VideoChannel*, const VideoMediaInfo&> SignalMediaMonitor;
-  sigslot::signal2<uint32, talk_base::WindowEvent> SignalScreencastWindowEvent;
-
-  bool SendIntraFrame();
-  bool RequestIntraFrame();
-  void EnableCpuAdaptation(bool enable);
-
-  sigslot::signal3<VideoChannel*, uint32, VideoMediaChannel::Error>
-      SignalMediaError;
-
- private:
-  // overrides from BaseChannel
-  virtual void ChangeState();
-  virtual const MediaContentDescription* GetFirstContent(
-      const SessionDescription* sdesc);
-  virtual bool SetLocalContent_w(const MediaContentDescription* content,
-                                 ContentAction action);
-  virtual bool SetRemoteContent_w(const MediaContentDescription* content,
-                                  ContentAction action);
-
-  void AddStream_w(uint32 ssrc, uint32 voice_ssrc);
-  void RemoveStream_w(uint32 ssrc);
-
-  void SendIntraFrame_w() {
-    media_channel()->SendIntraFrame();
-  }
-  void RequestIntraFrame_w() {
-    media_channel()->RequestIntraFrame();
-  }
-  void EnableCpuAdaptation_w(bool enable) {
-    // TODO: The following call will clear all other options, which is
-    // OK now since SetOptions is not used in video media channel. In the
-    // future, add GetOptions() method and change the options.
-    media_channel()->SetOptions(enable ? OPT_CPU_ADAPTATION : 0);
-  }
-
-  struct RenderMessageData : public talk_base::MessageData {
-    RenderMessageData(uint32 s, VideoRenderer* r) : ssrc(s), renderer(r) {}
-    uint32 ssrc;
-    VideoRenderer* renderer;
-  };
-
-  struct ScreencastMessageData : public talk_base::MessageData {
-    ScreencastMessageData(uint32 s, talk_base::WindowId id)
-        : ssrc(s), window_id(id) {}
-    uint32 ssrc;
-    talk_base::WindowId window_id;
-  };
-
-  struct ScreencastEventData : public talk_base::MessageData {
-    ScreencastEventData(uint32 s, talk_base::WindowEvent we)
-        : ssrc(s), event(we) {}
-    uint32 ssrc;
-    talk_base::WindowEvent event;
-  };
-
-  void SetRenderer_w(uint32 ssrc, VideoRenderer* renderer);
-
-  void AddScreencast_w(uint32 ssrc, talk_base::WindowId);
-  void RemoveScreencast_w(uint32 ssrc);
-  void OnScreencastWindowEvent_s(uint32 ssrc, talk_base::WindowEvent we);
-
-  virtual void OnMessage(talk_base::Message *pmsg);
-  virtual void OnConnectionMonitorUpdate(
-      SocketMonitor *monitor, const std::vector<ConnectionInfo> &infos);
-  virtual void OnMediaMonitorUpdate(
-      VideoMediaChannel *media_channel, const VideoMediaInfo& info);
-  virtual void OnScreencastWindowEvent(uint32 ssrc,
-                                       talk_base::WindowEvent event);
-  void OnVideoChannelError(uint32 ssrc, VideoMediaChannel::Error error);
-  void OnSrtpError(uint32 ssrc, SrtpFilter::Mode mode, SrtpFilter::Error error);
-
-
-  VoiceChannel *voice_channel_;
-  VideoRenderer *renderer_;
-  talk_base::scoped_ptr<VideoMediaMonitor> media_monitor_;
-};
-
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_CHANNEL_H_
diff --git a/third_party/libjingle/source/talk/session/phone/channel_unittest.cc b/third_party/libjingle/source/talk/session/phone/channel_unittest.cc
deleted file mode 100644
index 86d3b6d..0000000
--- a/third_party/libjingle/source/talk/session/phone/channel_unittest.cc
+++ /dev/null
@@ -1,1622 +0,0 @@
-// libjingle
-// Copyright 2009 Google Inc.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-//  1. Redistributions of source code must retain the above copyright notice,
-//     this list of conditions and the following disclaimer.
-//  2. Redistributions in binary form must reproduce the above copyright notice,
-//     this list of conditions and the following disclaimer in the documentation
-//     and/or other materials provided with the distribution.
-//  3. The name of the author may not be used to endorse or promote products
-//     derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include "talk/base/fileutils.h"
-#include "talk/base/gunit.h"
-#include "talk/base/helpers.h"
-#include "talk/base/logging.h"
-#include "talk/base/pathutils.h"
-#include "talk/base/signalthread.h"
-#include "talk/p2p/base/fakesession.h"
-#include "talk/session/phone/channel.h"
-#include "talk/session/phone/fakemediaengine.h"
-#include "talk/session/phone/fakertp.h"
-#include "talk/session/phone/mediasessionclient.h"
-#include "talk/session/phone/mediarecorder.h"
-#include "talk/session/phone/rtpdump.h"
-
-using cricket::CA_OFFER;
-using cricket::CA_ANSWER;
-using cricket::CA_UPDATE;
-
-static const cricket::AudioCodec kPcmuCodec(0, "PCMU", 64000, 8000, 1, 0);
-static const cricket::AudioCodec kPcmaCodec(8, "PCMA", 64000, 8000, 1, 0);
-static const cricket::AudioCodec kIsacCodec(103, "ISAC", 40000, 16000, 1, 0);
-static const cricket::VideoCodec kH264Codec(97, "H264", 640, 400, 30, 0);
-static const cricket::VideoCodec kH264SvcCodec(99, "H264-SVC", 320, 200, 15, 0);
-static const uint32 kSsrc1 = 0x1111;
-static const uint32 kSsrc2 = 0x2222;
-
-class VoiceTraits {
- public:
-  typedef cricket::VoiceChannel Channel;
-  typedef cricket::FakeVoiceMediaChannel MediaChannel;
-  typedef cricket::AudioContentDescription Content;
-  typedef cricket::AudioCodec Codec;
-  typedef cricket::VoiceMediaInfo MediaInfo;
-};
-
-class VideoTraits {
- public:
-  typedef cricket::VideoChannel Channel;
-  typedef cricket::FakeVideoMediaChannel MediaChannel;
-  typedef cricket::VideoContentDescription Content;
-  typedef cricket::VideoCodec Codec;
-  typedef cricket::VideoMediaInfo MediaInfo;
-};
-
-// Base class for Voice/VideoChannel tests
-template<class T>
-class ChannelTest : public testing::Test, public sigslot::has_slots<> {
- public:
-  enum Flags { RTCP = 0x1, RTCP_MUX = 0x2, SECURE = 0x4, SSRC_MUX = 0x8 };
-  ChannelTest(const uint8* rtp_data, int rtp_len,
-              const uint8* rtcp_data, int rtcp_len)
-      : media_channel1_(NULL),
-        media_channel2_(NULL),
-        rtp_packet_(reinterpret_cast<const char*>(rtp_data), rtp_len),
-        rtcp_packet_(reinterpret_cast<const char*>(rtcp_data), rtcp_len),
-        media_info_callbacks1_(),
-        media_info_callbacks2_(),
-        ssrc_(0),
-        error_(T::MediaChannel::ERROR_NONE) {
-  }
-
-  void CreateChannels(int flags1, int flags2) {
-    CreateChannels(new typename T::MediaChannel(NULL),
-                   new typename T::MediaChannel(NULL),
-                   flags1, flags2, talk_base::Thread::Current());
-  }
-  void CreateChannels(int flags) {
-     CreateChannels(new typename T::MediaChannel(NULL),
-                    new typename T::MediaChannel(NULL),
-                    flags, talk_base::Thread::Current());
-  }
-  void CreateChannels(int flags1, int flags2,
-                      talk_base::Thread* thread) {
-    CreateChannels(new typename T::MediaChannel(NULL),
-                   new typename T::MediaChannel(NULL),
-                   flags1, flags2, thread);
-  }
-  void CreateChannels(int flags,
-                      talk_base::Thread* thread) {
-    CreateChannels(new typename T::MediaChannel(NULL),
-                     new typename T::MediaChannel(NULL),
-                     flags, thread);
-  }
-  void CreateChannels(
-      typename T::MediaChannel* ch1, typename T::MediaChannel* ch2,
-      int flags1, int flags2, talk_base::Thread* thread) {
-    media_channel1_ = ch1;
-    media_channel2_ = ch2;
-    channel1_.reset(CreateChannel(thread, &media_engine_, ch1, &session1_,
-                                  (flags1 & RTCP) != 0));
-    channel2_.reset(CreateChannel(thread, &media_engine_, ch2, &session2_,
-                                  (flags2 & RTCP) != 0));
-    channel1_->SignalMediaMonitor.connect(
-        this, &ChannelTest<T>::OnMediaMonitor);
-    channel2_->SignalMediaMonitor.connect(
-        this, &ChannelTest<T>::OnMediaMonitor);
-    channel1_->SignalMediaError.connect(
-        this, &ChannelTest<T>::OnMediaChannelError);
-    channel2_->SignalMediaError.connect(
-        this, &ChannelTest<T>::OnMediaChannelError);
-    CreateContent(flags1, kPcmuCodec, kH264Codec, &media_content1_);
-    CreateContent(flags2, kPcmuCodec, kH264Codec, &media_content2_);
-    AddLegacyStreamInContent(kSsrc1, flags1, &media_content1_);
-    AddLegacyStreamInContent(kSsrc2, flags2, &media_content2_);
-  }
-
-  void CreateChannels(
-      typename T::MediaChannel* ch1, typename T::MediaChannel* ch2,
-      int flags, talk_base::Thread* thread) {
-    media_channel1_ = ch1;
-    media_channel2_ = ch2;
-    channel1_.reset(CreateChannel(thread, &media_engine_, ch1, &session1_,
-                                  (flags & RTCP) != 0));
-    channel2_.reset(CreateChannel(thread, &media_engine_, ch2, &session1_,
-                                  (flags & RTCP) != 0));
-    channel1_->SignalMediaMonitor.connect(
-        this, &ChannelTest<T>::OnMediaMonitor);
-    channel2_->SignalMediaMonitor.connect(
-        this, &ChannelTest<T>::OnMediaMonitor);
-    channel2_->SignalMediaError.connect(
-        this, &ChannelTest<T>::OnMediaChannelError);
-    CreateContent(flags, kPcmuCodec, kH264Codec, &media_content1_);
-    CreateContent(flags, kPcmuCodec, kH264Codec, &media_content2_);
-    AddLegacyStreamInContent(kSsrc1, flags, &media_content1_);
-    AddLegacyStreamInContent(kSsrc2, flags, &media_content2_);
-  }
-  typename T::Channel* CreateChannel(talk_base::Thread* thread,
-                                     cricket::MediaEngineInterface* engine,
-                                     typename T::MediaChannel* ch,
-                                     cricket::BaseSession* session,
-                                     bool rtcp) {
-    typename T::Channel* channel = new typename T::Channel(
-        thread, engine, ch, session, cricket::CN_AUDIO, rtcp);
-    if (!channel->Init()) {
-      delete channel;
-      channel = NULL;
-    }
-    return channel;
-  }
-
-  bool SendInitiate() {
-    bool result = channel1_->SetLocalContent(&media_content1_, CA_OFFER);
-    if (result) {
-      channel1_->Enable(true);
-      result = channel2_->SetRemoteContent(&media_content1_, CA_OFFER);
-      if (result) {
-        result = channel2_->SetLocalContent(&media_content2_, CA_ANSWER);
-        if (result) {
-          session1_.Connect(&session2_);
-        }
-      }
-    }
-    return result;
-  }
-  bool SendAccept() {
-    channel2_->Enable(true);
-    return channel1_->SetRemoteContent(&media_content2_, CA_ANSWER);
-  }
-  bool SendTerminate() {
-    channel1_.reset();
-    channel2_.reset();
-    return true;
-  }
-
-  bool AddStream1(int id) {
-    return channel1_->AddStream(id);
-  }
-  bool RemoveStream1(int id) {
-    return channel1_->RemoveStream(id);
-  }
-
-  cricket::FakeTransport* GetTransport1() {
-    return session1_.GetTransport(channel1_->content_name());
-  }
-  cricket::FakeTransport* GetTransport2() {
-    return session2_.GetTransport(channel2_->content_name());
-  }
-
-  bool SendRtp1() {
-    return media_channel1_->SendRtp(rtp_packet_.c_str(), rtp_packet_.size());
-  }
-  bool SendRtp2() {
-    return media_channel2_->SendRtp(rtp_packet_.c_str(), rtp_packet_.size());
-  }
-  bool SendRtcp1() {
-    return media_channel1_->SendRtcp(rtcp_packet_.c_str(), rtcp_packet_.size());
-  }
-  bool SendRtcp2() {
-    return media_channel2_->SendRtcp(rtcp_packet_.c_str(), rtcp_packet_.size());
-  }
-  // Methods to send custom data.
-  bool SendCustomRtp1(uint32 ssrc) {
-    std::string data(CreateRtpData(ssrc));
-    return media_channel1_->SendRtp(data.c_str(), data.size());
-  }
-  bool SendCustomRtp2(uint32 ssrc) {
-    std::string data(CreateRtpData(ssrc));
-    return media_channel2_->SendRtp(data.c_str(), data.size());
-  }
-  bool SendCustomRtcp1(uint32 ssrc) {
-    std::string data(CreateRtcpData(ssrc));
-    return media_channel1_->SendRtcp(data.c_str(), data.size());
-  }
-  bool SendCustomRtcp2(uint32 ssrc) {
-    std::string data(CreateRtcpData(ssrc));
-    return media_channel2_->SendRtcp(data.c_str(), data.size());
-  }
-  bool CheckRtp1() {
-    return media_channel1_->CheckRtp(rtp_packet_.c_str(), rtp_packet_.size());
-  }
-  bool CheckRtp2() {
-    return media_channel2_->CheckRtp(rtp_packet_.c_str(), rtp_packet_.size());
-  }
-  bool CheckRtcp1() {
-    return media_channel1_->CheckRtcp(rtcp_packet_.c_str(),
-                                      rtcp_packet_.size());
-  }
-  bool CheckRtcp2() {
-    return media_channel2_->CheckRtcp(rtcp_packet_.c_str(),
-                                      rtcp_packet_.size());
-  }
-  // Methods to check custom data.
-  bool CheckCustomRtp1(uint32 ssrc) {
-    std::string data(CreateRtpData(ssrc));
-    return media_channel1_->CheckRtp(data.c_str(), data.size());
-  }
-  bool CheckCustomRtp2(uint32 ssrc) {
-    std::string data(CreateRtpData(ssrc));
-    return media_channel2_->CheckRtp(data.c_str(), data.size());
-  }
-  bool CheckCustomRtcp1(uint32 ssrc) {
-    std::string data(CreateRtcpData(ssrc));
-    return media_channel1_->CheckRtcp(data.c_str(), data.size());
-  }
-  bool CheckCustomRtcp2(uint32 ssrc) {
-    std::string data(CreateRtcpData(ssrc));
-    return media_channel2_->CheckRtcp(data.c_str(), data.size());
-  }
-  std::string CreateRtpData(uint32 ssrc) {
-    std::string data(rtp_packet_);
-    // Set SSRC in the rtp packet copy.
-    talk_base::SetBE32(const_cast<char*>(data.c_str()) + 8, ssrc);
-    return data;
-  }
-  std::string CreateRtcpData(uint32 ssrc) {
-    std::string data(rtcp_packet_);
-    // Set SSRC in the rtcp packet copy.
-    talk_base::SetBE32(const_cast<char*>(data.c_str()) + 4, ssrc);
-    return data;
-  }
-
-  bool CheckNoRtp1() {
-    return media_channel1_->CheckNoRtp();
-  }
-  bool CheckNoRtp2() {
-    return media_channel2_->CheckNoRtp();
-  }
-  bool CheckNoRtcp1() {
-    return media_channel1_->CheckNoRtcp();
-  }
-  bool CheckNoRtcp2() {
-    return media_channel2_->CheckNoRtcp();
-  }
-
-  void CreateContent(int flags,
-                     const cricket::AudioCodec& audio_codec,
-                     const cricket::VideoCodec& video_codec,
-                     typename T::Content* content) {
-    // overridden in specialized classes
-  }
-
-  class CallThread : public talk_base::SignalThread {
-   public:
-    typedef bool (ChannelTest<T>::*Method)();
-    CallThread(ChannelTest<T>* obj, Method method, bool* result)
-        : obj_(obj),
-          method_(method),
-          result_(result) {
-      *result = false;
-    }
-    virtual void DoWork() {
-      bool result = (*obj_.*method_)();
-      if (result_) {
-        *result_ = result;
-      }
-    }
-   private:
-    ChannelTest<T>* obj_;
-    Method method_;
-    bool* result_;
-  };
-  void CallOnThread(typename CallThread::Method method, bool* result) {
-    CallThread* thread = new CallThread(this, method, result);
-    thread->Start();
-    thread->Release();
-  }
-
-  void CallOnThreadAndWaitForDone(typename CallThread::Method method,
-                                  bool* result) {
-    CallThread* thread = new CallThread(this, method, result);
-    thread->Start();
-    thread->Destroy(true);
-  }
-
-  bool CodecMatches(const typename T::Codec& c1, const typename T::Codec& c2) {
-    return false;  // overridden in specialized classes
-  }
-
-  void OnMediaMonitor(typename T::Channel* channel,
-                      const typename T::MediaInfo& info) {
-    if (channel == channel1_.get()) {
-      media_info_callbacks1_++;
-    } else if (channel == channel2_.get()) {
-      media_info_callbacks2_++;
-    }
-  }
-
-  void OnMediaChannelError(typename T::Channel* channel,
-                           uint32 ssrc,
-                           typename T::MediaChannel::Error error) {
-    ssrc_ = ssrc;
-    error_ = error;
-  }
-
-  void AddLegacyStreamInContent(uint32 ssrc, int flags,
-                        typename T::Content* content) {
-    // Base implementation.
-  }
-
-  // Tests that can be used by derived classes.
-
-  // Basic sanity check.
-  void TestInit() {
-    CreateChannels(0, 0);
-    EXPECT_FALSE(channel1_->secure());
-    EXPECT_FALSE(media_channel1_->sending());
-    EXPECT_FALSE(media_channel1_->playout());
-    EXPECT_TRUE(media_channel1_->codecs().empty());
-    EXPECT_TRUE(media_channel1_->streams().empty());
-    EXPECT_TRUE(media_channel1_->rtp_packets().empty());
-    EXPECT_TRUE(media_channel1_->rtcp_packets().empty());
-  }
-
-  // Test that SetRtcpCName sets the RTCP CNAME successfully.
-  void TestSetRtcpCName() {
-    static const char* kTestCName = "a@b.com";
-    CreateChannels(0, 0);
-    EXPECT_TRUE(channel1_->SetRtcpCName(kTestCName));
-    EXPECT_EQ(kTestCName, media_channel1_->rtcp_cname());
-    EXPECT_TRUE(channel2_->SetRtcpCName(kTestCName));
-    EXPECT_EQ(kTestCName, media_channel2_->rtcp_cname());
-  }
-
-  // Test that SetLocalContent and SetRemoteContent properly configure
-  // the codecs.
-  void TestSetContents() {
-    CreateChannels(0, 0);
-    typename T::Content content;
-    CreateContent(0, kPcmuCodec, kH264Codec, &content);
-    EXPECT_TRUE(channel1_->SetLocalContent(&content, CA_OFFER));
-    EXPECT_EQ(0U, media_channel1_->codecs().size());
-    EXPECT_TRUE(channel1_->SetRemoteContent(&content, CA_ANSWER));
-    ASSERT_EQ(1U, media_channel1_->codecs().size());
-    EXPECT_TRUE(CodecMatches(content.codecs()[0],
-                             media_channel1_->codecs()[0]));
-  }
-
-  // Test that SetLocalContent and SetRemoteContent properly deals
-  // with an empty offer.
-  void TestSetContentsNullOffer() {
-    CreateChannels(0, 0);
-    typename T::Content content;
-    EXPECT_TRUE(channel1_->SetLocalContent(&content, CA_OFFER));
-    CreateContent(0, kPcmuCodec, kH264Codec, &content);
-    EXPECT_EQ(0U, media_channel1_->codecs().size());
-    EXPECT_TRUE(channel1_->SetRemoteContent(&content, CA_ANSWER));
-    ASSERT_EQ(1U, media_channel1_->codecs().size());
-    EXPECT_TRUE(CodecMatches(content.codecs()[0],
-                             media_channel1_->codecs()[0]));
-  }
-
-  // Test that SetLocalContent and SetRemoteContent properly set RTCP
-  // mux.
-  void TestSetContentsRtcpMux() {
-    CreateChannels(RTCP, RTCP);
-    EXPECT_TRUE(channel1_->rtcp_transport_channel() != NULL);
-    EXPECT_TRUE(channel2_->rtcp_transport_channel() != NULL);
-    typename T::Content content;
-    CreateContent(0, kPcmuCodec, kH264Codec, &content);
-    // Both sides agree on mux. Should no longer be a separate RTCP channel.
-    content.set_rtcp_mux(true);
-    EXPECT_TRUE(channel1_->SetLocalContent(&content, CA_OFFER));
-    EXPECT_TRUE(channel1_->SetRemoteContent(&content, CA_ANSWER));
-    EXPECT_TRUE(channel1_->rtcp_transport_channel() == NULL);
-    // Only initiator supports mux. Should still have a separate RTCP channel.
-    EXPECT_TRUE(channel2_->SetLocalContent(&content, CA_OFFER));
-    content.set_rtcp_mux(false);
-    EXPECT_TRUE(channel2_->SetRemoteContent(&content, CA_ANSWER));
-    EXPECT_TRUE(channel2_->rtcp_transport_channel() != NULL);
-  }
-
-  // Test that SetRemoteContent properly deals with a content update.
-  void TestSetRemoteContentUpdate() {
-    CreateChannels(0, 0);
-    typename T::Content content;
-    CreateContent(RTCP | RTCP_MUX | SECURE, kPcmuCodec, kH264Codec, &content);
-    EXPECT_EQ(0U, media_channel1_->codecs().size());
-    EXPECT_TRUE(channel1_->SetLocalContent(&content, CA_OFFER));
-    EXPECT_TRUE(channel1_->SetRemoteContent(&content, CA_ANSWER));
-    ASSERT_EQ(1U, media_channel1_->codecs().size());
-    EXPECT_TRUE(CodecMatches(content.codecs()[0],
-                             media_channel1_->codecs()[0]));
-    // Now update with other codecs.
-    typename T::Content update_content;
-    CreateContent(0, kIsacCodec, kH264SvcCodec, &update_content);
-    EXPECT_TRUE(channel1_->SetRemoteContent(&update_content, CA_UPDATE));
-    ASSERT_EQ(1U, media_channel1_->codecs().size());
-    EXPECT_TRUE(CodecMatches(update_content.codecs()[0],
-                             media_channel1_->codecs()[0]));
-
-    // Now update without any codec.
-    typename T::Content empty_content;
-    EXPECT_TRUE(channel1_->SetRemoteContent(&empty_content, CA_UPDATE));
-    ASSERT_EQ(0U, media_channel1_->codecs().size());
-  }
-
-  // Test that Add/RemoveStream properly forward to the media channel.
-  void TestStreams() {
-    CreateChannels(0, 0);
-    EXPECT_TRUE(AddStream1(1));
-    EXPECT_TRUE(AddStream1(2));
-    EXPECT_EQ(2U, media_channel1_->streams().size());
-    EXPECT_TRUE(RemoveStream1(2));
-    EXPECT_EQ(1U, media_channel1_->streams().size());
-    EXPECT_TRUE(RemoveStream1(1));
-    EXPECT_EQ(0U, media_channel1_->streams().size());
-  }
-
-  // Test that we only start playout and sending at the right times.
-  void TestPlayoutAndSendingStates() {
-    CreateChannels(0, 0);
-    EXPECT_FALSE(media_channel1_->playout());
-    EXPECT_FALSE(media_channel1_->sending());
-    EXPECT_FALSE(media_channel2_->playout());
-    EXPECT_FALSE(media_channel2_->sending());
-    EXPECT_TRUE(channel1_->Enable(true));
-    EXPECT_FALSE(media_channel1_->playout());
-    EXPECT_FALSE(media_channel1_->sending());
-    EXPECT_TRUE(channel1_->SetLocalContent(&media_content1_, CA_OFFER));
-    EXPECT_TRUE(media_channel1_->playout());
-    EXPECT_FALSE(media_channel1_->sending());
-    EXPECT_TRUE(channel2_->SetRemoteContent(&media_content1_, CA_OFFER));
-    EXPECT_FALSE(media_channel2_->playout());
-    EXPECT_FALSE(media_channel2_->sending());
-    EXPECT_TRUE(channel2_->SetLocalContent(&media_content2_, CA_ANSWER));
-    EXPECT_FALSE(media_channel2_->playout());
-    EXPECT_FALSE(media_channel2_->sending());
-    session1_.Connect(&session2_);
-    EXPECT_TRUE(media_channel1_->playout());
-    EXPECT_FALSE(media_channel1_->sending());
-    EXPECT_FALSE(media_channel2_->playout());
-    EXPECT_FALSE(media_channel2_->sending());
-    EXPECT_TRUE(channel2_->Enable(true));
-    EXPECT_TRUE(media_channel2_->playout());
-    EXPECT_TRUE(media_channel2_->sending());
-    EXPECT_TRUE(channel1_->SetRemoteContent(&media_content2_, CA_ANSWER));
-    EXPECT_TRUE(media_channel1_->playout());
-    EXPECT_TRUE(media_channel1_->sending());
-  }
-
-  // Test setting up a call.
-  void TestCallSetup() {
-    CreateChannels(0, 0);
-    EXPECT_FALSE(channel1_->secure());
-    EXPECT_TRUE(SendInitiate());
-    EXPECT_TRUE(media_channel1_->playout());
-    EXPECT_FALSE(media_channel1_->sending());
-    EXPECT_TRUE(SendAccept());
-    EXPECT_FALSE(channel1_->secure());
-    EXPECT_TRUE(media_channel1_->sending());
-    EXPECT_EQ(1U, media_channel1_->codecs().size());
-    EXPECT_TRUE(media_channel2_->playout());
-    EXPECT_TRUE(media_channel2_->sending());
-    EXPECT_EQ(1U, media_channel2_->codecs().size());
-  }
-
-  // Test that we don't crash if packets are sent during call teardown
-  // when RTCP mux is enabled. This is a regression test against a specific
-  // race condition that would only occur when a RTCP packet was sent during
-  // teardown of a channel on which RTCP mux was enabled.
-  void TestCallTeardownRtcpMux() {
-    class LastWordMediaChannel : public T::MediaChannel {
-     public:
-      LastWordMediaChannel() : T::MediaChannel(NULL) {}
-      ~LastWordMediaChannel() {
-        T::MediaChannel::SendRtp(kPcmuFrame, sizeof(kPcmuFrame));
-        T::MediaChannel::SendRtcp(kRtcpReport, sizeof(kRtcpReport));
-      }
-    };
-    CreateChannels(new LastWordMediaChannel(), new LastWordMediaChannel(),
-                   RTCP | RTCP_MUX, RTCP | RTCP_MUX,
-                   talk_base::Thread::Current());
-    EXPECT_TRUE(SendInitiate());
-    EXPECT_TRUE(SendAccept());
-    EXPECT_TRUE(SendTerminate());
-  }
-
-  // Send voice RTP data to the other side and ensure it gets there.
-  void SendRtpToRtp() {
-    CreateChannels(0, 0);
-    EXPECT_TRUE(SendInitiate());
-    EXPECT_TRUE(SendAccept());
-    EXPECT_EQ(1U, GetTransport1()->channels().size());
-    EXPECT_EQ(1U, GetTransport2()->channels().size());
-    EXPECT_TRUE(SendRtp1());
-    EXPECT_TRUE(SendRtp2());
-    EXPECT_TRUE(CheckRtp1());
-    EXPECT_TRUE(CheckRtp2());
-    EXPECT_TRUE(CheckNoRtp1());
-    EXPECT_TRUE(CheckNoRtp2());
-  }
-
-  // Check that RTCP is not transmitted if both sides don't support RTCP.
-  void SendNoRtcpToNoRtcp() {
-    CreateChannels(0, 0);
-    EXPECT_TRUE(SendInitiate());
-    EXPECT_TRUE(SendAccept());
-    EXPECT_EQ(1U, GetTransport1()->channels().size());
-    EXPECT_EQ(1U, GetTransport2()->channels().size());
-    EXPECT_FALSE(SendRtcp1());
-    EXPECT_FALSE(SendRtcp2());
-    EXPECT_TRUE(CheckNoRtcp1());
-    EXPECT_TRUE(CheckNoRtcp2());
-  }
-
-  // Check that RTCP is not transmitted if the callee doesn't support RTCP.
-  void SendNoRtcpToRtcp() {
-    CreateChannels(0, RTCP);
-    EXPECT_TRUE(SendInitiate());
-    EXPECT_TRUE(SendAccept());
-    EXPECT_EQ(1U, GetTransport1()->channels().size());
-    EXPECT_EQ(2U, GetTransport2()->channels().size());
-    EXPECT_FALSE(SendRtcp1());
-    EXPECT_FALSE(SendRtcp2());
-    EXPECT_TRUE(CheckNoRtcp1());
-    EXPECT_TRUE(CheckNoRtcp2());
-  }
-
-  // Check that RTCP is not transmitted if the caller doesn't support RTCP.
-  void SendRtcpToNoRtcp() {
-    CreateChannels(RTCP, 0);
-    EXPECT_TRUE(SendInitiate());
-    EXPECT_TRUE(SendAccept());
-    EXPECT_EQ(2U, GetTransport1()->channels().size());
-    EXPECT_EQ(1U, GetTransport2()->channels().size());
-    EXPECT_FALSE(SendRtcp1());
-    EXPECT_FALSE(SendRtcp2());
-    EXPECT_TRUE(CheckNoRtcp1());
-    EXPECT_TRUE(CheckNoRtcp2());
-  }
-
-  // Check that RTCP is transmitted if both sides support RTCP.
-  void SendRtcpToRtcp() {
-    CreateChannels(RTCP, RTCP);
-    EXPECT_TRUE(SendInitiate());
-    EXPECT_TRUE(SendAccept());
-    EXPECT_EQ(2U, GetTransport1()->channels().size());
-    EXPECT_EQ(2U, GetTransport2()->channels().size());
-    EXPECT_TRUE(SendRtcp1());
-    EXPECT_TRUE(SendRtcp2());
-    EXPECT_TRUE(CheckRtcp1());
-    EXPECT_TRUE(CheckRtcp2());
-    EXPECT_TRUE(CheckNoRtcp1());
-    EXPECT_TRUE(CheckNoRtcp2());
-  }
-
-  // Check that RTCP is transmitted if only the initiator supports mux.
-  void SendRtcpMuxToRtcp() {
-    CreateChannels(RTCP | RTCP_MUX, RTCP);
-    EXPECT_TRUE(SendInitiate());
-    EXPECT_TRUE(SendAccept());
-    EXPECT_EQ(2U, GetTransport1()->channels().size());
-    EXPECT_EQ(2U, GetTransport2()->channels().size());
-    EXPECT_TRUE(SendRtcp1());
-    EXPECT_TRUE(SendRtcp2());
-    EXPECT_TRUE(CheckRtcp1());
-    EXPECT_TRUE(CheckRtcp2());
-    EXPECT_TRUE(CheckNoRtcp1());
-    EXPECT_TRUE(CheckNoRtcp2());
-  }
-
-  // Check that RTP and RTCP are transmitted ok when both sides support mux.
-  void SendRtcpMuxToRtcpMux() {
-    CreateChannels(RTCP | RTCP_MUX, RTCP | RTCP_MUX);
-    EXPECT_TRUE(SendInitiate());
-    EXPECT_EQ(2U, GetTransport1()->channels().size());
-    EXPECT_EQ(1U, GetTransport2()->channels().size());
-    EXPECT_TRUE(SendAccept());
-    EXPECT_EQ(1U, GetTransport1()->channels().size());
-    EXPECT_TRUE(SendRtp1());
-    EXPECT_TRUE(SendRtp2());
-    EXPECT_TRUE(SendRtcp1());
-    EXPECT_TRUE(SendRtcp2());
-    EXPECT_TRUE(CheckRtp1());
-    EXPECT_TRUE(CheckRtp2());
-    EXPECT_TRUE(CheckNoRtp1());
-    EXPECT_TRUE(CheckNoRtp2());
-    EXPECT_TRUE(CheckRtcp1());
-    EXPECT_TRUE(CheckRtcp2());
-    EXPECT_TRUE(CheckNoRtcp1());
-    EXPECT_TRUE(CheckNoRtcp2());
-  }
-
-  // Check that RTCP data sent by the initiator before the accept is not muxed.
-  void SendEarlyRtcpMuxToRtcp() {
-    CreateChannels(RTCP | RTCP_MUX, RTCP);
-    EXPECT_TRUE(SendInitiate());
-    EXPECT_EQ(2U, GetTransport1()->channels().size());
-    EXPECT_EQ(2U, GetTransport2()->channels().size());
-
-    // RTCP can be sent before the call is accepted, if the transport is ready.
-    // It should not be muxed though, as the remote side doesn't support mux.
-    EXPECT_TRUE(SendRtcp1());
-    EXPECT_TRUE(CheckNoRtp2());
-    EXPECT_TRUE(CheckRtcp2());
-
-    // Send RTCP packet from callee and verify that it is received.
-    EXPECT_TRUE(SendRtcp2());
-    EXPECT_TRUE(CheckNoRtp1());
-    EXPECT_TRUE(CheckRtcp1());
-
-    // Complete call setup and ensure everything is still OK.
-    EXPECT_TRUE(SendAccept());
-    EXPECT_EQ(2U, GetTransport1()->channels().size());
-    EXPECT_TRUE(SendRtcp1());
-    EXPECT_TRUE(CheckRtcp2());
-    EXPECT_TRUE(SendRtcp2());
-    EXPECT_TRUE(CheckRtcp1());
-  }
-
-
-  // Check that RTCP data is not muxed until both sides have enabled muxing,
-  // but that we properly demux before we get the accept message, since there
-  // is a race between RTP data and the jingle accept.
-  void SendEarlyRtcpMuxToRtcpMux() {
-    CreateChannels(RTCP | RTCP_MUX, RTCP | RTCP_MUX);
-    EXPECT_TRUE(SendInitiate());
-    EXPECT_EQ(2U, GetTransport1()->channels().size());
-    EXPECT_EQ(1U, GetTransport2()->channels().size());
-
-    // RTCP can't be sent yet, since the RTCP transport isn't writable, and
-    // we haven't yet received the accept that says we should mux.
-    EXPECT_FALSE(SendRtcp1());
-
-    // Send muxed RTCP packet from callee and verify that it is received.
-    EXPECT_TRUE(SendRtcp2());
-    EXPECT_TRUE(CheckNoRtp1());
-    EXPECT_TRUE(CheckRtcp1());
-
-    // Complete call setup and ensure everything is still OK.
-    EXPECT_TRUE(SendAccept());
-    EXPECT_EQ(1U, GetTransport1()->channels().size());
-    EXPECT_TRUE(SendRtcp1());
-    EXPECT_TRUE(CheckRtcp2());
-    EXPECT_TRUE(SendRtcp2());
-    EXPECT_TRUE(CheckRtcp1());
-  }
-
-  // Test that we properly send SRTP with RTCP in both directions.
-  void SendSrtpToSrtp() {
-    CreateChannels(RTCP | SECURE, RTCP | SECURE);
-    EXPECT_FALSE(channel1_->secure());
-    EXPECT_FALSE(channel2_->secure());
-    EXPECT_TRUE(SendInitiate());
-    EXPECT_TRUE(SendAccept());
-    EXPECT_TRUE(channel1_->secure());
-    EXPECT_TRUE(channel2_->secure());
-    EXPECT_TRUE(SendRtp1());
-    EXPECT_TRUE(SendRtp2());
-    EXPECT_TRUE(SendRtcp1());
-    EXPECT_TRUE(SendRtcp2());
-    EXPECT_TRUE(CheckRtp1());
-    EXPECT_TRUE(CheckRtp2());
-    EXPECT_TRUE(CheckNoRtp1());
-    EXPECT_TRUE(CheckNoRtp2());
-    EXPECT_TRUE(CheckRtcp1());
-    EXPECT_TRUE(CheckRtcp2());
-    EXPECT_TRUE(CheckNoRtcp1());
-    EXPECT_TRUE(CheckNoRtcp2());
-  }
-
-  // Test that we properly handling SRTP negotiating down to RTP.
-  void SendSrtpToRtp() {
-    CreateChannels(RTCP | SECURE, RTCP);
-    EXPECT_FALSE(channel1_->secure());
-    EXPECT_FALSE(channel2_->secure());
-    EXPECT_TRUE(SendInitiate());
-    EXPECT_TRUE(SendAccept());
-    EXPECT_FALSE(channel1_->secure());
-    EXPECT_FALSE(channel2_->secure());
-    EXPECT_TRUE(SendRtp1());
-    EXPECT_TRUE(SendRtp2());
-    EXPECT_TRUE(SendRtcp1());
-    EXPECT_TRUE(SendRtcp2());
-    EXPECT_TRUE(CheckRtp1());
-    EXPECT_TRUE(CheckRtp2());
-    EXPECT_TRUE(CheckNoRtp1());
-    EXPECT_TRUE(CheckNoRtp2());
-    EXPECT_TRUE(CheckRtcp1());
-    EXPECT_TRUE(CheckRtcp2());
-    EXPECT_TRUE(CheckNoRtcp1());
-    EXPECT_TRUE(CheckNoRtcp2());
-  }
-
-  // Test that we properly send SRTP with RTCP mux in both directions.
-  void SendSrtcpMux() {
-    CreateChannels(RTCP | RTCP_MUX  | SECURE, RTCP | RTCP_MUX | SECURE);
-    EXPECT_TRUE(SendInitiate());
-    EXPECT_TRUE(SendAccept());
-    EXPECT_TRUE(SendRtp1());
-    EXPECT_TRUE(SendRtp2());
-    EXPECT_TRUE(SendRtcp1());
-    EXPECT_TRUE(SendRtcp2());
-    EXPECT_TRUE(CheckRtp1());
-    EXPECT_TRUE(CheckRtp2());
-    EXPECT_TRUE(CheckNoRtp1());
-    EXPECT_TRUE(CheckNoRtp2());
-    EXPECT_TRUE(CheckRtcp1());
-    EXPECT_TRUE(CheckRtcp2());
-    EXPECT_TRUE(CheckNoRtcp1());
-    EXPECT_TRUE(CheckNoRtcp2());
-  }
-
-  // Test that we properly send RTP without SRTP from a thread.
-  void SendRtpToRtpOnThread() {
-    bool sent_rtp1, sent_rtp2, sent_rtcp1, sent_rtcp2;
-    CreateChannels(RTCP, RTCP);
-    EXPECT_TRUE(SendInitiate());
-    EXPECT_TRUE(SendAccept());
-    CallOnThread(&ChannelTest<T>::SendRtp1, &sent_rtp1);
-    CallOnThread(&ChannelTest<T>::SendRtp2, &sent_rtp2);
-    CallOnThread(&ChannelTest<T>::SendRtcp1, &sent_rtcp1);
-    CallOnThread(&ChannelTest<T>::SendRtcp2, &sent_rtcp2);
-    EXPECT_TRUE_WAIT(CheckRtp1(), 1000);
-    EXPECT_TRUE_WAIT(CheckRtp2(), 1000);
-    EXPECT_TRUE_WAIT(sent_rtp1, 1000);
-    EXPECT_TRUE_WAIT(sent_rtp2, 1000);
-    EXPECT_TRUE(CheckNoRtp1());
-    EXPECT_TRUE(CheckNoRtp2());
-    EXPECT_TRUE_WAIT(CheckRtcp1(), 1000);
-    EXPECT_TRUE_WAIT(CheckRtcp2(), 1000);
-    EXPECT_TRUE_WAIT(sent_rtcp1, 1000);
-    EXPECT_TRUE_WAIT(sent_rtcp2, 1000);
-    EXPECT_TRUE(CheckNoRtcp1());
-    EXPECT_TRUE(CheckNoRtcp2());
-  }
-
-  // Test that we properly send SRTP with RTCP from a thread.
-  void SendSrtpToSrtpOnThread() {
-    bool sent_rtp1, sent_rtp2, sent_rtcp1, sent_rtcp2;
-    CreateChannels(RTCP | SECURE, RTCP | SECURE);
-    EXPECT_TRUE(SendInitiate());
-    EXPECT_TRUE(SendAccept());
-    CallOnThread(&ChannelTest<T>::SendRtp1, &sent_rtp1);
-    CallOnThread(&ChannelTest<T>::SendRtp2, &sent_rtp2);
-    CallOnThread(&ChannelTest<T>::SendRtcp1, &sent_rtcp1);
-    CallOnThread(&ChannelTest<T>::SendRtcp2, &sent_rtcp2);
-    EXPECT_TRUE_WAIT(CheckRtp1(), 1000);
-    EXPECT_TRUE_WAIT(CheckRtp2(), 1000);
-    EXPECT_TRUE_WAIT(sent_rtp1, 1000);
-    EXPECT_TRUE_WAIT(sent_rtp2, 1000);
-    EXPECT_TRUE(CheckNoRtp1());
-    EXPECT_TRUE(CheckNoRtp2());
-    EXPECT_TRUE_WAIT(CheckRtcp1(), 1000);
-    EXPECT_TRUE_WAIT(CheckRtcp2(), 1000);
-    EXPECT_TRUE_WAIT(sent_rtcp1, 1000);
-    EXPECT_TRUE_WAIT(sent_rtcp2, 1000);
-    EXPECT_TRUE(CheckNoRtcp1());
-    EXPECT_TRUE(CheckNoRtcp2());
-  }
-
-  // Test that the mediachannel retains its sending state after the transport
-  // becomes non-writable.
-  void SendWithWritabilityLoss() {
-    CreateChannels(0, 0);
-    EXPECT_TRUE(SendInitiate());
-    EXPECT_TRUE(SendAccept());
-    EXPECT_EQ(1U, GetTransport1()->channels().size());
-    EXPECT_EQ(1U, GetTransport2()->channels().size());
-    EXPECT_TRUE(SendRtp1());
-    EXPECT_TRUE(SendRtp2());
-    EXPECT_TRUE(CheckRtp1());
-    EXPECT_TRUE(CheckRtp2());
-    EXPECT_TRUE(CheckNoRtp1());
-    EXPECT_TRUE(CheckNoRtp2());
-
-    GetTransport1()->SetDestination(NULL);
-    EXPECT_TRUE(media_channel1_->sending());
-    EXPECT_FALSE(SendRtp1());
-    EXPECT_TRUE(SendRtp2());
-    EXPECT_TRUE(CheckRtp1());
-    EXPECT_TRUE(CheckNoRtp2());
-
-    GetTransport1()->SetDestination(GetTransport2());
-    EXPECT_TRUE(media_channel1_->sending());
-    EXPECT_TRUE(SendRtp1());
-    EXPECT_TRUE(SendRtp2());
-    EXPECT_TRUE(CheckRtp1());
-    EXPECT_TRUE(CheckRtp2());
-    EXPECT_TRUE(CheckNoRtp1());
-    EXPECT_TRUE(CheckNoRtp2());
-  }
-
-  void SendSsrcMuxToSsrcMuxWithRtcpMux() {
-    CreateChannels(SSRC_MUX | RTCP | RTCP_MUX, SSRC_MUX | RTCP | RTCP_MUX);
-    EXPECT_TRUE(SendInitiate());
-    EXPECT_EQ(2U, GetTransport1()->channels().size());
-    EXPECT_EQ(1U, GetTransport2()->channels().size());
-    EXPECT_TRUE(SendAccept());
-    EXPECT_EQ(1U, GetTransport1()->channels().size());
-    EXPECT_EQ(1U, GetTransport2()->channels().size());
-    EXPECT_TRUE(channel1_->ssrc_filter()->IsActive());
-    // channel1 - should have media_content2 as remote. i.e. kSsrc2
-    EXPECT_TRUE(channel1_->ssrc_filter()->FindStream(kSsrc2));
-    EXPECT_TRUE(channel2_->ssrc_filter()->IsActive());
-    // channel2 - should have media_content1 as remote. i.e. kSsrc1
-    EXPECT_TRUE(channel2_->ssrc_filter()->FindStream(kSsrc1));
-    EXPECT_TRUE(SendCustomRtp1(kSsrc1));
-    EXPECT_TRUE(SendCustomRtp2(kSsrc2));
-    EXPECT_TRUE(SendCustomRtcp1(kSsrc1));
-    EXPECT_TRUE(SendCustomRtcp2(kSsrc2));
-    EXPECT_TRUE(CheckCustomRtp1(kSsrc2));
-    EXPECT_TRUE(CheckNoRtp1());
-    EXPECT_TRUE(CheckCustomRtp2(kSsrc1));
-    EXPECT_TRUE(CheckNoRtp2());
-    EXPECT_TRUE(CheckCustomRtcp1(kSsrc2));
-    EXPECT_TRUE(CheckNoRtcp1());
-    EXPECT_TRUE(CheckCustomRtcp2(kSsrc1));
-    EXPECT_TRUE(CheckNoRtcp2());
-  }
-
-  void SendSsrcMuxToSsrcMux() {
-    CreateChannels(SSRC_MUX | RTCP, SSRC_MUX | RTCP);
-    EXPECT_TRUE(SendInitiate());
-    EXPECT_EQ(2U, GetTransport1()->channels().size());
-    EXPECT_EQ(2U, GetTransport2()->channels().size());
-    EXPECT_TRUE(SendAccept());
-    EXPECT_EQ(2U, GetTransport1()->channels().size());
-    EXPECT_EQ(2U, GetTransport2()->channels().size());
-    EXPECT_TRUE(channel1_->ssrc_filter()->IsActive());
-    // channel1 - should have media_content2 as remote. i.e. kSsrc2
-    EXPECT_TRUE(channel1_->ssrc_filter()->FindStream(kSsrc2));
-    EXPECT_TRUE(channel2_->ssrc_filter()->IsActive());
-    // channel2 - should have media_content1 as remote. i.e. kSsrc1
-    EXPECT_TRUE(SendCustomRtp1(kSsrc1));
-    EXPECT_TRUE(SendCustomRtp2(kSsrc2));
-    EXPECT_TRUE(SendCustomRtcp1(kSsrc1));
-    EXPECT_TRUE(SendCustomRtcp2(kSsrc2));
-    EXPECT_TRUE(CheckCustomRtp1(kSsrc2));
-    EXPECT_FALSE(CheckCustomRtp1(kSsrc1));
-    EXPECT_TRUE(CheckCustomRtp2(kSsrc1));
-    EXPECT_FALSE(CheckCustomRtp2(kSsrc2));
-    EXPECT_TRUE(CheckCustomRtcp1(kSsrc2));
-    EXPECT_FALSE(CheckCustomRtcp1(kSsrc1));
-    EXPECT_TRUE(CheckCustomRtcp2(kSsrc1));
-    EXPECT_FALSE(CheckCustomRtcp2(kSsrc2));
-  }
-
-  // Test that the media monitor can be run and gives timely callbacks.
-  void TestMediaMonitor() {
-    static const int kTimeout = 500;
-    CreateChannels(0, 0);
-    EXPECT_TRUE(SendInitiate());
-    EXPECT_TRUE(SendAccept());
-    channel1_->StartMediaMonitor(100);
-    channel2_->StartMediaMonitor(100);
-    // Ensure we get callbacks and stop.
-    EXPECT_TRUE_WAIT(media_info_callbacks1_ > 0, kTimeout);
-    EXPECT_TRUE_WAIT(media_info_callbacks2_ > 0, kTimeout);
-    channel1_->StopMediaMonitor();
-    channel2_->StopMediaMonitor();
-    // Ensure a restart of a stopped monitor works.
-    channel1_->StartMediaMonitor(100);
-    EXPECT_TRUE_WAIT(media_info_callbacks1_ > 0, kTimeout);
-    channel1_->StopMediaMonitor();
-    // Ensure stopping a stopped monitor is OK.
-    channel1_->StopMediaMonitor();
-  }
-
-  void TestMediaSinks() {
-    CreateChannels(0, 0);
-    EXPECT_TRUE(SendInitiate());
-    EXPECT_TRUE(SendAccept());
-    EXPECT_FALSE(channel1_->HasSendSinks());
-    EXPECT_FALSE(channel1_->HasRecvSinks());
-
-    talk_base::Pathname path;
-    EXPECT_TRUE(talk_base::Filesystem::GetTemporaryFolder(path, true, NULL));
-    path.SetFilename("sink-test.rtpdump");
-    talk_base::scoped_ptr<cricket::RtpDumpSink> sink(
-        new cricket::RtpDumpSink(path.pathname()));
-    sink->set_packet_filter(cricket::PF_ALL);
-    EXPECT_TRUE(sink->Enable(true));
-    channel1_->RegisterSendSink(sink.get(), &cricket::RtpDumpSink::OnPacket);
-    EXPECT_TRUE(channel1_->HasSendSinks());
-    EXPECT_FALSE(channel1_->HasRecvSinks());
-    // The first packet is recorded with header + data.
-    EXPECT_TRUE(SendRtp1());
-    // The second packet is recorded with header only.
-    sink->set_packet_filter(cricket::PF_RTPHEADER);
-    EXPECT_TRUE(SendRtp1());
-    // The third packet is not recorded since sink is disabled.
-    EXPECT_TRUE(sink->Enable(false));
-    EXPECT_TRUE(SendRtp1());
-     // The fourth packet is not recorded since sink is unregistered.
-    EXPECT_TRUE(sink->Enable(true));
-    channel1_->UnregisterSendSink(sink.get());
-    EXPECT_TRUE(SendRtp1());
-    sink.reset();  // This will close the file.
-
-    // Read the recorded file and verify two packets.
-    talk_base::scoped_ptr<talk_base::StreamInterface> stream(
-        talk_base::Filesystem::OpenFile(path, "rb"));
-
-    cricket::RtpDumpReader reader(stream.get());
-    cricket::RtpDumpPacket packet;
-    EXPECT_EQ(talk_base::SR_SUCCESS, reader.ReadPacket(&packet));
-    std::string read_packet(reinterpret_cast<const char*>(&packet.data[0]),
-        packet.data.size());
-    EXPECT_EQ(rtp_packet_, read_packet);
-
-    EXPECT_EQ(talk_base::SR_SUCCESS, reader.ReadPacket(&packet));
-    size_t len = 0;
-    packet.GetRtpHeaderLen(&len);
-    EXPECT_EQ(len, packet.data.size());
-    EXPECT_EQ(0, memcmp(&packet.data[0], rtp_packet_.c_str(), len));
-
-    EXPECT_EQ(talk_base::SR_EOS, reader.ReadPacket(&packet));
-
-    // Delete the file for media recording.
-    stream.reset();
-    EXPECT_TRUE(talk_base::Filesystem::DeleteFile(path));
-  }
-
-  void TestSetContentFailure() {
-    CreateChannels(0, 0);
-    typename T::Content content;
-    cricket::SessionDescription* sdesc_loc = new cricket::SessionDescription();
-    cricket::SessionDescription* sdesc_rem = new cricket::SessionDescription();
-
-    // Set up the session description.
-    CreateContent(0, kPcmuCodec, kH264Codec, &content);
-    sdesc_loc->AddContent(cricket::CN_AUDIO, cricket::NS_JINGLE_RTP,
-                          new cricket::AudioContentDescription());
-    sdesc_loc->AddContent(cricket::CN_VIDEO, cricket::NS_JINGLE_RTP,
-                          new cricket::VideoContentDescription());
-    EXPECT_TRUE(session1_.set_local_description(sdesc_loc));
-    sdesc_rem->AddContent(cricket::CN_AUDIO, cricket::NS_JINGLE_RTP,
-                          new cricket::AudioContentDescription());
-    sdesc_rem->AddContent(cricket::CN_VIDEO, cricket::NS_JINGLE_RTP,
-                          new cricket::VideoContentDescription());
-    EXPECT_TRUE(session1_.set_remote_description(sdesc_rem));
-
-    // Test failures in SetLocalContent.
-    media_channel1_->set_fail_set_recv_codecs(true);
-    session1_.SetError(cricket::BaseSession::ERROR_NONE);
-    session1_.SignalState(&session1_, cricket::Session::STATE_SENTINITIATE);
-    EXPECT_EQ(cricket::BaseSession::ERROR_CONTENT, session1_.error());
-    media_channel1_->set_fail_set_recv_codecs(true);
-    session1_.SetError(cricket::BaseSession::ERROR_NONE);
-    session1_.SignalState(&session1_, cricket::Session::STATE_SENTACCEPT);
-    EXPECT_EQ(cricket::BaseSession::ERROR_CONTENT, session1_.error());
-
-    // Test failures in SetRemoteContent.
-    media_channel1_->set_fail_set_send_codecs(true);
-    session1_.SetError(cricket::BaseSession::ERROR_NONE);
-    session1_.SignalState(&session1_, cricket::Session::STATE_RECEIVEDINITIATE);
-    EXPECT_EQ(cricket::BaseSession::ERROR_CONTENT, session1_.error());
-    media_channel1_->set_fail_set_send_codecs(true);
-    session1_.SetError(cricket::BaseSession::ERROR_NONE);
-    session1_.SignalState(&session1_, cricket::Session::STATE_RECEIVEDACCEPT);
-    EXPECT_EQ(cricket::BaseSession::ERROR_CONTENT, session1_.error());
-  }
-
-  void TestFlushRtcp() {
-    bool send_rtcp1;
-
-    CreateChannels(RTCP, RTCP);
-    EXPECT_TRUE(SendInitiate());
-    EXPECT_TRUE(SendAccept());
-    EXPECT_EQ(2U, GetTransport1()->channels().size());
-    EXPECT_EQ(2U, GetTransport2()->channels().size());
-
-    // Send RTCP1 from a different thread.
-    CallOnThreadAndWaitForDone(&ChannelTest<T>::SendRtcp1, &send_rtcp1);
-    EXPECT_TRUE(send_rtcp1);
-    // The sending message is only posted.  channel2_ should be empty.
-    EXPECT_TRUE(CheckNoRtcp2());
-
-    // When channel1_ is deleted, the RTCP packet should be sent out to
-    // channel2_.
-    channel1_.reset();
-    EXPECT_TRUE(CheckRtcp2());
-  }
-
-  void TestChangeStateError() {
-    CreateChannels(RTCP, RTCP);
-    EXPECT_TRUE(SendInitiate());
-    media_channel2_->set_fail_set_send(true);
-    EXPECT_TRUE(channel2_->Enable(true));
-    EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_DEVICE_OPEN_FAILED,
-              error_);
-  }
-
-  void TestSrtpError() {
-    static const unsigned char kBadPacket[] = {
-      0x90, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
-    };
-    CreateChannels(RTCP | SECURE, RTCP | SECURE);
-    EXPECT_FALSE(channel1_->secure());
-    EXPECT_FALSE(channel2_->secure());
-    EXPECT_TRUE(SendInitiate());
-    EXPECT_TRUE(SendAccept());
-    EXPECT_TRUE(channel1_->secure());
-    EXPECT_TRUE(channel2_->secure());
-    channel2_->set_srtp_signal_silent_time(200);
-
-    // Testing failures in sending packets.
-    EXPECT_FALSE(media_channel2_->SendRtp(kBadPacket, sizeof(kBadPacket)));
-    // The first failure will trigger an error.
-    EXPECT_EQ_WAIT(T::MediaChannel::ERROR_REC_SRTP_ERROR, error_, 500);
-    error_ = T::MediaChannel::ERROR_NONE;
-    // The next 1 sec failures will not trigger an error.
-    EXPECT_FALSE(media_channel2_->SendRtp(kBadPacket, sizeof(kBadPacket)));
-    // Wait for a while to ensure no message comes in.
-    talk_base::Thread::Current()->ProcessMessages(210);
-    EXPECT_EQ(T::MediaChannel::ERROR_NONE, error_);
-    // The error will be triggered again.
-    EXPECT_FALSE(media_channel2_->SendRtp(kBadPacket, sizeof(kBadPacket)));
-    EXPECT_EQ_WAIT(T::MediaChannel::ERROR_REC_SRTP_ERROR, error_, 500);
-
-    // Testing failures in receiving packets.
-    error_ = T::MediaChannel::ERROR_NONE;
-    cricket::TransportChannel* transport_channel =
-        channel2_->transport_channel();
-    transport_channel->SignalReadPacket(
-        transport_channel, reinterpret_cast<const char*>(kBadPacket),
-        sizeof(kBadPacket));
-    EXPECT_EQ_WAIT(T::MediaChannel::ERROR_PLAY_SRTP_AUTH_FAILED, error_, 500);
-  }
-
- protected:
-  cricket::FakeSession session1_;
-  cricket::FakeSession session2_;
-  cricket::FakeMediaEngine media_engine_;
-  // The media channels are owned by the voice channel objects below.
-  typename T::MediaChannel* media_channel1_;
-  typename T::MediaChannel* media_channel2_;
-  talk_base::scoped_ptr<typename T::Channel> channel1_;
-  talk_base::scoped_ptr<typename T::Channel> channel2_;
-  typename T::Content media_content1_;
-  typename T::Content media_content2_;
-  // The RTP and RTCP packets to send in the tests.
-  std::string rtp_packet_;
-  std::string rtcp_packet_;
-  int media_info_callbacks1_;
-  int media_info_callbacks2_;
-  uint32 ssrc_;
-  typename T::MediaChannel::Error error_;
-};
-
-
-template<>
-void ChannelTest<VoiceTraits>::CreateContent(
-    int flags,
-    const cricket::AudioCodec& audio_codec,
-    const cricket::VideoCodec& video_codec,
-    cricket::AudioContentDescription* audio) {
-  audio->AddCodec(audio_codec);
-  audio->set_rtcp_mux((flags & RTCP_MUX) != 0);
-  if (flags & SECURE) {
-    audio->AddCrypto(cricket::CryptoParams(
-        1, cricket::CS_AES_CM_128_HMAC_SHA1_32,
-        "inline:" + talk_base::CreateRandomString(40), ""));
-  }
-}
-
-template<>
-bool ChannelTest<VoiceTraits>::CodecMatches(const cricket::AudioCodec& c1,
-                                            const cricket::AudioCodec& c2) {
-  return c1.name == c2.name && c1.clockrate == c2.clockrate &&
-      c1.bitrate == c2.bitrate && c1.channels == c2.channels;
-}
-
-template<>
-void ChannelTest<VoiceTraits>::AddLegacyStreamInContent(
-    uint32 ssrc, int flags, cricket::AudioContentDescription* audio) {
-  if (flags & SSRC_MUX)
-    audio->AddLegacyStream(ssrc);
-}
-
-class VoiceChannelTest
-    : public ChannelTest<VoiceTraits> {
- public:
-  typedef ChannelTest<VoiceTraits>
-  Base;
-  VoiceChannelTest() : Base(kPcmuFrame, sizeof(kPcmuFrame),
-                            kRtcpReport, sizeof(kRtcpReport)) {
-  }
-};
-
-// override to add NULL parameter
-template<>
-cricket::VideoChannel* ChannelTest<VideoTraits>::CreateChannel(
-    talk_base::Thread* thread, cricket::MediaEngineInterface* engine,
-    cricket::FakeVideoMediaChannel* ch, cricket::BaseSession* session,
-    bool rtcp) {
-  cricket::VideoChannel* channel = new cricket::VideoChannel(
-      thread, engine, ch, session, cricket::CN_VIDEO, rtcp, NULL);
-  if (!channel->Init()) {
-    delete channel;
-    channel = NULL;
-  }
-  return channel;
-}
-
-// override to add 0 parameter
-template<>
-bool ChannelTest<VideoTraits>::AddStream1(int id) {
-  return channel1_->AddStream(id, 0);
-}
-
-template<>
-void ChannelTest<VideoTraits>::CreateContent(
-    int flags,
-    const cricket::AudioCodec& audio_codec,
-    const cricket::VideoCodec& video_codec,
-    cricket::VideoContentDescription* video) {
-  video->AddCodec(video_codec);
-  video->set_rtcp_mux((flags & RTCP_MUX) != 0);
-  if (flags & SECURE) {
-    video->AddCrypto(cricket::CryptoParams(
-        1, cricket::CS_AES_CM_128_HMAC_SHA1_80,
-        "inline:" + talk_base::CreateRandomString(40), ""));
-  }
-}
-
-template<>
-bool ChannelTest<VideoTraits>::CodecMatches(const cricket::VideoCodec& c1,
-                                            const cricket::VideoCodec& c2) {
-  return c1.name == c2.name && c1.width == c2.width && c1.height == c2.height &&
-      c1.framerate == c2.framerate;
-}
-
-template<>
-void ChannelTest<VideoTraits>::AddLegacyStreamInContent(
-    uint32 ssrc, int flags, cricket::VideoContentDescription* video) {
-  if (flags & SSRC_MUX)
-    video->AddLegacyStream(ssrc);
-}
-
-class VideoChannelTest
-    : public ChannelTest<VideoTraits> {
- public:
-  typedef ChannelTest<VideoTraits>
-  Base;
-  VideoChannelTest() : Base(kH264Packet, sizeof(kH264Packet),
-                            kRtcpReport, sizeof(kRtcpReport)) {
-  }
-};
-
-
-// VoiceChannelTest
-
-TEST_F(VoiceChannelTest, TestInit) {
-  Base::TestInit();
-  EXPECT_FALSE(media_channel1_->muted());
-  EXPECT_TRUE(media_channel1_->dtmf_queue().empty());
-}
-
-TEST_F(VoiceChannelTest, TestSetRtcpCName) {
-  Base::TestSetRtcpCName();
-}
-
-TEST_F(VoiceChannelTest, TestSetContents) {
-  Base::TestSetContents();
-}
-
-TEST_F(VoiceChannelTest, TestSetContentsNullOffer) {
-  Base::TestSetContentsNullOffer();
-}
-
-TEST_F(VoiceChannelTest, TestSetContentsRtcpMux) {
-  Base::TestSetContentsRtcpMux();
-}
-
-TEST_F(VoiceChannelTest, TestSetRemoteContentUpdate) {
-  Base::TestSetRemoteContentUpdate();
-}
-
-TEST_F(VoiceChannelTest, TestStreams) {
-  Base::TestStreams();
-}
-
-TEST_F(VoiceChannelTest, TestPlayoutAndSendingStates) {
-  Base::TestPlayoutAndSendingStates();
-}
-
-TEST_F(VoiceChannelTest, TestCallSetup) {
-  Base::TestCallSetup();
-}
-
-TEST_F(VoiceChannelTest, TestCallTeardownRtcpMux) {
-  Base::TestCallTeardownRtcpMux();
-}
-
-TEST_F(VoiceChannelTest, SendRtpToRtp) {
-  Base::SendRtpToRtp();
-}
-
-TEST_F(VoiceChannelTest, SendNoRtcpToNoRtcp) {
-  Base::SendNoRtcpToNoRtcp();
-}
-
-TEST_F(VoiceChannelTest, SendNoRtcpToRtcp) {
-  Base::SendNoRtcpToRtcp();
-}
-
-TEST_F(VoiceChannelTest, SendRtcpToNoRtcp) {
-  Base::SendRtcpToNoRtcp();
-}
-
-TEST_F(VoiceChannelTest, SendRtcpToRtcp) {
-  Base::SendRtcpToRtcp();
-}
-
-TEST_F(VoiceChannelTest, SendRtcpMuxToRtcp) {
-  Base::SendRtcpMuxToRtcp();
-}
-
-TEST_F(VoiceChannelTest, SendRtcpMuxToRtcpMux) {
-  Base::SendRtcpMuxToRtcpMux();
-}
-
-TEST_F(VoiceChannelTest, SendEarlyRtcpMuxToRtcp) {
-  Base::SendEarlyRtcpMuxToRtcp();
-}
-
-TEST_F(VoiceChannelTest, SendEarlyRtcpMuxToRtcpMux) {
-  Base::SendEarlyRtcpMuxToRtcpMux();
-}
-
-TEST_F(VoiceChannelTest, SendSrtpToSrtp) {
-  Base::SendSrtpToSrtp();
-}
-
-TEST_F(VoiceChannelTest, SendSrtpToRtp) {
-  Base::SendSrtpToSrtp();
-}
-
-TEST_F(VoiceChannelTest, SendSrtcpMux) {
-  Base::SendSrtcpMux();
-}
-
-TEST_F(VoiceChannelTest, SendRtpToRtpOnThread) {
-  Base::SendRtpToRtpOnThread();
-}
-
-TEST_F(VoiceChannelTest, SendSrtpToSrtpOnThread) {
-  Base::SendSrtpToSrtpOnThread();
-}
-
-TEST_F(VoiceChannelTest, SendWithWritabilityLoss) {
-  Base::SendWithWritabilityLoss();
-}
-
-TEST_F(VoiceChannelTest, TestMediaMonitor) {
-  Base::TestMediaMonitor();
-}
-
-// Test that Mute properly forwards to the media channel.
-TEST_F(VoiceChannelTest, TestMute) {
-  CreateChannels(0, 0);
-  EXPECT_FALSE(media_channel1_->muted());
-  EXPECT_TRUE(channel1_->Mute(true));
-  EXPECT_TRUE(media_channel1_->muted());
-  EXPECT_TRUE(channel1_->Mute(false));
-  EXPECT_FALSE(media_channel1_->muted());
-}
-
-// Test that keyboard automute works correctly.
-TEST_F(VoiceChannelTest, TestKeyboardMute) {
-  CreateChannels(0, 0);
-  EXPECT_FALSE(media_channel1_->muted());
-  EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_NONE, error_);
-
-  cricket::VoiceMediaChannel::Error e =
-      cricket::VoiceMediaChannel::ERROR_REC_TYPING_NOISE_DETECTED;
-
-  // Typing doesn't mute automatically
-  media_channel1_->TriggerError(0, e);
-  talk_base::Thread::Current()->ProcessMessages(0);
-  EXPECT_EQ(e, error_);
-  EXPECT_FALSE(media_channel1_->muted());
-
-  // But it does when enabled
-  channel1_->set_mute_on_type(true, 200);
-  media_channel1_->TriggerError(0, e);
-  error_ = cricket::VoiceMediaChannel::ERROR_NONE;
-  EXPECT_TRUE_WAIT(error_ == e, 100);
-  EXPECT_TRUE(media_channel1_->muted());
-  EXPECT_TRUE_WAIT(!media_channel1_->muted(), 250);  // And resets.
-
-  // Muting manually preemts auto-unmute
-  media_channel1_->TriggerError(0, e);
-  error_ = cricket::VoiceMediaChannel::ERROR_NONE;
-  EXPECT_TRUE_WAIT(error_ == e, 100);
-  EXPECT_TRUE(media_channel1_->muted());
-  EXPECT_TRUE(channel1_->Mute(true));
-  talk_base::Thread::Current()->ProcessMessages(250);
-  EXPECT_TRUE(media_channel1_->muted());
-}
-
-// Test that PressDTMF properly forwards to the media channel.
-TEST_F(VoiceChannelTest, TestDtmf) {
-  CreateChannels(0, 0);
-  EXPECT_TRUE(SendInitiate());
-  EXPECT_TRUE(SendAccept());
-  EXPECT_EQ(0U, media_channel1_->dtmf_queue().size());
-  EXPECT_TRUE(channel1_->PressDTMF(1, true));
-  EXPECT_TRUE(channel1_->PressDTMF(8, false));
-  ASSERT_EQ(2U, media_channel1_->dtmf_queue().size());
-  EXPECT_EQ(1, media_channel1_->dtmf_queue()[0].first);
-  EXPECT_EQ(true, media_channel1_->dtmf_queue()[0].second);
-  EXPECT_EQ(8, media_channel1_->dtmf_queue()[1].first);
-  EXPECT_FALSE(media_channel1_->dtmf_queue()[1].second);
-}
-
-TEST_F(VoiceChannelTest, TestMediaSinks) {
-  Base::TestMediaSinks();
-}
-
-TEST_F(VoiceChannelTest, TestSetContentFailure) {
-  Base::TestSetContentFailure();
-}
-
-TEST_F(VoiceChannelTest, TestFlushRtcp) {
-  Base::TestFlushRtcp();
-}
-
-TEST_F(VoiceChannelTest, TestChangeStateError) {
-  Base::TestChangeStateError();
-}
-
-TEST_F(VoiceChannelTest, TestSrtpError) {
-  Base::TestSrtpError();
-}
-
-// Test that we can play a ringback tone properly.
-TEST_F(VoiceChannelTest, TestRingbackTone) {
-  CreateChannels(RTCP, RTCP);
-  EXPECT_FALSE(media_channel1_->ringback_tone_play());
-  EXPECT_TRUE(channel1_->SetRingbackTone("RIFF", 4));
-  EXPECT_TRUE(SendInitiate());
-  EXPECT_TRUE(SendAccept());
-  // Play ringback tone, no loop.
-  EXPECT_TRUE(channel1_->PlayRingbackTone(0, true, false));
-  EXPECT_EQ(0U, media_channel1_->ringback_tone_ssrc());
-  EXPECT_TRUE(media_channel1_->ringback_tone_play());
-  EXPECT_FALSE(media_channel1_->ringback_tone_loop());
-  // Stop the ringback tone.
-  EXPECT_TRUE(channel1_->PlayRingbackTone(0, false, false));
-  EXPECT_FALSE(media_channel1_->ringback_tone_play());
-  // Add a stream.
-  EXPECT_TRUE(AddStream1(1));
-  // Play ringback tone, looping, on the new stream.
-  EXPECT_TRUE(channel1_->PlayRingbackTone(1, true, true));
-  EXPECT_EQ(1U, media_channel1_->ringback_tone_ssrc());
-  EXPECT_TRUE(media_channel1_->ringback_tone_play());
-  EXPECT_TRUE(media_channel1_->ringback_tone_loop());
-  // Stop the ringback tone.
-  EXPECT_TRUE(channel1_->PlayRingbackTone(1, false, false));
-  EXPECT_FALSE(media_channel1_->ringback_tone_play());
-}
-
-// Test that we can scale the output volume properly for 1:1 calls.
-TEST_F(VoiceChannelTest, TestScaleVolume1to1Call) {
-  CreateChannels(RTCP, RTCP);
-  EXPECT_TRUE(SendInitiate());
-  EXPECT_TRUE(SendAccept());
-  double left, right;
-
-  // Default is (1.0, 1.0).
-  EXPECT_TRUE(media_channel1_->GetOutputScaling(0, &left, &right));
-  EXPECT_DOUBLE_EQ(1.0, left);
-  EXPECT_DOUBLE_EQ(1.0, right);
-  // invalid ssrc.
-  EXPECT_FALSE(media_channel1_->GetOutputScaling(3, &left, &right));
-
-  // Set scale to (1.5, 0.5).
-  EXPECT_TRUE(channel1_->SetOutputScaling(0, 1.5, 0.5));
-  EXPECT_TRUE(media_channel1_->GetOutputScaling(0, &left, &right));
-  EXPECT_DOUBLE_EQ(1.5, left);
-  EXPECT_DOUBLE_EQ(0.5, right);
-
-  // Set scale to (0, 0).
-  EXPECT_TRUE(channel1_->SetOutputScaling(0, 0.0, 0.0));
-  EXPECT_TRUE(media_channel1_->GetOutputScaling(0, &left, &right));
-  EXPECT_DOUBLE_EQ(0.0, left);
-  EXPECT_DOUBLE_EQ(0.0, right);
-}
-
-// Test that we can scale the output volume properly for multiway calls.
-TEST_F(VoiceChannelTest, TestScaleVolumeMultiwayCall) {
-  CreateChannels(RTCP, RTCP);
-  EXPECT_TRUE(SendInitiate());
-  EXPECT_TRUE(SendAccept());
-  EXPECT_TRUE(AddStream1(1));
-  EXPECT_TRUE(AddStream1(2));
-
-  double left, right;
-  // Default is (1.0, 1.0).
-  EXPECT_TRUE(media_channel1_->GetOutputScaling(0, &left, &right));
-  EXPECT_DOUBLE_EQ(1.0, left);
-  EXPECT_DOUBLE_EQ(1.0, right);
-  EXPECT_TRUE(media_channel1_->GetOutputScaling(1, &left, &right));
-  EXPECT_DOUBLE_EQ(1.0, left);
-  EXPECT_DOUBLE_EQ(1.0, right);
-  EXPECT_TRUE(media_channel1_->GetOutputScaling(2, &left, &right));
-  EXPECT_DOUBLE_EQ(1.0, left);
-  EXPECT_DOUBLE_EQ(1.0, right);
-  // invalid ssrc.
-  EXPECT_FALSE(media_channel1_->GetOutputScaling(3, &left, &right));
-
-  // Set scale to (1.5, 0.5) for ssrc = 1.
-  EXPECT_TRUE(channel1_->SetOutputScaling(1, 1.5, 0.5));
-  EXPECT_TRUE(media_channel1_->GetOutputScaling(1, &left, &right));
-  EXPECT_DOUBLE_EQ(1.5, left);
-  EXPECT_DOUBLE_EQ(0.5, right);
-  EXPECT_TRUE(media_channel1_->GetOutputScaling(2, &left, &right));
-  EXPECT_DOUBLE_EQ(1.0, left);
-  EXPECT_DOUBLE_EQ(1.0, right);
-  EXPECT_TRUE(media_channel1_->GetOutputScaling(0, &left, &right));
-  EXPECT_DOUBLE_EQ(1.0, left);
-  EXPECT_DOUBLE_EQ(1.0, right);
-
-  // Set scale to (0, 0) for all ssrcs.
-  EXPECT_TRUE(channel1_->SetOutputScaling(0,  0.0, 0.0));
-  EXPECT_TRUE(media_channel1_->GetOutputScaling(0, &left, &right));
-  EXPECT_DOUBLE_EQ(0.0, left);
-  EXPECT_DOUBLE_EQ(0.0, right);
-  EXPECT_TRUE(media_channel1_->GetOutputScaling(1, &left, &right));
-  EXPECT_DOUBLE_EQ(0.0, left);
-  EXPECT_DOUBLE_EQ(0.0, right);
-  EXPECT_TRUE(media_channel1_->GetOutputScaling(2, &left, &right));
-  EXPECT_DOUBLE_EQ(0.0, left);
-  EXPECT_DOUBLE_EQ(0.0, right);
-}
-
-TEST_F(VoiceChannelTest, SendSsrcMuxToSsrcMux) {
-  Base::SendSsrcMuxToSsrcMux();
-}
-
-TEST_F(VoiceChannelTest, SendSsrcMuxToSsrcMuxWithRtcpMux) {
-  Base::SendSsrcMuxToSsrcMuxWithRtcpMux();
-}
-
-// VideoChannelTest
-TEST_F(VideoChannelTest, TestInit) {
-  Base::TestInit();
-}
-
-TEST_F(VideoChannelTest, TestSetRtcpCName) {
-  Base::TestSetRtcpCName();
-}
-
-TEST_F(VideoChannelTest, TestSetContents) {
-  Base::TestSetContents();
-}
-
-TEST_F(VideoChannelTest, TestSetContentsNullOffer) {
-  Base::TestSetContentsNullOffer();
-}
-
-TEST_F(VideoChannelTest, TestSetContentsRtcpMux) {
-  Base::TestSetContentsRtcpMux();
-}
-
-TEST_F(VideoChannelTest, TestSetRemoteContentUpdate) {
-  Base::TestSetRemoteContentUpdate();
-}
-
-TEST_F(VideoChannelTest, TestStreams) {
-  Base::TestStreams();
-}
-
-TEST_F(VideoChannelTest, TestPlayoutAndSendingStates) {
-  Base::TestPlayoutAndSendingStates();
-}
-
-TEST_F(VideoChannelTest, TestCallSetup) {
-  Base::TestCallSetup();
-}
-
-TEST_F(VideoChannelTest, TestCallTeardownRtcpMux) {
-  Base::TestCallTeardownRtcpMux();
-}
-
-TEST_F(VideoChannelTest, SendRtpToRtp) {
-  Base::SendRtpToRtp();
-}
-
-TEST_F(VideoChannelTest, SendNoRtcpToNoRtcp) {
-  Base::SendNoRtcpToNoRtcp();
-}
-
-TEST_F(VideoChannelTest, SendNoRtcpToRtcp) {
-  Base::SendNoRtcpToRtcp();
-}
-
-TEST_F(VideoChannelTest, SendRtcpToNoRtcp) {
-  Base::SendRtcpToNoRtcp();
-}
-
-TEST_F(VideoChannelTest, SendRtcpToRtcp) {
-  Base::SendRtcpToRtcp();
-}
-
-TEST_F(VideoChannelTest, SendRtcpMuxToRtcp) {
-  Base::SendRtcpMuxToRtcp();
-}
-
-TEST_F(VideoChannelTest, SendRtcpMuxToRtcpMux) {
-  Base::SendRtcpMuxToRtcpMux();
-}
-
-TEST_F(VideoChannelTest, SendEarlyRtcpMuxToRtcp) {
-  Base::SendEarlyRtcpMuxToRtcp();
-}
-
-TEST_F(VideoChannelTest, SendEarlyRtcpMuxToRtcpMux) {
-  Base::SendEarlyRtcpMuxToRtcpMux();
-}
-
-TEST_F(VideoChannelTest, SendSrtpToSrtp) {
-  Base::SendSrtpToSrtp();
-}
-
-TEST_F(VideoChannelTest, SendSrtpToRtp) {
-  Base::SendSrtpToSrtp();
-}
-
-TEST_F(VideoChannelTest, SendSrtcpMux) {
-  Base::SendSrtcpMux();
-}
-
-TEST_F(VideoChannelTest, SendRtpToRtpOnThread) {
-  Base::SendRtpToRtpOnThread();
-}
-
-TEST_F(VideoChannelTest, SendSrtpToSrtpOnThread) {
-  Base::SendSrtpToSrtpOnThread();
-}
-
-TEST_F(VideoChannelTest, SendWithWritabilityLoss) {
-  Base::SendWithWritabilityLoss();
-}
-
-TEST_F(VideoChannelTest, TestMediaMonitor) {
-  Base::TestMediaMonitor();
-}
-
-TEST_F(VideoChannelTest, TestMediaSinks) {
-  Base::TestMediaSinks();
-}
-
-TEST_F(VideoChannelTest, TestSetContentFailure) {
-  Base::TestSetContentFailure();
-}
-
-TEST_F(VideoChannelTest, TestFlushRtcp) {
-  Base::TestFlushRtcp();
-}
-
-TEST_F(VideoChannelTest, SendSsrcMuxToSsrcMux) {
-  Base::SendSsrcMuxToSsrcMux();
-}
-
-TEST_F(VideoChannelTest, SendSsrcMuxToSsrcMuxWithRtcpMux) {
-  Base::SendSsrcMuxToSsrcMuxWithRtcpMux();
-}
-
-// TODO: Add VideoChannelTest.TestChangeStateError.
-
-TEST_F(VideoChannelTest, TestSrtpError) {
-  Base::TestSrtpError();
-}
diff --git a/third_party/libjingle/source/talk/session/phone/channelmanager.cc b/third_party/libjingle/source/talk/session/phone/channelmanager.cc
deleted file mode 100644
index 4b6cf39..0000000
--- a/third_party/libjingle/source/talk/session/phone/channelmanager.cc
+++ /dev/null
@@ -1,943 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2008, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/session/phone/channelmanager.h"
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <algorithm>
-
-#include "talk/base/common.h"
-#include "talk/base/logging.h"
-#include "talk/base/sigslotrepeater.h"
-#include "talk/base/stringencode.h"
-#include "talk/session/phone/soundclip.h"
-
-namespace cricket {
-
-enum {
-  MSG_CREATEVOICECHANNEL = 1,
-  MSG_DESTROYVOICECHANNEL = 2,
-  MSG_SETAUDIOOPTIONS = 3,
-  MSG_GETOUTPUTVOLUME = 4,
-  MSG_SETOUTPUTVOLUME = 5,
-  MSG_SETLOCALMONITOR = 6,
-  MSG_SETVOICELOGGING = 7,
-  MSG_CREATEVIDEOCHANNEL = 11,
-  MSG_DESTROYVIDEOCHANNEL = 12,
-  MSG_SETVIDEOOPTIONS = 13,
-  MSG_SETLOCALRENDERER = 14,
-  MSG_SETDEFAULTVIDEOENCODERCONFIG = 15,
-  MSG_SETVIDEOLOGGING = 16,
-  MSG_CREATESOUNDCLIP = 17,
-  MSG_DESTROYSOUNDCLIP = 18,
-  MSG_CAMERASTARTED = 19,
-  MSG_SETVIDEOCAPTURE = 20,
-  MSG_TERMINATE = 21,
-  MSG_REGISTERVIDEOPROCESSOR = 22,
-  MSG_UNREGISTERVIDEOPROCESSOR = 23,
-  MSG_REGISTERVOICEPROCESSOR = 24,
-  MSG_UNREGISTERVOICEPROCESSOR = 25,
-  MSG_SETVIDEOCAPTURER = 26,
-};
-
-struct CreationParams : public talk_base::MessageData {
-  CreationParams(BaseSession* session, const std::string& content_name,
-                 bool rtcp, VoiceChannel* voice_channel)
-      : session(session),
-        content_name(content_name),
-        rtcp(rtcp),
-        voice_channel(voice_channel),
-        video_channel(NULL) {}
-  BaseSession* session;
-  std::string content_name;
-  bool rtcp;
-  VoiceChannel* voice_channel;
-  VideoChannel* video_channel;
-};
-
-struct AudioOptions : public talk_base::MessageData {
-  AudioOptions(int o, const Device* in, const Device* out)
-      : options(o), in_device(in), out_device(out) {}
-  int options;
-  const Device* in_device;
-  const Device* out_device;
-  bool result;
-};
-
-struct VolumeLevel : public talk_base::MessageData {
-  VolumeLevel() : level(-1), result(false) {}
-  explicit VolumeLevel(int l) : level(l), result(false) {}
-  int level;
-  bool result;
-};
-
-struct VideoOptions : public talk_base::MessageData {
-  explicit VideoOptions(const Device* d) : cam_device(d), result(false) {}
-  const Device* cam_device;
-  bool result;
-};
-
-struct DefaultVideoEncoderConfig : public talk_base::MessageData {
-  explicit DefaultVideoEncoderConfig(const VideoEncoderConfig& c)
-      : config(c), result(false) {}
-  VideoEncoderConfig config;
-  bool result;
-};
-
-struct LocalMonitor : public talk_base::MessageData {
-  explicit LocalMonitor(bool e) : enable(e), result(false) {}
-  bool enable;
-  bool result;
-};
-
-struct LocalRenderer : public talk_base::MessageData {
-  explicit LocalRenderer(VideoRenderer* r) : renderer(r), result(false) {}
-  VideoRenderer* renderer;
-  bool result;
-};
-
-struct Capturer : public talk_base::MessageData {
-  Capturer(VideoCapturer* c, uint32 s)
-      : capturer(c),
-        ssrc(s),
-        result(false) {}
-  VideoCapturer* capturer;
-  uint32 ssrc;
-  bool result;
-};
-
-struct LoggingOptions : public talk_base::MessageData {
-  explicit LoggingOptions(int lev, const char* f) : level(lev), filter(f) {}
-  int level;
-  std::string filter;
-};
-
-struct CaptureParams : public talk_base::MessageData {
-  explicit CaptureParams(bool c) : capture(c), result(CR_FAILURE) {}
-  bool capture;
-  CaptureResult result;
-};
-
-struct VideoProcessorParams : public talk_base::MessageData {
-  VideoProcessorParams(uint32 s, VideoProcessor* p)
-      : ssrc(s), processor(p), result(false) {}
-  uint32 ssrc;
-  VideoProcessor* processor;
-  bool result;
-};
-
-struct VoiceProcessorParams : public talk_base::MessageData {
-  VoiceProcessorParams(uint32 c, VoiceProcessor* p, MediaProcessorDirection d)
-      : ssrc(c), direction(d), processor(p), result(false) {}
-  uint32 ssrc;
-  MediaProcessorDirection direction;
-  VoiceProcessor* processor;
-  bool result;
-};
-
-ChannelManager::ChannelManager(talk_base::Thread* worker_thread)
-    : media_engine_(MediaEngineFactory::Create()),
-      device_manager_(cricket::DeviceManagerFactory::Create()),
-      initialized_(false),
-      main_thread_(talk_base::Thread::Current()),
-      worker_thread_(worker_thread),
-      audio_in_device_(DeviceManagerInterface::kDefaultDeviceName),
-      audio_out_device_(DeviceManagerInterface::kDefaultDeviceName),
-      audio_options_(MediaEngineInterface::DEFAULT_AUDIO_OPTIONS),
-      local_renderer_(NULL),
-      capturing_(false),
-      monitoring_(false) {
-  Construct();
-}
-
-ChannelManager::ChannelManager(MediaEngineInterface* me,
-                               DeviceManagerInterface* dm,
-                               talk_base::Thread* worker_thread)
-    : media_engine_(me),
-      device_manager_(dm),
-      initialized_(false),
-      main_thread_(talk_base::Thread::Current()),
-      worker_thread_(worker_thread),
-      audio_in_device_(DeviceManagerInterface::kDefaultDeviceName),
-      audio_out_device_(DeviceManagerInterface::kDefaultDeviceName),
-      audio_options_(MediaEngineInterface::DEFAULT_AUDIO_OPTIONS),
-      local_renderer_(NULL),
-      capturing_(false),
-      monitoring_(false) {
-  Construct();
-}
-
-void ChannelManager::Construct() {
-  // Init the device manager immediately, and set up our default video device.
-  SignalDevicesChange.repeat(device_manager_->SignalDevicesChange);
-  device_manager_->Init();
-  // Set camera_device_ to the name of the default video capturer.
-  SetVideoOptions(DeviceManagerInterface::kDefaultDeviceName);
-
-  // Camera is started asynchronously, request callbacks when startup
-  // completes to be able to forward them to the rendering manager.
-  media_engine_->SignalVideoCaptureResult.connect(
-      this, &ChannelManager::OnVideoCaptureResult);
-}
-
-ChannelManager::~ChannelManager() {
-  if (initialized_)
-    Terminate();
-}
-
-int ChannelManager::GetCapabilities() {
-  return media_engine_->GetCapabilities() & device_manager_->GetCapabilities();
-}
-
-void ChannelManager::GetSupportedAudioCodecs(
-    std::vector<AudioCodec>* codecs) const {
-  codecs->clear();
-
-  for (std::vector<AudioCodec>::const_iterator it =
-           media_engine_->audio_codecs().begin();
-      it != media_engine_->audio_codecs().end(); ++it) {
-    codecs->push_back(*it);
-  }
-}
-
-void ChannelManager::GetSupportedVideoCodecs(
-    std::vector<VideoCodec>* codecs) const {
-  codecs->clear();
-
-  std::vector<VideoCodec>::const_iterator it;
-  for (it = media_engine_->video_codecs().begin();
-      it != media_engine_->video_codecs().end(); ++it) {
-    codecs->push_back(*it);
-  }
-}
-
-bool ChannelManager::Init() {
-  ASSERT(!initialized_);
-  if (initialized_) {
-    return false;
-  }
-
-  ASSERT(worker_thread_ != NULL);
-  if (worker_thread_ && worker_thread_->started()) {
-    if (media_engine_->Init()) {
-      initialized_ = true;
-
-      // Now that we're initialized, apply any stored preferences. A preferred
-      // device might have been unplugged. In this case, we fallback to the
-      // default device but keep the user preferences. The preferences are
-      // changed only when the Javascript FE changes them.
-      const std::string preferred_audio_in_device = audio_in_device_;
-      const std::string preferred_audio_out_device = audio_out_device_;
-      const std::string preferred_camera_device = camera_device_;
-      Device device;
-      if (!device_manager_->GetAudioInputDevice(audio_in_device_, &device)) {
-        LOG(LS_WARNING) << "The preferred microphone '" << audio_in_device_
-                        << "' is unavailable. Fall back to the default.";
-        audio_in_device_ = DeviceManagerInterface::kDefaultDeviceName;
-      }
-      if (!device_manager_->GetAudioOutputDevice(audio_out_device_, &device)) {
-        LOG(LS_WARNING) << "The preferred speaker '" << audio_out_device_
-                        << "' is unavailable. Fall back to the default.";
-        audio_out_device_ = DeviceManagerInterface::kDefaultDeviceName;
-      }
-      if (!device_manager_->GetVideoCaptureDevice(camera_device_, &device)) {
-        if (!camera_device_.empty()) {
-          LOG(LS_WARNING) << "The preferred camera '" << camera_device_
-                          << "' is unavailable. Fall back to the default.";
-        }
-        camera_device_ = DeviceManagerInterface::kDefaultDeviceName;
-      }
-
-      if (!SetAudioOptions(audio_in_device_, audio_out_device_,
-                           audio_options_)) {
-        LOG(LS_WARNING) << "Failed to SetAudioOptions with"
-                        << " microphone: " << audio_in_device_
-                        << " speaker: " << audio_out_device_
-                        << " options: " << audio_options_;
-      }
-      if (!SetVideoOptions(camera_device_) && !camera_device_.empty()) {
-        LOG(LS_WARNING) << "Failed to SetVideoOptions with camera: "
-                        << camera_device_;
-      }
-
-      // Restore the user preferences.
-      audio_in_device_ = preferred_audio_in_device;
-      audio_out_device_ = preferred_audio_out_device;
-      camera_device_ = preferred_camera_device;
-
-      // Now apply the default video codec that has been set earlier.
-      if (default_video_encoder_config_.max_codec.id != 0) {
-        SetDefaultVideoEncoderConfig(default_video_encoder_config_);
-      }
-      // And the local renderer.
-      if (local_renderer_) {
-        SetLocalRenderer(local_renderer_);
-      }
-    }
-  }
-  return initialized_;
-}
-
-void ChannelManager::Terminate() {
-  ASSERT(initialized_);
-  if (!initialized_) {
-    return;
-  }
-  Send(MSG_TERMINATE, NULL);
-  media_engine_->Terminate();
-  initialized_ = false;
-}
-
-void ChannelManager::Terminate_w() {
-  ASSERT(worker_thread_ == talk_base::Thread::Current());
-    // Need to destroy the voice/video channels
-  while (!video_channels_.empty()) {
-    DestroyVideoChannel_w(video_channels_.back());
-  }
-  while (!voice_channels_.empty()) {
-    DestroyVoiceChannel_w(voice_channels_.back());
-  }
-  while (!soundclips_.empty()) {
-    DestroySoundclip_w(soundclips_.back());
-  }
-}
-
-VoiceChannel* ChannelManager::CreateVoiceChannel(
-    BaseSession* session, const std::string& content_name, bool rtcp) {
-  CreationParams params(session, content_name, rtcp, NULL);
-  return (Send(MSG_CREATEVOICECHANNEL, &params)) ? params.voice_channel : NULL;
-}
-
-VoiceChannel* ChannelManager::CreateVoiceChannel_w(
-    BaseSession* session, const std::string& content_name, bool rtcp) {
-  // This is ok to alloc from a thread other than the worker thread
-  ASSERT(initialized_);
-  VoiceMediaChannel* media_channel = media_engine_->CreateChannel();
-  if (media_channel == NULL)
-    return NULL;
-
-  VoiceChannel* voice_channel = new VoiceChannel(
-      worker_thread_, media_engine_.get(), media_channel,
-      session, content_name, rtcp);
-  if (!voice_channel->Init()) {
-    delete voice_channel;
-    return NULL;
-  }
-  voice_channels_.push_back(voice_channel);
-  return voice_channel;
-}
-
-void ChannelManager::DestroyVoiceChannel(VoiceChannel* voice_channel) {
-  if (voice_channel) {
-    talk_base::TypedMessageData<VoiceChannel *> data(voice_channel);
-    Send(MSG_DESTROYVOICECHANNEL, &data);
-  }
-}
-
-void ChannelManager::DestroyVoiceChannel_w(VoiceChannel* voice_channel) {
-  // Destroy voice channel.
-  ASSERT(initialized_);
-  VoiceChannels::iterator it = std::find(voice_channels_.begin(),
-      voice_channels_.end(), voice_channel);
-  ASSERT(it != voice_channels_.end());
-  if (it == voice_channels_.end())
-    return;
-
-  voice_channels_.erase(it);
-  delete voice_channel;
-}
-
-VideoChannel* ChannelManager::CreateVideoChannel(
-    BaseSession* session, const std::string& content_name, bool rtcp,
-    VoiceChannel* voice_channel) {
-  CreationParams params(session, content_name, rtcp, voice_channel);
-  return (Send(MSG_CREATEVIDEOCHANNEL, &params)) ? params.video_channel : NULL;
-}
-
-VideoChannel* ChannelManager::CreateVideoChannel_w(
-    BaseSession* session, const std::string& content_name, bool rtcp,
-    VoiceChannel* voice_channel) {
-  // This is ok to alloc from a thread other than the worker thread
-  ASSERT(initialized_);
-  VideoMediaChannel* media_channel =
-      // voice_channel can be NULL in case of NullVoiceEngine.
-      media_engine_->CreateVideoChannel(voice_channel ?
-          voice_channel->media_channel() : NULL);
-  if (media_channel == NULL)
-    return NULL;
-
-  VideoChannel* video_channel = new VideoChannel(
-      worker_thread_, media_engine_.get(), media_channel,
-      session, content_name, rtcp, voice_channel);
-  if (!video_channel->Init()) {
-    delete video_channel;
-    return NULL;
-  }
-  video_channels_.push_back(video_channel);
-  return video_channel;
-}
-
-void ChannelManager::DestroyVideoChannel(VideoChannel* video_channel) {
-  if (video_channel) {
-    talk_base::TypedMessageData<VideoChannel *> data(video_channel);
-    Send(MSG_DESTROYVIDEOCHANNEL, &data);
-  }
-}
-
-void ChannelManager::DestroyVideoChannel_w(VideoChannel *video_channel) {
-  // Destroy voice channel.
-  ASSERT(initialized_);
-  VideoChannels::iterator it = std::find(video_channels_.begin(),
-      video_channels_.end(), video_channel);
-  ASSERT(it != video_channels_.end());
-  if (it == video_channels_.end())
-    return;
-
-  video_channels_.erase(it);
-  delete video_channel;
-}
-
-Soundclip* ChannelManager::CreateSoundclip() {
-  talk_base::TypedMessageData<Soundclip*> data(NULL);
-  Send(MSG_CREATESOUNDCLIP, &data);
-  return data.data();
-}
-
-Soundclip* ChannelManager::CreateSoundclip_w() {
-  ASSERT(initialized_);
-  ASSERT(worker_thread_ == talk_base::Thread::Current());
-
-  SoundclipMedia* soundclip_media = media_engine_->CreateSoundclip();
-  if (!soundclip_media) {
-    return NULL;
-  }
-
-  Soundclip* soundclip = new Soundclip(worker_thread_, soundclip_media);
-  soundclips_.push_back(soundclip);
-  return soundclip;
-}
-
-void ChannelManager::DestroySoundclip(Soundclip* soundclip) {
-  if (soundclip) {
-    talk_base::TypedMessageData<Soundclip*> data(soundclip);
-    Send(MSG_DESTROYSOUNDCLIP, &data);
-  }
-}
-
-void ChannelManager::DestroySoundclip_w(Soundclip* soundclip) {
-  // Destroy soundclip.
-  ASSERT(initialized_);
-  Soundclips::iterator it = std::find(soundclips_.begin(),
-      soundclips_.end(), soundclip);
-  ASSERT(it != soundclips_.end());
-  if (it == soundclips_.end())
-    return;
-
-  soundclips_.erase(it);
-  delete soundclip;
-}
-
-bool ChannelManager::GetAudioOptions(std::string* in_name,
-                                     std::string* out_name, int* opts) {
-  *in_name = audio_in_device_;
-  *out_name = audio_out_device_;
-  *opts = audio_options_;
-  return true;
-}
-
-bool ChannelManager::SetAudioOptions(const std::string& in_name,
-                                     const std::string& out_name, int opts) {
-  // Get device ids from DeviceManager.
-  Device in_dev, out_dev;
-  if (!device_manager_->GetAudioInputDevice(in_name, &in_dev)) {
-    LOG(LS_WARNING) << "Failed to GetAudioInputDevice: " << in_name;
-    return false;
-  }
-  if (!device_manager_->GetAudioOutputDevice(out_name, &out_dev)) {
-    LOG(LS_WARNING) << "Failed to GetAudioOutputDevice: " << out_name;
-    return false;
-  }
-
-  // If we're initialized, pass the settings to the media engine.
-  bool ret = true;
-  if (initialized_) {
-    AudioOptions options(opts, &in_dev, &out_dev);
-    ret = (Send(MSG_SETAUDIOOPTIONS, &options) && options.result);
-  }
-
-  // If all worked well, save the values for use in GetAudioOptions.
-  if (ret) {
-    audio_options_ = opts;
-    audio_in_device_ = in_name;
-    audio_out_device_ = out_name;
-  }
-  return ret;
-}
-
-bool ChannelManager::SetAudioOptions_w(int opts, const Device* in_dev,
-    const Device* out_dev) {
-  ASSERT(worker_thread_ == talk_base::Thread::Current());
-  ASSERT(initialized_);
-
-  // Set audio options
-  bool ret = media_engine_->SetAudioOptions(opts);
-
-  // Set the audio devices
-  if (ret) {
-    ret = media_engine_->SetSoundDevices(in_dev, out_dev);
-  }
-
-  return ret;
-}
-
-bool ChannelManager::GetOutputVolume(int* level) {
-  VolumeLevel volume;
-  if (!Send(MSG_GETOUTPUTVOLUME, &volume) || !volume.result) {
-    return false;
-  }
-
-  *level = volume.level;
-  return true;
-}
-
-bool ChannelManager::GetOutputVolume_w(int* level) {
-  ASSERT(worker_thread_ == talk_base::Thread::Current());
-  ASSERT(initialized_);
-  return media_engine_->GetOutputVolume(level);
-}
-
-bool ChannelManager::SetOutputVolume(int level) {
-  VolumeLevel volume(level);
-  return (Send(MSG_SETOUTPUTVOLUME, &volume) && volume.result);
-}
-
-bool ChannelManager::SetOutputVolume_w(int level) {
-  ASSERT(worker_thread_ == talk_base::Thread::Current());
-  ASSERT(initialized_);
-  return media_engine_->SetOutputVolume(level);
-}
-
-bool ChannelManager::GetVideoOptions(std::string* cam_name) {
-  *cam_name = camera_device_;
-  return true;
-}
-
-bool ChannelManager::SetVideoOptions(const std::string& cam_name) {
-  Device device;
-  if (!device_manager_->GetVideoCaptureDevice(cam_name, &device)) {
-    if (!cam_name.empty()) {
-      LOG(LS_WARNING) << "Device manager can't find camera: " << cam_name;
-    }
-    return false;
-  }
-
-  // If we're running, tell the media engine about it.
-  bool ret = true;
-  if (initialized_) {
-    VideoOptions options(&device);
-    ret = (Send(MSG_SETVIDEOOPTIONS, &options) && options.result);
-  }
-
-  // If everything worked, retain the name of the selected camera.
-  if (ret) {
-    camera_device_ = device.name;
-  }
-  return ret;
-}
-
-bool ChannelManager::SetVideoOptions_w(const Device* cam_device) {
-  ASSERT(worker_thread_ == talk_base::Thread::Current());
-  ASSERT(initialized_);
-
-  // Set the video input device
-  return media_engine_->SetVideoCaptureDevice(cam_device);
-}
-
-bool ChannelManager::SetDefaultVideoEncoderConfig(const VideoEncoderConfig& c) {
-  bool ret = true;
-  if (initialized_) {
-    DefaultVideoEncoderConfig config(c);
-    ret = Send(MSG_SETDEFAULTVIDEOENCODERCONFIG, &config) && config.result;
-  }
-  if (ret) {
-    default_video_encoder_config_ = c;
-  }
-  return ret;
-}
-
-bool ChannelManager::SetDefaultVideoEncoderConfig_w(
-    const VideoEncoderConfig& c) {
-  ASSERT(worker_thread_ == talk_base::Thread::Current());
-  ASSERT(initialized_);
-  return media_engine_->SetDefaultVideoEncoderConfig(c);
-}
-
-bool ChannelManager::SetLocalMonitor(bool enable) {
-  LocalMonitor monitor(enable);
-  bool ret = Send(MSG_SETLOCALMONITOR, &monitor) && monitor.result;
-  if (ret) {
-    monitoring_ = enable;
-  }
-  return ret;
-}
-
-bool ChannelManager::SetLocalMonitor_w(bool enable) {
-  ASSERT(worker_thread_ == talk_base::Thread::Current());
-  ASSERT(initialized_);
-  return media_engine_->SetLocalMonitor(enable);
-}
-
-bool ChannelManager::SetLocalRenderer(VideoRenderer* renderer) {
-  bool ret = true;
-  if (initialized_) {
-    LocalRenderer local(renderer);
-    ret = (Send(MSG_SETLOCALRENDERER, &local) && local.result);
-  }
-  if (ret) {
-    local_renderer_ = renderer;
-  }
-  return ret;
-}
-
-bool ChannelManager::SetLocalRenderer_w(VideoRenderer* renderer) {
-  ASSERT(worker_thread_ == talk_base::Thread::Current());
-  ASSERT(initialized_);
-  return media_engine_->SetLocalRenderer(renderer);
-}
-
-bool ChannelManager::SetVideoCapturer(VideoCapturer* capturer, uint32 ssrc) {
-  bool ret = true;
-  if (initialized_) {
-    Capturer capture(capturer, ssrc);
-    ret = (Send(MSG_SETVIDEOCAPTURER, &capture) && capture.result);
-  }
-  return ret;
-}
-
-bool ChannelManager::SetVideoCapturer_w(VideoCapturer* capturer, uint32 ssrc) {
-  ASSERT(worker_thread_ == talk_base::Thread::Current());
-  ASSERT(initialized_);
-  return media_engine_->SetVideoCapturer(capturer, ssrc);
-}
-
-CaptureResult ChannelManager::SetVideoCapture(bool capture) {
-  bool ret;
-  CaptureParams capture_params(capture);
-  ret = (Send(MSG_SETVIDEOCAPTURE, &capture_params) &&
-         (capture_params.result != CR_FAILURE));
-  if (ret) {
-    capturing_ = capture;
-  }
-  return capture_params.result;
-}
-
-CaptureResult ChannelManager::SetVideoCapture_w(bool capture) {
-  ASSERT(worker_thread_ == talk_base::Thread::Current());
-  ASSERT(initialized_);
-  return media_engine_->SetVideoCapture(capture);
-}
-
-void ChannelManager::SetVoiceLogging(int level, const char* filter) {
-  SetMediaLogging(false, level, filter);
-}
-
-void ChannelManager::SetVideoLogging(int level, const char* filter) {
-  SetMediaLogging(true, level, filter);
-}
-
-void ChannelManager::SetMediaLogging(bool video, int level,
-                                     const char* filter) {
-  // Can be called before initialization; in this case, the worker function
-  // is simply called on the main thread.
-  if (initialized_) {
-    LoggingOptions options(level, filter);
-    Send((video) ? MSG_SETVIDEOLOGGING : MSG_SETVOICELOGGING, &options);
-  } else {
-    SetMediaLogging_w(video, level, filter);
-  }
-}
-
-void ChannelManager::SetMediaLogging_w(bool video, int level,
-                                       const char* filter) {
-  // Can be called before initialization
-  ASSERT(worker_thread_ == talk_base::Thread::Current() || !initialized_);
-  if (video) {
-    media_engine_->SetVideoLogging(level, filter);
-  } else {
-    media_engine_->SetVoiceLogging(level, filter);
-  }
-}
-
-// TODO: For now pass this request through the mediaengine to the
-// voice and video engines to do the real work. Once the capturer refactoring
-// is done, we will access the capturer using the ssrc (similar to how the
-// renderer is accessed today) and register with it directly.
-bool ChannelManager::RegisterVideoProcessor(uint32 ssrc,
-                                            VideoProcessor* processor) {
-  VideoProcessorParams processor_params(ssrc, processor);
-  return (Send(MSG_REGISTERVIDEOPROCESSOR, &processor_params) &&
-      processor_params.result);
-}
-bool ChannelManager::RegisterVideoProcessor_w(uint32 ssrc,
-                                              VideoProcessor* processor) {
-  return media_engine_->RegisterVideoProcessor(processor);
-}
-
-bool ChannelManager::UnregisterVideoProcessor(uint32 ssrc,
-                                              VideoProcessor* processor) {
-  VideoProcessorParams processor_params(ssrc, processor);
-  return (Send(MSG_UNREGISTERVIDEOPROCESSOR, &processor_params) &&
-      processor_params.result);
-}
-bool ChannelManager::UnregisterVideoProcessor_w(uint32 ssrc,
-                                                VideoProcessor* processor) {
-  return media_engine_->UnregisterVideoProcessor(processor);
-}
-
-bool ChannelManager::RegisterVoiceProcessor(
-    uint32 ssrc,
-    VoiceProcessor* processor,
-    MediaProcessorDirection direction) {
-  VoiceProcessorParams processor_params(ssrc, processor, direction);
-  return (Send(MSG_REGISTERVOICEPROCESSOR, &processor_params) &&
-      processor_params.result);
-}
-bool ChannelManager::RegisterVoiceProcessor_w(
-    uint32 ssrc,
-    VoiceProcessor* processor,
-    MediaProcessorDirection direction) {
-  return media_engine_->RegisterVoiceProcessor(ssrc, processor, direction);
-}
-
-bool ChannelManager::UnregisterVoiceProcessor(
-    uint32 ssrc,
-    VoiceProcessor* processor,
-    MediaProcessorDirection direction) {
-  VoiceProcessorParams processor_params(ssrc, processor, direction);
-  return (Send(MSG_UNREGISTERVOICEPROCESSOR, &processor_params) &&
-      processor_params.result);
-}
-bool ChannelManager::UnregisterVoiceProcessor_w(
-    uint32 ssrc,
-    VoiceProcessor* processor,
-    MediaProcessorDirection direction) {
-  return media_engine_->UnregisterVoiceProcessor(ssrc, processor, direction);
-}
-
-bool ChannelManager::Send(uint32 id, talk_base::MessageData* data) {
-  if (!worker_thread_ || !initialized_) return false;
-  worker_thread_->Send(this, id, data);
-  return true;
-}
-
-void ChannelManager::OnVideoCaptureResult(VideoCapturer* capturer,
-                                          CaptureResult result) {
-  // TODO: Check capturer and signal failure only for camera video, not
-  // screencast.
-  capturing_ = result == CR_SUCCESS;
-  main_thread_->Post(this, MSG_CAMERASTARTED,
-                     new talk_base::TypedMessageData<CaptureResult>(result));
-}
-
-void ChannelManager::OnMessage(talk_base::Message* message) {
-  talk_base::MessageData* data = message->pdata;
-  switch (message->message_id) {
-    case MSG_CREATEVOICECHANNEL: {
-      CreationParams* p = static_cast<CreationParams*>(data);
-      p->voice_channel =
-          CreateVoiceChannel_w(p->session, p->content_name, p->rtcp);
-      break;
-    }
-    case MSG_DESTROYVOICECHANNEL: {
-      VoiceChannel* p = static_cast<talk_base::TypedMessageData<VoiceChannel*>*>
-          (data)->data();
-      DestroyVoiceChannel_w(p);
-      break;
-    }
-    case MSG_CREATEVIDEOCHANNEL: {
-      CreationParams* p = static_cast<CreationParams*>(data);
-      p->video_channel = CreateVideoChannel_w(p->session, p->content_name,
-                                              p->rtcp, p->voice_channel);
-      break;
-    }
-    case MSG_DESTROYVIDEOCHANNEL: {
-      VideoChannel* p = static_cast<talk_base::TypedMessageData<VideoChannel*>*>
-          (data)->data();
-      DestroyVideoChannel_w(p);
-      break;
-    }
-    case MSG_CREATESOUNDCLIP: {
-      talk_base::TypedMessageData<Soundclip*> *p =
-          static_cast<talk_base::TypedMessageData<Soundclip*>*>(data);
-      p->data() = CreateSoundclip_w();
-      break;
-    }
-    case MSG_DESTROYSOUNDCLIP: {
-      talk_base::TypedMessageData<Soundclip*> *p =
-          static_cast<talk_base::TypedMessageData<Soundclip*>*>(data);
-      DestroySoundclip_w(p->data());
-      break;
-    }
-    case MSG_SETAUDIOOPTIONS: {
-      AudioOptions* p = static_cast<AudioOptions*>(data);
-      p->result = SetAudioOptions_w(p->options,
-                                    p->in_device, p->out_device);
-      break;
-    }
-    case MSG_GETOUTPUTVOLUME: {
-      VolumeLevel* p = static_cast<VolumeLevel*>(data);
-      p->result = GetOutputVolume_w(&p->level);
-      break;
-    }
-    case MSG_SETOUTPUTVOLUME: {
-      VolumeLevel* p = static_cast<VolumeLevel*>(data);
-      p->result = SetOutputVolume_w(p->level);
-      break;
-    }
-    case MSG_SETLOCALMONITOR: {
-      LocalMonitor* p = static_cast<LocalMonitor*>(data);
-      p->result = SetLocalMonitor_w(p->enable);
-      break;
-    }
-    case MSG_SETVIDEOOPTIONS: {
-      VideoOptions* p = static_cast<VideoOptions*>(data);
-      p->result = SetVideoOptions_w(p->cam_device);
-      break;
-    }
-    case MSG_SETDEFAULTVIDEOENCODERCONFIG: {
-      DefaultVideoEncoderConfig* p =
-          static_cast<DefaultVideoEncoderConfig*>(data);
-      p->result = SetDefaultVideoEncoderConfig_w(p->config);
-      break;
-    }
-    case MSG_SETLOCALRENDERER: {
-      LocalRenderer* p = static_cast<LocalRenderer*>(data);
-      p->result = SetLocalRenderer_w(p->renderer);
-      break;
-    }
-    case MSG_SETVIDEOCAPTURER: {
-      Capturer* p = static_cast<Capturer*>(data);
-      p->result = SetVideoCapturer_w(p->capturer, p->ssrc);
-      break;
-    }
-    case MSG_SETVIDEOCAPTURE: {
-      CaptureParams* p = static_cast<CaptureParams*>(data);
-      p->result = SetVideoCapture_w(p->capture);
-      break;
-    }
-    case MSG_SETVOICELOGGING:
-    case MSG_SETVIDEOLOGGING: {
-      LoggingOptions* p = static_cast<LoggingOptions*>(data);
-      bool video = (message->message_id == MSG_SETVIDEOLOGGING);
-      SetMediaLogging_w(video, p->level, p->filter.c_str());
-      break;
-    }
-    case MSG_CAMERASTARTED: {
-      talk_base::TypedMessageData<CaptureResult>* data =
-          static_cast<talk_base::TypedMessageData<CaptureResult>*>(
-              message->pdata);
-      SignalVideoCaptureResult(data->data());
-      delete data;
-      break;
-    }
-    case MSG_TERMINATE: {
-      Terminate_w();
-      break;
-    }
-    case MSG_REGISTERVIDEOPROCESSOR: {
-      VideoProcessorParams* data =
-          static_cast<VideoProcessorParams*>(message->pdata);
-      data->result = RegisterVideoProcessor_w(data->ssrc, data->processor);
-      break;
-    }
-    case MSG_UNREGISTERVIDEOPROCESSOR: {
-      VideoProcessorParams* data =
-          static_cast<VideoProcessorParams*>(message->pdata);
-      data->result = UnregisterVideoProcessor_w(data->ssrc, data->processor);
-      break;
-    }
-    case MSG_REGISTERVOICEPROCESSOR: {
-      VoiceProcessorParams* data =
-          static_cast<VoiceProcessorParams*>(message->pdata);
-      data->result = RegisterVoiceProcessor_w(data->ssrc,
-                                              data->processor,
-                                              data->direction);
-      break;
-    }
-    case MSG_UNREGISTERVOICEPROCESSOR: {
-      VoiceProcessorParams* data =
-          static_cast<VoiceProcessorParams*>(message->pdata);
-      data->result = UnregisterVoiceProcessor_w(data->ssrc,
-                                              data->processor,
-                                              data->direction);
-      break;
-    }
-  }
-}
-
-static void GetDeviceNames(const std::vector<Device>& devs,
-                           std::vector<std::string>* names) {
-  names->clear();
-  for (size_t i = 0; i < devs.size(); ++i) {
-    names->push_back(devs[i].name);
-  }
-}
-
-bool ChannelManager::GetAudioInputDevices(std::vector<std::string>* names) {
-  names->clear();
-  std::vector<Device> devs;
-  bool ret = device_manager_->GetAudioInputDevices(&devs);
-  if (ret)
-    GetDeviceNames(devs, names);
-
-  return ret;
-}
-
-bool ChannelManager::GetAudioOutputDevices(std::vector<std::string>* names) {
-  names->clear();
-  std::vector<Device> devs;
-  bool ret = device_manager_->GetAudioOutputDevices(&devs);
-  if (ret)
-    GetDeviceNames(devs, names);
-
-  return ret;
-}
-
-bool ChannelManager::GetVideoCaptureDevices(std::vector<std::string>* names) {
-  names->clear();
-  std::vector<Device> devs;
-  bool ret = device_manager_->GetVideoCaptureDevices(&devs);
-  if (ret)
-    GetDeviceNames(devs, names);
-
-  return ret;
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/session/phone/channelmanager.h b/third_party/libjingle/source/talk/session/phone/channelmanager.h
deleted file mode 100644
index 24a1b5b..0000000
--- a/third_party/libjingle/source/talk/session/phone/channelmanager.h
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2008, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SESSION_PHONE_CHANNELMANAGER_H_
-#define TALK_SESSION_PHONE_CHANNELMANAGER_H_
-
-#include <string>
-#include <vector>
-
-#include "talk/base/criticalsection.h"
-#include "talk/base/sigslotrepeater.h"
-#include "talk/base/thread.h"
-#include "talk/p2p/base/session.h"
-#include "talk/session/phone/voicechannel.h"
-#include "talk/session/phone/mediaengine.h"
-
-namespace cricket {
-
-class Soundclip;
-class VideoProcessor;
-class VoiceChannel;
-class VoiceProcessor;
-
-// ChannelManager allows the MediaEngine to run on a separate thread, and takes
-// care of marshalling calls between threads. It also creates and keeps track of
-// voice and video channels; by doing so, it can temporarily pause all the
-// channels when a new audio or video device is chosen. The voice and video
-// channels are stored in separate vectors, to easily allow operations on just
-// voice or just video channels.
-// ChannelManager also allows the application to discover what devices it has
-// using device manager.
-class ChannelManager : public talk_base::MessageHandler,
-                       public sigslot::has_slots<> {
- public:
-  // Creates the channel manager, and specifies the worker thread to use.
-  explicit ChannelManager(talk_base::Thread* worker);
-  // For testing purposes. Allows the media engine and dev manager to be mocks.
-  // The ChannelManager takes ownership of these objects.
-  ChannelManager(MediaEngineInterface* me, DeviceManagerInterface* dm,
-                 talk_base::Thread* worker);
-  ~ChannelManager();
-
-  // Accessors for the worker thread, allowing it to be set after construction,
-  // but before Init. set_worker_thread will return false if called after Init.
-  talk_base::Thread* worker_thread() const { return worker_thread_; }
-  bool set_worker_thread(talk_base::Thread* thread) {
-    if (initialized_) return false;
-    worker_thread_ = thread;
-    return true;
-  }
-
-  // Gets capabilities. Can be called prior to starting the media engine.
-  int GetCapabilities();
-
-  // Retrieves the list of supported audio & video codec types.
-  // Can be called before starting the media engine.
-  void GetSupportedAudioCodecs(std::vector<AudioCodec>* codecs) const;
-  void GetSupportedVideoCodecs(std::vector<VideoCodec>* codecs) const;
-
-  // Indicates whether the media engine is started.
-  bool initialized() const { return initialized_; }
-  // Starts up the media engine.
-  bool Init();
-  // Shuts down the media engine.
-  void Terminate();
-
-  // The operations below all occur on the worker thread.
-
-  // Creates a voice channel, to be associated with the specified session.
-  VoiceChannel* CreateVoiceChannel(
-      BaseSession* session, const std::string& content_name, bool rtcp);
-  // Destroys a voice channel created with the Create API.
-  void DestroyVoiceChannel(VoiceChannel* voice_channel);
-  // Creates a video channel, synced with the specified voice channel, and
-  // associated with the specified session.
-  VideoChannel* CreateVideoChannel(
-      BaseSession* session, const std::string& content_name, bool rtcp,
-      VoiceChannel* voice_channel);
-  // Destroys a video channel created with the Create API.
-  void DestroyVideoChannel(VideoChannel* video_channel);
-
-  // Creates a soundclip.
-  Soundclip* CreateSoundclip();
-  // Destroys a soundclip created with the Create API.
-  void DestroySoundclip(Soundclip* soundclip);
-
-  // Indicates whether any channels exist.
-  bool has_channels() const {
-    return (!voice_channels_.empty() || !video_channels_.empty() ||
-            !soundclips_.empty());
-  }
-
-  // Configures the audio and video devices.
-  bool GetAudioOptions(std::string* wave_in_device,
-                       std::string* wave_out_device, int* opts);
-  bool SetAudioOptions(const std::string& wave_in_device,
-                       const std::string& wave_out_device, int opts);
-  bool GetOutputVolume(int* level);
-  bool SetOutputVolume(int level);
-  bool GetVideoOptions(std::string* cam_device);
-  bool SetVideoOptions(const std::string& cam_device);
-  bool SetDefaultVideoEncoderConfig(const VideoEncoderConfig& config);
-
-  // Starts/stops the local microphone and enables polling of the input level.
-  bool SetLocalMonitor(bool enable);
-  bool monitoring() const { return monitoring_; }
-  // Sets the local renderer where to renderer the local camera.
-  bool SetLocalRenderer(VideoRenderer* renderer);
-  // Sets the externally provided video capturer. The ssrc is the ssrc of the
-  // (video) stream for which the video capturer should be set.
-  bool SetVideoCapturer(VideoCapturer* capturer, uint32 ssrc);
-  // Starts and stops the local camera and renders it to the local renderer.
-  CaptureResult SetVideoCapture(bool capture);
-  bool capturing() const { return capturing_; }
-
-  // Configures the logging output of the mediaengine(s).
-  void SetVoiceLogging(int level, const char* filter);
-  void SetVideoLogging(int level, const char* filter);
-
-  // The channel manager handles the Tx side for Video processing,
-  // as well as Tx and Rx side for Voice processing.
-  // (The Rx Video processing will go throug the simplerenderingmanager,
-  //  to be implemented).
-  bool RegisterVideoProcessor(uint32 ssrc,
-                              VideoProcessor* processor);
-  bool UnregisterVideoProcessor(uint32 ssrc,
-                                VideoProcessor* processor);
-  bool RegisterVoiceProcessor(uint32 ssrc,
-                              VoiceProcessor* processor,
-                              MediaProcessorDirection direction);
-  bool UnregisterVoiceProcessor(uint32 ssrc,
-                                VoiceProcessor* processor,
-                                MediaProcessorDirection direction);
-
-  // The operations below occur on the main thread.
-
-  bool GetAudioInputDevices(std::vector<std::string>* names);
-  bool GetAudioOutputDevices(std::vector<std::string>* names);
-  bool GetVideoCaptureDevices(std::vector<std::string>* names);
-  sigslot::repeater0<> SignalDevicesChange;
-  sigslot::signal1<CaptureResult> SignalVideoCaptureResult;
-
- private:
-  typedef std::vector<VoiceChannel*> VoiceChannels;
-  typedef std::vector<VideoChannel*> VideoChannels;
-  typedef std::vector<Soundclip*> Soundclips;
-
-  void Construct();
-  bool Send(uint32 id, talk_base::MessageData* pdata);
-  void Terminate_w();
-  VoiceChannel* CreateVoiceChannel_w(
-      BaseSession* session, const std::string& content_name, bool rtcp);
-  void DestroyVoiceChannel_w(VoiceChannel* voice_channel);
-  VideoChannel* CreateVideoChannel_w(
-      BaseSession* session, const std::string& content_name, bool rtcp,
-      VoiceChannel* voice_channel);
-  void DestroyVideoChannel_w(VideoChannel* video_channel);
-  Soundclip* CreateSoundclip_w();
-  void DestroySoundclip_w(Soundclip* soundclip);
-  bool SetAudioOptions_w(int opts, const Device* in_dev,
-                         const Device* out_dev);
-  bool GetOutputVolume_w(int* level);
-  bool SetOutputVolume_w(int level);
-  bool SetLocalMonitor_w(bool enable);
-  bool SetVideoOptions_w(const Device* cam_device);
-  bool SetDefaultVideoEncoderConfig_w(const VideoEncoderConfig& config);
-  bool SetLocalRenderer_w(VideoRenderer* renderer);
-  bool SetVideoCapturer_w(VideoCapturer* capturer, uint32 ssrc);
-  CaptureResult SetVideoCapture_w(bool capture);
-  void SetMediaLogging(bool video, int level, const char* filter);
-  void SetMediaLogging_w(bool video, int level, const char* filter);
-  void OnVideoCaptureResult(VideoCapturer* capturer,
-                            CaptureResult result);
-  bool RegisterVideoProcessor_w(uint32 ssrc,
-                                VideoProcessor* processor);
-  bool UnregisterVideoProcessor_w(uint32 ssrc,
-                                  VideoProcessor* processor);
-  bool RegisterVoiceProcessor_w(uint32 ssrc,
-                                VoiceProcessor* processor,
-                                MediaProcessorDirection direction);
-  bool UnregisterVoiceProcessor_w(uint32 ssrc,
-                                  VoiceProcessor* processor,
-                                  MediaProcessorDirection direction);
-
-  void OnMessage(talk_base::Message *message);
-
-  talk_base::scoped_ptr<MediaEngineInterface> media_engine_;
-  talk_base::scoped_ptr<DeviceManagerInterface> device_manager_;
-  bool initialized_;
-  talk_base::Thread* main_thread_;
-  talk_base::Thread* worker_thread_;
-
-  VoiceChannels voice_channels_;
-  VideoChannels video_channels_;
-  Soundclips soundclips_;
-
-  std::string audio_in_device_;
-  std::string audio_out_device_;
-  int audio_options_;
-  std::string camera_device_;
-  VideoEncoderConfig default_video_encoder_config_;
-  VideoRenderer* local_renderer_;
-
-  bool capturing_;
-  bool monitoring_;
-};
-
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_CHANNELMANAGER_H_
diff --git a/third_party/libjingle/source/talk/session/phone/channelmanager_unittest.cc b/third_party/libjingle/source/talk/session/phone/channelmanager_unittest.cc
deleted file mode 100644
index 88e821f..0000000
--- a/third_party/libjingle/source/talk/session/phone/channelmanager_unittest.cc
+++ /dev/null
@@ -1,505 +0,0 @@
-// libjingle
-// Copyright 2008 Google Inc.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-//  1. Redistributions of source code must retain the above copyright notice,
-//     this list of conditions and the following disclaimer.
-//  2. Redistributions in binary form must reproduce the above copyright notice,
-//     this list of conditions and the following disclaimer in the documentation
-//     and/or other materials provided with the distribution.
-//  3. The name of the author may not be used to endorse or promote products
-//     derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include "talk/base/gunit.h"
-#include "talk/base/logging.h"
-#include "talk/base/thread.h"
-#include "talk/p2p/base/fakesession.h"
-#include "talk/session/phone/channelmanager.h"
-#include "talk/session/phone/fakedevicemanager.h"
-#include "talk/session/phone/fakemediaengine.h"
-#include "talk/session/phone/fakemediaprocessor.h"
-#include "talk/session/phone/nullvideorenderer.h"
-
-class ChannelManagerTest : public testing::Test {
- protected:
-  ChannelManagerTest() : fme_(NULL), fdm_(NULL), cm_(NULL) {
-  }
-
-  virtual void SetUp() {
-    fme_ = new cricket::FakeMediaEngine();
-    fdm_ = new cricket::FakeDeviceManager();
-    cm_ = new cricket::ChannelManager(fme_, fdm_, talk_base::Thread::Current());
-    session_ = new cricket::FakeSession();
-
-    std::vector<std::string> in_device_list, out_device_list, vid_device_list;
-    in_device_list.push_back("audio-in1");
-    in_device_list.push_back("audio-in2");
-    out_device_list.push_back("audio-out1");
-    out_device_list.push_back("audio-out2");
-    vid_device_list.push_back("video-in1");
-    vid_device_list.push_back("video-in2");
-    fdm_->SetAudioInputDevices(in_device_list);
-    fdm_->SetAudioOutputDevices(out_device_list);
-    fdm_->SetVideoCaptureDevices(vid_device_list);
-  }
-
-  virtual void TearDown() {
-    delete session_;
-    delete cm_;
-    cm_ = NULL;
-    fdm_ = NULL;
-    fme_ = NULL;
-  }
-
-  talk_base::Thread worker_;
-  cricket::FakeMediaEngine* fme_;
-  cricket::FakeDeviceManager* fdm_;
-  cricket::ChannelManager* cm_;
-  cricket::FakeSession* session_;
-};
-
-// Test that we startup/shutdown properly.
-TEST_F(ChannelManagerTest, StartupShutdown) {
-  EXPECT_FALSE(cm_->initialized());
-  EXPECT_EQ(talk_base::Thread::Current(), cm_->worker_thread());
-  EXPECT_TRUE(cm_->Init());
-  EXPECT_TRUE(cm_->initialized());
-  cm_->Terminate();
-  EXPECT_FALSE(cm_->initialized());
-}
-
-// Test that we startup/shutdown properly with a worker thread.
-TEST_F(ChannelManagerTest, StartupShutdownOnThread) {
-  worker_.Start();
-  EXPECT_FALSE(cm_->initialized());
-  EXPECT_EQ(talk_base::Thread::Current(), cm_->worker_thread());
-  EXPECT_TRUE(cm_->set_worker_thread(&worker_));
-  EXPECT_EQ(&worker_, cm_->worker_thread());
-  EXPECT_TRUE(cm_->Init());
-  EXPECT_TRUE(cm_->initialized());
-  // Setting the worker thread while initialized should fail.
-  EXPECT_FALSE(cm_->set_worker_thread(talk_base::Thread::Current()));
-  cm_->Terminate();
-  EXPECT_FALSE(cm_->initialized());
-}
-
-// Test that we fail to startup if we're given an unstarted thread.
-TEST_F(ChannelManagerTest, StartupShutdownOnUnstartedThread) {
-  EXPECT_TRUE(cm_->set_worker_thread(&worker_));
-  EXPECT_FALSE(cm_->Init());
-  EXPECT_FALSE(cm_->initialized());
-}
-
-// Test that we can create and destroy a voice and video channel.
-TEST_F(ChannelManagerTest, CreateDestroyChannels) {
-  EXPECT_TRUE(cm_->Init());
-  cricket::VoiceChannel* voice_channel = cm_->CreateVoiceChannel(
-      session_, cricket::CN_AUDIO, false);
-  EXPECT_TRUE(voice_channel != NULL);
-  cricket::VideoChannel* video_channel =
-      cm_->CreateVideoChannel(session_, cricket::CN_VIDEO,
-                              false, voice_channel);
-  EXPECT_TRUE(video_channel != NULL);
-  cm_->DestroyVideoChannel(video_channel);
-  cm_->DestroyVoiceChannel(voice_channel);
-  cm_->Terminate();
-}
-
-// Test that we can create and destroy a voice and video channel with a worker.
-TEST_F(ChannelManagerTest, CreateDestroyChannelsOnThread) {
-  worker_.Start();
-  EXPECT_TRUE(cm_->set_worker_thread(&worker_));
-  EXPECT_TRUE(cm_->Init());
-  cricket::VoiceChannel* voice_channel = cm_->CreateVoiceChannel(
-      session_, cricket::CN_AUDIO, false);
-  EXPECT_TRUE(voice_channel != NULL);
-  cricket::VideoChannel* video_channel =
-      cm_->CreateVideoChannel(session_, cricket::CN_VIDEO,
-                              false, voice_channel);
-  EXPECT_TRUE(video_channel != NULL);
-  cm_->DestroyVideoChannel(video_channel);
-  cm_->DestroyVoiceChannel(voice_channel);
-  cm_->Terminate();
-}
-
-// Test that we fail to create a voice/video channel if the session is unable
-// to create a cricket::TransportChannel
-TEST_F(ChannelManagerTest, NoTransportChannelTest) {
-  EXPECT_TRUE(cm_->Init());
-  session_->set_fail_channel_creation(true);
-  // The test is useless unless the session does not fail creating
-  // cricket::TransportChannel.
-  ASSERT_TRUE(session_->CreateChannel("audio", "rtp") == NULL);
-
-  cricket::VoiceChannel* voice_channel = cm_->CreateVoiceChannel(
-      session_, cricket::CN_AUDIO, false);
-  EXPECT_TRUE(voice_channel == NULL);
-  cricket::VideoChannel* video_channel =
-      cm_->CreateVideoChannel(session_, cricket::CN_VIDEO,
-                              false, voice_channel);
-  EXPECT_TRUE(video_channel == NULL);
-  cm_->Terminate();
-}
-
-// Test that SetDefaultVideoCodec passes through the right values.
-TEST_F(ChannelManagerTest, SetDefaultVideoEncoderConfig) {
-  cricket::VideoCodec codec(96, "G264", 1280, 720, 60, 0);
-  cricket::VideoEncoderConfig config(codec, 1, 2);
-  EXPECT_TRUE(cm_->Init());
-  EXPECT_TRUE(cm_->SetDefaultVideoEncoderConfig(config));
-  EXPECT_EQ(config, fme_->default_video_encoder_config());
-}
-
-// Test that SetDefaultVideoCodec passes through the right values.
-TEST_F(ChannelManagerTest, SetDefaultVideoCodecBeforeInit) {
-  cricket::VideoCodec codec(96, "G264", 1280, 720, 60, 0);
-  cricket::VideoEncoderConfig config(codec, 1, 2);
-  EXPECT_TRUE(cm_->SetDefaultVideoEncoderConfig(config));
-  EXPECT_TRUE(cm_->Init());
-  EXPECT_EQ(config, fme_->default_video_encoder_config());
-}
-
-TEST_F(ChannelManagerTest, SetAudioOptionsBeforeInit) {
-  // Test that values that we set before Init are applied.
-  EXPECT_TRUE(cm_->SetAudioOptions("audio-in1", "audio-out1", 0x2));
-  EXPECT_TRUE(cm_->Init());
-  EXPECT_EQ("audio-in1", fme_->audio_in_device());
-  EXPECT_EQ("audio-out1", fme_->audio_out_device());
-  EXPECT_EQ(0x2, fme_->audio_options());
-}
-
-TEST_F(ChannelManagerTest, GetAudioOptionsBeforeInit) {
-  std::string audio_in, audio_out;
-  int opts;
-  // Test that GetAudioOptions works before Init.
-  EXPECT_TRUE(cm_->SetAudioOptions("audio-in2", "audio-out2", 0x1));
-  EXPECT_TRUE(cm_->GetAudioOptions(&audio_in, &audio_out, &opts));
-  EXPECT_EQ("audio-in2", audio_in);
-  EXPECT_EQ("audio-out2", audio_out);
-  EXPECT_EQ(0x1, opts);
-  // Test that options set before Init can be gotten after Init.
-  EXPECT_TRUE(cm_->SetAudioOptions("audio-in1", "audio-out1", 0x2));
-  EXPECT_TRUE(cm_->Init());
-  EXPECT_TRUE(cm_->GetAudioOptions(&audio_in, &audio_out, &opts));
-  EXPECT_EQ("audio-in1", audio_in);
-  EXPECT_EQ("audio-out1", audio_out);
-  EXPECT_EQ(0x2, opts);
-}
-
-TEST_F(ChannelManagerTest, SetAudioOptions) {
-  // Test initial state.
-  EXPECT_TRUE(cm_->Init());
-  EXPECT_EQ("", fme_->audio_in_device());
-  EXPECT_EQ("", fme_->audio_out_device());
-  EXPECT_EQ(cricket::MediaEngineInterface::DEFAULT_AUDIO_OPTIONS,
-            fme_->audio_options());
-  // Test setting defaults.
-  EXPECT_TRUE(cm_->SetAudioOptions("", "", 0x3));
-  EXPECT_EQ("", fme_->audio_in_device());
-  EXPECT_EQ("", fme_->audio_out_device());
-  EXPECT_EQ(0x3, fme_->audio_options());
-  // Test setting specific values.
-  EXPECT_TRUE(cm_->SetAudioOptions("audio-in1", "audio-out1", 0x2));
-  EXPECT_EQ("audio-in1", fme_->audio_in_device());
-  EXPECT_EQ("audio-out1", fme_->audio_out_device());
-  EXPECT_EQ(0x2, fme_->audio_options());
-  // Test setting bad values.
-  EXPECT_FALSE(cm_->SetAudioOptions("audio-in9", "audio-out2", 0x1));
-}
-
-TEST_F(ChannelManagerTest, GetAudioOptions) {
-  std::string audio_in, audio_out;
-  int opts;
-  // Test initial state.
-  EXPECT_TRUE(cm_->Init());
-  EXPECT_TRUE(cm_->GetAudioOptions(&audio_in, &audio_out, &opts));
-  EXPECT_EQ(std::string(cricket::DeviceManagerInterface::kDefaultDeviceName),
-            audio_in);
-  EXPECT_EQ(std::string(cricket::DeviceManagerInterface::kDefaultDeviceName),
-            audio_out);
-  EXPECT_EQ(cricket::MediaEngineInterface::DEFAULT_AUDIO_OPTIONS, opts);
-  // Test that we get back specific values that we set.
-  EXPECT_TRUE(cm_->SetAudioOptions("audio-in1", "audio-out1", 0x2));
-  EXPECT_TRUE(cm_->GetAudioOptions(&audio_in, &audio_out, &opts));
-  EXPECT_EQ("audio-in1", audio_in);
-  EXPECT_EQ("audio-out1", audio_out);
-  EXPECT_EQ(0x2, opts);
-}
-
-TEST_F(ChannelManagerTest, SetVideoOptionsBeforeInit) {
-  // Test that values that we set before Init are applied.
-  EXPECT_TRUE(cm_->SetVideoOptions("video-in2"));
-  EXPECT_TRUE(cm_->Init());
-  EXPECT_EQ("video-in2", fme_->video_in_device());
-}
-
-TEST_F(ChannelManagerTest, GetVideoOptionsBeforeInit) {
-  std::string video_in;
-  // Test that GetVideoOptions works before Init.
-  EXPECT_TRUE(cm_->SetVideoOptions("video-in1"));
-  EXPECT_TRUE(cm_->GetVideoOptions(&video_in));
-  EXPECT_EQ("video-in1", video_in);
-  // Test that options set before Init can be gotten after Init.
-  EXPECT_TRUE(cm_->SetVideoOptions("video-in2"));
-  EXPECT_TRUE(cm_->Init());
-  EXPECT_TRUE(cm_->GetVideoOptions(&video_in));
-  EXPECT_EQ("video-in2", video_in);
-}
-
-TEST_F(ChannelManagerTest, SetVideoOptions) {
-  // Test setting defaults.
-  EXPECT_TRUE(cm_->Init());
-  EXPECT_TRUE(cm_->SetVideoOptions(""));  // will use DeviceManager default
-  EXPECT_EQ("video-in1", fme_->video_in_device());
-  // Test setting specific values.
-  EXPECT_TRUE(cm_->SetVideoOptions("video-in2"));
-  EXPECT_EQ("video-in2", fme_->video_in_device());
-  // TODO: Add test for invalid value here.
-}
-
-// Test unplugging and plugging back the preferred devices. When the preferred
-// device is unplugged, we fall back to the default device. When the preferred
-// device is plugged back, we use it.
-TEST_F(ChannelManagerTest, SetAudioOptionsUnplugPlug) {
-  // Set preferences "audio-in1" and "audio-out1" before init.
-  EXPECT_TRUE(cm_->SetAudioOptions("audio-in1", "audio-out1", 0x2));
-  // Unplug device "audio-in1" and "audio-out1".
-  std::vector<std::string> in_device_list, out_device_list;
-  in_device_list.push_back("audio-in2");
-  out_device_list.push_back("audio-out2");
-  fdm_->SetAudioInputDevices(in_device_list);
-  fdm_->SetAudioOutputDevices(out_device_list);
-  // Init should fall back to default devices.
-  EXPECT_TRUE(cm_->Init());
-  // The media engine should use the default.
-  EXPECT_EQ("", fme_->audio_in_device());
-  EXPECT_EQ("", fme_->audio_out_device());
-  // The channel manager keeps the preferences "audio-in1" and "audio-out1".
-  std::string audio_in, audio_out;
-  int opts;
-  EXPECT_TRUE(cm_->GetAudioOptions(&audio_in, &audio_out, &opts));
-  EXPECT_EQ("audio-in1", audio_in);
-  EXPECT_EQ("audio-out1", audio_out);
-  cm_->Terminate();
-
-  // Plug devices "audio-in2" and "audio-out2" back.
-  in_device_list.push_back("audio-in1");
-  out_device_list.push_back("audio-out1");
-  fdm_->SetAudioInputDevices(in_device_list);
-  fdm_->SetAudioOutputDevices(out_device_list);
-  // Init again. The preferences, "audio-in2" and "audio-out2", are used.
-  EXPECT_TRUE(cm_->Init());
-  EXPECT_EQ("audio-in1", fme_->audio_in_device());
-  EXPECT_EQ("audio-out1", fme_->audio_out_device());
-  EXPECT_TRUE(cm_->GetAudioOptions(&audio_in, &audio_out, &opts));
-  EXPECT_EQ("audio-in1", audio_in);
-  EXPECT_EQ("audio-out1", audio_out);
-}
-
-// We have one camera. Unplug it, fall back to no camera.
-TEST_F(ChannelManagerTest, SetVideoOptionsUnplugPlugOneCamera) {
-  // Set preferences "video-in1" before init.
-  std::vector<std::string> vid_device_list;
-  vid_device_list.push_back("video-in1");
-  fdm_->SetVideoCaptureDevices(vid_device_list);
-  EXPECT_TRUE(cm_->SetVideoOptions("video-in1"));
-
-  // Unplug "video-in1".
-  vid_device_list.clear();
-  fdm_->SetVideoCaptureDevices(vid_device_list);
-
-  // Init should fall back to avatar.
-  EXPECT_TRUE(cm_->Init());
-  // The media engine should use no camera.
-  EXPECT_EQ("", fme_->video_in_device());
-  // The channel manager keeps the user preference "video-in".
-  std::string video_in;
-  EXPECT_TRUE(cm_->GetVideoOptions(&video_in));
-  EXPECT_EQ("video-in1", video_in);
-  cm_->Terminate();
-
-  // Plug device "video-in1" back.
-  vid_device_list.push_back("video-in1");
-  fdm_->SetVideoCaptureDevices(vid_device_list);
-  // Init again. The user preferred device, "video-in1", is used.
-  EXPECT_TRUE(cm_->Init());
-  EXPECT_EQ("video-in1", fme_->video_in_device());
-  EXPECT_TRUE(cm_->GetVideoOptions(&video_in));
-  EXPECT_EQ("video-in1", video_in);
-}
-
-// We have multiple cameras. Unplug the preferred, fall back to another camera.
-TEST_F(ChannelManagerTest, SetVideoOptionsUnplugPlugTwoDevices) {
-  // Set video device to "video-in1" before init.
-  EXPECT_TRUE(cm_->SetVideoOptions("video-in1"));
-  // Unplug device "video-in1".
-  std::vector<std::string> vid_device_list;
-  vid_device_list.push_back("video-in2");
-  fdm_->SetVideoCaptureDevices(vid_device_list);
-  // Init should fall back to default device "video-in2".
-  EXPECT_TRUE(cm_->Init());
-  // The media engine should use the default device "video-in2".
-  EXPECT_EQ("video-in2", fme_->video_in_device());
-  // The channel manager keeps the user preference "video-in".
-  std::string video_in;
-  EXPECT_TRUE(cm_->GetVideoOptions(&video_in));
-  EXPECT_EQ("video-in1", video_in);
-  cm_->Terminate();
-
-  // Plug device "video-in1" back.
-  vid_device_list.push_back("video-in1");
-  fdm_->SetVideoCaptureDevices(vid_device_list);
-  // Init again. The user preferred device, "video-in1", is used.
-  EXPECT_TRUE(cm_->Init());
-  EXPECT_EQ("video-in1", fme_->video_in_device());
-  EXPECT_TRUE(cm_->GetVideoOptions(&video_in));
-  EXPECT_EQ("video-in1", video_in);
-}
-
-TEST_F(ChannelManagerTest, GetVideoOptions) {
-  std::string video_in;
-  // Test setting/getting defaults.
-  EXPECT_TRUE(cm_->Init());
-  EXPECT_TRUE(cm_->SetVideoOptions(""));
-  EXPECT_TRUE(cm_->GetVideoOptions(&video_in));
-  EXPECT_EQ("video-in1", video_in);
-  // Test setting/getting specific values.
-  EXPECT_TRUE(cm_->SetVideoOptions("video-in2"));
-  EXPECT_TRUE(cm_->GetVideoOptions(&video_in));
-  EXPECT_EQ("video-in2", video_in);
-}
-
-TEST_F(ChannelManagerTest, GetSetOutputVolume) {
-  int level;
-  // Setting and getting should fail before Init.
-  EXPECT_EQ(-1, fme_->output_volume());
-  EXPECT_FALSE(cm_->GetOutputVolume(&level));
-  EXPECT_FALSE(cm_->SetOutputVolume(99));
-  EXPECT_EQ(-1, fme_->output_volume());
-  // Setting and getting should work after Init.
-  EXPECT_TRUE(cm_->Init());
-  EXPECT_TRUE(cm_->GetOutputVolume(&level));
-  EXPECT_EQ(fme_->output_volume(), level);
-  EXPECT_TRUE(cm_->SetOutputVolume(99));
-  EXPECT_EQ(99, fme_->output_volume());
-  EXPECT_TRUE(cm_->GetOutputVolume(&level));
-  EXPECT_EQ(99, level);
-}
-
-// Test that a value set before Init is applied properly.
-TEST_F(ChannelManagerTest, SetLocalRendererBeforeInit) {
-  cricket::NullVideoRenderer renderer;
-  EXPECT_TRUE(cm_->SetLocalRenderer(&renderer));
-  EXPECT_TRUE(cm_->Init());
-  EXPECT_EQ(&renderer, fme_->local_renderer());
-}
-
-// Test that a value set after init is passed through properly.
-TEST_F(ChannelManagerTest, SetLocalRenderer) {
-  cricket::NullVideoRenderer renderer;
-  EXPECT_TRUE(cm_->Init());
-  EXPECT_TRUE(cm_->SetLocalRenderer(&renderer));
-  EXPECT_EQ(&renderer, fme_->local_renderer());
-}
-
-// Test that logging options set before Init are applied properly,
-// and retained even after Init.
-TEST_F(ChannelManagerTest, SetLoggingBeforeInit) {
-  cm_->SetVoiceLogging(talk_base::LS_INFO, "test-voice");
-  cm_->SetVideoLogging(talk_base::LS_VERBOSE, "test-video");
-  EXPECT_EQ(talk_base::LS_INFO, fme_->voice_loglevel());
-  EXPECT_STREQ("test-voice", fme_->voice_logfilter().c_str());
-  EXPECT_EQ(talk_base::LS_VERBOSE, fme_->video_loglevel());
-  EXPECT_STREQ("test-video", fme_->video_logfilter().c_str());
-  EXPECT_TRUE(cm_->Init());
-  EXPECT_EQ(talk_base::LS_INFO, fme_->voice_loglevel());
-  EXPECT_STREQ("test-voice", fme_->voice_logfilter().c_str());
-  EXPECT_EQ(talk_base::LS_VERBOSE, fme_->video_loglevel());
-  EXPECT_STREQ("test-video", fme_->video_logfilter().c_str());
-}
-
-// Test that logging options set after Init are applied properly.
-TEST_F(ChannelManagerTest, SetLogging) {
-  EXPECT_TRUE(cm_->Init());
-  cm_->SetVoiceLogging(talk_base::LS_INFO, "test-voice");
-  cm_->SetVideoLogging(talk_base::LS_VERBOSE, "test-video");
-  EXPECT_EQ(talk_base::LS_INFO, fme_->voice_loglevel());
-  EXPECT_STREQ("test-voice", fme_->voice_logfilter().c_str());
-  EXPECT_EQ(talk_base::LS_VERBOSE, fme_->video_loglevel());
-  EXPECT_STREQ("test-video", fme_->video_logfilter().c_str());
-}
-
-// Test that SetVideoCapture passes through the right value.
-TEST_F(ChannelManagerTest, SetVideoCapture) {
-  // Should fail until we are initialized.
-  EXPECT_FALSE(fme_->capture());
-  EXPECT_EQ(cricket::CR_FAILURE, cm_->SetVideoCapture(true));
-  EXPECT_FALSE(fme_->capture());
-  EXPECT_TRUE(cm_->Init());
-  EXPECT_FALSE(fme_->capture());
-  EXPECT_EQ(cricket::CR_SUCCESS, cm_->SetVideoCapture(true));
-  EXPECT_TRUE(fme_->capture());
-  EXPECT_EQ(cricket::CR_SUCCESS, cm_->SetVideoCapture(false));
-  EXPECT_FALSE(fme_->capture());
-}
-
-// Test that the Video/Voice Processors register and unregister
-TEST_F(ChannelManagerTest, RegisterProcessors) {
-  cricket::FakeMediaProcessor fmp;
-  EXPECT_TRUE(cm_->Init());
-  EXPECT_FALSE(fme_->video_processor_registered());
-  EXPECT_FALSE(fme_->voice_processor_registered(cricket::MPD_TX));
-  EXPECT_FALSE(fme_->voice_processor_registered(cricket::MPD_RX));
-
-  EXPECT_TRUE(cm_->RegisterVideoProcessor(1, &fmp));
-  EXPECT_TRUE(fme_->video_processor_registered());
-  EXPECT_FALSE(fme_->voice_processor_registered(cricket::MPD_TX));
-  EXPECT_FALSE(fme_->voice_processor_registered(cricket::MPD_RX));
-
-  EXPECT_TRUE(cm_->UnregisterVideoProcessor(1, &fmp));
-  EXPECT_FALSE(fme_->video_processor_registered());
-  EXPECT_FALSE(fme_->voice_processor_registered(cricket::MPD_TX));
-  EXPECT_FALSE(fme_->voice_processor_registered(cricket::MPD_RX));
-
-  EXPECT_TRUE(cm_->RegisterVoiceProcessor(1,
-                                          &fmp,
-                                          cricket::MPD_RX));
-  EXPECT_FALSE(fme_->video_processor_registered());
-  EXPECT_FALSE(fme_->voice_processor_registered(cricket::MPD_TX));
-  EXPECT_TRUE(fme_->voice_processor_registered(cricket::MPD_RX));
-
-
-  EXPECT_TRUE(cm_->UnregisterVoiceProcessor(1,
-                                            &fmp,
-                                            cricket::MPD_RX));
-  EXPECT_FALSE(fme_->video_processor_registered());
-  EXPECT_FALSE(fme_->voice_processor_registered(cricket::MPD_TX));
-  EXPECT_FALSE(fme_->voice_processor_registered(cricket::MPD_RX));
-
-  EXPECT_TRUE(cm_->RegisterVoiceProcessor(1,
-                                          &fmp,
-                                          cricket::MPD_TX));
-  EXPECT_FALSE(fme_->video_processor_registered());
-  EXPECT_TRUE(fme_->voice_processor_registered(cricket::MPD_TX));
-  EXPECT_FALSE(fme_->voice_processor_registered(cricket::MPD_RX));
-
-  EXPECT_TRUE(cm_->UnregisterVoiceProcessor(1,
-                                            &fmp,
-                                            cricket::MPD_TX));
-  EXPECT_FALSE(fme_->video_processor_registered());
-  EXPECT_FALSE(fme_->voice_processor_registered(cricket::MPD_TX));
-  EXPECT_FALSE(fme_->voice_processor_registered(cricket::MPD_RX));
-}
diff --git a/third_party/libjingle/source/talk/session/phone/codec.cc b/third_party/libjingle/source/talk/session/phone/codec.cc
deleted file mode 100644
index a200ca4..0000000
--- a/third_party/libjingle/source/talk/session/phone/codec.cc
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2007, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/session/phone/codec.h"
-
-#include <sstream>
-
-#include "talk/base/stringutils.h"
-
-namespace cricket {
-
-static const int kMaxStaticPayloadId = 95;
-
-bool AudioCodec::Matches(int payload, const std::string& nm) const {
-  // Match the codec id/name based on the typical static/dynamic name rules.
-  // Matching is case-insensitive.
-  return (payload <= kMaxStaticPayloadId) ?
-      (id == payload) : (_stricmp(name.c_str(), nm.c_str()) == 0);
-}
-
-bool AudioCodec::Matches(const AudioCodec& codec) const {
-  // If a nonzero clockrate is specified, it must match the actual clockrate.
-  // If a nonzero bitrate is specified, it must match the actual bitrate,
-  // unless the codec is VBR (0), where we just force the supplied value.
-  // The number of channels must match exactly.
-  // Preference is ignored.
-  // TODO: Treat a zero clockrate as 8000Hz, the RTP default clockrate.
-  return Matches(codec.id, codec.name) &&
-      ((codec.clockrate == 0 /*&& clockrate == 8000*/) ||
-          clockrate == codec.clockrate) &&
-      (codec.bitrate == 0 || bitrate <= 0 || bitrate == codec.bitrate) &&
-      (codec.channels == 0 || channels == codec.channels);
-}
-
-std::string AudioCodec::ToString() const {
-  std::ostringstream os;
-  os << "AudioCodec[" << id << ":" << name << ":" << clockrate << ":" << bitrate
-     << ":" << channels << ":" << preference << "]";
-  return os.str();
-}
-
-bool VideoCodec::Matches(int payload, const std::string& nm) const {
-  // Match the codec id/name based on the typical static/dynamic name rules.
-  // Matching is case-insensitive.
-  return (payload <= kMaxStaticPayloadId) ?
-      (id == payload) : (_stricmp(name.c_str(), nm.c_str()) == 0);
-}
-
-bool VideoCodec::Matches(const VideoCodec& codec) const {
-  // Only the id and name are matched.
-  return Matches(codec.id, codec.name);
-}
-
-std::string VideoCodec::ToString() const {
-  std::ostringstream os;
-  os << "VideoCodec[" << id << ":" << name << ":" << width << ":" << height
-     << ":" << framerate << ":" << preference << "]";
-  return os.str();
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/session/phone/codec.h b/third_party/libjingle/source/talk/session/phone/codec.h
deleted file mode 100644
index 08cc32e..0000000
--- a/third_party/libjingle/source/talk/session/phone/codec.h
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2007, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SESSION_PHONE_CODEC_H_
-#define TALK_SESSION_PHONE_CODEC_H_
-
-#include <map>
-#include <string>
-
-namespace cricket {
-
-typedef std::map<std::string, std::string> CodecParameterMap;
-
-struct AudioCodec {
-  int id;
-  std::string name;
-  int clockrate;
-  int bitrate;
-  int channels;
-  int preference;
-  CodecParameterMap params;
-
-  // Creates a codec with the given parameters.
-  AudioCodec(int pt, const std::string& nm, int cr, int br, int cs, int pr)
-      : id(pt), name(nm), clockrate(cr), bitrate(br),
-        channels(cs), preference(pr) {}
-
-  // Creates an empty codec.
-  AudioCodec() : id(0), clockrate(0), bitrate(0), channels(0), preference(0) {}
-
-  // Indicates if this codec is compatible with the specified codec.
-  bool Matches(int payload, const std::string& nm) const;
-  bool Matches(const AudioCodec& codec) const;
-
-  static bool Preferable(const AudioCodec& first, const AudioCodec& other) {
-    return first.preference > other.preference;
-  }
-
-  std::string ToString() const;
-
-  AudioCodec& operator=(const AudioCodec& c) {
-    this->id = c.id;  // id is reserved in objective-c
-    name = c.name;
-    clockrate = c.clockrate;
-    bitrate = c.bitrate;
-    channels = c.channels;
-    preference =  c.preference;
-    params = c.params;
-    return *this;
-  }
-
-  bool operator==(const AudioCodec& c) const {
-    return this->id == c.id &&  // id is reserved in objective-c
-           name == c.name &&
-           clockrate == c.clockrate &&
-           bitrate == c.bitrate &&
-           channels == c.channels &&
-           preference == c.preference &&
-           params == c.params;
-  }
-
-  bool operator!=(const AudioCodec& c) const {
-    return !(*this == c);
-  }
-};
-
-struct VideoCodec {
-  int id;
-  std::string name;
-  int width;
-  int height;
-  int framerate;
-  int preference;
-  CodecParameterMap params;
-
-  // Creates a codec with the given parameters.
-  VideoCodec(int pt, const std::string& nm, int w, int h, int fr, int pr)
-      : id(pt), name(nm), width(w), height(h), framerate(fr), preference(pr) {}
-
-  // Creates an empty codec.
-  VideoCodec()
-      : id(0), width(0), height(0), framerate(0), preference(0) {}
-
-  bool Matches(int payload, const std::string& nm) const;
-  bool Matches(const VideoCodec& codec) const;
-
-  static bool Preferable(const VideoCodec& first, const VideoCodec& other) {
-    return first.preference > other.preference;
-  }
-
-  std::string ToString() const;
-
-  VideoCodec& operator=(const VideoCodec& c) {
-    this->id = c.id;  // id is reserved in objective-c
-    name = c.name;
-    width = c.width;
-    height = c.height;
-    framerate = c.framerate;
-    preference =  c.preference;
-    params = c.params;
-    return *this;
-  }
-
-  bool operator==(const VideoCodec& c) const {
-    return this->id == c.id &&  // id is reserved in objective-c
-           name == c.name &&
-           width == c.width &&
-           height == c.height &&
-           framerate == c.framerate &&
-           preference == c.preference &&
-           params == c.params;
-  }
-
-  bool operator!=(const VideoCodec& c) const {
-    return !(*this == c);
-  }
-};
-
-struct VideoEncoderConfig {
-  static const int kDefaultMaxThreads = -1;
-  static const int kDefaultCpuProfile = -1;
-
-  VideoEncoderConfig()
-      : max_codec(),
-        num_threads(kDefaultMaxThreads),
-        cpu_profile(kDefaultCpuProfile) {
-  }
-
-  VideoEncoderConfig(const VideoCodec& c)
-      : max_codec(c),
-        num_threads(kDefaultMaxThreads),
-        cpu_profile(kDefaultCpuProfile) {
-  }
-
-  VideoEncoderConfig(const VideoCodec& c, int t, int p)
-      : max_codec(c),
-        num_threads(t),
-        cpu_profile(p) {
-  }
-
-  VideoEncoderConfig& operator=(const VideoEncoderConfig& config) {
-    max_codec = config.max_codec;
-    num_threads = config.num_threads;
-    cpu_profile = config.cpu_profile;
-    return *this;
-  }
-
-  bool operator==(const VideoEncoderConfig& config) const {
-    return max_codec == config.max_codec &&
-           num_threads == config.num_threads &&
-           cpu_profile == config.cpu_profile;
-  }
-
-  bool operator!=(const VideoEncoderConfig& config) const {
-    return !(*this == config);
-  }
-
-  VideoCodec max_codec;
-  int num_threads;
-  int cpu_profile;
-};
-
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_CODEC_H_
diff --git a/third_party/libjingle/source/talk/session/phone/codec_unittest.cc b/third_party/libjingle/source/talk/session/phone/codec_unittest.cc
deleted file mode 100644
index 18e1eb6..0000000
--- a/third_party/libjingle/source/talk/session/phone/codec_unittest.cc
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * libjingle
- * Copyright 2009--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/gunit.h"
-#include "talk/session/phone/codec.h"
-
-using cricket::AudioCodec;
-using cricket::VideoCodec;
-using cricket::VideoEncoderConfig;
-
-class CodecTest : public testing::Test {
- public:
-  CodecTest() {}
-};
-
-TEST_F(CodecTest, TestAudioCodecOperators) {
-  AudioCodec c0(96, "A", 44100, 20000, 2, 3);
-  AudioCodec c1(95, "A", 44100, 20000, 2, 3);
-  AudioCodec c2(96, "x", 44100, 20000, 2, 3);
-  AudioCodec c3(96, "A", 48000, 20000, 2, 3);
-  AudioCodec c4(96, "A", 44100, 10000, 2, 3);
-  AudioCodec c5(96, "A", 44100, 20000, 1, 3);
-  AudioCodec c6(96, "A", 44100, 20000, 2, 1);
-  EXPECT_TRUE(c0 != c1);
-  EXPECT_TRUE(c0 != c2);
-  EXPECT_TRUE(c0 != c3);
-  EXPECT_TRUE(c0 != c4);
-  EXPECT_TRUE(c0 != c5);
-  EXPECT_TRUE(c0 != c6);
-
-  AudioCodec c7;
-  AudioCodec c8(0, "", 0, 0, 0, 0);
-  AudioCodec c9 = c0;
-  EXPECT_TRUE(c8 == c7);
-  EXPECT_TRUE(c9 != c7);
-  EXPECT_TRUE(c9 == c0);
-
-  AudioCodec c10(c0);
-  AudioCodec c11(c0);
-  AudioCodec c12(c0);
-  AudioCodec c13(c0);
-  c10.params["x"] = "abc";
-  c11.params["x"] = "def";
-  c12.params["y"] = "abc";
-  c13.params["x"] = "abc";
-  EXPECT_TRUE(c10 != c0);
-  EXPECT_TRUE(c11 != c0);
-  EXPECT_TRUE(c11 != c10);
-  EXPECT_TRUE(c12 != c0);
-  EXPECT_TRUE(c12 != c10);
-  EXPECT_TRUE(c12 != c11);
-  EXPECT_TRUE(c13 == c10);
-}
-
-TEST_F(CodecTest, TestAudioCodecMatches) {
-  // Test a codec with a static payload type.
-  AudioCodec c0(95, "A", 44100, 20000, 2, 3);
-  EXPECT_TRUE(c0.Matches(95, ""));
-  EXPECT_FALSE(c0.Matches(96, ""));
-  EXPECT_TRUE(c0.Matches(AudioCodec(95, "", 44100, 20000, 2, 0)));
-  EXPECT_TRUE(c0.Matches(AudioCodec(95, "", 44100, 20000, 0, 0)));
-  EXPECT_TRUE(c0.Matches(AudioCodec(95, "", 44100, 0, 0, 0)));
-  EXPECT_TRUE(c0.Matches(AudioCodec(95, "", 0, 0, 0, 0)));
-  EXPECT_FALSE(c0.Matches(AudioCodec(96, "", 44100, 20000, 2, 0)));
-  EXPECT_FALSE(c0.Matches(AudioCodec(95, "", 55100, 20000, 2, 0)));
-  EXPECT_FALSE(c0.Matches(AudioCodec(95, "", 44100, 30000, 2, 0)));
-  EXPECT_FALSE(c0.Matches(AudioCodec(95, "", 44100, 20000, 1, 0)));
-  EXPECT_FALSE(c0.Matches(AudioCodec(95, "", 55100, 30000, 1, 0)));
-
-  // Test a codec with a dynamic payload type.
-  AudioCodec c1(96, "A", 44100, 20000, 2, 3);
-  EXPECT_TRUE(c1.Matches(96, "A"));
-  EXPECT_TRUE(c1.Matches(97, "A"));
-  EXPECT_TRUE(c1.Matches(96, "a"));
-  EXPECT_TRUE(c1.Matches(97, "a"));
-  EXPECT_FALSE(c1.Matches(96, ""));
-  EXPECT_FALSE(c1.Matches(95, "A"));
-  EXPECT_TRUE(c1.Matches(AudioCodec(96, "A", 0, 0, 0, 0)));
-  EXPECT_FALSE(c1.Matches(AudioCodec(96, "", 44100, 20000, 2, 0)));
-  EXPECT_FALSE(c1.Matches(AudioCodec(96, "A", 55100, 30000, 1, 0)));
-
-  // Test a codec with a dynamic payload type, and auto bitrate.
-  AudioCodec c2(97, "A", 16000, 0, 1, 3);
-  // Use default bitrate.
-  EXPECT_TRUE(c2.Matches(AudioCodec(97, "A", 16000, 0, 1, 0)));
-  EXPECT_TRUE(c2.Matches(AudioCodec(97, "A", 16000, 0, 0, 0)));
-  // Use explicit bitrate.
-  EXPECT_TRUE(c2.Matches(AudioCodec(97, "A", 16000, 32000, 1, 0)));
-  // Backward compatibility with clients that might send "-1" (for default).
-  EXPECT_TRUE(c2.Matches(AudioCodec(97, "A", 16000, -1, 1, 0)));
-}
-
-TEST_F(CodecTest, TestVideoCodecOperators) {
-  VideoCodec c0(96, "V", 320, 200, 30, 3);
-  VideoCodec c1(95, "V", 320, 200, 30, 3);
-  VideoCodec c2(96, "x", 320, 200, 30, 3);
-  VideoCodec c3(96, "V", 120, 200, 30, 3);
-  VideoCodec c4(96, "V", 320, 100, 30, 3);
-  VideoCodec c5(96, "V", 320, 200, 10, 3);
-  VideoCodec c6(96, "V", 320, 200, 30, 1);
-  EXPECT_TRUE(c0 != c1);
-  EXPECT_TRUE(c0 != c2);
-  EXPECT_TRUE(c0 != c3);
-  EXPECT_TRUE(c0 != c4);
-  EXPECT_TRUE(c0 != c5);
-  EXPECT_TRUE(c0 != c6);
-
-  VideoCodec c7;
-  VideoCodec c8(0, "", 0, 0, 0, 0);
-  VideoCodec c9 = c0;
-  EXPECT_TRUE(c8 == c7);
-  EXPECT_TRUE(c9 != c7);
-  EXPECT_TRUE(c9 == c0);
-
-  VideoCodec c10(c0);
-  VideoCodec c11(c0);
-  VideoCodec c12(c0);
-  VideoCodec c13(c0);
-  c10.params["x"] = "abc";
-  c11.params["x"] = "def";
-  c12.params["y"] = "abc";
-  c13.params["x"] = "abc";
-  EXPECT_TRUE(c10 != c0);
-  EXPECT_TRUE(c11 != c0);
-  EXPECT_TRUE(c11 != c10);
-  EXPECT_TRUE(c12 != c0);
-  EXPECT_TRUE(c12 != c10);
-  EXPECT_TRUE(c12 != c11);
-  EXPECT_TRUE(c13 == c10);
-}
-
-TEST_F(CodecTest, TestVideoCodecMatches) {
-  // Test a codec with a static payload type.
-  VideoCodec c0(95, "V", 320, 200, 30, 3);
-  EXPECT_TRUE(c0.Matches(95, ""));
-  EXPECT_FALSE(c0.Matches(96, ""));
-  EXPECT_TRUE(c0.Matches(VideoCodec(95, "", 640, 400, 15, 0)));
-  EXPECT_FALSE(c0.Matches(VideoCodec(96, "", 320, 200, 30, 0)));
-
-  // Test a codec with a dynamic payload type.
-  VideoCodec c1(96, "V", 320, 200, 30, 3);
-  EXPECT_TRUE(c1.Matches(96, "V"));
-  EXPECT_TRUE(c1.Matches(97, "V"));
-  EXPECT_TRUE(c1.Matches(96, "v"));
-  EXPECT_TRUE(c1.Matches(97, "v"));
-  EXPECT_FALSE(c1.Matches(96, ""));
-  EXPECT_FALSE(c1.Matches(95, "V"));
-  EXPECT_TRUE(c1.Matches(VideoCodec(96, "V", 640, 400, 15, 0)));
-  EXPECT_FALSE(c1.Matches(VideoCodec(96, "", 320, 200, 30, 0)));
-}
-
-TEST_F(CodecTest, TestVideoEncoderConfigOperators) {
-  VideoEncoderConfig c1(VideoCodec(
-      96, "SVC", 320, 200, 30, 3), 1, 2);
-  VideoEncoderConfig c2(VideoCodec(
-      95, "SVC", 320, 200, 30, 3), 1, 2);
-  VideoEncoderConfig c3(VideoCodec(
-      96, "xxx", 320, 200, 30, 3), 1, 2);
-  VideoEncoderConfig c4(VideoCodec(
-      96, "SVC", 120, 200, 30, 3), 1, 2);
-  VideoEncoderConfig c5(VideoCodec(
-      96, "SVC", 320, 100, 30, 3), 1, 2);
-  VideoEncoderConfig c6(VideoCodec(
-      96, "SVC", 320, 200, 10, 3), 1, 2);
-  VideoEncoderConfig c7(VideoCodec(
-      96, "SVC", 320, 200, 30, 1), 1, 2);
-  VideoEncoderConfig c8(VideoCodec(
-      96, "SVC", 320, 200, 30, 3), 0, 2);
-  VideoEncoderConfig c9(VideoCodec(
-      96, "SVC", 320, 200, 30, 3), 1, 1);
-  EXPECT_TRUE(c1 != c2);
-  EXPECT_TRUE(c1 != c2);
-  EXPECT_TRUE(c1 != c3);
-  EXPECT_TRUE(c1 != c4);
-  EXPECT_TRUE(c1 != c5);
-  EXPECT_TRUE(c1 != c6);
-  EXPECT_TRUE(c1 != c7);
-  EXPECT_TRUE(c1 != c8);
-  EXPECT_TRUE(c1 != c9);
-
-  VideoEncoderConfig c10;
-  VideoEncoderConfig c11(VideoCodec(
-      0, "", 0, 0, 0, 0));
-  VideoEncoderConfig c12(VideoCodec(
-      0, "", 0, 0, 0, 0),
-      VideoEncoderConfig::kDefaultMaxThreads,
-      VideoEncoderConfig::kDefaultCpuProfile);
-  VideoEncoderConfig c13 = c1;
-  VideoEncoderConfig c14(VideoCodec(
-      0, "", 0, 0, 0, 0), 0, 0);
-
-  EXPECT_TRUE(c11 == c10);
-  EXPECT_TRUE(c12 == c10);
-  EXPECT_TRUE(c13 != c10);
-  EXPECT_TRUE(c13 == c1);
-  EXPECT_TRUE(c14 != c11);
-  EXPECT_TRUE(c14 != c12);
-}
diff --git a/third_party/libjingle/source/talk/session/phone/cryptoparams.h b/third_party/libjingle/source/talk/session/phone/cryptoparams.h
deleted file mode 100644
index 15e94a0..0000000
--- a/third_party/libjingle/source/talk/session/phone/cryptoparams.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SESSION_PHONE_CRYPTOPARAMS_H_
-#define TALK_SESSION_PHONE_CRYPTOPARAMS_H_
-
-#include <string>
-
-namespace cricket {
-
-// Parameters for SRTP negotiation, as described in RFC 4568.
-struct CryptoParams {
-  CryptoParams() : tag(0) {}
-  CryptoParams(int t, const std::string& cs,
-               const std::string& kp, const std::string& sp)
-      : tag(t), cipher_suite(cs), key_params(kp), session_params(sp) {}
-
-  bool Matches(const CryptoParams& params) const {
-    return (tag == params.tag && cipher_suite == params.cipher_suite);
-  }
-
-  int tag;
-  std::string cipher_suite;
-  std::string key_params;
-  std::string session_params;
-};
-
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_CRYPTOPARAMS_H_
diff --git a/third_party/libjingle/source/talk/session/phone/currentspeakermonitor.cc b/third_party/libjingle/source/talk/session/phone/currentspeakermonitor.cc
deleted file mode 100644
index 1ca6bd9..0000000
--- a/third_party/libjingle/source/talk/session/phone/currentspeakermonitor.cc
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * libjingle
- * Copyright 2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/session/phone/currentspeakermonitor.h"
-
-#include "talk/base/logging.h"
-#include "talk/session/phone/call.h"
-
-namespace cricket {
-
-namespace {
-const int kMaxAudioLevel = 9;
-// To avoid overswitching, we disable switching for a period of time after a
-// switch is done.
-const int kDefaultMinTimeBetweenSwitches = 1000;
-}
-
-CurrentSpeakerMonitor::CurrentSpeakerMonitor(Call* call, BaseSession* session)
-    : started_(false),
-      call_(call),
-      session_(session),
-      current_speaker_ssrc_(0),
-      earliest_permitted_switch_time_(0),
-      min_time_between_switches_(kDefaultMinTimeBetweenSwitches) {
-}
-
-CurrentSpeakerMonitor::~CurrentSpeakerMonitor() {
-  Stop();
-}
-
-void CurrentSpeakerMonitor::Start() {
-  if (!started_) {
-    call_->SignalAudioMonitor.connect(
-        this, &CurrentSpeakerMonitor::OnAudioMonitor);
-    call_->SignalMediaSourcesUpdate.connect(
-        this, &CurrentSpeakerMonitor::OnMediaSourcesUpdate);
-
-    started_ = true;
-  }
-}
-
-void CurrentSpeakerMonitor::Stop() {
-  if (started_) {
-    call_->SignalAudioMonitor.disconnect(this);
-    call_->SignalMediaSourcesUpdate.disconnect(this);
-
-    started_ = false;
-    ssrc_to_speaking_state_map_.clear();
-    current_speaker_ssrc_ = 0;
-    earliest_permitted_switch_time_ = 0;
-  }
-}
-
-void CurrentSpeakerMonitor::set_min_time_between_switches(
-    uint32 min_time_between_switches) {
-  min_time_between_switches_ = min_time_between_switches;
-}
-
-void CurrentSpeakerMonitor::OnAudioMonitor(Call* call, const AudioInfo& info) {
-  std::map<uint32, int> active_ssrc_to_level_map;
-  cricket::AudioInfo::StreamList::const_iterator stream_list_it;
-  for (stream_list_it = info.active_streams.begin();
-       stream_list_it != info.active_streams.end(); ++stream_list_it) {
-    uint32 ssrc = stream_list_it->first;
-    active_ssrc_to_level_map[ssrc] = stream_list_it->second;
-
-    // It's possible we haven't yet added this source to our map.  If so,
-    // add it now with a "not speaking" state.
-    if (ssrc_to_speaking_state_map_.find(ssrc) ==
-        ssrc_to_speaking_state_map_.end()) {
-      ssrc_to_speaking_state_map_[ssrc] = SS_NOT_SPEAKING;
-    }
-  }
-
-  int max_level = 0;
-  uint32 loudest_speaker_ssrc = 0;
-
-  // Update the speaking states of all participants based on the new audio
-  // level information.  Also retain loudest speaker.
-  std::map<uint32, SpeakingState>::iterator state_it;
-  for (state_it = ssrc_to_speaking_state_map_.begin();
-       state_it != ssrc_to_speaking_state_map_.end(); ++state_it) {
-    bool is_previous_speaker = current_speaker_ssrc_ == state_it->first;
-
-    // This uses a state machine in order to gradually identify
-    // members as having started or stopped speaking. Matches the
-    // algorithm used by the hangouts js code.
-
-    std::map<uint32, int>::const_iterator level_it =
-        active_ssrc_to_level_map.find(state_it->first);
-    // Note that the stream map only contains streams with non-zero audio
-    // levels.
-    int level = (level_it != active_ssrc_to_level_map.end()) ?
-        level_it->second : 0;
-    switch (state_it->second) {
-      case SS_NOT_SPEAKING:
-        if (level > 0) {
-          // Reset level because we don't think they're really speaking.
-          level = 0;
-          state_it->second = SS_MIGHT_BE_SPEAKING;
-        } else {
-          // State unchanged.
-        }
-        break;
-      case SS_MIGHT_BE_SPEAKING:
-        if (level > 0) {
-          state_it->second = SS_SPEAKING;
-        } else {
-          state_it->second = SS_NOT_SPEAKING;
-        }
-        break;
-      case SS_SPEAKING:
-        if (level > 0) {
-          // State unchanged.
-        } else {
-          state_it->second = SS_WAS_SPEAKING_RECENTLY1;
-          if (is_previous_speaker) {
-            // Assume this is an inter-word silence and assign him the highest
-            // volume.
-            level = kMaxAudioLevel;
-          }
-        }
-        break;
-      case SS_WAS_SPEAKING_RECENTLY1:
-        if (level > 0) {
-          state_it->second = SS_SPEAKING;
-        } else {
-          state_it->second = SS_WAS_SPEAKING_RECENTLY2;
-          if (is_previous_speaker) {
-            // Assume this is an inter-word silence and assign him the highest
-            // volume.
-            level = kMaxAudioLevel;
-          }
-        }
-        break;
-      case SS_WAS_SPEAKING_RECENTLY2:
-        if (level > 0) {
-          state_it->second = SS_SPEAKING;
-        } else {
-          state_it->second = SS_NOT_SPEAKING;
-        }
-        break;
-    }
-
-    if (level > max_level) {
-      loudest_speaker_ssrc = state_it->first;
-      max_level = level;
-    } else if (level > 0 && level == max_level && is_previous_speaker) {
-      // Favor continuity of loudest speakers if audio levels are equal.
-      loudest_speaker_ssrc = state_it->first;
-    }
-  }
-
-  // We avoid over-switching by disabling switching for a period of time after
-  // a switch is done.
-  uint32 now = talk_base::Time();
-  if (earliest_permitted_switch_time_ <= now &&
-      current_speaker_ssrc_ != loudest_speaker_ssrc) {
-    current_speaker_ssrc_ = loudest_speaker_ssrc;
-    LOG(LS_INFO) << "Current speaker changed to " << current_speaker_ssrc_;
-    earliest_permitted_switch_time_ = now + min_time_between_switches_;
-    SignalUpdate(this, current_speaker_ssrc_);
-  }
-}
-
-void CurrentSpeakerMonitor::OnMediaSourcesUpdate(Call* call,
-                                                 Session* session,
-                                                 const MediaSources& sources) {
-  if (call == call_ && session == session_) {
-    // Update the speaking state map based on new or removed sources.
-    NamedSources::const_iterator it;
-    for (it = sources.audio().begin(); it != sources.audio().end(); it++) {
-      if (it->ssrc_set) {
-        if (it->removed) {
-          ssrc_to_speaking_state_map_.erase(it->ssrc);
-        } else if (ssrc_to_speaking_state_map_.find(it->ssrc) ==
-            ssrc_to_speaking_state_map_.begin()) {
-          ssrc_to_speaking_state_map_[it->ssrc] = SS_NOT_SPEAKING;
-        }
-      }
-    }
-  }
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/session/phone/currentspeakermonitor.h b/third_party/libjingle/source/talk/session/phone/currentspeakermonitor.h
deleted file mode 100644
index 84207fb..0000000
--- a/third_party/libjingle/source/talk/session/phone/currentspeakermonitor.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * libjingle
- * Copyright 2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// CurrentSpeakerMonitor monitors the audio levels for a session and determines
-// which participant is currently speaking.
-
-#ifndef TALK_SESSION_PHONE_CURRENTSPEAKERMONITOR_H_
-#define TALK_SESSION_PHONE_CURRENTSPEAKERMONITOR_H_
-
-#include <map>
-
-#include "talk/base/basictypes.h"
-#include "talk/base/sigslot.h"
-
-namespace cricket {
-
-class BaseSession;
-class Call;
-class Session;
-struct AudioInfo;
-struct MediaSources;
-
-// Note that the call's audio monitor must be started before this is started.
-// It's recommended that the audio monitor be started with a 100 ms period.
-class CurrentSpeakerMonitor : public sigslot::has_slots<> {
- public:
-  CurrentSpeakerMonitor(Call* call, BaseSession* session);
-  ~CurrentSpeakerMonitor();
-
-  BaseSession* session() const { return session_; }
-
-  void Start();
-  void Stop();
-
-  // Used by tests.  Note that the actual minimum time between switches
-  // enforced by the monitor will be the given value plus or minus the
-  // resolution of the system clock.
-  void set_min_time_between_switches(uint32 min_time_between_switches);
-
-  // This is fired when the current speaker changes, and provides his audio
-  // SSRC.  This only fires after the audio monitor on the underlying Call has
-  // been started.
-  sigslot::signal2<CurrentSpeakerMonitor*, uint32> SignalUpdate;
-
- private:
-  void OnAudioMonitor(Call* call, const AudioInfo& info);
-  void OnMediaSourcesUpdate(Call* call,
-                            Session* session,
-                            const MediaSources& sources);
-
-  // These are states that a participant will pass through so that we gradually
-  // recognize that they have started and stopped speaking.  This avoids
-  // "twitchiness".
-  enum SpeakingState {
-    SS_NOT_SPEAKING,
-    SS_MIGHT_BE_SPEAKING,
-    SS_SPEAKING,
-    SS_WAS_SPEAKING_RECENTLY1,
-    SS_WAS_SPEAKING_RECENTLY2
-  };
-
-  bool started_;
-  Call* call_;
-  BaseSession* session_;
-  std::map<uint32, SpeakingState> ssrc_to_speaking_state_map_;
-  uint32 current_speaker_ssrc_;
-  // To prevent overswitching, switching is disabled for some time after a
-  // switch is made.  This gives us the earliest time a switch is permitted.
-  uint32 earliest_permitted_switch_time_;
-  uint32 min_time_between_switches_;
-};
-
-}
-
-#endif  // TALK_SESSION_PHONE_CURRENTSPEAKERMONITOR_H_
diff --git a/third_party/libjingle/source/talk/session/phone/currentspeakermonitor_unittest.cc b/third_party/libjingle/source/talk/session/phone/currentspeakermonitor_unittest.cc
deleted file mode 100644
index 264fa25..0000000
--- a/third_party/libjingle/source/talk/session/phone/currentspeakermonitor_unittest.cc
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/gunit.h"
-#include "talk/base/thread.h"
-#include "talk/session/phone/call.h"
-#include "talk/session/phone/currentspeakermonitor.h"
-
-namespace cricket {
-
-static const uint32 kSsrc1 = 1001;
-static const uint32 kSsrc2 = 1002;
-static const uint32 kMinTimeBetweenSwitches = 10;
-// Due to limited system clock resolution, the CurrentSpeakerMonitor may
-// actually require more or less time between switches than that specified
-// in the call to set_min_time_between_switches.  To be safe, we sleep for
-// 90 ms more than the min time between switches before checking for a switch.
-// I am assuming system clocks do not have a coarser resolution than 90 ms.
-static const uint32 kSleepTimeBetweenSwitches = 100;
-
-class MockCall : public Call {
- public:
-  MockCall() : Call(NULL) {}
-
-  void EmitAudioMonitor(const AudioInfo& info) {
-    SignalAudioMonitor(this, info);
-  }
-};
-
-class CurrentSpeakerMonitorTest : public testing::Test,
-    public sigslot::has_slots<> {
- public:
-  CurrentSpeakerMonitorTest() {
-    call_ = new MockCall();
-    monitor_ = new CurrentSpeakerMonitor(call_, NULL);
-    // Shrink the minimum time betweeen switches to 10 ms so we don't have to
-    // slow down our tests.
-    monitor_->set_min_time_between_switches(kMinTimeBetweenSwitches);
-    monitor_->SignalUpdate.connect(this, &CurrentSpeakerMonitorTest::OnUpdate);
-    current_speaker_ = 0;
-    num_changes_ = 0;
-    monitor_->Start();
-  }
-
-  ~CurrentSpeakerMonitorTest() {
-    delete monitor_;
-    delete call_;
-  }
-
- protected:
-  MockCall* call_;
-  CurrentSpeakerMonitor* monitor_;
-  int num_changes_;
-  uint32 current_speaker_;
-
-  void OnUpdate(CurrentSpeakerMonitor* monitor, uint32 current_speaker) {
-    current_speaker_ = current_speaker;
-    num_changes_++;
-  }
-};
-
-static void InitAudioInfo(AudioInfo* info, int input_level, int output_level) {
-  info->input_level = input_level;
-  info->output_level = output_level;
-}
-
-TEST_F(CurrentSpeakerMonitorTest, NoActiveStreams) {
-  AudioInfo info;
-  InitAudioInfo(&info, 0, 0);
-  call_->EmitAudioMonitor(info);
-
-  EXPECT_EQ(current_speaker_, 0U);
-  EXPECT_EQ(num_changes_, 0);
-}
-
-TEST_F(CurrentSpeakerMonitorTest, MultipleActiveStreams) {
-  AudioInfo info;
-  InitAudioInfo(&info, 0, 0);
-
-  info.active_streams.push_back(std::make_pair(kSsrc1, 3));
-  info.active_streams.push_back(std::make_pair(kSsrc2, 7));
-  call_->EmitAudioMonitor(info);
-
-  // No speaker recognized because the initial sample is treated as possibly
-  // just noise and disregarded.
-  EXPECT_EQ(current_speaker_, 0U);
-  EXPECT_EQ(num_changes_, 0);
-
-  info.active_streams.push_back(std::make_pair(kSsrc1, 3));
-  info.active_streams.push_back(std::make_pair(kSsrc2, 7));
-  call_->EmitAudioMonitor(info);
-
-  EXPECT_EQ(current_speaker_, kSsrc2);
-  EXPECT_EQ(num_changes_, 1);
-}
-
-TEST_F(CurrentSpeakerMonitorTest, RapidSpeakerChange) {
-  AudioInfo info;
-  InitAudioInfo(&info, 0, 0);
-
-  info.active_streams.push_back(std::make_pair(kSsrc1, 3));
-  info.active_streams.push_back(std::make_pair(kSsrc2, 7));
-  call_->EmitAudioMonitor(info);
-
-  EXPECT_EQ(current_speaker_, 0U);
-  EXPECT_EQ(num_changes_, 0);
-
-  info.active_streams.push_back(std::make_pair(kSsrc1, 3));
-  info.active_streams.push_back(std::make_pair(kSsrc2, 7));
-  call_->EmitAudioMonitor(info);
-
-  EXPECT_EQ(current_speaker_, kSsrc2);
-  EXPECT_EQ(num_changes_, 1);
-
-  info.active_streams.push_back(std::make_pair(kSsrc1, 9));
-  info.active_streams.push_back(std::make_pair(kSsrc2, 1));
-  call_->EmitAudioMonitor(info);
-
-  // We expect no speaker change because of the rapid change.
-  EXPECT_EQ(current_speaker_, kSsrc2);
-  EXPECT_EQ(num_changes_, 1);
-}
-
-TEST_F(CurrentSpeakerMonitorTest, SpeakerChange) {
-  AudioInfo info;
-  InitAudioInfo(&info, 0, 0);
-
-  info.active_streams.push_back(std::make_pair(kSsrc1, 3));
-  info.active_streams.push_back(std::make_pair(kSsrc2, 7));
-  call_->EmitAudioMonitor(info);
-
-  EXPECT_EQ(current_speaker_, 0U);
-  EXPECT_EQ(num_changes_, 0);
-
-  info.active_streams.push_back(std::make_pair(kSsrc1, 3));
-  info.active_streams.push_back(std::make_pair(kSsrc2, 7));
-  call_->EmitAudioMonitor(info);
-
-  EXPECT_EQ(current_speaker_, kSsrc2);
-  EXPECT_EQ(num_changes_, 1);
-
-  // Wait so the changes don't come so rapidly.
-  talk_base::Thread::SleepMs(kSleepTimeBetweenSwitches);
-
-  info.active_streams.push_back(std::make_pair(kSsrc1, 9));
-  info.active_streams.push_back(std::make_pair(kSsrc2, 1));
-  call_->EmitAudioMonitor(info);
-
-  EXPECT_EQ(current_speaker_, kSsrc1);
-  EXPECT_EQ(num_changes_, 2);
-}
-
-TEST_F(CurrentSpeakerMonitorTest, InterwordSilence) {
-  AudioInfo info;
-  InitAudioInfo(&info, 0, 0);
-
-  info.active_streams.push_back(std::make_pair(kSsrc1, 3));
-  info.active_streams.push_back(std::make_pair(kSsrc2, 7));
-  call_->EmitAudioMonitor(info);
-
-  EXPECT_EQ(current_speaker_, 0U);
-  EXPECT_EQ(num_changes_, 0);
-
-  info.active_streams.push_back(std::make_pair(kSsrc1, 3));
-  info.active_streams.push_back(std::make_pair(kSsrc2, 7));
-  call_->EmitAudioMonitor(info);
-
-  EXPECT_EQ(current_speaker_, kSsrc2);
-  EXPECT_EQ(num_changes_, 1);
-
-  info.active_streams.push_back(std::make_pair(kSsrc1, 3));
-  info.active_streams.push_back(std::make_pair(kSsrc2, 7));
-  call_->EmitAudioMonitor(info);
-
-  EXPECT_EQ(current_speaker_, kSsrc2);
-  EXPECT_EQ(num_changes_, 1);
-
-  // Wait so the changes don't come so rapidly.
-  talk_base::Thread::SleepMs(kSleepTimeBetweenSwitches);
-
-  info.active_streams.push_back(std::make_pair(kSsrc1, 3));
-  info.active_streams.push_back(std::make_pair(kSsrc2, 0));
-  call_->EmitAudioMonitor(info);
-
-  // Current speaker shouldn't have changed because we treat this as an inter-
-  // word silence.
-  EXPECT_EQ(current_speaker_, kSsrc2);
-  EXPECT_EQ(num_changes_, 1);
-
-  info.active_streams.push_back(std::make_pair(kSsrc1, 3));
-  info.active_streams.push_back(std::make_pair(kSsrc2, 0));
-  call_->EmitAudioMonitor(info);
-
-  // Current speaker shouldn't have changed because we treat this as an inter-
-  // word silence.
-  EXPECT_EQ(current_speaker_, kSsrc2);
-  EXPECT_EQ(num_changes_, 1);
-
-  info.active_streams.push_back(std::make_pair(kSsrc1, 3));
-  info.active_streams.push_back(std::make_pair(kSsrc2, 0));
-  call_->EmitAudioMonitor(info);
-
-  // At this point, we should have concluded that SSRC2 stopped speaking.
-  EXPECT_EQ(current_speaker_, kSsrc1);
-  EXPECT_EQ(num_changes_, 2);
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/session/phone/devicemanager.cc b/third_party/libjingle/source/talk/session/phone/devicemanager.cc
deleted file mode 100644
index 67dfe41..0000000
--- a/third_party/libjingle/source/talk/session/phone/devicemanager.cc
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * libjingle
- * Copyright 2004 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/session/phone/devicemanager.h"
-
-#include "talk/base/logging.h"
-#include "talk/base/stringutils.h"
-#include "talk/base/thread.h"
-#include "talk/session/phone/mediacommon.h"
-
-namespace cricket {
-// Initialize to empty string.
-const char DeviceManagerInterface::kDefaultDeviceName[] = "";
-
-DeviceManager::DeviceManager()
-    : initialized_(false) {
-}
-
-DeviceManager::~DeviceManager() {
-  if (initialized()) {
-    Terminate();
-  }
-}
-
-bool DeviceManager::Init() {
-  if (!initialized()) {
-    if (!watcher()->Start()) {
-      return false;
-    }
-    set_initialized(true);
-  }
-  return true;
-}
-
-void DeviceManager::Terminate() {
-  if (initialized()) {
-    watcher()->Stop();
-    set_initialized(false);
-  }
-}
-
-int DeviceManager::GetCapabilities() {
-  std::vector<Device> devices;
-  int caps = VIDEO_RECV;
-  if (GetAudioInputDevices(&devices) && !devices.empty()) {
-    caps |= AUDIO_SEND;
-  }
-  if (GetAudioOutputDevices(&devices) && !devices.empty()) {
-    caps |= AUDIO_RECV;
-  }
-  if (GetVideoCaptureDevices(&devices) && !devices.empty()) {
-    caps |= VIDEO_SEND;
-  }
-  return caps;
-}
-
-bool DeviceManager::GetAudioInputDevices(std::vector<Device>* devices) {
-  return GetAudioDevices(true, devices);
-}
-
-bool DeviceManager::GetAudioOutputDevices(std::vector<Device>* devices) {
-  return GetAudioDevices(false, devices);
-}
-
-bool DeviceManager::GetAudioInputDevice(const std::string& name, Device* out) {
-  return GetAudioDevice(true, name, out);
-}
-
-bool DeviceManager::GetAudioOutputDevice(const std::string& name, Device* out) {
-  return GetAudioDevice(false, name, out);
-}
-
-bool DeviceManager::GetVideoCaptureDevices(std::vector<Device>* devices) {
-  devices->clear();
-#if defined(ANDROID) || defined(IOS)
-  // TODO: Incomplete. Use ANDROID implementation for IOS
-  // to quiet compiler.
-  // On Android, we treat the camera(s) as a single device. Even if there are
-  // multiple cameras, that's abstracted away at a higher level.
-  Device dev("camera", "1");    // name and ID
-  devices->push_back(dev);
-#else
-  return false;
-#endif
-}
-
-bool DeviceManager::GetVideoCaptureDevice(const std::string& name,
-                                          Device* out) {
-  // If the name is empty, return the default device.
-  if (name.empty() || name == kDefaultDeviceName) {
-    return GetDefaultVideoCaptureDevice(out);
-  }
-
-  std::vector<Device> devices;
-  if (!GetVideoCaptureDevices(&devices)) {
-    return false;
-  }
-
-  for (std::vector<Device>::const_iterator it = devices.begin();
-      it != devices.end(); ++it) {
-    if (name == it->name) {
-      *out = *it;
-      return true;
-    }
-  }
-
-  return false;
-}
-
-bool DeviceManager::GetAudioDevices(bool input,
-                                    std::vector<Device>* devs) {
-  devs->clear();
-#ifdef ANDROID
-  // Under Android, we don't access the device file directly.
-  // Arbitrary use 0 for the mic and 1 for the output.
-  // These ids are used in MediaEngine::SetSoundDevices(in, out);
-  // The strings are for human consumption.
-  if (input) {
-      devs->push_back(Device("audiorecord", 0));
-  } else {
-      devs->push_back(Device("audiotrack", 1));
-  }
-  return true;
-#else
-  return false;
-#endif
-}
-
-bool DeviceManager::GetAudioDevice(bool is_input, const std::string& name,
-                                   Device* out) {
-  // If the name is empty, return the default device id.
-  if (name.empty() || name == kDefaultDeviceName) {
-    *out = Device(name, -1);
-    return true;
-  }
-
-  std::vector<Device> devices;
-  bool ret = is_input ? GetAudioInputDevices(&devices) :
-                        GetAudioOutputDevices(&devices);
-  if (ret) {
-    ret = false;
-    for (size_t i = 0; i < devices.size(); ++i) {
-      if (devices[i].name == name) {
-        *out = devices[i];
-        ret = true;
-        break;
-      }
-    }
-  }
-  return ret;
-}
-
-bool DeviceManager::GetDefaultVideoCaptureDevice(Device* device) {
-  bool ret = false;
-  // We just return the first device.
-  std::vector<Device> devices;
-  ret = (GetVideoCaptureDevices(&devices) && !devices.empty());
-  if (ret) {
-    *device = devices[0];
-  }
-  return ret;
-}
-
-bool DeviceManager::ShouldDeviceBeIgnored(const std::string& device_name,
-    const char* const exclusion_list[]) {
-  // If exclusion_list is empty return directly.
-  if (!exclusion_list)
-    return false;
-
-  int i = 0;
-  while (exclusion_list[i]) {
-    if (strnicmp(device_name.c_str(), exclusion_list[i],
-        strlen(exclusion_list[i])) == 0) {
-      LOG(LS_INFO) << "Ignoring device " << device_name;
-      return true;
-    }
-    ++i;
-  }
-  return false;
-}
-
-bool DeviceManager::FilterDevices(std::vector<Device>* devices,
-    const char* const exclusion_list[]) {
-  if (!devices) {
-    return false;
-  }
-
-  for (std::vector<Device>::iterator it = devices->begin();
-       it != devices->end(); ) {
-    if (ShouldDeviceBeIgnored(it->name, exclusion_list)) {
-      it = devices->erase(it);
-    } else {
-      ++it;
-    }
-  }
-  return true;
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/session/phone/devicemanager.h b/third_party/libjingle/source/talk/session/phone/devicemanager.h
deleted file mode 100644
index 3cf3554..0000000
--- a/third_party/libjingle/source/talk/session/phone/devicemanager.h
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * libjingle
- * Copyright 2004 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SESSION_PHONE_DEVICEMANAGER_H_
-#define TALK_SESSION_PHONE_DEVICEMANAGER_H_
-
-#include <string>
-#include <vector>
-
-#include "talk/base/scoped_ptr.h"
-#include "talk/base/sigslot.h"
-#include "talk/base/stringencode.h"
-
-namespace cricket {
-
-// Used to represent an audio or video capture or render device.
-struct Device {
-  Device() {}
-  Device(const std::string& first, int second)
-      : name(first),
-        id(talk_base::ToString(second)) {
-  }
-  Device(const std::string& first, const std::string& second)
-      : name(first), id(second) {}
-
-  std::string name;
-  std::string id;
-};
-
-// DeviceManagerInterface - interface to manage the audio and
-// video devices on the system.
-class DeviceManagerInterface {
- public:
-  virtual ~DeviceManagerInterface() { }
-
-  // Initialization
-  virtual bool Init() = 0;
-  virtual void Terminate() = 0;
-
-  // Capabilities
-  virtual int GetCapabilities() = 0;
-
-  // Device enumeration
-  virtual bool GetAudioInputDevices(std::vector<Device>* devices) = 0;
-  virtual bool GetAudioOutputDevices(std::vector<Device>* devices) = 0;
-
-  virtual bool GetAudioInputDevice(const std::string& name, Device* out) = 0;
-  virtual bool GetAudioOutputDevice(const std::string& name, Device* out) = 0;
-
-  virtual bool GetVideoCaptureDevices(std::vector<Device>* devs) = 0;
-  virtual bool GetVideoCaptureDevice(const std::string& name, Device* out) = 0;
-
-  sigslot::signal0<> SignalDevicesChange;
-
-  static const char kDefaultDeviceName[];
-};
-
-class DeviceWatcher {
- public:
-  explicit DeviceWatcher(DeviceManagerInterface* dm) {}
-  virtual ~DeviceWatcher() {}
-  virtual bool Start() { return true; }
-  virtual void Stop() {}
-};
-
-class DeviceManagerFactory {
- public:
-  static DeviceManagerInterface* Create();
- private:
-  DeviceManagerFactory();
-};
-
-class DeviceManager : public DeviceManagerInterface {
- public:
-  DeviceManager();
-  virtual ~DeviceManager();
-
-  // Initialization
-  virtual bool Init();
-  virtual void Terminate();
-
-  // Capabilities
-  virtual int GetCapabilities();
-
-  // Device enumeration
-  virtual bool GetAudioInputDevices(std::vector<Device>* devices);
-  virtual bool GetAudioOutputDevices(std::vector<Device>* devices);
-
-  virtual bool GetAudioInputDevice(const std::string& name, Device* out);
-  virtual bool GetAudioOutputDevice(const std::string& name, Device* out);
-
-  virtual bool GetVideoCaptureDevices(std::vector<Device>* devs);
-  virtual bool GetVideoCaptureDevice(const std::string& name, Device* out);
-
-  // The exclusion_list MUST be a NULL terminated list.
-  static bool FilterDevices(std::vector<Device>* devices,
-      const char* const exclusion_list[]);
-  bool initialized() const { return initialized_; }
-
- protected:
-  virtual bool GetAudioDevices(bool input, std::vector<Device>* devs);
-  virtual bool GetAudioDevice(bool is_input, const std::string& name,
-                              Device* out);
-  virtual bool GetDefaultVideoCaptureDevice(Device* device);
-
-  void set_initialized(bool initialized) { initialized_ = initialized; }
-
-  void set_watcher(DeviceWatcher* watcher) { watcher_.reset(watcher); }
-  DeviceWatcher* watcher() { return watcher_.get(); }
-
- private:
-  // The exclusion_list MUST be a NULL terminated list.
-  static bool ShouldDeviceBeIgnored(const std::string& device_name,
-      const char* const exclusion_list[]);
-  bool initialized_;
-  talk_base::scoped_ptr<DeviceWatcher> watcher_;
-};
-
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_DEVICEMANAGER_H_
diff --git a/third_party/libjingle/source/talk/session/phone/devicemanager_mac.mm b/third_party/libjingle/source/talk/session/phone/devicemanager_mac.mm
deleted file mode 100644
index 3537ed9..0000000
--- a/third_party/libjingle/source/talk/session/phone/devicemanager_mac.mm
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/session/phone/devicemanager.h"
-
-#import <QTKit/QTKit.h>
-
-#include "talk/base/logging.h"
-
-@interface DeviceWatcherImpl : NSObject {
-@private
-  cricket::DeviceManager* manager_;
-}
-- (id)init:(cricket::DeviceManager*) dm;
-- (void)onDevicesChanged:(NSNotification *)notification;
-@end
-
-@implementation DeviceWatcherImpl
-- (id)init:(cricket::DeviceManager*) dm {
-  if ((self = [super init])) {
-    manager_ = dm;
-    [[NSNotificationCenter defaultCenter] addObserver:self
-        selector:@selector(onDevicesChanged:)
-        name:QTCaptureDeviceWasConnectedNotification
-        object:nil];
-    [[NSNotificationCenter defaultCenter] addObserver:self
-        selector:@selector(onDevicesChanged:)
-        name:QTCaptureDeviceWasDisconnectedNotification
-        object:nil];
-  }
-  return self;
-}
-- (void)dealloc {
-  [[NSNotificationCenter defaultCenter] removeObserver:self];
-  [super dealloc];
-}
-- (void)onDevicesChanged:(NSNotification *)notification {
-  manager_->OnDevicesChange();
-}
-@end
-
-namespace cricket {
-
-void* CreateDeviceWatcherCallback(DeviceManager* dm) {
-  return [[DeviceWatcherImpl alloc] init:dm];
-}
-void ReleaseDeviceWatcherCallback(void* watcher) {
-  DeviceWatcherImpl* watcher_impl = static_cast<DeviceWatcherImpl*>(watcher);
-  [watcher_impl release];
-}
-
-bool GetQTKitVideoDevices(std::vector<Device>* devices) {
-  NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
-
-  NSArray* qt_capture_devices =
-      [QTCaptureDevice inputDevicesWithMediaType:QTMediaTypeVideo];
-  NSUInteger count = [qt_capture_devices count];
-  LOG(LS_INFO) << count << " capture device(s) found:";
-  for (NSUInteger i = 0; i < count; ++i) {
-    QTCaptureDevice* qt_capture_device = [qt_capture_devices objectAtIndex:i];
-
-    static const NSString* kFormat = @"localizedDisplayName: \"%@\", "
-        "modelUniqueID: \"%@\", uniqueID \"%@\", isConnected: %d, isOpen: %d, "
-        "isInUseByAnotherApplication: %d";
-    NSString* info = [NSString stringWithFormat:kFormat,
-        [qt_capture_device localizedDisplayName],
-        [qt_capture_device modelUniqueID],
-        [qt_capture_device uniqueID],
-        [qt_capture_device isConnected],
-        [qt_capture_device isOpen],
-        [qt_capture_device isInUseByAnotherApplication]];
-    LOG(LS_INFO) << [info cStringUsingEncoding:NSUTF8StringEncoding];
-
-    std::string name([[qt_capture_device localizedDisplayName]
-                         cStringUsingEncoding:NSUTF8StringEncoding]);
-    devices->push_back(Device(name,
-       [[qt_capture_device uniqueID]
-           cStringUsingEncoding:NSUTF8StringEncoding]));
-  }
-
-  [pool drain];
-  return true;
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/session/phone/devicemanager_unittest.cc b/third_party/libjingle/source/talk/session/phone/devicemanager_unittest.cc
deleted file mode 100644
index a64eab9..0000000
--- a/third_party/libjingle/source/talk/session/phone/devicemanager_unittest.cc
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2008, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifdef WIN32
-#include "talk/base/win32.h"
-#include <objbase.h>
-#endif
-#include "talk/base/fileutils.h"
-#include "talk/base/gunit.h"
-#include "talk/base/logging.h"
-#include "talk/base/pathutils.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/base/stream.h"
-#include "talk/session/phone/devicemanager.h"
-#include "talk/session/phone/v4llookup.h"
-
-#ifdef LINUX
-// TODO: Figure out why this doesn't compile on Windows.
-#include "talk/base/fileutils_mock.h"
-#endif  // LINUX
-
-#include "talk/session/phone/devicemanager.h"
-
-using talk_base::Pathname;
-using talk_base::FileTimeType;
-using talk_base::scoped_ptr;
-using cricket::Device;
-using cricket::DeviceManager;
-using cricket::DeviceManagerFactory;
-using cricket::DeviceManagerInterface;
-
-// Test that we startup/shutdown properly.
-TEST(DeviceManagerTest, StartupShutdown) {
-  scoped_ptr<DeviceManagerInterface> dm(DeviceManagerFactory::Create());
-  EXPECT_TRUE(dm->Init());
-  dm->Terminate();
-}
-
-// Test CoInitEx behavior
-#ifdef WIN32
-TEST(DeviceManagerTest, CoInitialize) {
-  scoped_ptr<DeviceManagerInterface> dm(DeviceManagerFactory::Create());
-  std::vector<Device> devices;
-  // Ensure that calls to video device work if COM is not yet initialized.
-  EXPECT_TRUE(dm->Init());
-  EXPECT_TRUE(dm->GetVideoCaptureDevices(&devices));
-  dm->Terminate();
-  // Ensure that the ref count is correct.
-  EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_MULTITHREADED));
-  CoUninitialize();
-  // Ensure that Init works in COINIT_APARTMENTTHREADED setting.
-  EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_APARTMENTTHREADED));
-  EXPECT_TRUE(dm->Init());
-  dm->Terminate();
-  CoUninitialize();
-  // Ensure that the ref count is correct.
-  EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_APARTMENTTHREADED));
-  CoUninitialize();
-  // Ensure that Init works in COINIT_MULTITHREADED setting.
-  EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_MULTITHREADED));
-  EXPECT_TRUE(dm->Init());
-  dm->Terminate();
-  CoUninitialize();
-  // Ensure that the ref count is correct.
-  EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_MULTITHREADED));
-  CoUninitialize();
-}
-#endif
-
-// Test enumerating devices (although we may not find any).
-TEST(DeviceManagerTest, GetDevices) {
-  scoped_ptr<DeviceManagerInterface> dm(DeviceManagerFactory::Create());
-  std::vector<Device> audio_ins, audio_outs, video_ins;
-  std::vector<cricket::Device> video_in_devs;
-  cricket::Device def_video;
-  EXPECT_TRUE(dm->Init());
-  EXPECT_TRUE(dm->GetAudioInputDevices(&audio_ins));
-  EXPECT_TRUE(dm->GetAudioOutputDevices(&audio_outs));
-  EXPECT_TRUE(dm->GetVideoCaptureDevices(&video_ins));
-  EXPECT_TRUE(dm->GetVideoCaptureDevices(&video_in_devs));
-  EXPECT_EQ(video_ins.size(), video_in_devs.size());
-  // If we have any video devices, we should be able to pick a default.
-  EXPECT_TRUE(dm->GetVideoCaptureDevice(
-      cricket::DeviceManagerInterface::kDefaultDeviceName, &def_video)
-      != video_ins.empty());
-}
-
-// Test that we return correct ids for default and bogus devices.
-TEST(DeviceManagerTest, GetAudioDeviceIds) {
-  scoped_ptr<DeviceManagerInterface> dm(DeviceManagerFactory::Create());
-  Device device;
-  EXPECT_TRUE(dm->Init());
-  EXPECT_TRUE(dm->GetAudioInputDevice(
-      cricket::DeviceManagerInterface::kDefaultDeviceName, &device));
-  EXPECT_EQ("-1", device.id);
-  EXPECT_TRUE(dm->GetAudioOutputDevice(
-      cricket::DeviceManagerInterface::kDefaultDeviceName, &device));
-  EXPECT_EQ("-1", device.id);
-  EXPECT_FALSE(dm->GetAudioInputDevice("_NOT A REAL DEVICE_", &device));
-  EXPECT_FALSE(dm->GetAudioOutputDevice("_NOT A REAL DEVICE_", &device));
-}
-
-// Test that we get the video capture device by name properly.
-TEST(DeviceManagerTest, GetVideoDeviceIds) {
-  scoped_ptr<DeviceManagerInterface> dm(DeviceManagerFactory::Create());
-  Device device;
-  EXPECT_TRUE(dm->Init());
-  EXPECT_FALSE(dm->GetVideoCaptureDevice("_NOT A REAL DEVICE_", &device));
-  std::vector<Device> video_ins;
-  EXPECT_TRUE(dm->GetVideoCaptureDevices(&video_ins));
-  if (!video_ins.empty()) {
-    // Get the default device with the parameter kDefaultDeviceName.
-    EXPECT_TRUE(dm->GetVideoCaptureDevice(
-        cricket::DeviceManagerInterface::kDefaultDeviceName, &device));
-
-    // Get the first device with the parameter video_ins[0].name.
-    EXPECT_TRUE(dm->GetVideoCaptureDevice(video_ins[0].name, &device));
-    EXPECT_EQ(device.name, video_ins[0].name);
-    EXPECT_EQ(device.id, video_ins[0].id);
-  }
-}
-
-TEST(DeviceManagerTest, VerifyDevicesListsAreCleared) {
-  const std::string imaginary("_NOT A REAL DEVICE_");
-  scoped_ptr<DeviceManagerInterface> dm(DeviceManagerFactory::Create());
-  std::vector<Device> audio_ins, audio_outs, video_ins;
-  audio_ins.push_back(Device(imaginary, imaginary));
-  audio_outs.push_back(Device(imaginary, imaginary));
-  video_ins.push_back(Device(imaginary, imaginary));
-  EXPECT_TRUE(dm->Init());
-  EXPECT_TRUE(dm->GetAudioInputDevices(&audio_ins));
-  EXPECT_TRUE(dm->GetAudioOutputDevices(&audio_outs));
-  EXPECT_TRUE(dm->GetVideoCaptureDevices(&video_ins));
-  for (size_t i = 0; i < audio_ins.size(); ++i) {
-    EXPECT_NE(imaginary, audio_ins[i].name);
-  }
-  for (size_t i = 0; i < audio_outs.size(); ++i) {
-    EXPECT_NE(imaginary, audio_outs[i].name);
-  }
-  for (size_t i = 0; i < video_ins.size(); ++i) {
-    EXPECT_NE(imaginary, video_ins[i].name);
-  }
-}
-
-static bool CompareDeviceList(std::vector<Device>& devices,
-    const char* const device_list[], int list_size) {
-  if (list_size != static_cast<int>(devices.size())) {
-    return false;
-  }
-  for (int i = 0; i < list_size; ++i) {
-    if (devices[i].name.compare(device_list[i]) != 0) {
-      return false;
-    }
-  }
-  return true;
-}
-
-TEST(DeviceManagerTest, VerifyFilterDevices) {
-  static const char* const kTotalDevicesName[] = {
-      "Google Camera Adapters are tons of fun.",
-      "device1",
-      "device2",
-      "device3",
-      "device4",
-      "device5",
-      "Google Camera Adapter 0",
-      "Google Camera Adapter 1",
-  };
-  static const char* const kFilteredDevicesName[] = {
-      "device2",
-      "device4",
-      "Google Camera Adapter",
-      NULL,
-  };
-  static const char* const kDevicesName[] = {
-      "device1",
-      "device3",
-      "device5",
-  };
-  std::vector<Device> devices;
-  for (int i = 0; i < ARRAY_SIZE(kTotalDevicesName); ++i) {
-    devices.push_back(Device(kTotalDevicesName[i], i));
-  }
-  EXPECT_TRUE(CompareDeviceList(devices, kTotalDevicesName,
-                                ARRAY_SIZE(kTotalDevicesName)));
-  // Return false if given NULL as the exclusion list.
-  EXPECT_TRUE(DeviceManager::FilterDevices(&devices, NULL));
-  // The devices should not change.
-  EXPECT_TRUE(CompareDeviceList(devices, kTotalDevicesName,
-                                ARRAY_SIZE(kTotalDevicesName)));
-  EXPECT_TRUE(DeviceManager::FilterDevices(&devices, kFilteredDevicesName));
-  EXPECT_TRUE(CompareDeviceList(devices, kDevicesName,
-                                ARRAY_SIZE(kDevicesName)));
-}
-
-#ifdef LINUX
-class FakeV4LLookup : public cricket::V4LLookup {
- public:
-  explicit FakeV4LLookup(std::vector<std::string> device_paths)
-      : device_paths_(device_paths) {}
-
- protected:
-  bool CheckIsV4L2Device(const std::string& device) {
-    return std::find(device_paths_.begin(), device_paths_.end(), device)
-        != device_paths_.end();
-  }
-
- private:
-  std::vector<std::string> device_paths_;
-};
-
-TEST(DeviceManagerTest, GetVideoCaptureDevices_K2_6) {
-  std::vector<std::string> devices;
-  devices.push_back("/dev/video0");
-  devices.push_back("/dev/video5");
-  cricket::V4LLookup::SetV4LLookup(new FakeV4LLookup(devices));
-
-  std::vector<talk_base::FakeFileSystem::File> files;
-  files.push_back(talk_base::FakeFileSystem::File("/dev/video0", ""));
-  files.push_back(talk_base::FakeFileSystem::File("/dev/video5", ""));
-  files.push_back(talk_base::FakeFileSystem::File(
-      "/sys/class/video4linux/video0/name", "Video Device 1"));
-  files.push_back(talk_base::FakeFileSystem::File(
-      "/sys/class/video4linux/video1/model", "Bad Device"));
-  files.push_back(
-      talk_base::FakeFileSystem::File("/sys/class/video4linux/video5/model",
-                                      "Video Device 2"));
-  talk_base::FilesystemScope fs(new talk_base::FakeFileSystem(files));
-
-  scoped_ptr<DeviceManagerInterface> dm(DeviceManagerFactory::Create());
-  std::vector<Device> video_ins;
-  EXPECT_TRUE(dm->Init());
-  EXPECT_TRUE(dm->GetVideoCaptureDevices(&video_ins));
-  EXPECT_EQ(2u, video_ins.size());
-  EXPECT_EQ("Video Device 1", video_ins.at(0).name);
-  EXPECT_EQ("Video Device 2", video_ins.at(1).name);
-}
-
-TEST(DeviceManagerTest, GetVideoCaptureDevices_K2_4) {
-  std::vector<std::string> devices;
-  devices.push_back("/dev/video0");
-  devices.push_back("/dev/video5");
-  cricket::V4LLookup::SetV4LLookup(new FakeV4LLookup(devices));
-
-  std::vector<talk_base::FakeFileSystem::File> files;
-  files.push_back(talk_base::FakeFileSystem::File("/dev/video0", ""));
-  files.push_back(talk_base::FakeFileSystem::File("/dev/video5", ""));
-  files.push_back(talk_base::FakeFileSystem::File(
-          "/proc/video/dev/video0",
-          "param1: value1\nname: Video Device 1\n param2: value2\n"));
-  files.push_back(talk_base::FakeFileSystem::File(
-          "/proc/video/dev/video1",
-          "param1: value1\nname: Bad Device\n param2: value2\n"));
-  files.push_back(talk_base::FakeFileSystem::File(
-          "/proc/video/dev/video5",
-          "param1: value1\nname:   Video Device 2\n param2: value2\n"));
-  talk_base::FilesystemScope fs(new talk_base::FakeFileSystem(files));
-
-  scoped_ptr<DeviceManagerInterface> dm(DeviceManagerFactory::Create());
-  std::vector<Device> video_ins;
-  EXPECT_TRUE(dm->Init());
-  EXPECT_TRUE(dm->GetVideoCaptureDevices(&video_ins));
-  EXPECT_EQ(2u, video_ins.size());
-  EXPECT_EQ("Video Device 1", video_ins.at(0).name);
-  EXPECT_EQ("Video Device 2", video_ins.at(1).name);
-}
-
-TEST(DeviceManagerTest, GetVideoCaptureDevices_KUnknown) {
-  std::vector<std::string> devices;
-  devices.push_back("/dev/video0");
-  devices.push_back("/dev/video5");
-  cricket::V4LLookup::SetV4LLookup(new FakeV4LLookup(devices));
-
-  std::vector<talk_base::FakeFileSystem::File> files;
-  files.push_back(talk_base::FakeFileSystem::File("/dev/video0", ""));
-  files.push_back(talk_base::FakeFileSystem::File("/dev/video1", ""));
-  files.push_back(talk_base::FakeFileSystem::File("/dev/video5", ""));
-  talk_base::FilesystemScope fs(new talk_base::FakeFileSystem(files));
-
-  scoped_ptr<DeviceManagerInterface> dm(DeviceManagerFactory::Create());
-  std::vector<Device> video_ins;
-  EXPECT_TRUE(dm->Init());
-  EXPECT_TRUE(dm->GetVideoCaptureDevices(&video_ins));
-  EXPECT_EQ(2u, video_ins.size());
-  EXPECT_EQ("/dev/video0", video_ins.at(0).name);
-  EXPECT_EQ("/dev/video5", video_ins.at(1).name);
-}
-#endif  // LINUX
diff --git a/third_party/libjingle/source/talk/session/phone/dummydevicemanager.cc b/third_party/libjingle/source/talk/session/phone/dummydevicemanager.cc
deleted file mode 100644
index 5c2d1c2..0000000
--- a/third_party/libjingle/source/talk/session/phone/dummydevicemanager.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * libjingle
- * Copyright 2004 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/session/phone/dummydevicemanager.h"
-
-namespace cricket {
-
-DeviceManagerInterface* DeviceManagerFactory::Create() {
-  return new DummyDeviceManager();
-}
-
-};  // namespace cricket
diff --git a/third_party/libjingle/source/talk/session/phone/dummydevicemanager.h b/third_party/libjingle/source/talk/session/phone/dummydevicemanager.h
deleted file mode 100644
index 18bc63b..0000000
--- a/third_party/libjingle/source/talk/session/phone/dummydevicemanager.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * libjingle
- * Copyright 2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SESSION_PHONE_DUMMYDEVICEMANAGER_H_
-#define TALK_SESSION_PHONE_DUMMYDEVICEMANAGER_H_
-
-#include <vector>
-
-#include "talk/session/phone/fakedevicemanager.h"
-#include "talk/session/phone/mediacommon.h"
-
-namespace cricket {
-
-class DummyDeviceManager : public FakeDeviceManager {
- public:
-  DummyDeviceManager() {
-    std::vector<std::string> devices;
-    devices.push_back(DeviceManagerInterface::kDefaultDeviceName);
-    SetAudioInputDevices(devices);
-    SetAudioOutputDevices(devices);
-    SetVideoCaptureDevices(devices);
-  }
-};
-
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_DUMMYDEVICEMANAGER_H_
diff --git a/third_party/libjingle/source/talk/session/phone/dummydevicemanager_unittest.cc b/third_party/libjingle/source/talk/session/phone/dummydevicemanager_unittest.cc
deleted file mode 100644
index 3fe734e..0000000
--- a/third_party/libjingle/source/talk/session/phone/dummydevicemanager_unittest.cc
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/gunit.h"
-#include "talk/session/phone/dummydevicemanager.h"
-
-using cricket::Device;
-using cricket::DummyDeviceManager;
-
-// Test that we startup/shutdown properly.
-TEST(DummyDeviceManagerTest, StartupShutdown) {
-  DummyDeviceManager dm;
-  EXPECT_TRUE(dm.Init());
-  dm.Terminate();
-}
-
-// Test enumerating capabilities.
-TEST(DummyDeviceManagerTest, GetCapabilities) {
-  DummyDeviceManager dm;
-  int capabilities = dm.GetCapabilities();
-  EXPECT_EQ((cricket::AUDIO_SEND | cricket::AUDIO_RECV |
-      cricket::VIDEO_SEND | cricket::VIDEO_RECV), capabilities);
-}
-
-// Test enumerating devices.
-TEST(DummyDeviceManagerTest, GetDevices) {
-  DummyDeviceManager dm;
-  EXPECT_TRUE(dm.Init());
-  std::vector<Device> audio_ins, audio_outs, video_ins;
-  EXPECT_TRUE(dm.GetAudioInputDevices(&audio_ins));
-  EXPECT_TRUE(dm.GetAudioOutputDevices(&audio_outs));
-  EXPECT_TRUE(dm.GetVideoCaptureDevices(&video_ins));
-}
-
-// Test that we return correct ids for default and bogus devices.
-TEST(DummyDeviceManagerTest, GetAudioDeviceIds) {
-  DummyDeviceManager dm;
-  Device device;
-  EXPECT_TRUE(dm.Init());
-  EXPECT_TRUE(dm.GetAudioInputDevice(
-      cricket::DeviceManagerInterface::kDefaultDeviceName, &device));
-  EXPECT_EQ("-1", device.id);
-  EXPECT_TRUE(dm.GetAudioOutputDevice(
-      cricket::DeviceManagerInterface::kDefaultDeviceName, &device));
-  EXPECT_EQ("-1", device.id);
-  EXPECT_FALSE(dm.GetAudioInputDevice("_NOT A REAL DEVICE_", &device));
-  EXPECT_FALSE(dm.GetAudioOutputDevice("_NOT A REAL DEVICE_", &device));
-}
-
-// Test that we get the video capture device by name properly.
-TEST(DummyDeviceManagerTest, GetVideoDeviceIds) {
-  DummyDeviceManager dm;
-  Device device;
-  EXPECT_TRUE(dm.Init());
-  EXPECT_FALSE(dm.GetVideoCaptureDevice("_NOT A REAL DEVICE_", &device));
-  EXPECT_TRUE(dm.GetVideoCaptureDevice(
-      cricket::DeviceManagerInterface::kDefaultDeviceName, &device));
-}
-
-TEST(DummyDeviceManagerTest, VerifyDevicesListsAreCleared) {
-  const std::string imaginary("_NOT A REAL DEVICE_");
-  DummyDeviceManager dm;
-  std::vector<Device> audio_ins, audio_outs, video_ins;
-  audio_ins.push_back(Device(imaginary, imaginary));
-  audio_outs.push_back(Device(imaginary, imaginary));
-  video_ins.push_back(Device(imaginary, imaginary));
-  EXPECT_TRUE(dm.Init());
-  EXPECT_TRUE(dm.GetAudioInputDevices(&audio_ins));
-  EXPECT_TRUE(dm.GetAudioOutputDevices(&audio_outs));
-  EXPECT_TRUE(dm.GetVideoCaptureDevices(&video_ins));
-  for (size_t i = 0; i < audio_ins.size(); ++i) {
-    EXPECT_NE(imaginary, audio_ins[i].name);
-  }
-  for (size_t i = 0; i < audio_outs.size(); ++i) {
-    EXPECT_NE(imaginary, audio_outs[i].name);
-  }
-  for (size_t i = 0; i < video_ins.size(); ++i) {
-    EXPECT_NE(imaginary, video_ins[i].name);
-  }
-}
diff --git a/third_party/libjingle/source/talk/session/phone/fakedevicemanager.h b/third_party/libjingle/source/talk/session/phone/fakedevicemanager.h
deleted file mode 100644
index c096007..0000000
--- a/third_party/libjingle/source/talk/session/phone/fakedevicemanager.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * libjingle
- * Copyright 2008--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SESSION_PHONE_FAKEDEVICEMANAGER_H_
-#define TALK_SESSION_PHONE_FAKEDEVICEMANAGER_H_
-
-#include <string>
-#include <vector>
-
-#include "talk/session/phone/devicemanager.h"
-#include "talk/session/phone/mediacommon.h"
-
-namespace cricket {
-
-class FakeDeviceManager : public DeviceManagerInterface {
- public:
-  FakeDeviceManager() {}
-  virtual bool Init() {
-    return true;
-  }
-  virtual void Terminate() {
-  }
-  virtual int GetCapabilities() {
-    std::vector<Device> devices;
-    int caps = VIDEO_RECV;
-    if (!input_devices_.empty()) {
-      caps |= AUDIO_SEND;
-    }
-    if (!output_devices_.empty()) {
-      caps |= AUDIO_RECV;
-    }
-    if (!vidcap_devices_.empty()) {
-      caps |= VIDEO_SEND;
-    }
-    return caps;
-  }
-  virtual bool GetAudioInputDevices(std::vector<Device>* devs) {
-    *devs = input_devices_;
-    return true;
-  }
-  virtual bool GetAudioOutputDevices(std::vector<Device>* devs) {
-    *devs = output_devices_;
-    return true;
-  }
-  virtual bool GetAudioInputDevice(const std::string& name, Device* out) {
-    return GetAudioDevice(true, name, out);
-  }
-  virtual bool GetAudioOutputDevice(const std::string& name, Device* out) {
-    return GetAudioDevice(false, name, out);
-  }
-  virtual bool GetVideoCaptureDevices(std::vector<Device>* devs) {
-    *devs = vidcap_devices_;
-    return true;
-  }
-
-  virtual bool GetDefaultVideoCaptureDevice(Device* device) {
-    if (vidcap_devices_.empty()) {
-      return false;
-    }
-    *device = vidcap_devices_[0];
-    return true;
-  }
-
-#ifdef OSX
-  bool QtKitToSgDevice(const std::string& qtkit_name, Device* out) {
-    out->name = qtkit_name;
-    out->id = "sg:" + qtkit_name;
-    return true;
-  }
-#endif
-
-  void SetAudioInputDevices(const std::vector<std::string>& devices) {
-    input_devices_.clear();
-    for (size_t i = 0; i < devices.size(); ++i) {
-      input_devices_.push_back(Device(devices[i], i));
-    }
-    SignalDevicesChange();
-  }
-  void SetAudioOutputDevices(const std::vector<std::string>& devices) {
-    output_devices_.clear();
-    for (size_t i = 0; i < devices.size(); ++i) {
-      output_devices_.push_back(Device(devices[i], i));
-    }
-    SignalDevicesChange();
-  }
-  void SetVideoCaptureDevices(const std::vector<std::string>& devices) {
-    vidcap_devices_.clear();
-    for (size_t i = 0; i < devices.size(); ++i) {
-      vidcap_devices_.push_back(Device(devices[i], i));
-    }
-    SignalDevicesChange();
-  }
-  virtual bool GetVideoCaptureDevice(const std::string& name,
-                                     Device* out) {
-    if (vidcap_devices_.empty())
-      return false;
-
-    // If the name is empty, return the default device.
-    if (name.empty() || name == kDefaultDeviceName) {
-      *out = vidcap_devices_[0];
-      return true;
-    }
-
-    return FindDeviceByName(vidcap_devices_, name, out);
-  }
-  bool GetAudioDevice(bool is_input, const std::string& name,
-                      Device* out) {
-    // If the name is empty, return the default device.
-    if (name.empty() || name == kDefaultDeviceName) {
-      *out = Device(name, -1);
-      return true;
-    }
-
-    return FindDeviceByName((is_input ? input_devices_ : output_devices_),
-                            name, out);
-  }
-  static bool FindDeviceByName(const std::vector<Device>& devices,
-                               const std::string& name,
-                               Device* out) {
-    for (std::vector<Device>::const_iterator it = devices.begin();
-         it != devices.end(); ++it) {
-      if (name == it->name) {
-        *out = *it;
-        return true;
-      }
-    }
-    return false;
-  }
- private:
-  std::vector<Device> input_devices_;
-  std::vector<Device> output_devices_;
-  std::vector<Device> vidcap_devices_;
-};
-
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_FAKEDEVICEMANAGER_H_
diff --git a/third_party/libjingle/source/talk/session/phone/fakemediaengine.h b/third_party/libjingle/source/talk/session/phone/fakemediaengine.h
deleted file mode 100644
index 65a9e6a..0000000
--- a/third_party/libjingle/source/talk/session/phone/fakemediaengine.h
+++ /dev/null
@@ -1,753 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SESSION_PHONE_FAKEMEDIAENGINE_H_
-#define TALK_SESSION_PHONE_FAKEMEDIAENGINE_H_
-
-#include <list>
-#include <map>
-#include <set>
-#include <string>
-#include <vector>
-
-#include "talk/base/buffer.h"
-#include "talk/session/phone/mediaengine.h"
-#include "talk/session/phone/rtputils.h"
-
-namespace cricket {
-
-class FakeMediaEngine;
-class FakeVideoEngine;
-class FakeVoiceEngine;
-
-// A common helper class that handles sending and receiving RTP/RTCP packets.
-template<class Base>
-class RtpHelper : public Base {
- public:
-  RtpHelper()
-      : options_(0),
-        sending_(false),
-        playout_(false),
-        fail_set_send_codecs_(false),
-        fail_set_recv_codecs_(false),
-        send_ssrc_(0) {
-  }
-  const std::vector<RtpHeaderExtension>& recv_extensions() {
-    return recv_extensions_;
-  }
-  const std::vector<RtpHeaderExtension>& send_extensions() {
-    return send_extensions_;
-  }
-  bool sending() const { return sending_; }
-  bool playout() const { return playout_; }
-  const std::list<std::string>& rtp_packets() const { return rtp_packets_; }
-  const std::list<std::string>& rtcp_packets() const { return rtcp_packets_; }
-  int options() const { return options_; }
-  const uint32 send_ssrc() { return send_ssrc_; }
-
-  bool SendRtp(const void* data, int len) {
-    if (!sending_ || !Base::network_interface_) {
-      return false;
-    }
-    talk_base::Buffer packet(data, len, kMaxRtpPacketLen);
-    return Base::network_interface_->SendPacket(&packet);
-  }
-  bool SendRtcp(const void* data, int len) {
-    if (!Base::network_interface_) {
-      return false;
-    }
-    talk_base::Buffer packet(data, len, kMaxRtpPacketLen);
-    return Base::network_interface_->SendRtcp(&packet);
-  }
-
-  bool CheckRtp(const void* data, int len) {
-    bool success = !rtp_packets_.empty();
-    if (success) {
-      std::string packet = rtp_packets_.front();
-      rtp_packets_.pop_front();
-      success = (packet == std::string(static_cast<const char*>(data), len));
-    }
-    return success;
-  }
-  bool CheckRtcp(const void* data, int len) {
-    bool success = !rtcp_packets_.empty();
-    if (success) {
-      std::string packet = rtcp_packets_.front();
-      rtcp_packets_.pop_front();
-      success = (packet == std::string(static_cast<const char*>(data), len));
-    }
-    return success;
-  }
-  bool CheckNoRtp() {
-    return rtp_packets_.empty();
-  }
-  bool CheckNoRtcp() {
-    return rtcp_packets_.empty();
-  }
-  virtual bool SetOptions(int options) {
-    options_ = options;
-    return true;
-  }
-  virtual bool SetRecvRtpHeaderExtensions(
-      const std::vector<RtpHeaderExtension>& extensions) {
-    recv_extensions_ = extensions;
-    return true;
-  }
-  virtual bool SetSendRtpHeaderExtensions(
-      const std::vector<RtpHeaderExtension>& extensions) {
-    send_extensions_ = extensions;
-    return true;
-  }
-  void set_fail_set_send_codecs(bool fail) {
-    fail_set_send_codecs_ = fail;
-  }
-  void set_fail_set_recv_codecs(bool fail) {
-    fail_set_recv_codecs_ = fail;
-  }
-  virtual void SetSendSsrc(uint32 ssrc) {
-    send_ssrc_ = ssrc;
-  }
-
- protected:
-  void set_sending(bool send) { sending_ = send; }
-  void set_playout(bool playout) { playout_ = playout; }
-  virtual void OnPacketReceived(talk_base::Buffer* packet) {
-    rtp_packets_.push_back(std::string(packet->data(), packet->length()));
-  }
-  virtual void OnRtcpReceived(talk_base::Buffer* packet) {
-    rtcp_packets_.push_back(std::string(packet->data(), packet->length()));
-  }
-  bool fail_set_send_codecs() const {
-    return fail_set_send_codecs_;
-  }
-  bool fail_set_recv_codecs() const {
-    return fail_set_recv_codecs_;
-  }
-
- private:
-  int options_;
-  bool sending_;
-  bool playout_;
-  std::vector<RtpHeaderExtension> recv_extensions_;
-  std::vector<RtpHeaderExtension> send_extensions_;
-  std::list<std::string> rtp_packets_;
-  std::list<std::string> rtcp_packets_;
-  bool fail_set_send_codecs_;
-  bool fail_set_recv_codecs_;
-  uint32 send_ssrc_;
-};
-
-class FakeVoiceMediaChannel : public RtpHelper<VoiceMediaChannel> {
- public:
-  typedef std::pair<int, bool> DtmfEvent;
-  explicit FakeVoiceMediaChannel(FakeVoiceEngine* engine)
-      : engine_(engine),
-        muted_(false),
-        fail_set_send_(false),
-        ringback_tone_ssrc_(0),
-        ringback_tone_play_(false),
-        ringback_tone_loop_(false) {
-    output_scalings_[0] = OutputScaling();  // For default channel.
-  }
-  ~FakeVoiceMediaChannel();
-  const std::vector<AudioCodec>& recv_codecs() const { return recv_codecs_; }
-  const std::vector<AudioCodec>& send_codecs() const { return send_codecs_; }
-  const std::vector<AudioCodec>& codecs() const { return send_codecs(); }
-  bool muted() const { return muted_; }
-  const std::set<uint32>& streams() const { return streams_; }
-  const std::vector<DtmfEvent>& dtmf_queue() const { return dtmf_queue_; }
-  const std::string& rtcp_cname() const { return rtcp_cname_; }
-
-  uint32 ringback_tone_ssrc() const { return ringback_tone_ssrc_; }
-  bool ringback_tone_play() const { return ringback_tone_play_; }
-  bool ringback_tone_loop() const { return ringback_tone_loop_; }
-
-  virtual bool SetRecvCodecs(const std::vector<AudioCodec> &codecs) {
-    if (fail_set_recv_codecs()) {
-      // Fake the failure in SetRecvCodecs.
-      return false;
-    }
-    recv_codecs_= codecs;
-    return true;
-  }
-  virtual bool SetSendCodecs(const std::vector<AudioCodec> &codecs) {
-    if (fail_set_send_codecs()) {
-      // Fake the failure in SetSendCodecs.
-      return false;
-    }
-    send_codecs_= codecs;
-    return true;
-  }
-  virtual bool SetPlayout(bool playout) {
-    set_playout(playout);
-    return true;
-  }
-  virtual bool SetSend(SendFlags flag) {
-    if (fail_set_send_) {
-      return false;
-    }
-    set_sending(flag != SEND_NOTHING);
-    return true;
-  }
-  virtual bool SetRtcpCName(const std::string& cname) {
-    rtcp_cname_ = cname;
-    return true;
-  }
-  virtual bool SetSendBandwidth(bool autobw, int bps) { return true; }
-  virtual bool Mute(bool on) {
-    muted_ = on;
-    return true;
-  }
-
-  virtual bool AddStream(uint32 ssrc) {
-    streams_.insert(ssrc);
-    output_scalings_[ssrc] = OutputScaling();
-    return true;
-  }
-  virtual bool RemoveStream(uint32 ssrc) {
-    streams_.erase(ssrc);
-    output_scalings_.erase(ssrc);
-    return true;
-  }
-
-  virtual bool GetActiveStreams(AudioInfo::StreamList* streams) {
-    return true;
-  }
-  virtual int GetOutputLevel() { return 0; }
-
-  virtual bool SetRingbackTone(const char *buf, int len) { return true; }
-  virtual bool PlayRingbackTone(uint32 ssrc, bool play, bool loop) {
-    ringback_tone_ssrc_ = ssrc;
-    ringback_tone_play_ = play;
-    ringback_tone_loop_ = loop;
-    return true;
-  }
-
-  virtual bool PressDTMF(int event, bool playout) {
-    dtmf_queue_.push_back(std::make_pair(event, playout));
-    return true;
-  }
-
-  virtual bool SetOutputScaling(uint32 ssrc, double left, double right) {
-    if (0 == ssrc) {
-      std::map<uint32, OutputScaling>::iterator it;
-      for (it = output_scalings_.begin(); it != output_scalings_.end(); ++it) {
-        it->second.left = left;
-        it->second.right = right;
-      }
-      return true;
-    } else if (output_scalings_.find(ssrc) != output_scalings_.end()) {
-      output_scalings_[ssrc].left = left;
-      output_scalings_[ssrc].right = right;
-      return true;
-    }
-    return false;
-  }
-  virtual bool GetOutputScaling(uint32 ssrc, double* left, double* right) {
-    if (output_scalings_.find(ssrc) == output_scalings_.end()) return false;
-    *left = output_scalings_[ssrc].left;
-    *right = output_scalings_[ssrc].right;
-    return true;
-  }
-
-  virtual bool GetStats(VoiceMediaInfo* info) { return false; }
-  virtual void GetLastMediaError(uint32* ssrc,
-                                 VoiceMediaChannel::Error* error) {
-    *ssrc = 0;
-    *error = fail_set_send_ ? VoiceMediaChannel::ERROR_REC_DEVICE_OPEN_FAILED
-        : VoiceMediaChannel::ERROR_NONE;
-  }
-
-  void set_fail_set_send(bool fail) { fail_set_send_ = fail; }
-  void TriggerError(uint32 ssrc, VoiceMediaChannel::Error error) {
-    VoiceMediaChannel::SignalMediaError(ssrc, error);
-  }
-
- private:
-  struct OutputScaling {
-    OutputScaling() : left(1.0), right(1.0) {}
-    double left, right;
-  };
-
-  FakeVoiceEngine* engine_;
-  std::vector<AudioCodec> recv_codecs_;
-  std::vector<AudioCodec> send_codecs_;
-  bool muted_;
-  std::set<uint32> streams_;
-  std::map<uint32, OutputScaling> output_scalings_;
-  std::vector<DtmfEvent> dtmf_queue_;
-  std::string rtcp_cname_;
-  bool fail_set_send_;
-  uint32 ringback_tone_ssrc_;
-  bool ringback_tone_play_;
-  bool ringback_tone_loop_;
-};
-
-class FakeVideoMediaChannel : public RtpHelper<VideoMediaChannel> {
- public:
-  explicit FakeVideoMediaChannel(FakeVideoEngine* engine)
-      : engine_(engine),
-        muted_(false),
-        screen_casting_(false),
-        sent_intra_frame_(false),
-        requested_intra_frame_(false) {
-  }
-  ~FakeVideoMediaChannel();
-
-  const std::vector<VideoCodec>& recv_codecs() const { return recv_codecs_; }
-  const std::vector<VideoCodec>& send_codecs() const { return send_codecs_; }
-  const std::vector<VideoCodec>& codecs() const { return send_codecs(); }
-  bool muted() const { return muted_; }
-  bool rendering() const { return playout(); }
-  const std::map<uint32, VideoRenderer*>& streams() const { return streams_; }
-  const std::string rtcp_cname() const { return rtcp_cname_; }
-
-  virtual bool SetRecvCodecs(const std::vector<VideoCodec>& codecs) {
-    if (fail_set_recv_codecs()) {
-      // Fake the failure in SetRecvCodecs.
-      return false;
-    }
-    recv_codecs_= codecs;
-    return true;
-  }
-  virtual bool SetSendCodecs(const std::vector<VideoCodec>& codecs) {
-    if (fail_set_send_codecs()) {
-      // Fake the failure in SetSendCodecs.
-      return false;
-    }
-    send_codecs_= codecs;
-    return true;
-  }
-  virtual bool SetRender(bool render) {
-    set_playout(render);
-    return true;
-  }
-  virtual bool SetRenderer(uint32 ssrc, VideoRenderer* r) {
-    if (ssrc != 0 && streams_.find(ssrc) == streams_.end()) {
-      return false;
-    }
-    if (ssrc != 0) {
-      streams_[ssrc] = r;
-    }
-    return true;
-  }
-
-  virtual bool SetSend(bool send) {
-    set_sending(send);
-    return true;
-  }
-  virtual bool AddScreencast(uint32 ssrc, talk_base::WindowId id) {
-    screen_casting_ = true;
-    return true;
-  }
-  virtual bool RemoveScreencast(uint32 ssrc) {
-    screen_casting_ = false;
-    return true;
-  }
-  virtual bool SetRtcpCName(const std::string& cname) {
-    rtcp_cname_ = cname;
-    return true;
-  }
-  virtual bool SetSendBandwidth(bool autobw, int bps) { return true; }
-  virtual bool Mute(bool on) {
-    muted_ = on;
-    return true;
-  }
-
-  virtual bool AddStream(uint32 ssrc, uint32 voice_ssrc) {
-    if (streams_.find(ssrc) != streams_.end()) {
-      return false;
-    }
-    streams_[ssrc] = NULL;
-    return true;
-  }
-  virtual bool RemoveStream(uint32 ssrc) {
-    streams_.erase(ssrc);
-    return true;
-  }
-
-  virtual bool GetStats(VideoMediaInfo* info) { return false; }
-  virtual bool SendIntraFrame() {
-    sent_intra_frame_= true;
-    return true;
-  }
-  virtual bool RequestIntraFrame() {
-    requested_intra_frame_ = true;
-    return true;
-  }
-  void set_sent_intra_frame(bool v) { sent_intra_frame_ = v; }
-  bool sent_intra_frame() const { return sent_intra_frame_; }
-  void set_requested_intra_frame(bool v) { requested_intra_frame_ = v; }
-  bool requested_intra_frame() const { return requested_intra_frame_; }
-
-  bool IsScreencasting() {
-    return screen_casting_;
-  }
-
- private:
-  FakeVideoEngine* engine_;
-  std::vector<VideoCodec> recv_codecs_;
-  std::vector<VideoCodec> send_codecs_;
-  std::map<uint32, VideoRenderer*> streams_;
-  bool muted_;
-  bool screen_casting_;
-  std::string rtcp_cname_;
-  bool sent_intra_frame_;
-  bool requested_intra_frame_;
-};
-
-class FakeSoundclipMedia : public SoundclipMedia {
- public:
-  virtual bool PlaySound(const char *buf, int len, int flags) {
-    return true;
-  }
-};
-
-// A base class for all of the shared parts between FakeVoiceEngine
-// and FakeVideoEngine.
-class FakeBaseEngine {
- public:
-  FakeBaseEngine()
-      : loglevel_(-1),
-        options_(0),
-        options_changed_(false),
-        fail_create_channel_(false) {
-  }
-
-  bool Init() { return true; }
-  void Terminate() {}
-
-  bool SetOptions(int options) {
-    options_ = options;
-    options_changed_ = true;
-    return true;
-  }
-
-  void SetLogging(int level, const char* filter) {
-    loglevel_ = level;
-    logfilter_ = filter;
-  }
-
-  void set_fail_create_channel(bool fail) { fail_create_channel_ = fail; }
-
- protected:
-  int loglevel_;
-  std::string logfilter_;
-  int options_;
-  // Flag used by optionsmessagehandler_unittest for checking whether any
-  // relevant setting has been updated.
-  // TODO: Replace with explicit checks of before & after values.
-  bool options_changed_;
-  bool fail_create_channel_;
-};
-
-class FakeVoiceEngine : public FakeBaseEngine {
- public:
-  FakeVoiceEngine()
-      : output_volume_(-1),
-        rx_processor_(NULL),
-        tx_processor_(NULL) {
-  }
-
-  int GetCapabilities() {
-    return AUDIO_SEND | AUDIO_RECV;
-  }
-
-  VoiceMediaChannel* CreateChannel() {
-    if (fail_create_channel_) {
-      return NULL;
-    }
-
-    FakeVoiceMediaChannel* ch = new FakeVoiceMediaChannel(this);
-    channels_.push_back(ch);
-    return ch;
-  }
-  FakeVoiceMediaChannel* GetChannel(size_t index) {
-    return (channels_.size() > index) ? channels_[index] : NULL;
-  }
-  void UnregisterChannel(VoiceMediaChannel* channel) {
-    channels_.erase(std::find(channels_.begin(), channels_.end(), channel));
-  }
-  SoundclipMedia* CreateSoundclip() {
-    return new FakeSoundclipMedia();
-  }
-
-  const std::vector<AudioCodec>& codecs() {
-    return codecs_;
-  }
-  void SetCodecs(const std::vector<AudioCodec> codecs) {
-    codecs_ = codecs;
-  }
-
-  bool SetDevices(const Device* in_device,
-                          const Device* out_device) {
-    in_device_ = (in_device) ? in_device->name : "";
-    out_device_ = (out_device) ? out_device->name : "";
-    options_changed_ = true;
-    return true;
-  }
-
-  bool GetOutputVolume(int* level) {
-    *level = output_volume_;
-    return true;
-  }
-
-  bool SetOutputVolume(int level) {
-    output_volume_ = level;
-    options_changed_ = true;
-    return true;
-  }
-
-  int GetInputLevel() {
-    return 0;
-  }
-
-  bool SetLocalMonitor(bool enable) {
-    return true;
-  }
-
-  bool RegisterProcessor(uint32 ssrc,
-                         VoiceProcessor* voice_processor,
-                         MediaProcessorDirection direction) {
-    if (direction == MPD_RX) {
-      rx_processor_ = voice_processor;
-      return true;
-    } else if (direction == MPD_TX) {
-      tx_processor_ = voice_processor;
-      return true;
-    }
-    return false;
-  }
-
-  bool UnregisterProcessor(uint32 ssrc,
-                           VoiceProcessor* voice_processor,
-                           MediaProcessorDirection direction) {
-    bool unregistered = false;
-    if (direction & MPD_RX) {
-      rx_processor_ = NULL;
-      unregistered = true;
-    }
-    if (direction & MPD_TX) {
-      tx_processor_ = NULL;
-      unregistered = true;
-    }
-    return unregistered;
-  }
-
- private:
-  std::vector<FakeVoiceMediaChannel*> channels_;
-  std::vector<AudioCodec> codecs_;
-  int output_volume_;
-  std::string in_device_;
-  std::string out_device_;
-  VoiceProcessor* rx_processor_;
-  VoiceProcessor* tx_processor_;
-
-  friend class FakeMediaEngine;
-};
-
-class FakeVideoEngine : public FakeBaseEngine {
- public:
-  FakeVideoEngine()
-      : renderer_(NULL),
-        capture_(false),
-        processor_(NULL) {
-  }
-
-  int GetCapabilities() {
-    return VIDEO_SEND | VIDEO_RECV;
-  }
-  bool SetDefaultEncoderConfig(const VideoEncoderConfig& config) {
-    default_encoder_config_ = config;
-    return true;
-  }
-  const VideoEncoderConfig& default_encoder_config() const {
-    return default_encoder_config_;
-  }
-
-  VideoMediaChannel* CreateChannel(VoiceMediaChannel* channel) {
-    if (fail_create_channel_) {
-      return NULL;
-    }
-
-    FakeVideoMediaChannel* ch = new FakeVideoMediaChannel(this);
-    channels_.push_back(ch);
-    return ch;
-  }
-  FakeVideoMediaChannel* GetChannel(size_t index) {
-    return (channels_.size() > index) ? channels_[index] : NULL;
-  }
-  void UnregisterChannel(VideoMediaChannel* channel) {
-    channels_.erase(std::find(channels_.begin(), channels_.end(), channel));
-  }
-
-  const std::vector<VideoCodec>& codecs() {
-    return codecs_;
-  }
-  bool FindCodec(const VideoCodec& in) {
-    for (size_t i = 0; i < codecs_.size(); ++i) {
-      if (codecs_[i].Matches(in)) {
-        return true;
-      }
-    }
-    return false;
-  }
-  void SetCodecs(const std::vector<VideoCodec> codecs) {
-    codecs_ = codecs;
-  }
-
-  bool SetCaptureDevice(const Device* device) {
-    in_device_ = (device) ? device->name : "";
-    options_changed_ = true;
-    return true;
-  }
-  bool SetLocalRenderer(VideoRenderer* r) {
-    renderer_ = r;
-    return true;
-  }
-  bool SetVideoCapturer(VideoCapturer* /*capturer*/, uint32 /*ssrc*/) {
-    return false;
-  }
-  CaptureResult SetCapture(bool capture) {
-    capture_ = capture;
-    return CR_SUCCESS;
-  }
-  bool RegisterProcessor(VideoProcessor* video_processor) {
-    processor_ = video_processor;
-    return true;
-  }
-
-  bool UnregisterProcessor(VideoProcessor* video_processor) {
-    processor_ = NULL;
-    return true;
-  }
-
-  sigslot::signal2<VideoCapturer*, CaptureResult> SignalCaptureResult;
-
- private:
-  std::vector<FakeVideoMediaChannel*> channels_;
-  std::vector<VideoCodec> codecs_;
-  VideoEncoderConfig default_encoder_config_;
-  std::string in_device_;
-  VideoRenderer* renderer_;
-  bool capture_;
-  VideoProcessor* processor_;
-
-  friend class FakeMediaEngine;
-};
-
-class FakeMediaEngine
-    : public CompositeMediaEngine<FakeVoiceEngine, FakeVideoEngine> {
- public:
-  FakeMediaEngine() {
-    voice_ = FakeVoiceEngine();
-    video_ = FakeVideoEngine();
-  }
-  virtual ~FakeMediaEngine() {}
-
-  virtual void SetAudioCodecs(const std::vector<AudioCodec> codecs) {
-    voice_.SetCodecs(codecs);
-  }
-
-  virtual void SetVideoCodecs(const std::vector<VideoCodec> codecs) {
-    video_.SetCodecs(codecs);
-  }
-
-  FakeVoiceMediaChannel* GetVoiceChannel(size_t index) {
-    return voice_.GetChannel(index);
-  }
-
-  FakeVideoMediaChannel* GetVideoChannel(size_t index) {
-    return video_.GetChannel(index);
-  }
-
-  int audio_options() const { return voice_.options_; }
-  int output_volume() const { return voice_.output_volume_; }
-  const VideoEncoderConfig& default_video_encoder_config() const {
-    return video_.default_encoder_config_;
-  }
-  const std::string& audio_in_device() const { return voice_.in_device_; }
-  const std::string& audio_out_device() const { return voice_.out_device_; }
-  const std::string& video_in_device() const { return video_.in_device_; }
-  VideoRenderer* local_renderer() { return video_.renderer_; }
-  int voice_loglevel() const { return voice_.loglevel_; }
-  const std::string& voice_logfilter() const { return voice_.logfilter_; }
-  int video_loglevel() const { return video_.loglevel_; }
-  const std::string& video_logfilter() const { return video_.logfilter_; }
-  bool capture() const { return video_.capture_; }
-  bool options_changed() const {
-    return voice_.options_changed_ || video_.options_changed_;
-  }
-  void clear_options_changed() {
-    video_.options_changed_ = false;
-    voice_.options_changed_ = false;
-  }
-  void set_fail_create_channel(bool fail) {
-    voice_.set_fail_create_channel(fail);
-    video_.set_fail_create_channel(fail);
-  }
-  bool video_processor_registered () const {return video_.processor_ != NULL;}
-  bool voice_processor_registered(MediaProcessorDirection direction) const {
-    if (direction == MPD_RX) {
-      return voice_.rx_processor_ != NULL;
-    } else if (direction == MPD_TX) {
-      return voice_.tx_processor_ != NULL;
-    }
-    return false;
-  }
-};
-
-// CompositeMediaEngine with FakeVoiceEngine to expose SetAudioCodecs to
-// establish a media connectionwith minimum set of audio codes required
-template<class VIDEO>
-class CompositeMediaEngineWithFakeVoiceEngine
-    : public CompositeMediaEngine<FakeVoiceEngine, VIDEO> {
- public:
-  CompositeMediaEngineWithFakeVoiceEngine() {}
-  virtual ~CompositeMediaEngineWithFakeVoiceEngine() {}
-
-  virtual void SetAudioCodecs(const std::vector<AudioCodec>& codecs) {
-    CompositeMediaEngine<FakeVoiceEngine, VIDEO>::voice_.SetCodecs(codecs);
-  }
-};
-
-// Have to come afterwards due to declaration order
-inline FakeVoiceMediaChannel::~FakeVoiceMediaChannel() {
-  if (engine_) {
-    engine_->UnregisterChannel(this);
-  }
-}
-
-inline FakeVideoMediaChannel::~FakeVideoMediaChannel() {
-  if (engine_) {
-    engine_->UnregisterChannel(this);
-  }
-}
-
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_FAKEMEDIAENGINE_H_
diff --git a/third_party/libjingle/source/talk/session/phone/fakemediaprocessor.h b/third_party/libjingle/source/talk/session/phone/fakemediaprocessor.h
deleted file mode 100644
index 7b88595..0000000
--- a/third_party/libjingle/source/talk/session/phone/fakemediaprocessor.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * libjingle
- * Copyright 2004 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SESSION_PHONE_FAKEMEDIAPROCESSOR_H_
-#define TALK_SESSION_PHONE_FAKEMEDIAPROCESSOR_H_
-
-#include "talk/session/phone/videoprocessor.h"
-#include "talk/session/phone/voiceprocessor.h"
-
-namespace cricket {
-
-class AudioFrame;
-
-class FakeMediaProcessor : public VoiceProcessor, public VideoProcessor {
- public:
-  FakeMediaProcessor()
-      : voice_frame_count_(0),
-        video_frame_count_(0) {
-  }
-  virtual ~FakeMediaProcessor() {}
-
-  virtual void OnFrame(uint32 ssrc,
-                       AudioFrame* frame) {
-    ++voice_frame_count_;
-  }
-  virtual void OnFrame(uint32 ssrc,
-                       VideoFrame* frame_ptr) {
-    ++video_frame_count_;
-  }
-  virtual void OnVoiceMute(uint32 ssrc, bool muted) {}
-  virtual void OnVideoMute(uint32 ssrc, bool muted) {}
-
-  int voice_frame_count() const { return voice_frame_count_; }
-  int video_frame_count() const { return video_frame_count_; }
-
- private:
-  // TODO: make is a map so that we can multiple ssrcs
-  int  voice_frame_count_;
-  int  video_frame_count_;
-};
-
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_FAKEMEDIAPROCESSOR_H_
diff --git a/third_party/libjingle/source/talk/session/phone/fakertp.h b/third_party/libjingle/source/talk/session/phone/fakertp.h
deleted file mode 100644
index 30e3793..0000000
--- a/third_party/libjingle/source/talk/session/phone/fakertp.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2008, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// Fake RTP and RTCP packets to use in unit tests.
-
-#ifndef TALK_SESSION_PHONE_FAKERTP_H_
-#define TALK_SESSION_PHONE_FAKERTP_H_
-
-// A typical PCMU RTP packet.
-// PT=0, SN=1, TS=0, SSRC=1
-// all data FF
-static const unsigned char kPcmuFrame[] = {
-  0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-};
-
-// A typical Receiver Report RTCP packet.
-// PT=RR, LN=1, SSRC=1
-// send SSRC=2, all other fields 0
-static const unsigned char kRtcpReport[] = {
-  0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
-  0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-// PT = 97, TS = 0, Seq = 1, SSRC = 2
-// H264 - NRI = 1, Type = 1, bit stream = FF
-
-static const unsigned char kH264Packet[] = {
-  0x80, 0x61, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
-  0x21, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-};
-
-#endif  // TALK_SESSION_PHONE_FAKERTP_H_
diff --git a/third_party/libjingle/source/talk/session/phone/fakewebrtcdeviceinfo.h b/third_party/libjingle/source/talk/session/phone/fakewebrtcdeviceinfo.h
deleted file mode 100644
index c969236..0000000
--- a/third_party/libjingle/source/talk/session/phone/fakewebrtcdeviceinfo.h
+++ /dev/null
@@ -1,123 +0,0 @@
-// libjingle
-// Copyright 2004--2011 Google Inc.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-//  1. Redistributions of source code must retain the above copyright notice,
-//     this list of conditions and the following disclaimer.
-//  2. Redistributions in binary form must reproduce the above copyright notice,
-//     this list of conditions and the following disclaimer in the documentation
-//     and/or other materials provided with the distribution.
-//  3. The name of the author may not be used to endorse or promote products
-//     derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef TALK_SESSION_PHONE_FAKEWEBRTCDEVICEINFO_H_
-#define TALK_SESSION_PHONE_FAKEWEBRTCDEVICEINFO_H_
-
-#include <vector>
-
-#include "talk/base/stringutils.h"
-#include "talk/session/phone/webrtcvideocapturer.h"
-
-// Fake class for mocking out webrtc::VideoCaptureModule::DeviceInfo.
-class FakeWebRtcDeviceInfo : public webrtc::VideoCaptureModule::DeviceInfo {
- public:
-  struct Device {
-    Device(const std::string& n, const std::string& i) : name(n), id(i) {}
-    std::string name;
-    std::string id;
-    std::string product;
-    std::vector<webrtc::VideoCaptureCapability> caps;
-  };
-  FakeWebRtcDeviceInfo() {}
-  void AddDevice(const std::string& device_name, const std::string& device_id) {
-    devices_.push_back(Device(device_name, device_id));
-  }
-  void AddCapability(const std::string& device_id,
-                     const webrtc::VideoCaptureCapability& cap) {
-    Device* dev = GetDeviceById(
-        reinterpret_cast<const WebRtc_UWord8*>(device_id.c_str()));
-    if (!dev) return;
-    dev->caps.push_back(cap);
-  }
-  virtual WebRtc_UWord32 NumberOfDevices() {
-    return devices_.size();
-  }
-  virtual WebRtc_Word32 GetDeviceName(WebRtc_UWord32 device_num,
-                                      WebRtc_UWord8* device_name,
-                                      WebRtc_UWord32 device_name_len,
-                                      WebRtc_UWord8* device_id,
-                                      WebRtc_UWord32 device_id_len,
-                                      WebRtc_UWord8* product_id,
-                                      WebRtc_UWord32 product_id_len) {
-    Device* dev = GetDeviceByIndex(device_num);
-    if (!dev) return -1;
-    talk_base::strcpyn(reinterpret_cast<char*>(device_name), device_name_len,
-                       dev->name.c_str());
-    talk_base::strcpyn(reinterpret_cast<char*>(device_id), device_id_len,
-                       dev->id.c_str());
-    if (product_id) {
-      talk_base::strcpyn(reinterpret_cast<char*>(product_id), product_id_len,
-                         dev->product.c_str());
-    }
-    return 0;
-  }
-  virtual WebRtc_Word32 NumberOfCapabilities(const WebRtc_UWord8* device_id) {
-    Device* dev = GetDeviceById(device_id);
-    if (!dev) return -1;
-    return dev->caps.size();
-  }
-  virtual WebRtc_Word32 GetCapability(const WebRtc_UWord8* device_id,
-                                      const WebRtc_UWord32 device_cap_num,
-                                      webrtc::VideoCaptureCapability& cap) {
-    Device* dev = GetDeviceById(device_id);
-    if (!dev) return -1;
-    if (device_cap_num >= dev->caps.size()) return -1;
-    cap = dev->caps[device_cap_num];
-    return 0;
-  }
-  virtual WebRtc_Word32 GetOrientation(const WebRtc_UWord8* device_id,
-                                       webrtc::VideoCaptureRotation& rotation) {
-    return -1;  // not implemented
-  }
-  virtual WebRtc_Word32 GetBestMatchedCapability(
-      const WebRtc_UWord8* device_id,
-      const webrtc::VideoCaptureCapability requested,
-      webrtc::VideoCaptureCapability& resulting) {
-    return -1;  // not implemented
-  }
-  virtual WebRtc_Word32 DisplayCaptureSettingsDialogBox(
-      const WebRtc_UWord8* device_id, const WebRtc_UWord8* dialog_title,
-      void* parent, WebRtc_UWord32 x, WebRtc_UWord32 y) {
-    return -1;  // not implemented
-  }
-
-  Device* GetDeviceByIndex(size_t num) {
-    return (num < devices_.size()) ? &devices_[num] : NULL;
-  }
-  Device* GetDeviceById(const WebRtc_UWord8* device_id) {
-    for (size_t i = 0; i < devices_.size(); ++i) {
-      if (devices_[i].id == reinterpret_cast<const char*>(device_id)) {
-        return &devices_[i];
-      }
-    }
-    return NULL;
-  }
-
- private:
-  std::vector<Device> devices_;
-};
-
-#endif  // TALK_SESSION_PHONE_FAKEWEBRTCDEVICEINFO_H_
diff --git a/third_party/libjingle/source/talk/session/phone/fakewebrtcvcmfactory.h b/third_party/libjingle/source/talk/session/phone/fakewebrtcvcmfactory.h
deleted file mode 100644
index e5c660c..0000000
--- a/third_party/libjingle/source/talk/session/phone/fakewebrtcvcmfactory.h
+++ /dev/null
@@ -1,63 +0,0 @@
-// libjingle
-// Copyright 2004--2011 Google Inc.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-//  1. Redistributions of source code must retain the above copyright notice,
-//     this list of conditions and the following disclaimer.
-//  2. Redistributions in binary form must reproduce the above copyright notice,
-//     this list of conditions and the following disclaimer in the documentation
-//     and/or other materials provided with the distribution.
-//  3. The name of the author may not be used to endorse or promote products
-//     derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef TALK_SESSION_PHONE_FAKEWEBRTCVCMFACTORY_H_
-#define TALK_SESSION_PHONE_FAKEWEBRTCVCMFACTORY_H_
-
-#include <vector>
-
-#include "talk/session/phone/fakewebrtcvideocapturemodule.h"
-#include "talk/session/phone/webrtcvideocapturer.h"
-
-// Factory class to allow the fakes above to be injected into
-// WebRtcVideoCapturer.
-class FakeWebRtcVcmFactory : public cricket::WebRtcVcmFactoryInterface {
- public:
-  virtual webrtc::VideoCaptureModule* Create(int module_id,
-                                             const WebRtc_UWord8* device_id) {
-    if (!device_info.GetDeviceById(device_id)) return NULL;
-    FakeWebRtcVideoCaptureModule* module =
-        new FakeWebRtcVideoCaptureModule(this, module_id);
-    modules.push_back(module);
-    return module;
-  }
-  virtual webrtc::VideoCaptureModule::DeviceInfo* CreateDeviceInfo(int id) {
-    return &device_info;
-  }
-  virtual void DestroyDeviceInfo(webrtc::VideoCaptureModule::DeviceInfo* info) {
-  }
-  void OnDestroyed(webrtc::VideoCaptureModule* module) {
-    std::remove(modules.begin(), modules.end(), module);
-  }
-  FakeWebRtcDeviceInfo device_info;
-  std::vector<FakeWebRtcVideoCaptureModule*> modules;
-};
-
-FakeWebRtcVideoCaptureModule::~FakeWebRtcVideoCaptureModule() {
-  if (factory_)
-    factory_->OnDestroyed(this);
-}
-
-#endif  // TALK_SESSION_PHONE_FAKEWEBRTCVCMFACTORY_H_
diff --git a/third_party/libjingle/source/talk/session/phone/fakewebrtcvideocapturemodule.h b/third_party/libjingle/source/talk/session/phone/fakewebrtcvideocapturemodule.h
deleted file mode 100644
index e3d7db1..0000000
--- a/third_party/libjingle/source/talk/session/phone/fakewebrtcvideocapturemodule.h
+++ /dev/null
@@ -1,169 +0,0 @@
-// libjingle
-// Copyright 2004--2011 Google Inc.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-//  1. Redistributions of source code must retain the above copyright notice,
-//     this list of conditions and the following disclaimer.
-//  2. Redistributions in binary form must reproduce the above copyright notice,
-//     this list of conditions and the following disclaimer in the documentation
-//     and/or other materials provided with the distribution.
-//  3. The name of the author may not be used to endorse or promote products
-//     derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef TALK_SESSION_PHONE_FAKEWEBRTCVIDEOCAPTUREMODULE_H_
-#define TALK_SESSION_PHONE_FAKEWEBRTCVIDEOCAPTUREMODULE_H_
-
-#include <vector>
-
-#include "talk/session/phone/testutils.h"
-#include "talk/session/phone/fakewebrtcdeviceinfo.h"
-#include "talk/session/phone/webrtcvideocapturer.h"
-
-class FakeWebRtcVcmFactory;
-
-// Fake class for mocking out webrtc::VideoCaptureModule.
-class FakeWebRtcVideoCaptureModule : public webrtc::VideoCaptureModule {
- public:
-  FakeWebRtcVideoCaptureModule(FakeWebRtcVcmFactory* factory, WebRtc_Word32 id)
-      : factory_(factory),
-        id_(id),
-        callback_(NULL),
-        running_(false),
-        delay_(0) {
-  }
-  virtual int32_t Version(char* version,
-                          uint32_t& remaining_buffer_in_bytes,
-                          uint32_t& position) const {
-    return 0;
-  }
-  virtual int32_t TimeUntilNextProcess() {
-    return 0;
-  }
-  virtual int32_t Process() {
-    return 0;
-  }
-  virtual WebRtc_Word32 ChangeUniqueId(const WebRtc_Word32 id) {
-    id_ = id;
-    return 0;
-  }
-  virtual WebRtc_Word32 RegisterCaptureDataCallback(
-      webrtc::VideoCaptureDataCallback& callback) {
-    callback_ = &callback;
-    return 0;
-  }
-  virtual WebRtc_Word32 DeRegisterCaptureDataCallback() {
-    callback_ = NULL;
-    return 0;
-  }
-  virtual WebRtc_Word32 RegisterCaptureCallback(
-      webrtc::VideoCaptureFeedBack& callback) {
-    return -1;  // not implemented
-  }
-  virtual WebRtc_Word32 DeRegisterCaptureCallback() {
-    return 0;
-  }
-  virtual WebRtc_Word32 StartCapture(
-      const webrtc::VideoCaptureCapability& cap) {
-    if (running_) return -1;
-    cap_ = cap;
-    running_ = true;
-    return 0;
-  }
-  virtual WebRtc_Word32 StopCapture() {
-    running_ = false;
-    return 0;
-  }
-  virtual WebRtc_Word32 StartSendImage(const webrtc::VideoFrame& frame,
-                                       WebRtc_Word32 framerate) {
-    return -1;  // not implemented
-  }
-  virtual WebRtc_Word32 StopSendImage() {
-    return 0;
-  }
-  virtual const WebRtc_UWord8* CurrentDeviceName() const {
-    return NULL;  // not implemented
-  }
-  virtual bool CaptureStarted() {
-    return running_;
-  }
-  virtual WebRtc_Word32 CaptureSettings(
-      webrtc::VideoCaptureCapability& settings) {
-    if (!running_) return -1;
-    settings = cap_;
-    return 0;
-  }
-  virtual WebRtc_Word32 SetCaptureDelay(WebRtc_Word32 delay) {
-    delay_ = delay;
-    return 0;
-  }
-  virtual WebRtc_Word32 CaptureDelay() {
-    return delay_;
-  }
-  virtual WebRtc_Word32 SetCaptureRotation(
-      webrtc::VideoCaptureRotation rotation) {
-    return -1;  // not implemented
-  }
-  virtual VideoCaptureEncodeInterface* GetEncodeInterface(
-      const webrtc::VideoCodec& codec) {
-    return NULL;  // not implemented
-  }
-  virtual WebRtc_Word32 EnableFrameRateCallback(const bool enable) {
-    return -1;  // not implemented
-  }
-  virtual WebRtc_Word32 EnableNoPictureAlarm(const bool enable) {
-    return -1;  // not implemented
-  }
-  virtual int32_t AddRef() {
-    return 0;
-  }
-  virtual int32_t Release() {
-    delete this;
-    return 0;
-  }
-
-  bool SendFrame(int w, int h) {
-    if (!running_) return false;
-    webrtc::VideoFrame sample;
-    sample.SetWidth(w);
-    sample.SetHeight(h);
-    if (sample.VerifyAndAllocate(I420_SIZE(w, h)) == -1 ||
-        sample.SetLength(sample.Size()) == -1) {
-      return false;
-    }
-    if (callback_) {
-      callback_->OnIncomingCapturedFrame(id_, sample,
-                                         webrtc::kVideoCodecUnknown);
-    }
-    return true;
-  }
-
-  const webrtc::VideoCaptureCapability& cap() const {
-    return cap_;
-  }
-
- private:
-  // Ref-counted, use Release() instead.
-  ~FakeWebRtcVideoCaptureModule();
-
-  FakeWebRtcVcmFactory* factory_;
-  int id_;
-  webrtc::VideoCaptureDataCallback* callback_;
-  bool running_;
-  webrtc::VideoCaptureCapability cap_;
-  int delay_;
-};
-
-#endif  // TALK_SESSION_PHONE_FAKEWEBRTCVIDEOCAPTUREMODULE_H_
diff --git a/third_party/libjingle/source/talk/session/phone/filemediaengine.cc b/third_party/libjingle/source/talk/session/phone/filemediaengine.cc
deleted file mode 100644
index 2a7b8d8..0000000
--- a/third_party/libjingle/source/talk/session/phone/filemediaengine.cc
+++ /dev/null
@@ -1,311 +0,0 @@
-// libjingle
-// Copyright 2004--2005, Google Inc.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-//  1. Redistributions of source code must retain the above copyright notice,
-//     this list of conditions and the following disclaimer.
-//  2. Redistributions in binary form must reproduce the above copyright notice,
-//     this list of conditions and the following disclaimer in the documentation
-//     and/or other materials provided with the distribution.
-//  3. The name of the author may not be used to endorse or promote products
-//     derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include "talk/session/phone/filemediaengine.h"
-
-#include <climits>
-
-#include "talk/base/buffer.h"
-#include "talk/base/event.h"
-#include "talk/base/logging.h"
-#include "talk/base/pathutils.h"
-#include "talk/base/stream.h"
-#include "talk/session/phone/rtpdump.h"
-#include "talk/session/phone/rtputils.h"
-
-namespace cricket {
-
-///////////////////////////////////////////////////////////////////////////
-// Implementation of FileMediaEngine.
-///////////////////////////////////////////////////////////////////////////
-int FileMediaEngine::GetCapabilities() {
-  int capabilities = 0;
-  if (!voice_input_filename_.empty()) {
-    capabilities |= AUDIO_SEND;
-  }
-  if (!voice_output_filename_.empty()) {
-    capabilities |= AUDIO_RECV;
-  }
-  if (!video_input_filename_.empty()) {
-    capabilities |= VIDEO_SEND;
-  }
-  if (!video_output_filename_.empty()) {
-    capabilities |= VIDEO_RECV;
-  }
-  return capabilities;
-}
-
-VoiceMediaChannel* FileMediaEngine::CreateChannel() {
-  talk_base::FileStream* input_file_stream = NULL;
-  talk_base::FileStream* output_file_stream = NULL;
-
-  if (voice_input_filename_.empty() && voice_output_filename_.empty())
-    return NULL;
-  if (!voice_input_filename_.empty()) {
-    input_file_stream = talk_base::Filesystem::OpenFile(
-        talk_base::Pathname(voice_input_filename_), "rb");
-    if (!input_file_stream) {
-      LOG(LS_ERROR) << "Not able to open the input audio stream file.";
-      return NULL;
-    }
-  }
-
-  if (!voice_output_filename_.empty()) {
-    output_file_stream = talk_base::Filesystem::OpenFile(
-        talk_base::Pathname(voice_output_filename_), "wb");
-    if (!output_file_stream) {
-      delete input_file_stream;
-      LOG(LS_ERROR) << "Not able to open the output audio stream file.";
-      return NULL;
-    }
-  }
-
-  return new FileVoiceChannel(input_file_stream, output_file_stream);
-}
-
-VideoMediaChannel* FileMediaEngine::CreateVideoChannel(
-    VoiceMediaChannel* voice_ch) {
-  talk_base::FileStream* input_file_stream = NULL;
-  talk_base::FileStream* output_file_stream = NULL;
-
-  if (video_input_filename_.empty() && video_output_filename_.empty())
-      return NULL;
-
-  if (!video_input_filename_.empty()) {
-    input_file_stream = talk_base::Filesystem::OpenFile(
-        talk_base::Pathname(video_input_filename_), "rb");
-    if (!input_file_stream) {
-      LOG(LS_ERROR) << "Not able to open the input video stream file.";
-      return NULL;
-    }
-  }
-
-  if (!video_output_filename_.empty()) {
-    output_file_stream = talk_base::Filesystem::OpenFile(
-        talk_base::Pathname(video_output_filename_), "wb");
-    if (!output_file_stream) {
-      delete input_file_stream;
-      LOG(LS_ERROR) << "Not able to open the output video stream file.";
-      return NULL;
-    }
-  }
-
-  return new FileVideoChannel(input_file_stream, output_file_stream);
-}
-
-///////////////////////////////////////////////////////////////////////////
-// Definition of RtpSenderReceiver.
-///////////////////////////////////////////////////////////////////////////
-class RtpSenderReceiver
-    : public talk_base::Thread, public talk_base::MessageHandler {
- public:
-  RtpSenderReceiver(MediaChannel* channel,
-                    talk_base::StreamInterface* input_file_stream,
-                    talk_base::StreamInterface* output_file_stream);
-
-  // Called by media channel. Context: media channel thread.
-  bool SetSend(bool send);
-  void SetSendSsrc(uint32 ssrc);
-  void OnPacketReceived(talk_base::Buffer* packet);
-
-  // Override virtual method of parent MessageHandler. Context: Worker Thread.
-  virtual void OnMessage(talk_base::Message* pmsg);
-
- private:
-  // Read the next RTP dump packet, whose RTP SSRC is the same as first_ssrc_.
-  // Return true if successful.
-  bool ReadNextPacket(RtpDumpPacket* packet);
-  // Send a RTP packet to the network. The input parameter data points to the
-  // start of the RTP packet and len is the packet size. Return true if the sent
-  // size is equal to len.
-  bool SendRtpPacket(const void* data, size_t len);
-
-  MediaChannel* media_channel_;
-  talk_base::scoped_ptr<talk_base::StreamInterface> input_stream_;
-  talk_base::scoped_ptr<talk_base::StreamInterface> output_stream_;
-  talk_base::scoped_ptr<RtpDumpLoopReader> rtp_dump_reader_;
-  talk_base::scoped_ptr<RtpDumpWriter> rtp_dump_writer_;
-  // RTP dump packet read from the input stream.
-  RtpDumpPacket rtp_dump_packet_;
-  uint32 start_send_time_;
-  bool sending_;
-  bool first_packet_;
-  uint32 first_ssrc_;
-
-  DISALLOW_COPY_AND_ASSIGN(RtpSenderReceiver);
-};
-
-///////////////////////////////////////////////////////////////////////////
-// Implementation of RtpSenderReceiver.
-///////////////////////////////////////////////////////////////////////////
-RtpSenderReceiver::RtpSenderReceiver(
-    MediaChannel* channel,
-    talk_base::StreamInterface* input_file_stream,
-    talk_base::StreamInterface* output_file_stream)
-    : media_channel_(channel),
-      sending_(false),
-      first_packet_(true) {
-  input_stream_.reset(input_file_stream);
-  if (input_stream_.get()) {
-    rtp_dump_reader_.reset(new RtpDumpLoopReader(input_stream_.get()));
-    // Start the sender thread, which reads rtp dump records, waits based on
-    // the record timestamps, and sends the RTP packets to the network.
-    Thread::Start();
-  }
-
-  // Create a rtp dump writer for the output RTP dump stream.
-  output_stream_.reset(output_file_stream);
-  if (output_stream_.get()) {
-    rtp_dump_writer_.reset(new RtpDumpWriter(output_stream_.get()));
-  }
-}
-
-bool RtpSenderReceiver::SetSend(bool send) {
-  bool was_sending = sending_;
-  sending_ = send;
-  if (!was_sending && sending_) {
-    PostDelayed(0, this);  // Wake up the send thread.
-    start_send_time_ = talk_base::Time();
-  }
-  return true;
-}
-
-void RtpSenderReceiver::SetSendSsrc(uint32 ssrc) {
-  if (rtp_dump_reader_.get()) {
-    rtp_dump_reader_->SetSsrc(ssrc);
-  }
-}
-
-void RtpSenderReceiver::OnPacketReceived(talk_base::Buffer* packet) {
-  if (rtp_dump_writer_.get()) {
-    rtp_dump_writer_->WriteRtpPacket(packet->data(), packet->length());
-  }
-}
-
-void RtpSenderReceiver::OnMessage(talk_base::Message* pmsg) {
-  if (!sending_) {
-    // If the sender thread is not sending, ignore this message. The thread goes
-    // to sleep until SetSend(true) wakes it up.
-    return;
-  }
-
-  if (!first_packet_) {
-    // Send the previously read packet.
-    SendRtpPacket(&rtp_dump_packet_.data[0], rtp_dump_packet_.data.size());
-  }
-
-  if (ReadNextPacket(&rtp_dump_packet_)) {
-    int wait = talk_base::TimeUntil(
-        start_send_time_ + rtp_dump_packet_.elapsed_time);
-    wait = talk_base::_max(0, wait);
-    PostDelayed(wait, this);
-  } else {
-    Quit();
-  }
-}
-
-bool RtpSenderReceiver::ReadNextPacket(RtpDumpPacket* packet) {
-  while (talk_base::SR_SUCCESS == rtp_dump_reader_->ReadPacket(packet)) {
-    uint32 ssrc;
-    if (!packet->GetRtpSsrc(&ssrc)) {
-      return false;
-    }
-    if (first_packet_) {
-      first_packet_ = false;
-      first_ssrc_ = ssrc;
-    }
-    if (ssrc == first_ssrc_) {
-      return true;
-    }
-  }
-  return false;
-}
-
-bool RtpSenderReceiver::SendRtpPacket(const void* data, size_t len) {
-  if (!media_channel_ || !media_channel_->network_interface()) {
-    return false;
-  }
-
-  talk_base::Buffer packet(data, len, kMaxRtpPacketLen);
-  return media_channel_->network_interface()->SendPacket(&packet);
-}
-
-///////////////////////////////////////////////////////////////////////////
-// Implementation of FileVoiceChannel.
-///////////////////////////////////////////////////////////////////////////
-FileVoiceChannel::FileVoiceChannel(
-    talk_base::StreamInterface* input_file_stream,
-    talk_base::StreamInterface* output_file_stream)
-    : rtp_sender_receiver_(new RtpSenderReceiver(this, input_file_stream,
-                                                 output_file_stream)) {}
-
-FileVoiceChannel::~FileVoiceChannel() {}
-
-bool FileVoiceChannel::SetSendCodecs(const std::vector<AudioCodec>& codecs) {
-  // TODO: Check the format of RTP dump input.
-  return true;
-}
-
-bool FileVoiceChannel::SetSend(SendFlags flag) {
-  return rtp_sender_receiver_->SetSend(flag != SEND_NOTHING);
-}
-
-void FileVoiceChannel::SetSendSsrc(uint32 ssrc) {
-  rtp_sender_receiver_->SetSendSsrc(ssrc);
-}
-
-void FileVoiceChannel::OnPacketReceived(talk_base::Buffer* packet) {
-  rtp_sender_receiver_->OnPacketReceived(packet);
-}
-
-///////////////////////////////////////////////////////////////////////////
-// Implementation of FileVideoChannel.
-///////////////////////////////////////////////////////////////////////////
-FileVideoChannel::FileVideoChannel(
-    talk_base::StreamInterface* input_file_stream,
-    talk_base::StreamInterface* output_file_stream)
-    : rtp_sender_receiver_(new RtpSenderReceiver(this, input_file_stream,
-                                                 output_file_stream)) {}
-
-FileVideoChannel::~FileVideoChannel() {}
-
-bool FileVideoChannel::SetSendCodecs(const std::vector<VideoCodec>& codecs) {
-  // TODO: Check the format of RTP dump input.
-  return true;
-}
-
-bool FileVideoChannel::SetSend(bool send) {
-  return rtp_sender_receiver_->SetSend(send);
-}
-
-void FileVideoChannel::SetSendSsrc(uint32 ssrc) {
-  rtp_sender_receiver_->SetSendSsrc(ssrc);
-}
-
-void FileVideoChannel::OnPacketReceived(talk_base::Buffer* packet) {
-  rtp_sender_receiver_->OnPacketReceived(packet);
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/session/phone/filemediaengine.h b/third_party/libjingle/source/talk/session/phone/filemediaengine.h
deleted file mode 100644
index f179d19..0000000
--- a/third_party/libjingle/source/talk/session/phone/filemediaengine.h
+++ /dev/null
@@ -1,249 +0,0 @@
-// libjingle
-// Copyright 2004--2005, Google Inc.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-//  1. Redistributions of source code must retain the above copyright notice,
-//     this list of conditions and the following disclaimer.
-//  2. Redistributions in binary form must reproduce the above copyright notice,
-//     this list of conditions and the following disclaimer in the documentation
-//     and/or other materials provided with the distribution.
-//  3. The name of the author may not be used to endorse or promote products
-//     derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef TALK_SESSION_PHONE_FILEMEDIAENGINE_H_
-#define TALK_SESSION_PHONE_FILEMEDIAENGINE_H_
-
-#include <string>
-#include <vector>
-
-#include "talk/base/scoped_ptr.h"
-#include "talk/base/stream.h"
-#include "talk/session/phone/codec.h"
-#include "talk/session/phone/mediachannel.h"
-#include "talk/session/phone/mediaengine.h"
-
-namespace talk_base {
-class StreamInterface;
-}
-
-namespace cricket {
-
-// A media engine contains a capturer, an encoder, and a sender in the sender
-// side and a receiver, a decoder, and a renderer in the receiver side.
-// FileMediaEngine simulates the capturer and the encoder via an input RTP dump
-// stream and simulates the decoder and the renderer via an output RTP dump
-// stream. Depending on the parameters of the constructor, FileMediaEngine can
-// act as file voice engine, file video engine, or both. Currently, we use
-// only the RTP dump packets. TODO: Enable RTCP packets.
-class FileMediaEngine : public MediaEngineInterface {
- public:
-  FileMediaEngine() {}
-  virtual ~FileMediaEngine() {}
-
-  // Set the file name of the input or output RTP dump for voice or video.
-  // Should be called before the channel is created.
-  void set_voice_input_filename(const std::string& filename) {
-    voice_input_filename_ = filename;
-  }
-  void set_voice_output_filename(const std::string& filename) {
-    voice_output_filename_ = filename;
-  }
-  void set_video_input_filename(const std::string& filename) {
-    video_input_filename_ = filename;
-  }
-  void set_video_output_filename(const std::string& filename) {
-    video_output_filename_ = filename;
-  }
-
-  // Should be called before codecs() and video_codecs() are called. We need to
-  // set the voice and video codecs; otherwise, Jingle initiation will fail.
-  void set_voice_codecs(const std::vector<AudioCodec>& codecs) {
-    voice_codecs_ = codecs;
-  }
-  void set_video_codecs(const std::vector<VideoCodec>& codecs) {
-    video_codecs_ = codecs;
-  }
-
-  // Implement pure virtual methods of MediaEngine.
-  virtual bool Init() { return true; }
-  virtual void Terminate() {}
-  virtual int GetCapabilities();
-  virtual VoiceMediaChannel* CreateChannel();
-  virtual VideoMediaChannel* CreateVideoChannel(VoiceMediaChannel* voice_ch);
-  virtual SoundclipMedia* CreateSoundclip() { return NULL; }
-  virtual bool SetAudioOptions(int options) { return true; }
-  virtual bool SetVideoOptions(int options) { return true; }
-  virtual bool SetDefaultVideoEncoderConfig(const VideoEncoderConfig& config) {
-    return true;
-  }
-  virtual bool SetSoundDevices(const Device* in_dev, const Device* out_dev) {
-    return true;
-  }
-  virtual bool SetVideoCaptureDevice(const Device* cam_device) { return true; }
-  virtual bool SetVideoCapturer(VideoCapturer* /*capturer*/, uint32 /*ssrc*/) {
-    return true;
-  }
-  virtual bool GetOutputVolume(int* level) { *level = 0; return true; }
-  virtual bool SetOutputVolume(int level) { return true; }
-  virtual int GetInputLevel() { return 0; }
-  virtual bool SetLocalMonitor(bool enable) { return true; }
-  virtual bool SetLocalRenderer(VideoRenderer* renderer) { return true; }
-  // TODO: control channel send?
-  virtual CaptureResult SetVideoCapture(bool capture) { return CR_SUCCESS; }
-  virtual const std::vector<AudioCodec>& audio_codecs() {
-    return voice_codecs_;
-  }
-  virtual const std::vector<VideoCodec>& video_codecs() {
-    return video_codecs_;
-  }
-  virtual bool FindAudioCodec(const AudioCodec& codec) { return true; }
-  virtual bool FindVideoCodec(const VideoCodec& codec) { return true; }
-  virtual void SetVoiceLogging(int min_sev, const char* filter) {}
-  virtual void SetVideoLogging(int min_sev, const char* filter) {}
-
-  virtual bool RegisterVideoProcessor(VideoProcessor* processor) {
-    return true;
-  }
-  virtual bool UnregisterVideoProcessor(VideoProcessor* processor) {
-    return true;
-  }
-  virtual bool RegisterVoiceProcessor(uint32 ssrc,
-                                      VoiceProcessor* processor,
-                                      MediaProcessorDirection direction) {
-    return true;
-  }
-  virtual bool UnregisterVoiceProcessor(uint32 ssrc,
-                                        VoiceProcessor* processor,
-                                        MediaProcessorDirection direction) {
-    return true;
-  }
-
- private:
-  std::string voice_input_filename_;
-  std::string voice_output_filename_;
-  std::string video_input_filename_;
-  std::string video_output_filename_;
-  std::vector<AudioCodec> voice_codecs_;
-  std::vector<VideoCodec> video_codecs_;
-
-  DISALLOW_COPY_AND_ASSIGN(FileMediaEngine);
-};
-
-class RtpSenderReceiver;  // Forward declaration. Defined in the .cc file.
-
-class FileVoiceChannel : public VoiceMediaChannel {
- public:
-  FileVoiceChannel(talk_base::StreamInterface* input_file_stream,
-      talk_base::StreamInterface* output_file_stream);
-  virtual ~FileVoiceChannel();
-
-  // Implement pure virtual methods of VoiceMediaChannel.
-  virtual bool SetRecvCodecs(const std::vector<AudioCodec>& codecs) {
-    return true;
-  }
-  virtual bool SetSendCodecs(const std::vector<AudioCodec>& codecs);
-  virtual bool SetRecvRtpHeaderExtensions(
-      const std::vector<RtpHeaderExtension>& extensions) {
-    return true;
-  }
-  virtual bool SetSendRtpHeaderExtensions(
-      const std::vector<RtpHeaderExtension>& extensions) {
-    return true;
-  }
-  virtual bool SetPlayout(bool playout) { return true; }
-  virtual bool SetSend(SendFlags flag);
-  virtual bool AddStream(uint32 ssrc) { return true; }
-  virtual bool RemoveStream(uint32 ssrc) { return true; }
-  virtual bool GetActiveStreams(AudioInfo::StreamList* actives) { return true; }
-  virtual int GetOutputLevel() { return 0; }
-  virtual bool SetOutputScaling(uint32 ssrc, double left, double right) {
-    return false;
-  }
-  virtual bool GetOutputScaling(uint32 ssrc, double* left, double* right) {
-    return false;
-  }
-  virtual bool SetRingbackTone(const char* buf, int len) { return true; }
-  virtual bool PlayRingbackTone(uint32 ssrc, bool play, bool loop) {
-    return true;
-  }
-  virtual bool PressDTMF(int event, bool playout) { return true; }
-  virtual bool GetStats(VoiceMediaInfo* info) { return true; }
-
-  // Implement pure virtual methods of MediaChannel.
-  virtual void OnPacketReceived(talk_base::Buffer* packet);
-  virtual void OnRtcpReceived(talk_base::Buffer* packet) {}
-  virtual void SetSendSsrc(uint32 ssrc);
-  virtual bool SetRtcpCName(const std::string& cname) { return true; }
-  virtual bool Mute(bool on) { return false; }
-  virtual bool SetSendBandwidth(bool autobw, int bps) { return true; }
-  virtual bool SetOptions(int options) { return true; }
-
- private:
-  talk_base::scoped_ptr<RtpSenderReceiver> rtp_sender_receiver_;
-  DISALLOW_COPY_AND_ASSIGN(FileVoiceChannel);
-};
-
-class FileVideoChannel : public VideoMediaChannel {
- public:
-  FileVideoChannel(talk_base::StreamInterface* input_file_stream,
-      talk_base::StreamInterface* output_file_stream);
-  virtual ~FileVideoChannel();
-
-  // Implement pure virtual methods of VideoMediaChannel.
-  virtual bool SetRecvCodecs(const std::vector<VideoCodec>& codecs) {
-    return true;
-  }
-  virtual bool SetSendCodecs(const std::vector<VideoCodec>& codecs);
-  virtual bool SetRecvRtpHeaderExtensions(
-      const std::vector<RtpHeaderExtension>& extensions) {
-    return true;
-  }
-  virtual bool SetSendRtpHeaderExtensions(
-      const std::vector<RtpHeaderExtension>& extensions) {
-    return true;
-  }
-  virtual bool SetRender(bool render) { return true; }
-  virtual bool SetSend(bool send);
-  virtual bool AddStream(uint32 ssrc, uint32 voice_ssrc) { return true; }
-  virtual bool RemoveStream(uint32 ssrc) { return true; }
-  virtual bool SetRenderer(uint32 ssrc, VideoRenderer* renderer) {
-    return true;
-  }
-  virtual bool AddScreencast(uint32 ssrc, talk_base::WindowId id) {
-    return true;
-  }
-  virtual bool RemoveScreencast(uint32 ssrc) { return true; }
-  virtual bool GetStats(VideoMediaInfo* info) { return true; }
-  virtual bool SendIntraFrame() { return false; }
-  virtual bool RequestIntraFrame() { return false; }
-
-  // Implement pure virtual methods of MediaChannel.
-  virtual void OnPacketReceived(talk_base::Buffer* packet);
-  virtual void OnRtcpReceived(talk_base::Buffer* packet) {}
-  virtual void SetSendSsrc(uint32 ssrc);
-  virtual bool SetRtcpCName(const std::string& cname) { return true; }
-  virtual bool Mute(bool on) { return false; }
-  virtual bool SetSendBandwidth(bool autobw, int bps) { return true; }
-  virtual bool SetOptions(int options) { return true; }
-
- private:
-  talk_base::scoped_ptr<RtpSenderReceiver> rtp_sender_receiver_;
-  DISALLOW_COPY_AND_ASSIGN(FileVideoChannel);
-};
-
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_FILEMEDIAENGINE_H_
diff --git a/third_party/libjingle/source/talk/session/phone/filemediaengine_unittest.cc b/third_party/libjingle/source/talk/session/phone/filemediaengine_unittest.cc
deleted file mode 100644
index cab7120..0000000
--- a/third_party/libjingle/source/talk/session/phone/filemediaengine_unittest.cc
+++ /dev/null
@@ -1,462 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <set>
-
-#include "talk/base/buffer.h"
-#include "talk/base/gunit.h"
-#include "talk/base/helpers.h"
-#include "talk/base/pathutils.h"
-#include "talk/base/stream.h"
-#include "talk/session/phone/filemediaengine.h"
-#include "talk/session/phone/rtpdump.h"
-#include "talk/session/phone/testutils.h"
-
-namespace cricket {
-
-static const int kWaitTimeMs = 100;
-static const std::string kFakeFileName = "foobar";
-
-//////////////////////////////////////////////////////////////////////////////
-// Media channel sends RTP packets via NetworkInterface. Rather than sending
-// packets to the network, FileNetworkInterface writes packets to a stream and
-// feeds packets back to the channel via OnPacketReceived.
-//////////////////////////////////////////////////////////////////////////////
-class FileNetworkInterface : public MediaChannel::NetworkInterface {
- public:
-  FileNetworkInterface(talk_base::StreamInterface* output, MediaChannel* ch)
-      : media_channel_(ch),
-        num_sent_packets_(0) {
-    if (output) {
-      dump_writer_.reset(new RtpDumpWriter(output));
-    }
-  }
-
-  // Implement pure virtual methods of NetworkInterface.
-  virtual bool SendPacket(talk_base::Buffer* packet) {
-    if (!packet) return false;
-
-    if (media_channel_) {
-      media_channel_->OnPacketReceived(packet);
-    }
-    if (dump_writer_.get() &&
-        talk_base::SR_SUCCESS != dump_writer_->WriteRtpPacket(
-            packet->data(), packet->length())) {
-      return false;
-    }
-
-    ++num_sent_packets_;
-    return true;
-  }
-
-  virtual bool SendRtcp(talk_base::Buffer* packet) { return false; }
-  virtual int SetOption(MediaChannel::NetworkInterface::SocketType type,
-      talk_base::Socket::Option opt, int option) {
-    return 0;
-  }
-
-  size_t num_sent_packets() const { return num_sent_packets_; }
-
- private:
-  MediaChannel* media_channel_;
-  talk_base::scoped_ptr<RtpDumpWriter> dump_writer_;
-  size_t num_sent_packets_;
-
-  DISALLOW_COPY_AND_ASSIGN(FileNetworkInterface);
-};
-
-class FileMediaEngineTest : public testing::Test {
- public:
-  virtual void SetUp() {
-    setup_ok_ = true;
-    setup_ok_ &= GetTempFilename(&voice_input_filename_);
-    setup_ok_ &= GetTempFilename(&voice_output_filename_);
-    setup_ok_ &= GetTempFilename(&video_input_filename_);
-    setup_ok_ &= GetTempFilename(&video_output_filename_);
-  }
-  virtual void TearDown() {
-    // Force to close the dump files, if opened.
-    voice_channel_.reset();
-    video_channel_.reset();
-
-    DeleteTempFile(voice_input_filename_);
-    DeleteTempFile(voice_output_filename_);
-    DeleteTempFile(video_input_filename_);
-    DeleteTempFile(video_output_filename_);
-  }
-
- protected:
-  bool CreateEngineAndChannels(const std::string& voice_in,
-                               const std::string& voice_out,
-                               const std::string& video_in,
-                               const std::string& video_out,
-                               size_t ssrc_count) {
-    // Force to close the dump files, if opened.
-    voice_channel_.reset();
-    video_channel_.reset();
-
-    bool ret = setup_ok_;
-    if (!voice_in.empty()) {
-      ret &= WriteTestPacketsToFile(voice_in, ssrc_count);
-    }
-    if (!video_in.empty()) {
-      ret &= WriteTestPacketsToFile(video_in, ssrc_count);
-    }
-
-    engine_.reset(new FileMediaEngine);
-    engine_->set_voice_input_filename(voice_in);
-    engine_->set_voice_output_filename(voice_out);
-    engine_->set_video_input_filename(video_in);
-    engine_->set_video_output_filename(video_out);
-
-    voice_channel_.reset(engine_->CreateChannel());
-    video_channel_.reset(engine_->CreateVideoChannel(NULL));
-
-    return ret;
-  }
-
-  bool GetTempFilename(std::string* filename) {
-    talk_base::Pathname temp_path;
-    if (!talk_base::Filesystem::GetTemporaryFolder(temp_path, true, NULL)) {
-      return false;
-    }
-    temp_path.SetPathname(
-        talk_base::Filesystem::TempFilename(temp_path, "fme-test-"));
-
-    if (filename) {
-      *filename = temp_path.pathname();
-    }
-    return true;
-  }
-
-  bool WriteTestPacketsToFile(const std::string& filename, size_t ssrc_count) {
-    talk_base::scoped_ptr<talk_base::StreamInterface> stream(
-        talk_base::Filesystem::OpenFile(talk_base::Pathname(filename), "wb"));
-    bool ret = (NULL != stream.get());
-    RtpDumpWriter writer(stream.get());
-
-    for (size_t i = 0; i < ssrc_count; ++i) {
-      ret &= RtpTestUtility::WriteTestPackets(
-          RtpTestUtility::GetTestPacketCount(), false,
-          RtpTestUtility::kDefaultSsrc + i, &writer);
-    }
-    return ret;
-  }
-
-  void DeleteTempFile(std::string filename) {
-    talk_base::Pathname pathname(filename);
-    if (talk_base::Filesystem::IsFile(talk_base::Pathname(pathname))) {
-      talk_base::Filesystem::DeleteFile(pathname);
-    }
-  }
-
-  bool GetSsrcAndPacketCounts(talk_base::StreamInterface* stream,
-                              size_t* ssrc_count, size_t* packet_count) {
-    talk_base::scoped_ptr<RtpDumpReader> reader(new RtpDumpReader(stream));
-    size_t count = 0;
-    RtpDumpPacket packet;
-    std::set<uint32> ssrcs;
-    while (talk_base::SR_SUCCESS == reader->ReadPacket(&packet)) {
-      count++;
-      uint32 ssrc;
-      if (!packet.GetRtpSsrc(&ssrc)) {
-        return false;
-      }
-      ssrcs.insert(ssrc);
-    }
-    if (ssrc_count) {
-      *ssrc_count = ssrcs.size();
-    }
-    if (packet_count) {
-      *packet_count = count;
-    }
-    return true;
-  }
-
-  static const uint32 kWaitTimeout = 3000;
-  bool setup_ok_;
-  std::string voice_input_filename_;
-  std::string voice_output_filename_;
-  std::string video_input_filename_;
-  std::string video_output_filename_;
-  talk_base::scoped_ptr<FileMediaEngine> engine_;
-  talk_base::scoped_ptr<VoiceMediaChannel> voice_channel_;
-  talk_base::scoped_ptr<VideoMediaChannel> video_channel_;
-};
-
-TEST_F(FileMediaEngineTest, TestDefaultImplementation) {
-  EXPECT_TRUE(CreateEngineAndChannels("", "", "", "", 1));
-  EXPECT_TRUE(engine_->Init());
-  EXPECT_EQ(0, engine_->GetCapabilities());
-  EXPECT_TRUE(NULL == voice_channel_.get());
-  EXPECT_TRUE(NULL == video_channel_.get());
-  EXPECT_TRUE(NULL == engine_->CreateSoundclip());
-  EXPECT_TRUE(engine_->SetAudioOptions(0));
-  EXPECT_TRUE(engine_->SetVideoOptions(0));
-  VideoEncoderConfig video_encoder_config;
-  EXPECT_TRUE(engine_->SetDefaultVideoEncoderConfig(video_encoder_config));
-  EXPECT_TRUE(engine_->SetSoundDevices(NULL, NULL));
-  EXPECT_TRUE(engine_->SetVideoCaptureDevice(NULL));
-  EXPECT_TRUE(engine_->SetOutputVolume(0));
-  EXPECT_EQ(0, engine_->GetInputLevel());
-  EXPECT_TRUE(engine_->SetLocalMonitor(true));
-  EXPECT_TRUE(engine_->SetLocalRenderer(NULL));
-  EXPECT_EQ(CR_SUCCESS, engine_->SetVideoCapture(true));
-  EXPECT_EQ(0U, engine_->audio_codecs().size());
-  EXPECT_EQ(0U, engine_->video_codecs().size());
-  AudioCodec voice_codec;
-  EXPECT_TRUE(engine_->FindAudioCodec(voice_codec));
-  VideoCodec video_codec;
-  EXPECT_TRUE(engine_->FindVideoCodec(video_codec));
-  engine_->Terminate();
-}
-
-// Test that when file path is not pointing to a valid stream file, the channel
-// creation function should fail and return NULL.
-TEST_F(FileMediaEngineTest, TestBadFilePath) {
-  engine_.reset(new FileMediaEngine);
-  engine_->set_voice_input_filename(kFakeFileName);
-  engine_->set_video_input_filename(kFakeFileName);
-  EXPECT_TRUE(engine_->CreateChannel() == NULL);
-  EXPECT_TRUE(engine_->CreateVideoChannel(NULL) == NULL);
-}
-
-TEST_F(FileMediaEngineTest, TestCodecs) {
-  EXPECT_TRUE(CreateEngineAndChannels("", "", "", "", 1));
-  std::vector<AudioCodec> voice_codecs = engine_->audio_codecs();
-  std::vector<VideoCodec> video_codecs = engine_->video_codecs();
-  EXPECT_EQ(0U, voice_codecs.size());
-  EXPECT_EQ(0U, video_codecs.size());
-
-  AudioCodec voice_codec(103, "ISAC", 16000, 0, 1, 0);
-  voice_codecs.push_back(voice_codec);
-  engine_->set_voice_codecs(voice_codecs);
-  voice_codecs = engine_->audio_codecs();
-  ASSERT_EQ(1U, voice_codecs.size());
-  EXPECT_EQ(voice_codec, voice_codecs[0]);
-
-  VideoCodec video_codec(96, "H264-SVC", 320, 240, 30, 0);
-  video_codecs.push_back(video_codec);
-  engine_->set_video_codecs(video_codecs);
-  video_codecs = engine_->video_codecs();
-  ASSERT_EQ(1U, video_codecs.size());
-  EXPECT_EQ(video_codec, video_codecs[0]);
-}
-
-// Test that the capabilities and channel creation of the Filemedia engine
-// depend on the stream parameters passed to its constructor.
-TEST_F(FileMediaEngineTest, TestGetCapabilities) {
-  EXPECT_TRUE(CreateEngineAndChannels(voice_input_filename_, "", "", "", 1));
-  EXPECT_EQ(AUDIO_SEND, engine_->GetCapabilities());
-  EXPECT_TRUE(NULL != voice_channel_.get());
-  EXPECT_TRUE(NULL == video_channel_.get());
-
-  EXPECT_TRUE(CreateEngineAndChannels(voice_input_filename_,
-                                      voice_output_filename_, "", "", 1));
-  EXPECT_EQ(AUDIO_SEND | AUDIO_RECV, engine_->GetCapabilities());
-  EXPECT_TRUE(NULL != voice_channel_.get());
-  EXPECT_TRUE(NULL == video_channel_.get());
-
-  EXPECT_TRUE(CreateEngineAndChannels("", "", video_input_filename_, "", 1));
-  EXPECT_EQ(VIDEO_SEND, engine_->GetCapabilities());
-  EXPECT_TRUE(NULL == voice_channel_.get());
-  EXPECT_TRUE(NULL != video_channel_.get());
-
-  EXPECT_TRUE(CreateEngineAndChannels(voice_input_filename_,
-                                      voice_output_filename_,
-                                      video_input_filename_,
-                                      video_output_filename_,
-                                      1));
-  EXPECT_EQ(AUDIO_SEND | AUDIO_RECV | VIDEO_SEND | VIDEO_RECV,
-            engine_->GetCapabilities());
-  EXPECT_TRUE(NULL != voice_channel_.get());
-  EXPECT_TRUE(NULL != video_channel_.get());
-}
-
-// FileVideoChannel is the same as FileVoiceChannel in terms of receiving and
-// sending the RTP packets. We therefore test only FileVoiceChannel.
-
-// Test that SetSend() controls whether a voice channel sends RTP packets.
-TEST_F(FileMediaEngineTest, TestVoiceChannelSetSend) {
-  EXPECT_TRUE(CreateEngineAndChannels(voice_input_filename_,
-                                      voice_output_filename_, "", "", 1));
-  EXPECT_TRUE(NULL != voice_channel_.get());
-  talk_base::MemoryStream net_dump;
-  FileNetworkInterface net_interface(&net_dump, voice_channel_.get());
-  voice_channel_->SetInterface(&net_interface);
-
-  // The channel is not sending yet.
-  talk_base::Thread::Current()->ProcessMessages(kWaitTimeMs);
-  EXPECT_EQ(0U, net_interface.num_sent_packets());
-
-  // The channel starts sending.
-  voice_channel_->SetSend(SEND_MICROPHONE);
-  EXPECT_TRUE_WAIT(net_interface.num_sent_packets() >= 1U, kWaitTimeout);
-
-  // The channel stops sending.
-  voice_channel_->SetSend(SEND_NOTHING);
-  // Wait until packets are all delivered.
-  talk_base::Thread::Current()->ProcessMessages(kWaitTimeMs);
-  size_t old_number = net_interface.num_sent_packets();
-  talk_base::Thread::Current()->ProcessMessages(kWaitTimeMs);
-  EXPECT_EQ(old_number, net_interface.num_sent_packets());
-
-  // The channel starts sending again.
-  voice_channel_->SetSend(SEND_MICROPHONE);
-  EXPECT_TRUE_WAIT(net_interface.num_sent_packets() > old_number, kWaitTimeout);
-
-  // When the function exits, the net_interface object is released. The sender
-  // thread may call net_interface to send packets, which results in a segment
-  // fault. We hence stop sending and wait until all packets are delivered
-  // before we exit this function.
-  voice_channel_->SetSend(SEND_NOTHING);
-  talk_base::Thread::Current()->ProcessMessages(kWaitTimeMs);
-}
-
-// Test the sender thread of the channel. The sender sends RTP packets
-// continuously with proper sequence number, timestamp, and payload.
-TEST_F(FileMediaEngineTest, TestVoiceChannelSenderThread) {
-  EXPECT_TRUE(CreateEngineAndChannels(voice_input_filename_,
-                                      voice_output_filename_, "", "", 1));
-  EXPECT_TRUE(NULL != voice_channel_.get());
-  talk_base::MemoryStream net_dump;
-  FileNetworkInterface net_interface(&net_dump, voice_channel_.get());
-  voice_channel_->SetInterface(&net_interface);
-
-  voice_channel_->SetSend(SEND_MICROPHONE);
-  // Wait until the number of sent packets is no less than 2 * kPacketNumber.
-  EXPECT_TRUE_WAIT(
-      net_interface.num_sent_packets() >=
-          2 * RtpTestUtility::GetTestPacketCount(),
-      kWaitTimeout);
-  voice_channel_->SetSend(SEND_NOTHING);
-  // Wait until packets are all delivered.
-  talk_base::Thread::Current()->ProcessMessages(kWaitTimeMs);
-  EXPECT_TRUE(RtpTestUtility::VerifyTestPacketsFromStream(
-      2 * RtpTestUtility::GetTestPacketCount(), &net_dump,
-      RtpTestUtility::kDefaultSsrc));
-
-  // Each sent packet is dumped to net_dump and is also feed to the channel
-  // via OnPacketReceived, which in turn writes the packets into voice_output_.
-  // We next verify the packets in voice_output_.
-  voice_channel_.reset();  // Force to close the files.
-  talk_base::scoped_ptr<talk_base::StreamInterface> voice_output_;
-  voice_output_.reset(talk_base::Filesystem::OpenFile(
-      talk_base::Pathname(voice_output_filename_), "rb"));
-  EXPECT_TRUE(voice_output_.get() != NULL);
-  EXPECT_TRUE(RtpTestUtility::VerifyTestPacketsFromStream(
-      2 * RtpTestUtility::GetTestPacketCount(), voice_output_.get(),
-      RtpTestUtility::kDefaultSsrc));
-}
-
-// Test that we can specify the ssrc for outgoing RTP packets.
-TEST_F(FileMediaEngineTest, TestVoiceChannelSendSsrc) {
-  EXPECT_TRUE(CreateEngineAndChannels(voice_input_filename_,
-                                      voice_output_filename_, "", "", 1));
-  EXPECT_TRUE(NULL != voice_channel_.get());
-  const uint32 send_ssrc = RtpTestUtility::kDefaultSsrc + 1;
-  voice_channel_->SetSendSsrc(send_ssrc);
-
-  talk_base::MemoryStream net_dump;
-  FileNetworkInterface net_interface(&net_dump, voice_channel_.get());
-  voice_channel_->SetInterface(&net_interface);
-
-  voice_channel_->SetSend(SEND_MICROPHONE);
-  // Wait until the number of sent packets is no less than 2 * kPacketNumber.
-  EXPECT_TRUE_WAIT(
-      net_interface.num_sent_packets() >=
-          2 * RtpTestUtility::GetTestPacketCount(),
-      kWaitTimeout);
-  voice_channel_->SetSend(SEND_NOTHING);
-  // Wait until packets are all delivered.
-  talk_base::Thread::Current()->ProcessMessages(kWaitTimeMs);
-  EXPECT_TRUE(RtpTestUtility::VerifyTestPacketsFromStream(
-      2 * RtpTestUtility::GetTestPacketCount(), &net_dump, send_ssrc));
-
-  // Each sent packet is dumped to net_dump and is also feed to the channel
-  // via OnPacketReceived, which in turn writes the packets into voice_output_.
-  // We next verify the packets in voice_output_.
-  voice_channel_.reset();  // Force to close the files.
-  talk_base::scoped_ptr<talk_base::StreamInterface> voice_output_;
-  voice_output_.reset(talk_base::Filesystem::OpenFile(
-      talk_base::Pathname(voice_output_filename_), "rb"));
-  EXPECT_TRUE(voice_output_.get() != NULL);
-  EXPECT_TRUE(RtpTestUtility::VerifyTestPacketsFromStream(
-      2 * RtpTestUtility::GetTestPacketCount(), voice_output_.get(),
-      send_ssrc));
-}
-
-// Test the sender thread of the channel, where the input rtpdump has two SSRCs.
-TEST_F(FileMediaEngineTest, TestVoiceChannelSenderThreadTwoSsrcs) {
-  EXPECT_TRUE(CreateEngineAndChannels(voice_input_filename_,
-                                      voice_output_filename_, "", "", 2));
-  // Verify that voice_input_filename_ contains 2 *
-  // RtpTestUtility::GetTestPacketCount() packets
-  // with different SSRCs.
-  talk_base::scoped_ptr<talk_base::StreamInterface> input_stream(
-      talk_base::Filesystem::OpenFile(
-          talk_base::Pathname(voice_input_filename_), "rb"));
-  ASSERT_TRUE(NULL != input_stream.get());
-  size_t ssrc_count;
-  size_t packet_count;
-  EXPECT_TRUE(GetSsrcAndPacketCounts(input_stream.get(), &ssrc_count,
-                                     &packet_count));
-  EXPECT_EQ(2U, ssrc_count);
-  EXPECT_EQ(2 * RtpTestUtility::GetTestPacketCount(), packet_count);
-  input_stream.reset();
-
-  // Send 2 * RtpTestUtility::GetTestPacketCount() packets and verify that all
-  // these packets have the same SSRCs (that is, the packets with different
-  // SSRCs are skipped by the filemediaengine).
-  EXPECT_TRUE(NULL != voice_channel_.get());
-  talk_base::MemoryStream net_dump;
-  FileNetworkInterface net_interface(&net_dump, voice_channel_.get());
-  voice_channel_->SetInterface(&net_interface);
-  voice_channel_->SetSend(SEND_MICROPHONE);
-  EXPECT_TRUE_WAIT(
-      net_interface.num_sent_packets() >=
-          2 * RtpTestUtility::GetTestPacketCount(),
-      kWaitTimeout);
-  voice_channel_->SetSend(SEND_NOTHING);
-  // Wait until packets are all delivered.
-  talk_base::Thread::Current()->ProcessMessages(kWaitTimeMs);
-  net_dump.Rewind();
-  EXPECT_TRUE(GetSsrcAndPacketCounts(&net_dump, &ssrc_count, &packet_count));
-  EXPECT_EQ(1U, ssrc_count);
-  EXPECT_GE(packet_count, 2 * RtpTestUtility::GetTestPacketCount());
-}
-
-// Test SendIntraFrame() and RequestIntraFrame() of video channel.
-TEST_F(FileMediaEngineTest, TestVideoChannelIntraFrame) {
-  EXPECT_TRUE(CreateEngineAndChannels("", "", video_input_filename_,
-                                      video_output_filename_, 1));
-  EXPECT_TRUE(NULL != video_channel_.get());
-  EXPECT_FALSE(video_channel_->SendIntraFrame());
-  EXPECT_FALSE(video_channel_->RequestIntraFrame());
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/session/phone/filevideocapturer.cc b/third_party/libjingle/source/talk/session/phone/filevideocapturer.cc
deleted file mode 100644
index 00272c5..0000000
--- a/third_party/libjingle/source/talk/session/phone/filevideocapturer.cc
+++ /dev/null
@@ -1,350 +0,0 @@
-// libjingle
-// Copyright 2004--2005, Google Inc.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-//  1. Redistributions of source code must retain the above copyright notice,
-//     this list of conditions and the following disclaimer.
-//  2. Redistributions in binary form must reproduce the above copyright notice,
-//     this list of conditions and the following disclaimer in the documentation
-//     and/or other materials provided with the distribution.
-//  3. The name of the author may not be used to endorse or promote products
-//     derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Implementation of VideoRecorder and FileVideoCapturer.
-
-#include "talk/session/phone/filevideocapturer.h"
-
-#include "talk/base/bytebuffer.h"
-#include "talk/base/logging.h"
-#include "talk/base/thread.h"
-
-namespace cricket {
-
-/////////////////////////////////////////////////////////////////////
-// Implementation of class VideoRecorder
-/////////////////////////////////////////////////////////////////////
-bool VideoRecorder::Start(const std::string& filename, bool write_header) {
-  Stop();
-  write_header_ = write_header;
-  int err;
-  if (!video_file_.Open(filename, "wb", &err)) {
-    LOG(LS_ERROR) << "Unable to open file " << filename << " err=" << err;
-    return false;
-  }
-  return true;
-}
-
-void VideoRecorder::Stop() {
-  video_file_.Close();
-}
-
-bool VideoRecorder::RecordFrame(const CapturedFrame& frame) {
-  if (talk_base::SS_CLOSED == video_file_.GetState()) {
-    LOG(LS_ERROR) << "File not opened yet";
-    return false;
-  }
-
-  uint32 size = 0;
-  if (!frame.GetDataSize(&size)) {
-    LOG(LS_ERROR) << "Unable to calculate the data size of the frame";
-    return false;
-  }
-
-  if (write_header_) {
-    // Convert the frame header to bytebuffer.
-    talk_base::ByteBuffer buffer;
-    buffer.WriteUInt32(frame.width);
-    buffer.WriteUInt32(frame.height);
-    buffer.WriteUInt32(frame.fourcc);
-    buffer.WriteUInt32(frame.pixel_width);
-    buffer.WriteUInt32(frame.pixel_height);
-    buffer.WriteUInt64(frame.elapsed_time);
-    buffer.WriteUInt64(frame.time_stamp);
-    buffer.WriteUInt32(size);
-
-    // Write the bytebuffer to file.
-    if (talk_base::SR_SUCCESS != video_file_.Write(buffer.Data(),
-                                                   buffer.Length(),
-                                                   NULL,
-                                                   NULL)) {
-      LOG(LS_ERROR) << "Failed to write frame header";
-      return false;
-    }
-  }
-  // Write the frame data to file.
-  if (talk_base::SR_SUCCESS != video_file_.Write(frame.data,
-                                                 size,
-                                                 NULL,
-                                                 NULL)) {
-    LOG(LS_ERROR) << "Failed to write frame data";
-    return false;
-  }
-
-  return true;
-}
-
-///////////////////////////////////////////////////////////////////////
-// Definition of private class FileReadThread that periodically reads
-// frames from a file.
-///////////////////////////////////////////////////////////////////////
-class FileVideoCapturer::FileReadThread
-    : public talk_base::Thread, public talk_base::MessageHandler {
- public:
-  explicit FileReadThread(FileVideoCapturer* capturer)
-      : capturer_(capturer),
-        finished_(false) {
-  }
-
-  // Override virtual method of parent Thread. Context: Worker Thread.
-  virtual void Run() {
-    // Read the first frame and start the message pump. The pump runs until
-    // Stop() is called externally or Quit() is called by OnMessage().
-    int waiting_time_ms = 0;
-    if (capturer_ && capturer_->ReadFrame(true, &waiting_time_ms)) {
-      PostDelayed(waiting_time_ms, this);
-      Thread::Run();
-    }
-    finished_ = true;
-  }
-
-  // Override virtual method of parent MessageHandler. Context: Worker Thread.
-  virtual void OnMessage(talk_base::Message* /*pmsg*/) {
-    int waiting_time_ms = 0;
-    if (capturer_ && capturer_->ReadFrame(false, &waiting_time_ms)) {
-      PostDelayed(waiting_time_ms, this);
-    } else {
-      Quit();
-    }
-  }
-
-  // Check if Run() is finished.
-  bool Finished() const { return finished_; }
-
- private:
-  FileVideoCapturer* capturer_;
-  bool finished_;
-
-  DISALLOW_COPY_AND_ASSIGN(FileReadThread);
-};
-
-/////////////////////////////////////////////////////////////////////
-// Implementation of class FileVideoCapturer
-/////////////////////////////////////////////////////////////////////
-static const int64 kNumNanoSecsPerMilliSec = 1000000;
-
-FileVideoCapturer::FileVideoCapturer()
-    : frame_buffer_size_(0),
-      file_read_thread_(NULL),
-      repeat_(0),
-      start_time_ns_(0),
-      last_frame_timestamp_ns_(0),
-      ignore_framerate_(false) {
-}
-
-FileVideoCapturer::~FileVideoCapturer() {
-  Stop();
-  delete[] static_cast<char*> (captured_frame_.data);
-}
-
-bool FileVideoCapturer::Init(const std::string& filename) {
-  if (IsRunning()) {
-    LOG(LS_ERROR) << "The file video capturer is already running";
-    return false;
-  }
-  // Open the file.
-  int err;
-  if (!video_file_.Open(filename, "rb", &err)) {
-    LOG(LS_ERROR) << "Unable to open the file " << filename << " err=" << err;
-    return false;
-  }
-  // Read the first frame's header to determine the supported format.
-  CapturedFrame frame;
-  if (talk_base::SR_SUCCESS != ReadFrameHeader(&frame)) {
-    LOG(LS_ERROR) << "Failed to read the first frame header";
-    video_file_.Close();
-    return false;
-  }
-  // Seek back to the start of the file.
-  if (!video_file_.SetPosition(0)) {
-    LOG(LS_ERROR) << "Failed to seek back to beginning of the file";
-    video_file_.Close();
-    return false;
-  }
-
-  // Enumerate the supported formats. We have only one supported format. We set
-  // the frame interval to kMinimumInterval here. In Start(), if the capture
-  // format's interval is greater than kMinimumInterval, we use the interval;
-  // otherwise, we use the timestamp in the file to control the interval.
-  VideoFormat format(frame.width, frame.height, VideoFormat::kMinimumInterval,
-                     frame.fourcc);
-  std::vector<VideoFormat> supported;
-  supported.push_back(format);
-
-  SetId(filename);
-  SetSupportedFormats(supported);
-  return true;
-}
-
-CaptureResult FileVideoCapturer::Start(const VideoFormat& capture_format) {
-  if (IsRunning()) {
-    LOG(LS_ERROR) << "The file video capturer is already running";
-    return CR_FAILURE;
-  }
-
-  if (talk_base::SS_CLOSED == video_file_.GetState()) {
-    LOG(LS_ERROR) << "File not opened yet";
-    return CR_NO_DEVICE;
-  } else if (!video_file_.SetPosition(0)) {
-    LOG(LS_ERROR) << "Failed to seek back to beginning of the file";
-    return CR_FAILURE;
-  }
-
-  SetCaptureFormat(&capture_format);
-  // Create a thread to read the file.
-  file_read_thread_ = new FileReadThread(this);
-  bool ret = file_read_thread_->Start();
-  start_time_ns_ = kNumNanoSecsPerMilliSec *
-      static_cast<int64>(talk_base::Time());
-  if (ret) {
-    LOG(LS_INFO) << "File video capturer '" << GetId() << "' started";
-    return CR_SUCCESS;
-  } else {
-    LOG(LS_ERROR) << "File video capturer '" << GetId() << "' failed to start";
-    return CR_FAILURE;
-  }
-}
-
-bool FileVideoCapturer::IsRunning() {
-  return file_read_thread_ && !file_read_thread_->Finished();
-}
-
-void FileVideoCapturer::Stop() {
-  if (file_read_thread_) {
-    file_read_thread_->Stop();
-    file_read_thread_ = NULL;
-    LOG(LS_INFO) << "File video capturer '" << GetId() << "' stopped";
-  }
-  SetCaptureFormat(NULL);
-}
-
-bool FileVideoCapturer::GetPreferredFourccs(std::vector<uint32>* fourccs) {
-  if (!fourccs) {
-    return false;
-  }
-
-  fourccs->push_back(GetSupportedFormats()->at(0).fourcc);
-  return true;
-}
-
-talk_base::StreamResult FileVideoCapturer::ReadFrameHeader(
-    CapturedFrame* frame) {
-  // We first read kFrameHeaderSize bytes from the file stream to a memory
-  // buffer, then construct a bytebuffer from the memory buffer, and finally
-  // read the frame header from the bytebuffer.
-  char header[CapturedFrame::kFrameHeaderSize];
-  talk_base::StreamResult sr;
-  sr = video_file_.Read(header,
-                        CapturedFrame::kFrameHeaderSize,
-                        NULL,
-                        NULL);
-  if (talk_base::SR_SUCCESS == sr) {
-    talk_base::ByteBuffer buffer(header, CapturedFrame::kFrameHeaderSize);
-    buffer.ReadUInt32(reinterpret_cast<uint32*>(&frame->width));
-    buffer.ReadUInt32(reinterpret_cast<uint32*>(&frame->height));
-    buffer.ReadUInt32(&frame->fourcc);
-    buffer.ReadUInt32(&frame->pixel_width);
-    buffer.ReadUInt32(&frame->pixel_height);
-    buffer.ReadUInt64(reinterpret_cast<uint64*>(&frame->elapsed_time));
-    buffer.ReadUInt64(reinterpret_cast<uint64*>(&frame->time_stamp));
-    buffer.ReadUInt32(&frame->data_size);
-  }
-
-  return sr;
-}
-
-// Executed in the context of FileReadThread.
-bool FileVideoCapturer::ReadFrame(bool first_frame, int* wait_time_ms) {
-  uint32 start_read_time_ms = talk_base::Time();
-
-  // 1. Signal the previously read frame to downstream.
-  if (!first_frame) {
-    captured_frame_.time_stamp = kNumNanoSecsPerMilliSec *
-        static_cast<int64>(start_read_time_ms);
-    captured_frame_.elapsed_time = captured_frame_.time_stamp - start_time_ns_;
-    SignalFrameCaptured(this, &captured_frame_);
-  }
-
-  // 2. Read the next frame.
-  if (talk_base::SS_CLOSED == video_file_.GetState()) {
-    LOG(LS_ERROR) << "File not opened yet";
-    return false;
-  }
-  // 2.1 Read the frame header.
-  talk_base::StreamResult result = ReadFrameHeader(&captured_frame_);
-  if (talk_base::SR_EOS == result) {  // Loop back if repeat.
-    if (repeat_ != talk_base::kForever) {
-      if (repeat_ > 0) {
-        --repeat_;
-      } else {
-        return false;
-      }
-    }
-
-    if (video_file_.SetPosition(0)) {
-      result = ReadFrameHeader(&captured_frame_);
-    }
-  }
-  if (talk_base::SR_SUCCESS != result) {
-    LOG(LS_ERROR) << "Failed to read the frame header";
-    return false;
-  }
-  // 2.2 Reallocate memory for the frame data if necessary.
-  if (frame_buffer_size_ < captured_frame_.data_size) {
-    frame_buffer_size_ = captured_frame_.data_size;
-    delete[] static_cast<char*> (captured_frame_.data);
-    captured_frame_.data = new char[frame_buffer_size_];
-  }
-  // 2.3 Read the frame adata.
-  if (talk_base::SR_SUCCESS != video_file_.Read(captured_frame_.data,
-                                                captured_frame_.data_size,
-                                                NULL, NULL)) {
-    LOG(LS_ERROR) << "Failed to read frame data";
-    return false;
-  }
-
-  // 3. Decide how long to wait for the next frame.
-  *wait_time_ms = 0;
-
-  // If the capture format's interval is not kMinimumInterval, we use it to
-  // control the rate; otherwise, we use the timestamp in the file to control
-  // the rate.
-  if (!first_frame && !ignore_framerate_) {
-    int64 interval_ns =
-        GetCaptureFormat()->interval > VideoFormat::kMinimumInterval ?
-        GetCaptureFormat()->interval :
-        captured_frame_.time_stamp - last_frame_timestamp_ns_;
-    int interval_ms = static_cast<int>(interval_ns / kNumNanoSecsPerMilliSec);
-    interval_ms -= talk_base::Time() - start_read_time_ms;
-    if (interval_ms > 0) {
-      *wait_time_ms = interval_ms;
-    }
-  }
-  // Keep the original timestamp read from the file.
-  last_frame_timestamp_ns_ = captured_frame_.time_stamp;
-  return true;
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/session/phone/filevideocapturer.h b/third_party/libjingle/source/talk/session/phone/filevideocapturer.h
deleted file mode 100644
index 6423c02..0000000
--- a/third_party/libjingle/source/talk/session/phone/filevideocapturer.h
+++ /dev/null
@@ -1,135 +0,0 @@
-// libjingle
-// Copyright 2004--2005, Google Inc.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-//  1. Redistributions of source code must retain the above copyright notice,
-//     this list of conditions and the following disclaimer.
-//  2. Redistributions in binary form must reproduce the above copyright notice,
-//     this list of conditions and the following disclaimer in the documentation
-//     and/or other materials provided with the distribution.
-//  3. The name of the author may not be used to endorse or promote products
-//     derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// This file contains two classes, VideoRecorder and FileVideoCapturer.
-// VideoRecorder records the captured frames into a file. The file stores a
-// sequence of captured frames; each frame has a header defined in struct
-// CapturedFrame, followed by the frame data.
-//
-// FileVideoCapturer, a subclass of VideoCapturer, is a simulated video capturer
-// that periodically reads images from a previously recorded file.
-
-#ifndef TALK_SESSION_PHONE_FILEVIDEOCAPTURER_H_
-#define TALK_SESSION_PHONE_FILEVIDEOCAPTURER_H_
-
-#include <string>
-#include <vector>
-
-#include "talk/base/stream.h"
-#include "talk/session/phone/videocapturer.h"
-
-namespace talk_base {
-class FileStream;
-}
-
-namespace cricket {
-
-// Utility class to record the frames captured by a video capturer into a file.
-class VideoRecorder {
- public:
-  VideoRecorder() {}
-  ~VideoRecorder() { Stop(); }
-
-  // Start the recorder by opening the specified file. Return true if the file
-  // is opened successfully. write_header should normally be true; false means
-  // write raw frame pixel data to file without any headers.
-  bool Start(const std::string& filename, bool write_header);
-  // Stop the recorder by closing the file.
-  void Stop();
-  // Record a video frame to the file. Return true if the frame is written to
-  // the file successfully. This method needs to be called after Start() and
-  // before Stop().
-  bool RecordFrame(const CapturedFrame& frame);
-
- private:
-  talk_base::FileStream video_file_;
-  bool write_header_;
-
-  DISALLOW_COPY_AND_ASSIGN(VideoRecorder);
-};
-
-// Simulated video capturer that periodically reads frames from a file.
-class FileVideoCapturer : public VideoCapturer {
- public:
-  FileVideoCapturer();
-  virtual ~FileVideoCapturer();
-
-  // Set how many times to repeat reading the file. Repeat forever if the
-  // parameter is talk_base::kForever(-1); no repeat if the parameter is 0 or
-  // less than -1.
-  void set_repeat(int repeat) { repeat_ = repeat; }
-
-  // If ignore_framerate is true, file is read as quickly as possible. If
-  // false, read rate is controlled by the timestamps in the video file
-  // (thus simulating camera capture). Default value set to false.
-  void set_ignore_framerate(bool ignore_framerate) {
-    ignore_framerate_ = ignore_framerate;
-  }
-
-  bool Init(const std::string& filename);
-
-  // Override virtual methods of parent class VideoCapturer.
-  virtual CaptureResult Start(const VideoFormat& capture_format);
-  virtual void Stop();
-  virtual bool IsRunning();
-
- protected:
-  // Override virtual methods of parent class VideoCapturer.
-  virtual bool GetPreferredFourccs(std::vector<uint32>* fourccs);
-
-  // Read the frame header from the file stream, video_file_.
-  talk_base::StreamResult ReadFrameHeader(CapturedFrame* frame);
-
-  // Read a frame and determine how long to wait for the next frame. If the
-  // frame is read successfully, Set the output parameter, wait_time_ms and
-  // return true. Otherwise, do not change wait_time_ms and return false.
-  bool ReadFrame(bool first_frame, int* wait_time_ms);
-
-  // Return the CapturedFrame - useful for extracting contents after reading
-  // a frame. Should be used only while still reading a file (i.e. only while
-  // the CapturedFrame object still exists).
-  const CapturedFrame* frame() const {
-    return &captured_frame_;
-  }
-
- private:
-  class FileReadThread;  // Forward declaration, defined in .cc.
-
-  talk_base::FileStream video_file_;
-  CapturedFrame captured_frame_;
-  // The number of bytes allocated buffer for captured_frame_.data.
-  uint32 frame_buffer_size_;
-  FileReadThread* file_read_thread_;
-  int repeat_;  // How many times to repeat the file.
-  int64 start_time_ns_;  // Time when the file video capturer starts.
-  int64 last_frame_timestamp_ns_;  // Timestamp of last read frame.
-  bool ignore_framerate_;
-
-  DISALLOW_COPY_AND_ASSIGN(FileVideoCapturer);
-};
-
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_FILEVIDEOCAPTURER_H_
diff --git a/third_party/libjingle/source/talk/session/phone/filevideocapturer_unittest.cc b/third_party/libjingle/source/talk/session/phone/filevideocapturer_unittest.cc
deleted file mode 100644
index 8692703..0000000
--- a/third_party/libjingle/source/talk/session/phone/filevideocapturer_unittest.cc
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2008, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdio.h>
-#include <vector>
-
-#include "talk/base/gunit.h"
-#include "talk/base/logging.h"
-#include "talk/base/thread.h"
-#include "talk/session/phone/filevideocapturer.h"
-#include "talk/session/phone/testutils.h"
-
-namespace {
-
-class FileVideoCapturerTest : public testing::Test {
- public:
-  virtual void SetUp() {
-    capturer_.reset(new cricket::FileVideoCapturer);
-  }
-
-  bool OpenFile(const std::string& filename) {
-    return capturer_->Init(cricket::GetTestFilePath(filename));
-  }
-
- protected:
-  class VideoCapturerListener : public sigslot::has_slots<> {
-   public:
-    VideoCapturerListener()
-        : frame_count_(0),
-          frame_width_(0),
-          frame_height_(0),
-          resolution_changed_(false) {
-    }
-
-    void OnFrameCaptured(cricket::VideoCapturer* capturer,
-                         const cricket::CapturedFrame* frame) {
-      ++frame_count_;
-      if (1 == frame_count_) {
-        frame_width_ = frame->width;
-        frame_height_ = frame->height;
-      } else if (frame_width_ != frame->width ||
-          frame_height_ != frame->height) {
-        resolution_changed_ = true;
-      }
-    }
-
-    int frame_count() const { return frame_count_; }
-    int frame_width() const { return frame_width_; }
-    int frame_height() const { return frame_height_; }
-    bool resolution_changed() const { return resolution_changed_; }
-
-   private:
-    int frame_count_;
-    int frame_width_;
-    int frame_height_;
-    bool resolution_changed_;
-  };
-
-  talk_base::scoped_ptr<cricket::FileVideoCapturer> capturer_;
-  cricket::VideoFormat capture_format_;
-};
-
-TEST_F(FileVideoCapturerTest, TestNotOpened) {
-  EXPECT_EQ("", capturer_->GetId());
-  EXPECT_EQ(NULL, capturer_->GetSupportedFormats());
-  EXPECT_EQ(NULL, capturer_->GetCaptureFormat());
-  EXPECT_FALSE(capturer_->IsRunning());
-}
-
-TEST_F(FileVideoCapturerTest, TestInvalidOpen) {
-  EXPECT_FALSE(OpenFile("NotmeNotme"));
-}
-
-TEST_F(FileVideoCapturerTest, TestOpen) {
-  EXPECT_TRUE(OpenFile("captured-320x240-2s-48.frames"));
-  EXPECT_NE("", capturer_->GetId());
-  EXPECT_TRUE(NULL != capturer_->GetSupportedFormats());
-  EXPECT_EQ(1U, capturer_->GetSupportedFormats()->size());
-  EXPECT_EQ(NULL, capturer_->GetCaptureFormat());  // not started yet
-  EXPECT_FALSE(capturer_->IsRunning());
-}
-
-TEST_F(FileVideoCapturerTest, TestLargeSmallDesiredFormat) {
-  EXPECT_TRUE(OpenFile("captured-320x240-2s-48.frames"));
-  // desired format with large resolution.
-  cricket::VideoFormat desired(
-      3200, 2400, cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_ANY);
-  EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &capture_format_));
-  EXPECT_EQ(320, capture_format_.width);
-  EXPECT_EQ(240, capture_format_.height);
-
-  // Desired format with small resolution.
-  desired.width = 0;
-  desired.height = 0;
-  EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &capture_format_));
-  EXPECT_EQ(320, capture_format_.width);
-  EXPECT_EQ(240, capture_format_.height);
-}
-
-TEST_F(FileVideoCapturerTest, TestSupportedAsDesiredFormat) {
-  EXPECT_TRUE(OpenFile("captured-320x240-2s-48.frames"));
-  // desired format same as the capture format supported by the file
-  cricket::VideoFormat desired = capturer_->GetSupportedFormats()->at(0);
-  EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &capture_format_));
-  EXPECT_TRUE(desired == capture_format_);
-
-  // desired format same as the supported capture format except the fourcc
-  desired.fourcc = cricket::FOURCC_ANY;
-  EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &capture_format_));
-  EXPECT_NE(capture_format_.fourcc, desired.fourcc);
-
-  // desired format with minimum interval
-  desired.interval = cricket::VideoFormat::kMinimumInterval;
-  EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &capture_format_));
-}
-
-TEST_F(FileVideoCapturerTest, TestNoRepeat) {
-  EXPECT_TRUE(OpenFile("captured-320x240-2s-48.frames"));
-  VideoCapturerListener listener;
-  capturer_->SignalFrameCaptured.connect(
-      &listener, &VideoCapturerListener::OnFrameCaptured);
-  capturer_->set_repeat(0);
-  capture_format_ = capturer_->GetSupportedFormats()->at(0);
-  EXPECT_EQ(cricket::CR_SUCCESS, capturer_->Start(capture_format_));
-  EXPECT_TRUE_WAIT(!capturer_->IsRunning(), 20000);
-  EXPECT_EQ(48, listener.frame_count());
-}
-
-TEST_F(FileVideoCapturerTest, TestRepeatForever) {
-  // Start the capturer_ with 50 fps and read no less than 150 frames.
-  EXPECT_TRUE(OpenFile("captured-320x240-2s-48.frames"));
-  VideoCapturerListener listener;
-  capturer_->SignalFrameCaptured.connect(
-      &listener, &VideoCapturerListener::OnFrameCaptured);
-  capturer_->set_repeat(talk_base::kForever);
-  capture_format_ = capturer_->GetSupportedFormats()->at(0);
-  capture_format_.interval = cricket::VideoFormat::FpsToInterval(50);
-  EXPECT_EQ(cricket::CR_SUCCESS, capturer_->Start(capture_format_));
-  EXPECT_TRUE(NULL != capturer_->GetCaptureFormat());
-  EXPECT_TRUE(capture_format_ == *capturer_->GetCaptureFormat());
-  EXPECT_TRUE_WAIT(!capturer_->IsRunning() ||
-                   listener.frame_count() >= 150, 20000);
-  capturer_->Stop();
-  EXPECT_FALSE(capturer_->IsRunning());
-  EXPECT_GE(listener.frame_count(), 150);
-  EXPECT_FALSE(listener.resolution_changed());
-  EXPECT_EQ(listener.frame_width(), capture_format_.width);
-  EXPECT_EQ(listener.frame_height(), capture_format_.height);
-}
-
-}  // unnamed namespace
diff --git a/third_party/libjingle/source/talk/session/phone/gdivideorenderer.cc b/third_party/libjingle/source/talk/session/phone/gdivideorenderer.cc
deleted file mode 100644
index 0ee75ab..0000000
--- a/third_party/libjingle/source/talk/session/phone/gdivideorenderer.cc
+++ /dev/null
@@ -1,266 +0,0 @@
-// libjingle
-// Copyright 2004 Google Inc.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-//  1. Redistributions of source code must retain the above copyright notice,
-//     this list of conditions and the following disclaimer.
-//  2. Redistributions in binary form must reproduce the above copyright notice,
-//     this list of conditions and the following disclaimer in the documentation
-//     and/or other materials provided with the distribution.
-//  3. The name of the author may not be used to endorse or promote products
-//     derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Implementation of GdiVideoRenderer on Windows
-
-#ifdef WIN32
-
-#include "talk/session/phone/gdivideorenderer.h"
-
-#include "talk/base/scoped_ptr.h"
-#include "talk/base/thread.h"
-#include "talk/base/win32window.h"
-#include "talk/session/phone/videocommon.h"
-#include "talk/session/phone/videoframe.h"
-
-namespace cricket {
-
-/////////////////////////////////////////////////////////////////////////////
-// Definition of private class VideoWindow. We use a worker thread to manage
-// the window.
-/////////////////////////////////////////////////////////////////////////////
-class GdiVideoRenderer::VideoWindow : public talk_base::Win32Window {
- public:
-  VideoWindow(int x, int y, int width, int height);
-  virtual ~VideoWindow();
-
-  // Called when the video size changes. If it is called the first time, we
-  // create and start the thread. Otherwise, we send kSetSizeMsg to the thread.
-  // Context: non-worker thread.
-  bool SetSize(int width, int height);
-
-  // Called when a new frame is available. Upon this call, we send
-  // kRenderFrameMsg to the window thread. Context: non-worker thread. It may be
-  // better to pass RGB bytes to VideoWindow. However, we pass VideoFrame to put
-  // all the thread synchronization within VideoWindow.
-  bool RenderFrame(const VideoFrame* frame);
-
- protected:
-  // Override virtual method of talk_base::Win32Window. Context: worker Thread.
-  virtual bool OnMessage(UINT uMsg, WPARAM wParam, LPARAM lParam,
-                         LRESULT& result);
-
- private:
-  enum { kSetSizeMsg = WM_USER, kRenderFrameMsg};
-
-  class WindowThread : public talk_base::Thread {
-   public:
-    explicit WindowThread(VideoWindow* window) : window_(window) {}
-
-    // Override virtual method of talk_base::Thread. Context: worker Thread.
-    virtual void Run() {
-      // Initialize the window
-      if (!window_ || !window_->Initialize()) {
-        return;
-      }
-      // Run the message loop
-      MSG msg;
-      while (GetMessage(&msg, NULL, 0, 0) > 0) {
-        TranslateMessage(&msg);
-        DispatchMessage(&msg);
-      }
-    }
-
-  private:
-    VideoWindow* window_;
-  };
-
-  // Context: worker Thread.
-  bool Initialize();
-  void OnPaint();
-  void OnSize(int width, int height, bool frame_changed);
-  void OnRenderFrame(const VideoFrame* frame);
-
-  BITMAPINFO bmi_;
-  talk_base::scoped_array<uint8> image_;
-  talk_base::scoped_ptr<WindowThread> window_thread_;
-  // The initial position of the window.
-  int initial_x_;
-  int initial_y_;
-};
-
-/////////////////////////////////////////////////////////////////////////////
-// Implementation of class VideoWindow
-/////////////////////////////////////////////////////////////////////////////
-GdiVideoRenderer::VideoWindow::VideoWindow(
-    int x, int y, int width, int height)
-    : initial_x_(x),
-      initial_y_(y) {
-  memset(&bmi_.bmiHeader, 0, sizeof(bmi_.bmiHeader));
-  bmi_.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
-  bmi_.bmiHeader.biPlanes = 1;
-  bmi_.bmiHeader.biBitCount = 32;
-  bmi_.bmiHeader.biCompression = BI_RGB;
-  bmi_.bmiHeader.biWidth = width;
-  bmi_.bmiHeader.biHeight = -height;
-  bmi_.bmiHeader.biSizeImage = width * height * 4;
-
-  image_.reset(new uint8[bmi_.bmiHeader.biSizeImage]);
-}
-
-GdiVideoRenderer::VideoWindow::~VideoWindow() {
-  // Context: caller Thread. We cannot call Destroy() since the window was
-  // created by another thread. Instead, we send WM_CLOSE message.
-  if (handle()) {
-    SendMessage(handle(), WM_CLOSE, 0, 0);
-  }
-}
-
-bool GdiVideoRenderer::VideoWindow::SetSize(int width, int height) {
-  if (!window_thread_.get()) {
-    // Create and start the window thread.
-    window_thread_.reset(new WindowThread(this));
-    return window_thread_->Start();
-  } else if (width != bmi_.bmiHeader.biWidth ||
-      height != -bmi_.bmiHeader.biHeight) {
-    SendMessage(handle(), kSetSizeMsg, 0, MAKELPARAM(width, height));
-  }
-  return true;
-}
-
-bool GdiVideoRenderer::VideoWindow::RenderFrame(const VideoFrame* frame) {
-  if (!handle()) {
-    return false;
-  }
-
-  SendMessage(handle(), kRenderFrameMsg, reinterpret_cast<WPARAM>(frame), 0);
-  return true;
-}
-
-bool GdiVideoRenderer::VideoWindow::OnMessage(UINT uMsg, WPARAM wParam,
-                                              LPARAM lParam, LRESULT& result) {
-  switch (uMsg) {
-    case WM_PAINT:
-      OnPaint();
-      return true;
-
-    case WM_DESTROY:
-      PostQuitMessage(0);  // post WM_QUIT to end the message loop in Run()
-      return false;
-
-    case WM_SIZE:  // The window UI was resized.
-      OnSize(LOWORD(lParam), HIWORD(lParam), false);
-      return true;
-
-    case kSetSizeMsg:  // The video resolution changed.
-      OnSize(LOWORD(lParam), HIWORD(lParam), true);
-      return true;
-
-    case kRenderFrameMsg:
-      OnRenderFrame(reinterpret_cast<const VideoFrame*>(wParam));
-      return true;
-  }
-  return false;
-}
-
-bool GdiVideoRenderer::VideoWindow::Initialize() {
-  if (!talk_base::Win32Window::Create(
-      NULL, L"Video Renderer",
-      WS_OVERLAPPEDWINDOW | WS_SIZEBOX,
-      WS_EX_APPWINDOW,
-      initial_x_, initial_y_,
-      bmi_.bmiHeader.biWidth, -bmi_.bmiHeader.biHeight)) {
-        return false;
-  }
-  OnSize(bmi_.bmiHeader.biWidth, -bmi_.bmiHeader.biHeight, false);
-  return true;
-}
-
-void GdiVideoRenderer::VideoWindow::OnPaint() {
-  RECT rcClient;
-  GetClientRect(handle(), &rcClient);
-  PAINTSTRUCT ps;
-  HDC hdc = BeginPaint(handle(), &ps);
-  StretchDIBits(hdc,
-    0, 0, rcClient.right, rcClient.bottom,  // destination rect
-    0, 0, bmi_.bmiHeader.biWidth, -bmi_.bmiHeader.biHeight,  // source rect
-    image_.get(), &bmi_, DIB_RGB_COLORS, SRCCOPY);
-  EndPaint(handle(), &ps);
-}
-
-void GdiVideoRenderer::VideoWindow::OnSize(int width, int height,
-                                           bool frame_changed) {
-  // Get window and client sizes
-  RECT rcClient, rcWindow;
-  GetClientRect(handle(), &rcClient);
-  GetWindowRect(handle(), &rcWindow);
-
-  // Find offset between window size and client size
-  POINT ptDiff;
-  ptDiff.x = (rcWindow.right - rcWindow.left) - rcClient.right;
-  ptDiff.y = (rcWindow.bottom - rcWindow.top) - rcClient.bottom;
-
-  // Resize client
-  MoveWindow(handle(), rcWindow.left, rcWindow.top,
-             width + ptDiff.x, height + ptDiff.y, false);
-  UpdateWindow(handle());
-  ShowWindow(handle(), SW_SHOW);
-
-  if (frame_changed && (width != bmi_.bmiHeader.biWidth ||
-    height != -bmi_.bmiHeader.biHeight)) {
-    // Update the bmi and image buffer
-    bmi_.bmiHeader.biWidth = width;
-    bmi_.bmiHeader.biHeight = -height;
-    bmi_.bmiHeader.biSizeImage = width * height * 4;
-    image_.reset(new uint8[bmi_.bmiHeader.biSizeImage]);
-  }
-}
-
-void GdiVideoRenderer::VideoWindow::OnRenderFrame(const VideoFrame* frame) {
-  if (!frame) {
-    return;
-  }
-  // Convert frame to ARGB format, which is accepted by GDI
-  frame->ConvertToRgbBuffer(cricket::FOURCC_ARGB, image_.get(),
-                            bmi_.bmiHeader.biSizeImage,
-                            bmi_.bmiHeader.biWidth * 4);
-  InvalidateRect(handle(), 0, 0);
-}
-
-/////////////////////////////////////////////////////////////////////////////
-// Implementation of class GdiVideoRenderer
-/////////////////////////////////////////////////////////////////////////////
-GdiVideoRenderer::GdiVideoRenderer(int x, int y)
-    : initial_x_(x),
-      initial_y_(y) {
-}
-GdiVideoRenderer::~GdiVideoRenderer() {}
-
-bool GdiVideoRenderer::SetSize(int width, int height, int reserved) {
-  if (!window_.get()) {  // Create the window for the first frame
-    window_.reset(new VideoWindow(initial_x_, initial_y_, width, height));
-  }
-  return window_->SetSize(width, height);
-}
-
-bool GdiVideoRenderer::RenderFrame(const VideoFrame* frame) {
-  if (!frame || !window_.get()) {
-    return false;
-  }
-  return window_->RenderFrame(frame);
-}
-
-}  // namespace cricket
-#endif  // WIN32
diff --git a/third_party/libjingle/source/talk/session/phone/gdivideorenderer.h b/third_party/libjingle/source/talk/session/phone/gdivideorenderer.h
deleted file mode 100644
index 7be1cca..0000000
--- a/third_party/libjingle/source/talk/session/phone/gdivideorenderer.h
+++ /dev/null
@@ -1,60 +0,0 @@
-// libjingle
-// Copyright 2004--2005, Google Inc.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-//  1. Redistributions of source code must retain the above copyright notice,
-//     this list of conditions and the following disclaimer.
-//  2. Redistributions in binary form must reproduce the above copyright notice,
-//     this list of conditions and the following disclaimer in the documentation
-//     and/or other materials provided with the distribution.
-//  3. The name of the author may not be used to endorse or promote products
-//     derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Definition of class GdiVideoRenderer that implements the abstract class
-// cricket::VideoRenderer via GDI on Windows.
-
-#ifndef TALK_SESSION_PHONE_GDIVIDEORENDERER_H_
-#define TALK_SESSION_PHONE_GDIVIDEORENDERER_H_
-
-#ifdef WIN32
-#include "talk/base/scoped_ptr.h"
-#include "talk/session/phone/videorenderer.h"
-
-namespace cricket {
-
-class GdiVideoRenderer : public VideoRenderer {
- public:
-  GdiVideoRenderer(int x, int y);
-  virtual ~GdiVideoRenderer();
-
-  // Implementation of pure virtual methods of VideoRenderer.
-  // These two methods may be executed in different threads.
-  // SetSize is called before RenderFrame.
-  virtual bool SetSize(int width, int height, int reserved);
-  virtual bool RenderFrame(const VideoFrame* frame);
-
- private:
-  class VideoWindow;  // forward declaration, defined in the .cc file
-  talk_base::scoped_ptr<VideoWindow> window_;
-  // The initial position of the window.
-  int initial_x_;
-  int initial_y_;
-};
-
-}  // namespace cricket
-
-#endif  // WIN32
-#endif  // TALK_SESSION_PHONE_GDIVIDEORENDERER_H_
diff --git a/third_party/libjingle/source/talk/session/phone/gtkvideorenderer.cc b/third_party/libjingle/source/talk/session/phone/gtkvideorenderer.cc
deleted file mode 100644
index 9b17c78..0000000
--- a/third_party/libjingle/source/talk/session/phone/gtkvideorenderer.cc
+++ /dev/null
@@ -1,153 +0,0 @@
-// libjingle
-// Copyright 2004 Google Inc.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-//  1. Redistributions of source code must retain the above copyright notice,
-//     this list of conditions and the following disclaimer.
-//  2. Redistributions in binary form must reproduce the above copyright notice,
-//     this list of conditions and the following disclaimer in the documentation
-//     and/or other materials provided with the distribution.
-//  3. The name of the author may not be used to endorse or promote products
-//     derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Implementation of GtkVideoRenderer
-
-#include "talk/session/phone/gtkvideorenderer.h"
-
-#include <gtk/gtk.h>
-
-#include "talk/session/phone/videocommon.h"
-#include "talk/session/phone/videoframe.h"
-
-namespace cricket {
-
-class ScopedGdkLock {
- public:
-  ScopedGdkLock() {
-    gdk_threads_enter();
-  }
-
-  ~ScopedGdkLock() {
-    gdk_threads_leave();
-  }
-};
-
-GtkVideoRenderer::GtkVideoRenderer(int x, int y)
-    : window_(NULL),
-      draw_area_(NULL),
-      initial_x_(x),
-      initial_y_(y) {
-  g_thread_init(NULL);
-  gdk_threads_init();
-}
-
-GtkVideoRenderer::~GtkVideoRenderer() {
-  if (window_) {
-    ScopedGdkLock lock;
-    gtk_widget_destroy(window_);
-    // Run the Gtk main loop to tear down the window.
-    Pump();
-  }
-  // Don't need to destroy draw_area_ because it is not top-level, so it is
-  // implicitly destroyed by the above.
-}
-
-bool GtkVideoRenderer::SetSize(int width, int height, int reserved) {
-  ScopedGdkLock lock;
-
-  // For the first frame, initialize the GTK window
-  if ((!window_ && !Initialize(width, height)) || IsClosed()) {
-    return false;
-  }
-
-  image_.reset(new uint8[width * height * 4]);
-  gtk_widget_set_size_request(draw_area_, width, height);
-  return true;
-}
-
-bool GtkVideoRenderer::RenderFrame(const VideoFrame* frame) {
-  if (!frame) {
-    return false;
-  }
-
-  // convert I420 frame to ABGR format, which is accepted by GTK
-  frame->ConvertToRgbBuffer(cricket::FOURCC_ABGR,
-                            image_.get(),
-                            frame->GetWidth() * frame->GetHeight() * 4,
-                            frame->GetWidth() * 4);
-
-  ScopedGdkLock lock;
-
-  if (IsClosed()) {
-    return false;
-  }
-
-  // draw the ABGR image
-  gdk_draw_rgb_32_image(draw_area_->window,
-                        draw_area_->style->fg_gc[GTK_STATE_NORMAL],
-                        0,
-                        0,
-                        frame->GetWidth(),
-                        frame->GetHeight(),
-                        GDK_RGB_DITHER_MAX,
-                        image_.get(),
-                        frame->GetWidth() * 4);
-
-  // Run the Gtk main loop to refresh the window.
-  Pump();
-  return true;
-}
-
-bool GtkVideoRenderer::Initialize(int width, int height) {
-  gtk_init(NULL, NULL);
-  window_ = gtk_window_new(GTK_WINDOW_TOPLEVEL);
-  draw_area_ = gtk_drawing_area_new();
-  if (!window_ || !draw_area_) {
-    return false;
-  }
-
-  gtk_window_set_position(GTK_WINDOW(window_), GTK_WIN_POS_CENTER);
-  gtk_window_set_title(GTK_WINDOW(window_), "Video Renderer");
-  gtk_window_set_resizable(GTK_WINDOW(window_), FALSE);
-  gtk_widget_set_size_request(draw_area_, width, height);
-  gtk_container_add(GTK_CONTAINER(window_), draw_area_);
-  gtk_widget_show_all(window_);
-  gtk_window_move(GTK_WINDOW(window_), initial_x_, initial_y_);
-
-  image_.reset(new uint8[width * height * 4]);
-  return true;
-}
-
-void GtkVideoRenderer::Pump() {
-  while (gtk_events_pending()) {
-    gtk_main_iteration();
-  }
-}
-
-bool GtkVideoRenderer::IsClosed() const {
-  if (!window_) {
-    // Not initialized yet, so hasn't been closed.
-    return false;
-  }
-
-  if (!GTK_IS_WINDOW(window_) || !GTK_IS_DRAWING_AREA(draw_area_)) {
-    return true;
-  }
-
-  return false;
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/session/phone/gtkvideorenderer.h b/third_party/libjingle/source/talk/session/phone/gtkvideorenderer.h
deleted file mode 100644
index 8c36a79..0000000
--- a/third_party/libjingle/source/talk/session/phone/gtkvideorenderer.h
+++ /dev/null
@@ -1,69 +0,0 @@
-// libjingle
-// Copyright 2004--2005, Google Inc.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-//  1. Redistributions of source code must retain the above copyright notice,
-//     this list of conditions and the following disclaimer.
-//  2. Redistributions in binary form must reproduce the above copyright notice,
-//     this list of conditions and the following disclaimer in the documentation
-//     and/or other materials provided with the distribution.
-//  3. The name of the author may not be used to endorse or promote products
-//     derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Definition of class GtkVideoRenderer that implements the abstract class
-// cricket::VideoRenderer via GTK.
-
-#ifndef TALK_SESSION_PHONE_GTKVIDEORENDERER_H_
-#define TALK_SESSION_PHONE_GTKVIDEORENDERER_H_
-
-#include "talk/base/basictypes.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/session/phone/videorenderer.h"
-
-typedef struct _GtkWidget GtkWidget;  // forward declaration, defined in gtk.h
-
-namespace cricket {
-
-class GtkVideoRenderer : public VideoRenderer {
- public:
-  GtkVideoRenderer(int x, int y);
-  virtual ~GtkVideoRenderer();
-
-  // Implementation of pure virtual methods of VideoRenderer.
-  // These two methods may be executed in different threads.
-  // SetSize is called before RenderFrame.
-  virtual bool SetSize(int width, int height, int reserved);
-  virtual bool RenderFrame(const VideoFrame* frame);
-
- private:
-  // Initialize the attributes when the first frame arrives.
-  bool Initialize(int width, int height);
-  // Pump the Gtk event loop until there are no events left.
-  void Pump();
-  // Check if the window has been closed.
-  bool IsClosed() const;
-
-  talk_base::scoped_array<uint8> image_;
-  GtkWidget* window_;
-  GtkWidget* draw_area_;
-  // The initial position of the window.
-  int initial_x_;
-  int initial_y_;
-};
-
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_GTKVIDEORENDERER_H_
diff --git a/third_party/libjingle/source/talk/session/phone/libudevsymboltable.cc b/third_party/libjingle/source/talk/session/phone/libudevsymboltable.cc
deleted file mode 100644
index b312306..0000000
--- a/third_party/libjingle/source/talk/session/phone/libudevsymboltable.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/session/phone/libudevsymboltable.h"
-
-namespace cricket {
-
-LATE_BINDING_SYMBOL_TABLE_DEFINE_BEGIN(LibUDevSymbolTable, "libudev.so.0")
-#define X(sym) \
-    LATE_BINDING_SYMBOL_TABLE_DEFINE_ENTRY(LibUDevSymbolTable, sym)
-LIBUDEV_SYMBOLS_LIST
-#undef X
-LATE_BINDING_SYMBOL_TABLE_DEFINE_END(LibUDevSymbolTable)
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/session/phone/libudevsymboltable.h b/third_party/libjingle/source/talk/session/phone/libudevsymboltable.h
deleted file mode 100644
index 0dbef6c..0000000
--- a/third_party/libjingle/source/talk/session/phone/libudevsymboltable.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SESSION_PHONE_LIBUDEVSYMBOLTABLE_H_
-#define TALK_SESSION_PHONE_LIBUDEVSYMBOLTABLE_H_
-
-#include "talk/base/latebindingsymboltable.h"
-
-namespace cricket {
-
-// The libudev symbols we need, as an X-Macro list.
-// This list must contain precisely every libudev function that is used in
-// devicemanager.cc.
-#define LIBUDEV_SYMBOLS_LIST \
-  X(udev_device_unref) \
-  X(udev_monitor_enable_receiving) \
-  X(udev_monitor_filter_add_match_subsystem_devtype) \
-  X(udev_monitor_get_fd) \
-  X(udev_monitor_new_from_netlink) \
-  X(udev_monitor_receive_device) \
-  X(udev_monitor_unref) \
-  X(udev_new) \
-  X(udev_unref)
-
-LATE_BINDING_SYMBOL_TABLE_DECLARE_BEGIN(LibUDevSymbolTable)
-#define X(sym) \
-    LATE_BINDING_SYMBOL_TABLE_DECLARE_ENTRY(LibUDevSymbolTable, sym)
-LIBUDEV_SYMBOLS_LIST
-#undef X
-LATE_BINDING_SYMBOL_TABLE_DECLARE_END(LibUDevSymbolTable)
-
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_LIBUDEVSYMBOLTABLE_H_
diff --git a/third_party/libjingle/source/talk/session/phone/linphonemediaengine.cc b/third_party/libjingle/source/talk/session/phone/linphonemediaengine.cc
deleted file mode 100644
index 3188efa..0000000
--- a/third_party/libjingle/source/talk/session/phone/linphonemediaengine.cc
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * libjingle
- * Copyright 2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef MSILBC_LIBRARY
-#define MSILBC_LIBRARY "/usr/lib/mediastreamer/plugins/libmsilbc.so"
-#endif
-
-// LinphoneMediaEngine is a Linphone implementation of MediaEngine
-extern "C" {
-#include <mediastreamer2/mediastream.h>
-#include <mediastreamer2/mssndcard.h>
-#include <mediastreamer2/msfilter.h>
-}
-
-#include "talk/session/phone/linphonemediaengine.h"
-
-#include "talk/base/buffer.h"
-#include "talk/base/event.h"
-#include "talk/base/logging.h"
-#include "talk/base/pathutils.h"
-#include "talk/base/stream.h"
-#include "talk/session/phone/rtpdump.h"
-
-#ifndef WIN32
-#include <libgen.h>
-#endif
-
-namespace cricket {
-
-///////////////////////////////////////////////////////////////////////////
-// Implementation of LinphoneMediaEngine.
-///////////////////////////////////////////////////////////////////////////
-LinphoneMediaEngine::LinphoneMediaEngine(const std::string& ringWav,  const std::string& callWav) : ring_wav_(ringWav), call_wav_(callWav) { }
-
-bool LinphoneMediaEngine::Init() {
-  ortp_init();
-  ms_init();
-
-#ifdef HAVE_ILBC
-#ifndef WIN32
-  char * path = strdup(MSILBC_LIBRARY);
-  char * dirc = dirname(path);
-  ms_load_plugins(dirc);
-#endif
-  if (ms_filter_codec_supported("iLBC"))
-    have_ilbc = 1;
-  else
-    have_ilbc = 0;
-#else
-  have_ilbc = 0;
-#endif
-
-#ifdef HAVE_SPEEX
-  voice_codecs_.push_back(AudioCodec(110, payload_type_speex_wb.mime_type, payload_type_speex_wb.clock_rate, 0, 1, 8));
-  voice_codecs_.push_back(AudioCodec(111, payload_type_speex_nb.mime_type, payload_type_speex_nb.clock_rate, 0, 1, 7));
-#endif
-
-#ifdef HAVE_ILBC
-  if (have_ilbc)
-    voice_codecs_.push_back(AudioCodec(102, payload_type_ilbc.mime_type, payload_type_ilbc.clock_rate, 0, 1, 4));
-#endif
-
-  voice_codecs_.push_back(AudioCodec(0, payload_type_pcmu8000.mime_type, payload_type_pcmu8000.clock_rate, 0, 1, 2));
-  voice_codecs_.push_back(AudioCodec(101, payload_type_telephone_event.mime_type, payload_type_telephone_event.clock_rate, 0, 1, 1));
-  return true;
-}
-
-void LinphoneMediaEngine::Terminate() {
-  fflush(stdout);
-}
-
-
-int LinphoneMediaEngine::GetCapabilities() {
-  int capabilities = 0;
-  capabilities |= AUDIO_SEND;
-  capabilities |= AUDIO_RECV;
-  return capabilities;
-}
-
-VoiceMediaChannel* LinphoneMediaEngine::CreateChannel() {
-  return new LinphoneVoiceChannel(this);
-}
-
-VideoMediaChannel* LinphoneMediaEngine::CreateVideoChannel(VoiceMediaChannel* voice_ch) {
-  return NULL;
-}
-
-bool LinphoneMediaEngine::FindAudioCodec(const AudioCodec &c) {
-  if (c.id == 0)
-    return true;
-  if (c.name == payload_type_telephone_event.mime_type)
-    return true;
-#ifdef HAVE_SPEEX
-  if (c.name == payload_type_speex_wb.mime_type && c.clockrate == payload_type_speex_wb.clock_rate)
-    return true;
-  if (c.name == payload_type_speex_nb.mime_type && c.clockrate == payload_type_speex_nb.clock_rate)
-    return true;
-#endif
-#ifdef HAVE_ILBC
-  if (have_ilbc && c.name == payload_type_ilbc.mime_type)
-    return true;
-#endif
-  return false;
-}
-
-///////////////////////////////////////////////////////////////////////////
-// Implementation of LinphoneVoiceChannel.
-///////////////////////////////////////////////////////////////////////////
-LinphoneVoiceChannel::LinphoneVoiceChannel(LinphoneMediaEngine*eng)
-    : pt_(-1),
-      audio_stream_(0),
-      engine_(eng),
-      ring_stream_(0)
-{
-
-  talk_base::Thread *thread = talk_base::ThreadManager::CurrentThread();
-  talk_base::SocketServer *ss = thread->socketserver();
-  socket_.reset(ss->CreateAsyncSocket(SOCK_DGRAM));
-
-  socket_->Bind(talk_base::SocketAddress("localhost",3000));
-  socket_->SignalReadEvent.connect(this, &LinphoneVoiceChannel::OnIncomingData);
-
-}
-
-LinphoneVoiceChannel::~LinphoneVoiceChannel()
-{
-  fflush(stdout);
-  StopRing();
-
-  if (audio_stream_)
-    audio_stream_stop(audio_stream_);
-}
-
-bool LinphoneVoiceChannel::SetPlayout(bool playout) {
-  play_ = playout;
-  return true;
-}
-
-bool LinphoneVoiceChannel::SetSendCodecs(const std::vector<AudioCodec>& codecs) {
-
-  bool first = true;
-  std::vector<AudioCodec>::const_iterator i;
-
-  ortp_set_log_level_mask(ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR|ORTP_FATAL);
-
-  for (i = codecs.begin(); i < codecs.end(); i++) {
-
-    if (!engine_->FindAudioCodec(*i))
-      continue;
-#ifdef HAVE_ILBC
-    if (engine_->have_ilbc && i->name == payload_type_ilbc.mime_type) {
-      rtp_profile_set_payload(&av_profile, i->id, &payload_type_ilbc);
-    }
-#endif
-#ifdef HAVE_SPEEX
-    if (i->name == payload_type_speex_wb.mime_type && i->clockrate == payload_type_speex_wb.clock_rate) {
-      rtp_profile_set_payload(&av_profile, i->id, &payload_type_speex_wb);
-    } else if (i->name == payload_type_speex_nb.mime_type && i->clockrate == payload_type_speex_nb.clock_rate) {
-      rtp_profile_set_payload(&av_profile, i->id, &payload_type_speex_nb);
-    }
-#endif
-
-    if (i->id == 0)
-      rtp_profile_set_payload(&av_profile, 0, &payload_type_pcmu8000);
-
-    if (i->name == payload_type_telephone_event.mime_type) {
-      rtp_profile_set_payload(&av_profile, i->id, &payload_type_telephone_event);
-    }
-
-    if (first) {
-      StopRing();
-      LOG(LS_INFO) << "Using " << i->name << "/" << i->clockrate;
-      pt_ = i->id;
-      audio_stream_ = audio_stream_start(&av_profile, 2000, "127.0.0.1", 3000, i->id, 250, 0);
-      first = false;
-    }
-  }
-
-  if (first) {
-    StopRing();
-    // We're being asked to set an empty list of codecs. This will only happen when
-    // working with a buggy client; let's try PCMU.
-    LOG(LS_WARNING) << "Received empty list of codces; using PCMU/8000";
-    audio_stream_ = audio_stream_start(&av_profile, 2000, "127.0.0.1", 3000, 0, 250, 0);
-  }
-
-  return true;
-}
-
-bool LinphoneVoiceChannel::SetSend(SendFlags flag) {
-  mute_ = !flag;
-  return true;
-}
-
-void LinphoneVoiceChannel::OnPacketReceived(talk_base::Buffer* packet) {
-  const void* data = packet->data();
-  int len = packet->length();
-  uint8 buf[2048];
-  memcpy(buf, data, len);
-
-  /* We may receive packets with payload type 13: comfort noise. Linphone can't
-   * handle them, so let's ignore those packets.
-   */
-  int payloadtype = buf[1] & 0x7f;
-  if (play_ && payloadtype != 13)
-    socket_->SendTo(buf, len, talk_base::SocketAddress("localhost",2000));
-}
-
-void LinphoneVoiceChannel::StartRing(bool bIncomingCall)
-{
-  MSSndCard *sndcard = NULL;
-  sndcard=ms_snd_card_manager_get_default_card(ms_snd_card_manager_get());
-  if (sndcard)
-  {
-    if (bIncomingCall)
-    {
-      if (engine_->GetRingWav().size() > 0)
-      {
-        LOG(LS_VERBOSE) << "incoming ring. sound file: " << engine_->GetRingWav().c_str() << "\n";
-        ring_stream_ = ring_start (engine_->GetRingWav().c_str(), 1, sndcard);
-      }
-    }
-    else
-    {
-      if (engine_->GetCallWav().size() > 0)
-      {
-        LOG(LS_VERBOSE) << "outgoing ring. sound file: " << engine_->GetCallWav().c_str() << "\n";
-        ring_stream_ = ring_start (engine_->GetCallWav().c_str(), 1, sndcard);
-      }
-    }
-  }
-}
-
-void LinphoneVoiceChannel::StopRing()
-{
-  if (ring_stream_) {
-    ring_stop(ring_stream_);
-    ring_stream_ = 0;
-  }
-}
-
-void LinphoneVoiceChannel::OnIncomingData(talk_base::AsyncSocket *s)
-{
-  char *buf[2048];
-  int len;
-  len = s->Recv(buf, sizeof(buf));
-  talk_base::Buffer packet(buf, len);
-  if (network_interface_ && !mute_)
-    network_interface_->SendPacket(&packet);
-}
-
-}
diff --git a/third_party/libjingle/source/talk/session/phone/linphonemediaengine.h b/third_party/libjingle/source/talk/session/phone/linphonemediaengine.h
deleted file mode 100644
index 883580c..0000000
--- a/third_party/libjingle/source/talk/session/phone/linphonemediaengine.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * libjingle
- * Copyright 2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// LinphoneMediaEngine is a Linphone implementation of MediaEngine
-
-#ifndef TALK_SESSION_PHONE_LINPHONEMEDIAENGINE_H_
-#define TALK_SESSION_PHONE_LINPHONEMEDIAENGINE_H_
-
-#include <string>
-#include <vector>
-
-extern "C" {
-#include <mediastreamer2/mediastream.h>
-}
-
-#include "talk/base/scoped_ptr.h"
-#include "talk/session/phone/codec.h"
-#include "talk/session/phone/mediachannel.h"
-#include "talk/session/phone/mediaengine.h"
-
-namespace talk_base {
-class StreamInterface;
-}
-
-namespace cricket {
-
-class LinphoneMediaEngine : public MediaEngineInterface {
- public:
-  LinphoneMediaEngine(const std::string& ringWav,  const std::string& callWav);
-  virtual ~LinphoneMediaEngine() {}
-
-  // Should be called before codecs() and video_codecs() are called. We need to
-  // set the voice and video codecs; otherwise, Jingle initiation will fail.
-  void set_voice_codecs(const std::vector<AudioCodec>& codecs) {
-    voice_codecs_ = codecs;
-  }
-  void set_video_codecs(const std::vector<VideoCodec>& codecs) {
-    video_codecs_ = codecs;
-  }
-
-  // Implement pure virtual methods of MediaEngine.
-  virtual bool Init();
-  virtual void Terminate();
-  virtual int GetCapabilities();
-  virtual VoiceMediaChannel* CreateChannel();
-  virtual VideoMediaChannel* CreateVideoChannel(VoiceMediaChannel* voice_ch);
-  virtual SoundclipMedia* CreateSoundclip() { return NULL; }
-  virtual bool SetAudioOptions(int options) { return true; }
-  virtual bool SetVideoOptions(int options) { return true; }
-  virtual bool SetDefaultVideoEncoderConfig(const VideoEncoderConfig& config) {
-    return true;
-  }
-  virtual bool SetSoundDevices(const Device* in_dev, const Device* out_dev) {
-    return true;
-  }
-  virtual bool SetVideoCaptureDevice(const Device* cam_device) { return true; }
-  virtual bool SetOutputVolume(int level) { return true; }
-  virtual int GetInputLevel() { return 0; }
-  virtual bool SetLocalMonitor(bool enable) { return true; }
-  virtual bool SetLocalRenderer(VideoRenderer* renderer) { return true; }
-  // TODO: control channel send?
-  virtual CaptureResult SetVideoCapture(bool capture) { return CR_SUCCESS; }
-  virtual const std::vector<AudioCodec>& audio_codecs() {
-    return voice_codecs_;
-  }
-  virtual const std::vector<VideoCodec>& video_codecs() {
-    return video_codecs_;
-  }
-  virtual bool FindAudioCodec(const AudioCodec& codec);
-  virtual bool FindVideoCodec(const VideoCodec& codec) { return true; }
-  virtual void SetVoiceLogging(int min_sev, const char* filter) {}
-  virtual void SetVideoLogging(int min_sev, const char* filter) {}
-
-  std::string GetRingWav(){return ring_wav_;}
-  std::string GetCallWav(){return call_wav_;}
-
-  int have_ilbc;
-
- private:
-  std::string voice_input_filename_;
-  std::string voice_output_filename_;
-  std::string video_input_filename_;
-  std::string video_output_filename_;
-  std::vector<AudioCodec> voice_codecs_;
-  std::vector<VideoCodec> video_codecs_;
-
-  std::string ring_wav_;
-  std::string call_wav_;
-
-  DISALLOW_COPY_AND_ASSIGN(LinphoneMediaEngine);
-};
-
-class LinphoneVoiceChannel : public VoiceMediaChannel {
- public:
-  LinphoneVoiceChannel(LinphoneMediaEngine *eng);
-  virtual ~LinphoneVoiceChannel();
-
-  // Implement pure virtual methods of VoiceMediaChannel.
-  virtual bool SetRecvCodecs(const std::vector<AudioCodec>& codecs) { return true; }
-  virtual bool SetSendCodecs(const std::vector<AudioCodec>& codecs);
-  virtual bool SetPlayout(bool playout);
-  virtual bool SetSend(SendFlags flag);
-  virtual bool AddStream(uint32 ssrc) { return true; }
-  virtual bool RemoveStream(uint32 ssrc) { return true; }
-  virtual bool GetActiveStreams(AudioInfo::StreamList* actives) { return true; }
-  virtual int GetOutputLevel() { return 0; }
-  virtual bool SetOutputScaling(uint32 ssrc, double left, double right) {
-    return false;
-  }
-  virtual bool GetOutputScaling(uint32 ssrc, double* left, double* right) {
-    return false;
-  }
-  virtual void SetRingbackTone(const char* buf, int len) {}
-  virtual bool PlayRingbackTone(bool play, bool loop) { return true; }
-  virtual bool PressDTMF(int event, bool playout) { return true; }
-  virtual bool GetStats(VoiceMediaInfo* info) { return true; }
-
-  // Implement pure virtual methods of MediaChannel.
-  virtual void OnPacketReceived(talk_base::Buffer* packet);
-  virtual void OnRtcpReceived(talk_base::Buffer* packet) {}
-  virtual void SetSendSsrc(uint32 id) {}  // TODO: change RTP packet?
-  virtual bool SetRtcpCName(const std::string& cname) { return true; }
-  virtual bool Mute(bool on) { return mute_; }
-  virtual bool SetSendBandwidth(bool autobw, int bps) { return true; }
-  virtual bool SetOptions(int options) { return true; }
-  virtual bool SetRecvRtpHeaderExtensions(
-      const std::vector<RtpHeaderExtension>& extensions) { return true; }
-  virtual bool SetSendRtpHeaderExtensions(
-      const std::vector<RtpHeaderExtension>& extensions) { return true; }
-
-  virtual void StartRing(bool bIncomingCall);
-  virtual void StopRing();
-
- private:
-  int pt_;
-  bool mute_;
-  bool play_;
-  AudioStream *audio_stream_;
-  LinphoneMediaEngine *engine_;
-  RingStream* ring_stream_;
-  talk_base::scoped_ptr<talk_base::AsyncSocket> socket_;
-  void OnIncomingData(talk_base::AsyncSocket *s);
-
-  DISALLOW_COPY_AND_ASSIGN(LinphoneVoiceChannel);
-};
-
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_LINPHONEMEDIAENGINE_H_
diff --git a/third_party/libjingle/source/talk/session/phone/linuxdevicemanager.cc b/third_party/libjingle/source/talk/session/phone/linuxdevicemanager.cc
deleted file mode 100644
index 6bad677..0000000
--- a/third_party/libjingle/source/talk/session/phone/linuxdevicemanager.cc
+++ /dev/null
@@ -1,410 +0,0 @@
-/*
- * libjingle
- * Copyright 2004 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/session/phone/linuxdevicemanager.h"
-
-#include <libudev.h>
-#include <unistd.h>
-#include "talk/base/linux.h"
-#include "talk/base/logging.h"
-#include "talk/base/fileutils.h"
-#include "talk/base/pathutils.h"
-#include "talk/base/physicalsocketserver.h"
-#include "talk/base/stream.h"
-#include "talk/base/stringutils.h"
-#include "talk/base/thread.h"
-#include "talk/session/phone/libudevsymboltable.h"
-#include "talk/session/phone/mediacommon.h"
-#include "talk/session/phone/v4llookup.h"
-#include "talk/sound/platformsoundsystem.h"
-#include "talk/sound/platformsoundsystemfactory.h"
-#include "talk/sound/sounddevicelocator.h"
-#include "talk/sound/soundsysteminterface.h"
-
-namespace cricket {
-
-DeviceManagerInterface* DeviceManagerFactory::Create() {
-  return new LinuxDeviceManager();
-}
-
-class LinuxDeviceWatcher
-    : public DeviceWatcher,
-      private talk_base::Dispatcher {
- public:
-  explicit LinuxDeviceWatcher(DeviceManagerInterface* dm);
-  virtual ~LinuxDeviceWatcher();
-  virtual bool Start();
-  virtual void Stop();
-
- private:
-  virtual uint32 GetRequestedEvents();
-  virtual void OnPreEvent(uint32 ff);
-  virtual void OnEvent(uint32 ff, int err);
-  virtual int GetDescriptor();
-  virtual bool IsDescriptorClosed();
-
-  DeviceManagerInterface* manager_;
-  LibUDevSymbolTable libudev_;
-  struct udev* udev_;
-  struct udev_monitor* udev_monitor_;
-  bool registered_;
-};
-
-#define LATE(sym) LATESYM_GET(LibUDevSymbolTable, &libudev_, sym)
-
-static const char* const kFilteredAudioDevicesName[] = {
-#if defined(CHROMEOS)
-    "surround40:",
-    "surround41:",
-    "surround50:",
-    "surround51:",
-    "surround71:",
-    "iec958:",      // S/PDIF
-#endif
-    NULL,
-};
-static const char* kFilteredVideoDevicesName[] = {
-    NULL,
-};
-
-LinuxDeviceManager::LinuxDeviceManager()
-    : sound_system_(new PlatformSoundSystemFactory()) {
-  set_watcher(new LinuxDeviceWatcher(this));
-}
-
-LinuxDeviceManager::~LinuxDeviceManager() {
-}
-
-bool LinuxDeviceManager::GetAudioDevices(bool input,
-                                         std::vector<Device>* devs) {
-  devs->clear();
-  if (!sound_system_.get()) {
-    return false;
-  }
-  SoundSystemInterface::SoundDeviceLocatorList list;
-  bool success;
-  if (input) {
-    success = sound_system_->EnumerateCaptureDevices(&list);
-  } else {
-    success = sound_system_->EnumeratePlaybackDevices(&list);
-  }
-  if (!success) {
-    LOG(LS_ERROR) << "Can't enumerate devices";
-    sound_system_.release();
-    return false;
-  }
-  // We have to start the index at 1 because GIPS VoiceEngine puts the default
-  // device at index 0, but Enumerate(Capture|Playback)Devices does not include
-  // a locator for the default device.
-  int index = 1;
-  for (SoundSystemInterface::SoundDeviceLocatorList::iterator i = list.begin();
-       i != list.end();
-       ++i, ++index) {
-    devs->push_back(Device((*i)->name(), index));
-  }
-  SoundSystemInterface::ClearSoundDeviceLocatorList(&list);
-  sound_system_.release();
-  return FilterDevices(devs, kFilteredAudioDevicesName);
-}
-
-static const std::string kVideoMetaPathK2_4("/proc/video/dev/");
-static const std::string kVideoMetaPathK2_6("/sys/class/video4linux/");
-
-enum MetaType { M2_4, M2_6, NONE };
-
-static void ScanDeviceDirectory(const std::string& devdir,
-                                std::vector<Device>* devices) {
-  talk_base::scoped_ptr<talk_base::DirectoryIterator> directoryIterator(
-      talk_base::Filesystem::IterateDirectory());
-
-  if (directoryIterator->Iterate(talk_base::Pathname(devdir))) {
-    do {
-      std::string filename = directoryIterator->Name();
-      std::string device_name = devdir + filename;
-      if (!directoryIterator->IsDots()) {
-        if (filename.find("video") == 0 &&
-            V4LLookup::IsV4L2Device(device_name)) {
-          devices->push_back(Device(device_name, device_name));
-        }
-      }
-    } while (directoryIterator->Next());
-  }
-}
-
-static std::string GetVideoDeviceNameK2_6(const std::string& device_meta_path) {
-  std::string device_name;
-
-  talk_base::scoped_ptr<talk_base::FileStream> device_meta_stream(
-      talk_base::Filesystem::OpenFile(device_meta_path, "r"));
-
-  if (device_meta_stream.get() != NULL) {
-    if (device_meta_stream->ReadLine(&device_name) != talk_base::SR_SUCCESS) {
-      LOG(LS_ERROR) << "Failed to read V4L2 device meta " << device_meta_path;
-    }
-    device_meta_stream->Close();
-  }
-
-  return device_name;
-}
-
-static std::string Trim(const std::string& s, const std::string& drop = " \t") {
-  std::string::size_type first = s.find_first_not_of(drop);
-  std::string::size_type last  = s.find_last_not_of(drop);
-
-  if (first == std::string::npos || last == std::string::npos)
-    return std::string("");
-
-  return s.substr(first, last - first + 1);
-}
-
-static std::string GetVideoDeviceNameK2_4(const std::string& device_meta_path) {
-  talk_base::ConfigParser::MapVector all_values;
-
-  talk_base::ConfigParser config_parser;
-  talk_base::FileStream* file_stream =
-      talk_base::Filesystem::OpenFile(device_meta_path, "r");
-
-  if (file_stream == NULL) return "";
-
-  config_parser.Attach(file_stream);
-  config_parser.Parse(&all_values);
-
-  for (talk_base::ConfigParser::MapVector::iterator i = all_values.begin();
-      i != all_values.end(); ++i) {
-    talk_base::ConfigParser::SimpleMap::iterator device_name_i =
-        i->find("name");
-
-    if (device_name_i != i->end()) {
-      return device_name_i->second;
-    }
-  }
-
-  return "";
-}
-
-static std::string GetVideoDeviceName(MetaType meta,
-    const std::string& device_file_name) {
-  std::string device_meta_path;
-  std::string device_name;
-  std::string meta_file_path;
-
-  if (meta == M2_6) {
-    meta_file_path = kVideoMetaPathK2_6 + device_file_name + "/name";
-
-    LOG(LS_INFO) << "Trying " + meta_file_path;
-    device_name = GetVideoDeviceNameK2_6(meta_file_path);
-
-    if (device_name.empty()) {
-      meta_file_path = kVideoMetaPathK2_6 + device_file_name + "/model";
-
-      LOG(LS_INFO) << "Trying " << meta_file_path;
-      device_name = GetVideoDeviceNameK2_6(meta_file_path);
-    }
-  } else {
-    meta_file_path = kVideoMetaPathK2_4 + device_file_name;
-    LOG(LS_INFO) << "Trying " << meta_file_path;
-    device_name = GetVideoDeviceNameK2_4(meta_file_path);
-  }
-
-  if (device_name.empty()) {
-    device_name = "/dev/" + device_file_name;
-    LOG(LS_ERROR)
-      << "Device name not found, defaulting to device path " << device_name;
-  }
-
-  LOG(LS_INFO) << "Name for " << device_file_name << " is " << device_name;
-
-  return Trim(device_name);
-}
-
-static void ScanV4L2Devices(std::vector<Device>* devices) {
-  LOG(LS_INFO) << ("Enumerating V4L2 devices");
-
-  MetaType meta;
-  std::string metadata_dir;
-
-  talk_base::scoped_ptr<talk_base::DirectoryIterator> directoryIterator(
-      talk_base::Filesystem::IterateDirectory());
-
-  // Try and guess kernel version
-  if (directoryIterator->Iterate(kVideoMetaPathK2_6)) {
-    meta = M2_6;
-    metadata_dir = kVideoMetaPathK2_6;
-  } else if (directoryIterator->Iterate(kVideoMetaPathK2_4)) {
-    meta = M2_4;
-    metadata_dir = kVideoMetaPathK2_4;
-  } else {
-    meta = NONE;
-  }
-
-  if (meta != NONE) {
-    LOG(LS_INFO) << "V4L2 device metadata found at " << metadata_dir;
-
-    do {
-      std::string filename = directoryIterator->Name();
-
-      if (filename.find("video") == 0) {
-        std::string device_path = "/dev/" + filename;
-
-        if (V4LLookup::IsV4L2Device(device_path)) {
-          devices->push_back(
-              Device(GetVideoDeviceName(meta, filename), device_path));
-        }
-      }
-    } while (directoryIterator->Next());
-  } else {
-    LOG(LS_ERROR) << "Unable to detect v4l2 metadata directory";
-  }
-
-  if (devices->size() == 0) {
-    LOG(LS_INFO) << "Plan B. Scanning all video devices in /dev directory";
-    ScanDeviceDirectory("/dev/", devices);
-  }
-
-  LOG(LS_INFO) << "Total V4L2 devices found : " << devices->size();
-}
-
-bool LinuxDeviceManager::GetVideoCaptureDevices(std::vector<Device>* devices) {
-  devices->clear();
-  ScanV4L2Devices(devices);
-  return FilterDevices(devices, kFilteredVideoDevicesName);
-}
-
-LinuxDeviceWatcher::LinuxDeviceWatcher(DeviceManagerInterface* dm)
-    : DeviceWatcher(dm),
-      manager_(dm),
-      udev_(NULL),
-      udev_monitor_(NULL),
-      registered_(false) {
-}
-
-LinuxDeviceWatcher::~LinuxDeviceWatcher() {
-}
-
-bool LinuxDeviceWatcher::Start() {
-  // We deliberately return true in the failure paths here because libudev is
-  // not a critical component of a Linux system so it may not be present/usable,
-  // and we don't want to halt LinuxDeviceManager initialization in such a case.
-  if (!libudev_.Load()) {
-    LOG(LS_WARNING) << "libudev not present/usable; LinuxDeviceWatcher disabled";
-    return true;
-  }
-  udev_ = LATE(udev_new)();
-  if (!udev_) {
-    LOG_ERR(LS_ERROR) << "udev_new()";
-    return true;
-  }
-  // The second argument here is the event source. It can be either "kernel" or
-  // "udev", but "udev" is the only correct choice. Apps listen on udev and the
-  // udev daemon in turn listens on the kernel.
-  udev_monitor_ = LATE(udev_monitor_new_from_netlink)(udev_, "udev");
-  if (!udev_monitor_) {
-    LOG_ERR(LS_ERROR) << "udev_monitor_new_from_netlink()";
-    return true;
-  }
-  // We only listen for changes in the video devices. Audio devices are more or
-  // less unimportant because receiving device change notifications really only
-  // matters for broadcasting updated send/recv capabilities based on whether
-  // there is at least one device available, and almost all computers have at
-  // least one audio device. Also, PulseAudio device notifications don't come
-  // from the udev daemon, they come from the PulseAudio daemon, so we'd only
-  // want to listen for audio device changes from udev if using ALSA. For
-  // simplicity, we don't bother with any audio stuff at all.
-  if (LATE(udev_monitor_filter_add_match_subsystem_devtype)(udev_monitor_,
-                                                            "video4linux",
-                                                            NULL) < 0) {
-    LOG_ERR(LS_ERROR) << "udev_monitor_filter_add_match_subsystem_devtype()";
-    return true;
-  }
-  if (LATE(udev_monitor_enable_receiving)(udev_monitor_) < 0) {
-    LOG_ERR(LS_ERROR) << "udev_monitor_enable_receiving()";
-    return true;
-  }
-  static_cast<talk_base::PhysicalSocketServer*>(
-      talk_base::Thread::Current()->socketserver())->Add(this);
-  registered_ = true;
-  return true;
-}
-
-void LinuxDeviceWatcher::Stop() {
-  if (registered_) {
-    static_cast<talk_base::PhysicalSocketServer*>(
-        talk_base::Thread::Current()->socketserver())->Remove(this);
-    registered_ = false;
-  }
-  if (udev_monitor_) {
-    LATE(udev_monitor_unref)(udev_monitor_);
-    udev_monitor_ = NULL;
-  }
-  if (udev_) {
-    LATE(udev_unref)(udev_);
-    udev_ = NULL;
-  }
-  libudev_.Unload();
-}
-
-uint32 LinuxDeviceWatcher::GetRequestedEvents() {
-  return talk_base::DE_READ;
-}
-
-void LinuxDeviceWatcher::OnPreEvent(uint32 ff) {
-  // Nothing to do.
-}
-
-void LinuxDeviceWatcher::OnEvent(uint32 ff, int err) {
-  udev_device* device = LATE(udev_monitor_receive_device)(udev_monitor_);
-  if (!device) {
-    // Probably the socket connection to the udev daemon was terminated (perhaps
-    // the daemon crashed or is being restarted?).
-    LOG_ERR(LS_WARNING) << "udev_monitor_receive_device()";
-    // Stop listening to avoid potential livelock (an fd with EOF in it is
-    // always considered readable).
-    static_cast<talk_base::PhysicalSocketServer*>(
-        talk_base::Thread::Current()->socketserver())->Remove(this);
-    registered_ = false;
-    return;
-  }
-  // Else we read the device successfully.
-
-  // Since we already have our own filesystem-based device enumeration code, we
-  // simply re-enumerate rather than inspecting the device event.
-  LATE(udev_device_unref)(device);
-  manager_->SignalDevicesChange();
-}
-
-int LinuxDeviceWatcher::GetDescriptor() {
-  return LATE(udev_monitor_get_fd)(udev_monitor_);
-}
-
-bool LinuxDeviceWatcher::IsDescriptorClosed() {
-  // If it is closed then we will just get an error in
-  // udev_monitor_receive_device and unregister, so we don't need to check for
-  // it separately.
-  return false;
-}
-
-};  // namespace cricket
diff --git a/third_party/libjingle/source/talk/session/phone/linuxdevicemanager.h b/third_party/libjingle/source/talk/session/phone/linuxdevicemanager.h
deleted file mode 100644
index dce3286..0000000
--- a/third_party/libjingle/source/talk/session/phone/linuxdevicemanager.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * libjingle
- * Copyright 2004 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SESSION_PHONE_LINUXDEVICEMANAGER_H_
-#define TALK_SESSION_PHONE_LINUXDEVICEMANAGER_H_
-
-#include <string>
-#include <vector>
-
-#include "talk/base/sigslot.h"
-#include "talk/base/stringencode.h"
-#include "talk/session/phone/devicemanager.h"
-#include "talk/sound/soundsystemfactory.h"
-
-namespace cricket {
-
-class LinuxDeviceManager : public DeviceManager {
- public:
-  LinuxDeviceManager();
-  virtual ~LinuxDeviceManager();
-
-  virtual bool GetVideoCaptureDevices(std::vector<Device>* devs);
-
- private:
-  virtual bool GetAudioDevices(bool input, std::vector<Device>* devs);
-  SoundSystemHandle sound_system_;
-};
-
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_LINUXDEVICEMANAGER_H_
diff --git a/third_party/libjingle/source/talk/session/phone/macdevicemanager.cc b/third_party/libjingle/source/talk/session/phone/macdevicemanager.cc
deleted file mode 100644
index bad5ea9..0000000
--- a/third_party/libjingle/source/talk/session/phone/macdevicemanager.cc
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * libjingle
- * Copyright 2004 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/session/phone/macdevicemanager.h"
-
-#include <CoreAudio/CoreAudio.h>
-#include <QuickTime/QuickTime.h>
-
-#include "talk/base/logging.h"
-#include "talk/base/stringutils.h"
-#include "talk/base/thread.h"
-#include "talk/session/phone/mediacommon.h"
-
-class DeviceWatcherImpl;
-
-namespace cricket {
-
-DeviceManagerInterface* DeviceManagerFactory::Create() {
-  return new MacDeviceManager();
-}
-
-class MacDeviceWatcher : public DeviceWatcher {
- public:
-  explicit MacDeviceWatcher(DeviceManagerInterface* dm);
-  virtual ~MacDeviceWatcher();
-  virtual bool Start();
-  virtual void Stop();
-
- private:
-  DeviceManagerInterface* manager_;
-  DeviceWatcherImpl* impl_;
-};
-
-static const char* kFilteredAudioDevicesName[] = {
-    NULL,
-};
-// TODO: Try to get hold of a copy of Final Cut to understand why we
-//               crash while scanning their components on OS X.
-static const char* const kFilteredVideoDevicesName[] =  {
-    "Google Camera Adapter",   // Our own magiccams
-    "DVCPRO HD",               // Final cut
-    "Sonix SN9C201p",          // Crashes in OpenAComponent and CloseComponent
-    NULL,
-};
-static const int kVideoDeviceOpenAttempts = 3;
-static const UInt32 kAudioDeviceNameLength = 64;
-// Obj-C functions defined in macdevicemanagermm.mm
-// TODO: have a shared header for these function defines.
-extern DeviceWatcherImpl* CreateDeviceWatcherCallback(
-    DeviceManagerInterface* dm);
-extern void ReleaseDeviceWatcherCallback(DeviceWatcherImpl* impl);
-extern bool GetQTKitVideoDevices(std::vector<Device>* out);
-static bool GetAudioDeviceIDs(bool inputs, std::vector<AudioDeviceID>* out);
-static bool GetAudioDeviceName(AudioDeviceID id, bool input, std::string* out);
-
-MacDeviceManager::MacDeviceManager() {
-  set_watcher(new MacDeviceWatcher(this));
-}
-
-MacDeviceManager::~MacDeviceManager() {
-}
-
-bool MacDeviceManager::GetVideoCaptureDevices(std::vector<Device>* devices) {
-  devices->clear();
-  if (!GetQTKitVideoDevices(devices)) {
-    return false;
-  }
-  return FilterDevices(devices, kFilteredVideoDevicesName);
-}
-
-bool MacDeviceManager::GetAudioDevices(bool input,
-                                       std::vector<Device>* devs) {
-  devs->clear();
-  std::vector<AudioDeviceID> dev_ids;
-  bool ret = GetAudioDeviceIDs(input, &dev_ids);
-  if (!ret) {
-    return false;
-  }
-  for (size_t i = 0; i < dev_ids.size(); ++i) {
-    std::string name;
-    if (GetAudioDeviceName(dev_ids[i], input, &name)) {
-      devs->push_back(Device(name, dev_ids[i]));
-    }
-  }
-  return FilterDevices(devs, kFilteredAudioDevicesName);
-}
-
-static bool GetAudioDeviceIDs(bool input,
-                              std::vector<AudioDeviceID>* out_dev_ids) {
-  UInt32 propsize;
-  OSErr err = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices,
-                                           &propsize, NULL);
-  if (0 != err) {
-    LOG(LS_ERROR) << "Couldn't get information about property, "
-                  << "so no device list acquired.";
-    return false;
-  }
-
-  size_t num_devices = propsize / sizeof(AudioDeviceID);
-  talk_base::scoped_array<AudioDeviceID> device_ids(
-      new AudioDeviceID[num_devices]);
-
-  err = AudioHardwareGetProperty(kAudioHardwarePropertyDevices,
-                                 &propsize, device_ids.get());
-  if (0 != err) {
-    LOG(LS_ERROR) << "Failed to get device ids, "
-                  << "so no device listing acquired.";
-    return false;
-  }
-
-  for (size_t i = 0; i < num_devices; ++i) {
-    AudioDeviceID an_id = device_ids[i];
-    // find out the number of channels for this direction
-    // (input/output) on this device -
-    // we'll ignore anything with no channels.
-    err = AudioDeviceGetPropertyInfo(an_id, 0, input,
-                                     kAudioDevicePropertyStreams,
-                                     &propsize, NULL);
-    if (0 == err) {
-      unsigned num_channels = propsize / sizeof(AudioStreamID);
-      if (0 < num_channels) {
-        out_dev_ids->push_back(an_id);
-      }
-    } else {
-      LOG(LS_ERROR) << "No property info for stream property for device id "
-                    << an_id << "(is_input == " << input
-                    << "), so not including it in the list.";
-    }
-  }
-
-  return true;
-}
-
-static bool GetAudioDeviceName(AudioDeviceID id,
-                               bool input,
-                               std::string* out_name) {
-  UInt32 nameLength = kAudioDeviceNameLength;
-  char name[kAudioDeviceNameLength + 1];
-  OSErr err = AudioDeviceGetProperty(id, 0, input,
-                                     kAudioDevicePropertyDeviceName,
-                                     &nameLength, name);
-  if (0 != err) {
-    LOG(LS_ERROR) << "No name acquired for device id " << id;
-    return false;
-  }
-
-  *out_name = name;
-  return true;
-}
-
-MacDeviceWatcher::MacDeviceWatcher(DeviceManagerInterface* manager)
-    : DeviceWatcher(manager),
-      manager_(manager),
-      impl_(NULL) {
-}
-
-MacDeviceWatcher::~MacDeviceWatcher() {
-}
-
-bool MacDeviceWatcher::Start() {
-  if (!impl_) {
-    impl_ = CreateDeviceWatcherCallback(manager_);
-  }
-  return impl_ != NULL;
-}
-
-void MacDeviceWatcher::Stop() {
-  if (impl_) {
-    ReleaseDeviceWatcherCallback(impl_);
-    impl_ = NULL;
-  }
-}
-
-};  // namespace cricket
diff --git a/third_party/libjingle/source/talk/session/phone/macdevicemanager.h b/third_party/libjingle/source/talk/session/phone/macdevicemanager.h
deleted file mode 100644
index ec4cfc0..0000000
--- a/third_party/libjingle/source/talk/session/phone/macdevicemanager.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * libjingle
- * Copyright 2004 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SESSION_PHONE_MACDEVICEMANAGER_H_
-#define TALK_SESSION_PHONE_MACDEVICEMANAGER_H_
-
-#include <string>
-#include <vector>
-
-#include "talk/base/sigslot.h"
-#include "talk/base/stringencode.h"
-#include "talk/session/phone/devicemanager.h"
-
-namespace cricket {
-
-class DeviceWatcher;
-
-class MacDeviceManager : public DeviceManager {
- public:
-  MacDeviceManager();
-  virtual ~MacDeviceManager();
-
-  virtual bool GetVideoCaptureDevices(std::vector<Device>* devs);
-
- private:
-  virtual bool GetAudioDevices(bool input, std::vector<Device>* devs);
-  bool FilterDevice(const Device& d);
-};
-
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_MACDEVICEMANAGER_H_
diff --git a/third_party/libjingle/source/talk/session/phone/macdevicemanagermm.mm b/third_party/libjingle/source/talk/session/phone/macdevicemanagermm.mm
deleted file mode 100644
index db970c2..0000000
--- a/third_party/libjingle/source/talk/session/phone/macdevicemanagermm.mm
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/session/phone/devicemanager.h"
-
-#import <assert.h>
-#import <QTKit/QTKit.h>
-
-#include "talk/base/logging.h"
-
-@interface DeviceWatcherImpl : NSObject {
- @private
-  cricket::DeviceManagerInterface* manager_;
-}
-- (id)init:(cricket::DeviceManagerInterface*)manager;
-- (void)onDevicesChanged:(NSNotification *)notification;
-@end
-
-@implementation DeviceWatcherImpl
-- (id)init:(cricket::DeviceManagerInterface*)manager {
-  if ((self = [super init])) {
-    assert(manager != NULL);
-    manager_ = manager;
-    [[NSNotificationCenter defaultCenter] addObserver:self
-        selector:@selector(onDevicesChanged:)
-        name:QTCaptureDeviceWasConnectedNotification
-        object:nil];
-    [[NSNotificationCenter defaultCenter] addObserver:self
-        selector:@selector(onDevicesChanged:)
-        name:QTCaptureDeviceWasDisconnectedNotification
-        object:nil];
-  }
-  return self;
-}
-
-- (void)dealloc {
-  [[NSNotificationCenter defaultCenter] removeObserver:self];
-  [super dealloc];
-}
-- (void)onDevicesChanged:(NSNotification *)notification {
-  manager_->SignalDevicesChange();
-}
-@end
-
-namespace cricket {
-
-DeviceWatcherImpl* CreateDeviceWatcherCallback(
-    DeviceManagerInterface* manager) {
-  NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
-  DeviceWatcherImpl* impl = [[DeviceWatcherImpl alloc] init:manager];
-  [pool drain];
-  return impl;
-}
-
-void ReleaseDeviceWatcherCallback(DeviceWatcherImpl* watcher) {
-  NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
-  [watcher release];
-  [pool drain];
-}
-
-bool GetQTKitVideoDevices(std::vector<Device>* devices) {
-  NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
-
-  NSArray* qt_capture_devices =
-      [QTCaptureDevice inputDevicesWithMediaType:QTMediaTypeVideo];
-  NSUInteger count = [qt_capture_devices count];
-  LOG(LS_INFO) << count << " capture device(s) found:";
-  for (QTCaptureDevice* qt_capture_device in qt_capture_devices) {
-    static NSString* const kFormat = @"localizedDisplayName: \"%@\", "
-        @"modelUniqueID: \"%@\", uniqueID \"%@\", isConnected: %d, isOpen: %d, "
-        @"isInUseByAnotherApplication: %d";
-    NSString* info = [NSString stringWithFormat:kFormat,
-        [qt_capture_device localizedDisplayName],
-        [qt_capture_device modelUniqueID],
-        [qt_capture_device uniqueID],
-        [qt_capture_device isConnected],
-        [qt_capture_device isOpen],
-        [qt_capture_device isInUseByAnotherApplication]];
-    LOG(LS_INFO) << [info UTF8String];
-
-    std::string name([[qt_capture_device localizedDisplayName]
-                         UTF8String]);
-    devices->push_back(Device(name,
-       [[qt_capture_device uniqueID]
-           UTF8String]));
-  }
-
-  [pool drain];
-  return true;
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/session/phone/mediachannel.h b/third_party/libjingle/source/talk/session/phone/mediachannel.h
deleted file mode 100644
index 33fc49c..0000000
--- a/third_party/libjingle/source/talk/session/phone/mediachannel.h
+++ /dev/null
@@ -1,431 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SESSION_PHONE_MEDIACHANNEL_H_
-#define TALK_SESSION_PHONE_MEDIACHANNEL_H_
-
-#include <string>
-#include <vector>
-
-#include "talk/base/basictypes.h"
-#include "talk/base/sigslot.h"
-#include "talk/base/socket.h"
-#include "talk/base/window.h"
-#include "talk/session/phone/codec.h"
-// TODO: re-evaluate this include
-#include "talk/session/phone/audiomonitor.h"
-
-namespace talk_base {
-class Buffer;
-}
-
-namespace cricket {
-
-class VideoRenderer;
-
-const int kMinRtpHeaderExtensionId = 1;
-const int kMaxRtpHeaderExtensionId = 255;
-
-// A class for playing out soundclips.
-class SoundclipMedia {
- public:
-  enum SoundclipFlags {
-    SF_LOOP = 1,
-  };
-
-  virtual ~SoundclipMedia() {}
-
-  // Plays a sound out to the speakers with the given audio stream. The stream
-  // must be 16-bit little-endian 16 kHz PCM. If a stream is already playing
-  // on this SoundclipMedia, it is stopped. If clip is NULL, nothing is played.
-  // Returns whether it was successful.
-  virtual bool PlaySound(const char *clip, int len, int flags) = 0;
-};
-
-struct RtpHeaderExtension {
-  RtpHeaderExtension(const std::string& u, int i) : uri(u), id(i) {}
-  std::string uri;
-  int id;
-  // TODO: SendRecv direction;
-};
-
-enum VoiceMediaChannelOptions {
-  OPT_CONFERENCE = 0x10000,   // tune the audio stream for conference mode
-  OPT_AGC_MINUS_10DB = 0x80000000,  // tune the audio stream for vcs
-                                    // with different target levels.
-};
-
-enum VideoMediaChannelOptions {
-  // Increase the output framerate by 2x by interpolating frames
-  OPT_INTERPOLATE = 0x10000,
-  // Enable video adaptation due to cpu load.
-  OPT_CPU_ADAPTATION = 0x20000
-};
-
-class MediaChannel : public sigslot::has_slots<> {
- public:
-  class NetworkInterface {
-   public:
-    enum SocketType { ST_RTP, ST_RTCP };
-    virtual bool SendPacket(talk_base::Buffer* packet) = 0;
-    virtual bool SendRtcp(talk_base::Buffer* packet) = 0;
-    virtual int SetOption(SocketType type, talk_base::Socket::Option opt,
-                          int option) = 0;
-    virtual ~NetworkInterface() {}
-  };
-
-  MediaChannel() : network_interface_(NULL) {}
-  virtual ~MediaChannel() {}
-
-  // Gets/sets the abstract inteface class for sending RTP/RTCP data.
-  NetworkInterface *network_interface() { return network_interface_; }
-  virtual void SetInterface(NetworkInterface *iface) {
-    network_interface_ = iface;
-  }
-
-  // Called when a RTP packet is received.
-  virtual void OnPacketReceived(talk_base::Buffer* packet) = 0;
-  // Called when a RTCP packet is received.
-  virtual void OnRtcpReceived(talk_base::Buffer* packet) = 0;
-  // Sets the SSRC to be used for outgoing data.
-  virtual void SetSendSsrc(uint32 id) = 0;
-  // Set the CNAME of RTCP
-  virtual bool SetRtcpCName(const std::string& cname) = 0;
-  // Mutes the channel.
-  virtual bool Mute(bool on) = 0;
-
-  // Sets the RTP extension headers and IDs to use when sending RTP.
-  virtual bool SetRecvRtpHeaderExtensions(
-      const std::vector<RtpHeaderExtension>& extensions) = 0;
-  virtual bool SetSendRtpHeaderExtensions(
-      const std::vector<RtpHeaderExtension>& extensions) = 0;
-  // Sets the rate control to use when sending data.
-  virtual bool SetSendBandwidth(bool autobw, int bps) = 0;
-  // Sets the media options to use.
-  virtual bool SetOptions(int options) = 0;
-  // TODO: add virtual int GetOptions() = 0;
-
- protected:
-  NetworkInterface *network_interface_;
-};
-
-enum SendFlags {
-  SEND_NOTHING,
-  SEND_RINGBACKTONE,
-  SEND_MICROPHONE
-};
-
-struct VoiceSenderInfo {
-  VoiceSenderInfo()
-      : ssrc(0),
-        bytes_sent(0),
-        packets_sent(0),
-        packets_lost(0),
-        fraction_lost(0.0),
-        ext_seqnum(0),
-        rtt_ms(0),
-        jitter_ms(0),
-        audio_level(0),
-        echo_delay_median_ms(0),
-        echo_delay_std_ms(0),
-        echo_return_loss(0),
-        echo_return_loss_enhancement(0) {
-  }
-
-  uint32 ssrc;
-  std::string codec_name;
-  int bytes_sent;
-  int packets_sent;
-  int packets_lost;
-  float fraction_lost;
-  int ext_seqnum;
-  int rtt_ms;
-  int jitter_ms;
-  int audio_level;
-  int echo_delay_median_ms;
-  int echo_delay_std_ms;
-  int echo_return_loss;
-  int echo_return_loss_enhancement;
-};
-
-struct VoiceReceiverInfo {
-  VoiceReceiverInfo()
-      : ssrc(0),
-        bytes_rcvd(0),
-        packets_rcvd(0),
-        packets_lost(0),
-        fraction_lost(0.0),
-        ext_seqnum(0),
-        jitter_ms(0),
-        jitter_buffer_ms(0),
-        jitter_buffer_preferred_ms(0),
-        delay_estimate_ms(0),
-        audio_level(0) {
-  }
-
-  uint32 ssrc;
-  int bytes_rcvd;
-  int packets_rcvd;
-  int packets_lost;
-  float fraction_lost;
-  int ext_seqnum;
-  int jitter_ms;
-  int jitter_buffer_ms;
-  int jitter_buffer_preferred_ms;
-  int delay_estimate_ms;
-  int audio_level;
-};
-
-struct VideoSenderInfo {
-  VideoSenderInfo()
-      : ssrc(0),
-        bytes_sent(0),
-        packets_sent(0),
-        packets_cached(0),
-        packets_lost(0),
-        fraction_lost(0.0),
-        firs_rcvd(0),
-        nacks_rcvd(0),
-        rtt_ms(0),
-        frame_width(0),
-        frame_height(0),
-        framerate_input(0),
-        framerate_sent(0),
-        nominal_bitrate(0),
-        preferred_bitrate(0) {
-  }
-
-  uint32 ssrc;
-  std::string codec_name;
-  int bytes_sent;
-  int packets_sent;
-  int packets_cached;
-  int packets_lost;
-  float fraction_lost;
-  int firs_rcvd;
-  int nacks_rcvd;
-  int rtt_ms;
-  int frame_width;
-  int frame_height;
-  int framerate_input;
-  int framerate_sent;
-  int nominal_bitrate;
-  int preferred_bitrate;
-};
-
-struct VideoReceiverInfo {
-  VideoReceiverInfo()
-      : ssrc(0),
-        bytes_rcvd(0),
-        packets_rcvd(0),
-        packets_lost(0),
-        packets_concealed(0),
-        fraction_lost(0.0),
-        firs_sent(0),
-        nacks_sent(0),
-        frame_width(0),
-        frame_height(0),
-        framerate_rcvd(0),
-        framerate_decoded(0),
-        framerate_output(0) {
-  }
-
-  uint32 ssrc;
-  int bytes_rcvd;
-  // vector<int> layer_bytes_rcvd;
-  int packets_rcvd;
-  int packets_lost;
-  int packets_concealed;
-  float fraction_lost;
-  int firs_sent;
-  int nacks_sent;
-  int frame_width;
-  int frame_height;
-  int framerate_rcvd;
-  int framerate_decoded;
-  int framerate_output;
-};
-
-struct BandwidthEstimationInfo {
-  BandwidthEstimationInfo()
-      : available_send_bandwidth(0),
-        available_recv_bandwidth(0),
-        target_enc_bitrate(0),
-        actual_enc_bitrate(0),
-        retransmit_bitrate(0),
-        transmit_bitrate(0),
-        bucket_delay(0) {
-  }
-
-  int available_send_bandwidth;
-  int available_recv_bandwidth;
-  int target_enc_bitrate;
-  int actual_enc_bitrate;
-  int retransmit_bitrate;
-  int transmit_bitrate;
-  int bucket_delay;
-};
-
-struct VoiceMediaInfo {
-  void Clear() {
-    senders.clear();
-    receivers.clear();
-  }
-  std::vector<VoiceSenderInfo> senders;
-  std::vector<VoiceReceiverInfo> receivers;
-};
-
-struct VideoMediaInfo {
-  void Clear() {
-    senders.clear();
-    receivers.clear();
-    bw_estimations.clear();
-  }
-  std::vector<VideoSenderInfo> senders;
-  std::vector<VideoReceiverInfo> receivers;
-  std::vector<BandwidthEstimationInfo> bw_estimations;
-};
-
-class VoiceMediaChannel : public MediaChannel {
- public:
-  enum Error {
-    ERROR_NONE = 0,                       // No error.
-    ERROR_OTHER,                          // Other errors.
-    ERROR_REC_DEVICE_OPEN_FAILED = 100,   // Could not open mic.
-    ERROR_REC_DEVICE_MUTED,               // Mic was muted by OS.
-    ERROR_REC_DEVICE_SILENT,              // No background noise picked up.
-    ERROR_REC_DEVICE_SATURATION,          // Mic input is clipping.
-    ERROR_REC_DEVICE_REMOVED,             // Mic was removed while active.
-    ERROR_REC_RUNTIME_ERROR,              // Processing is encountering errors.
-    ERROR_REC_SRTP_ERROR,                 // Generic SRTP failure.
-    ERROR_REC_SRTP_AUTH_FAILED,           // Failed to authenticate packets.
-    ERROR_REC_TYPING_NOISE_DETECTED,      // Typing noise is detected.
-    ERROR_PLAY_DEVICE_OPEN_FAILED = 200,  // Could not open playout.
-    ERROR_PLAY_DEVICE_MUTED,              // Playout muted by OS.
-    ERROR_PLAY_DEVICE_REMOVED,            // Playout removed while active.
-    ERROR_PLAY_RUNTIME_ERROR,             // Errors in voice processing.
-    ERROR_PLAY_SRTP_ERROR,                // Generic SRTP failure.
-    ERROR_PLAY_SRTP_AUTH_FAILED,          // Failed to authenticate packets.
-    ERROR_PLAY_SRTP_REPLAY,               // Packet replay detected.
-  };
-
-  VoiceMediaChannel() {}
-  virtual ~VoiceMediaChannel() {}
-  // Sets the codecs/payload types to be used for incoming media.
-  virtual bool SetRecvCodecs(const std::vector<AudioCodec>& codecs) = 0;
-  // Sets the codecs/payload types to be used for outgoing media.
-  virtual bool SetSendCodecs(const std::vector<AudioCodec>& codecs) = 0;
-  // Starts or stops playout of received audio.
-  virtual bool SetPlayout(bool playout) = 0;
-  // Starts or stops sending (and potentially capture) of local audio.
-  virtual bool SetSend(SendFlags flag) = 0;
-  // Adds a new receive-only stream with the specified SSRC.
-  virtual bool AddStream(uint32 ssrc) = 0;
-  // Removes a stream added with AddStream.
-  virtual bool RemoveStream(uint32 ssrc) = 0;
-  // Gets current energy levels for all incoming streams.
-  virtual bool GetActiveStreams(AudioInfo::StreamList* actives) = 0;
-  // Get the current energy level of the stream sent to the speaker.
-  virtual int GetOutputLevel() = 0;
-  // Set left and right scale for speaker output volume of the specified ssrc.
-  virtual bool SetOutputScaling(uint32 ssrc, double left, double right) = 0;
-  // Get left and right scale for speaker output volume of the specified ssrc.
-  virtual bool GetOutputScaling(uint32 ssrc, double* left, double* right) = 0;
-  // Specifies a ringback tone to be played during call setup.
-  virtual bool SetRingbackTone(const char *buf, int len) = 0;
-  // Plays or stops the aforementioned ringback tone
-  virtual bool PlayRingbackTone(uint32 ssrc, bool play, bool loop) = 0;
-  // Sends a out-of-band DTMF signal using the specified event.
-  virtual bool PressDTMF(int event, bool playout) = 0;
-  // Gets quality stats for the channel.
-  virtual bool GetStats(VoiceMediaInfo* info) = 0;
-  // Gets last reported error for this media channel.
-  virtual void GetLastMediaError(uint32* ssrc,
-                                 VoiceMediaChannel::Error* error) {
-    ASSERT(error != NULL);
-    *error = ERROR_NONE;
-  }
-
-  // Signal errors from MediaChannel.  Arguments are:
-  //     ssrc(uint32), and error(VoiceMediaChannel::Error).
-  sigslot::signal2<uint32, VoiceMediaChannel::Error> SignalMediaError;
-};
-
-class VideoMediaChannel : public MediaChannel {
- public:
-  enum Error {
-    ERROR_NONE = 0,                       // No error.
-    ERROR_OTHER,                          // Other errors.
-    ERROR_REC_DEVICE_OPEN_FAILED = 100,   // Could not open camera.
-    ERROR_REC_DEVICE_NO_DEVICE,           // No camera.
-    ERROR_REC_DEVICE_IN_USE,              // Device is in already use.
-    ERROR_REC_DEVICE_REMOVED,             // Device is removed.
-    ERROR_REC_SRTP_ERROR,                 // Generic sender SRTP failure.
-    ERROR_REC_SRTP_AUTH_FAILED,           // Failed to authenticate packets.
-    ERROR_PLAY_SRTP_ERROR = 200,          // Generic receiver SRTP failure.
-    ERROR_PLAY_SRTP_AUTH_FAILED,          // Failed to authenticate packets.
-    ERROR_PLAY_SRTP_REPLAY,               // Packet replay detected.
-  };
-
-  VideoMediaChannel() { renderer_ = NULL; }
-  virtual ~VideoMediaChannel() {}
-  // Sets the codecs/payload types to be used for incoming media.
-  virtual bool SetRecvCodecs(const std::vector<VideoCodec> &codecs) = 0;
-  // Sets the codecs/payload types to be used for outgoing media.
-  virtual bool SetSendCodecs(const std::vector<VideoCodec> &codecs) = 0;
-  // Starts or stops playout of received video.
-  virtual bool SetRender(bool render) = 0;
-  // Starts or stops transmission (and potentially capture) of local video.
-  virtual bool SetSend(bool send) = 0;
-  // Adds a new receive-only stream with the specified SSRC.
-  virtual bool AddStream(uint32 ssrc, uint32 voice_ssrc) = 0;
-  // Removes a stream added with AddStream.
-  virtual bool RemoveStream(uint32 ssrc) = 0;
-  // Sets the renderer object to be used for the specified stream.
-  // If SSRC is 0, the renderer is used for the 'default' stream.
-  virtual bool SetRenderer(uint32 ssrc, VideoRenderer* renderer) = 0;
-  virtual bool AddScreencast(uint32 ssrc, talk_base::WindowId id) = 0;
-  virtual bool RemoveScreencast(uint32 ssrc) = 0;
-  // Gets quality stats for the channel.
-  virtual bool GetStats(VideoMediaInfo* info) = 0;
-
-  // Send an intra frame to the receivers.
-  virtual bool SendIntraFrame() = 0;
-  // Reuqest each of the remote senders to send an intra frame.
-  virtual bool RequestIntraFrame() = 0;
-
-  // Signals events from the currently active window.
-  sigslot::signal2<uint32, talk_base::WindowEvent> SignalScreencastWindowEvent;
-  sigslot::signal2<uint32, Error> SignalMediaError;
-
- protected:
-  VideoRenderer *renderer_;
-};
-
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_MEDIACHANNEL_H_
diff --git a/third_party/libjingle/source/talk/session/phone/mediacommon.h b/third_party/libjingle/source/talk/session/phone/mediacommon.h
deleted file mode 100644
index 7a606e3..0000000
--- a/third_party/libjingle/source/talk/session/phone/mediacommon.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2007, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SESSION_PHONE_MEDIACOMMON_H_
-#define TALK_SESSION_PHONE_MEDIACOMMON_H_
-
-namespace cricket {
-
-enum MediaCapabilities {
-  AUDIO_RECV = 1 << 0,
-  AUDIO_SEND = 1 << 1,
-  VIDEO_RECV = 1 << 2,
-  VIDEO_SEND = 1 << 3,
-};
-
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_MEDIACOMMON_H_
diff --git a/third_party/libjingle/source/talk/session/phone/mediaengine.cc b/third_party/libjingle/source/talk/session/phone/mediaengine.cc
deleted file mode 100644
index 21fb83d..0000000
--- a/third_party/libjingle/source/talk/session/phone/mediaengine.cc
+++ /dev/null
@@ -1,69 +0,0 @@
-//
-// libjingle
-// Copyright 2004--2007, Google Inc.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-//  1. Redistributions of source code must retain the above copyright notice,
-//     this list of conditions and the following disclaimer.
-//  2. Redistributions in binary form must reproduce the above copyright notice,
-//     this list of conditions and the following disclaimer in the documentation
-//     and/or other materials provided with the distribution.
-//  3. The name of the author may not be used to endorse or promote products
-//     derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-
-#include "talk/session/phone/mediaengine.h"
-
-#if defined(HAVE_LINPHONE)
-#include "talk/session/phone/linphonemediaengine.h"
-#elif defined(ANDROID)
-#include "talk/session/phone/androidmediaengine.h"
-#else
-#if defined(HAVE_WEBRTC_VOICE)
-#include "talk/session/phone/webrtcvoiceengine.h"
-#endif  // HAVE_WEBRTC_VOICE
-#if defined(HAVE_WEBRTC_VIDEO)
-#include "talk/session/phone/webrtcvideoengine.h"
-#endif  // HAVE_WEBRTC_VIDEO
-#endif  // HAVE_LINPHONE
-
-namespace cricket {
-#if defined(HAVE_WEBRTC_VOICE)
-#define AUDIO_ENG_NAME WebRtcVoiceEngine
-#endif
-
-#if defined(HAVE_WEBRTC_VIDEO)
-template<>
-CompositeMediaEngine<WebRtcVoiceEngine, WebRtcVideoEngine>::
-    CompositeMediaEngine() {
-  video_.SetVoiceEngine(&voice_);
-}
-#define VIDEO_ENG_NAME WebRtcVideoEngine
-#endif
-
-MediaEngineInterface* MediaEngineFactory::Create() {
-#if defined(HAVE_LINPHONE)
-  return new LinphoneMediaEngine("", "");
-#elif defined(ANDROID)
-  return AndroidMediaEngineFactory::Create();
-#elif defined(AUDIO_ENG_NAME) && defined(VIDEO_ENG_NAME)
-  return new CompositeMediaEngine<AUDIO_ENG_NAME, VIDEO_ENG_NAME>();
-#else
-  return new NullMediaEngine();
-#endif
-}
-
-};  // namespace cricket
diff --git a/third_party/libjingle/source/talk/session/phone/mediaengine.h b/third_party/libjingle/source/talk/session/phone/mediaengine.h
deleted file mode 100644
index 0f42adb..0000000
--- a/third_party/libjingle/source/talk/session/phone/mediaengine.h
+++ /dev/null
@@ -1,338 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2007, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SESSION_PHONE_MEDIAENGINE_H_
-#define TALK_SESSION_PHONE_MEDIAENGINE_H_
-
-#ifdef OSX
-#include <CoreAudio/CoreAudio.h>
-#endif
-
-#include <string>
-#include <vector>
-
-#include "talk/base/sigslotrepeater.h"
-#include "talk/session/phone/codec.h"
-#include "talk/session/phone/devicemanager.h"
-#include "talk/session/phone/mediachannel.h"
-#include "talk/session/phone/mediacommon.h"
-#include "talk/session/phone/videoprocessor.h"
-#include "talk/session/phone/videocommon.h"
-#include "talk/session/phone/voiceprocessor.h"
-
-namespace cricket {
-
-class VideoCapturer;
-
-// MediaEngineInterface is an abstraction of a media engine which can be
-// subclassed to support different media componentry backends.
-// It supports voice and video operations in the same class to facilitate
-// proper synchronization between both media types.
-class MediaEngineInterface {
- public:
-  // Bitmask flags for options that may be supported by the media engine
-  // implementation
-  enum AudioOptions {
-    ECHO_CANCELLATION = 1 << 0,
-    AUTO_GAIN_CONTROL = 1 << 1,
-    NOISE_SUPPRESSION = 1 << 2,
-    DEFAULT_AUDIO_OPTIONS = ECHO_CANCELLATION | AUTO_GAIN_CONTROL
-  };
-  enum VideoOptions {
-  };
-
-  virtual ~MediaEngineInterface() {}
-
-  // Initialization
-  // Starts the engine.
-  virtual bool Init() = 0;
-  // Shuts down the engine.
-  virtual void Terminate() = 0;
-  // Returns what the engine is capable of, as a set of Capabilities, above.
-  virtual int GetCapabilities() = 0;
-
-  // MediaChannel creation
-  // Creates a voice media channel. Returns NULL on failure.
-  virtual VoiceMediaChannel *CreateChannel() = 0;
-  // Creates a video media channel, paired with the specified voice channel.
-  // Returns NULL on failure.
-  virtual VideoMediaChannel *CreateVideoChannel(
-      VoiceMediaChannel* voice_media_channel) = 0;
-
-  // Creates a soundclip object for playing sounds on. Returns NULL on failure.
-  virtual SoundclipMedia *CreateSoundclip() = 0;
-
-  // Configuration
-  // Sets global audio options. "options" are from AudioOptions, above.
-  virtual bool SetAudioOptions(int options) = 0;
-  // Sets global video options. "options" are from VideoOptions, above.
-  virtual bool SetVideoOptions(int options) = 0;
-  // Sets the default (maximum) codec/resolution and encoder option to capture
-  // and encode video.
-  virtual bool SetDefaultVideoEncoderConfig(const VideoEncoderConfig& config)
-      = 0;
-
-  // Device selection
-  // TODO: Add method for selecting the soundclip device.
-  virtual bool SetSoundDevices(const Device* in_device,
-                               const Device* out_device) = 0;
-  virtual bool SetVideoCaptureDevice(const Device* cam_device) = 0;
-  // Sets the externally provided video capturer. The ssrc is the ssrc of the
-  // (video) stream for which the video capturer should be set.
-  virtual bool SetVideoCapturer(VideoCapturer* capturer, uint32 ssrc) = 0;
-
-  // Device configuration
-  // Gets the current speaker volume, as a value between 0 and 255.
-  virtual bool GetOutputVolume(int* level) = 0;
-  // Sets the current speaker volume, as a value between 0 and 255.
-  virtual bool SetOutputVolume(int level) = 0;
-
-  // Local monitoring
-  // Gets the current microphone level, as a value between 0 and 10.
-  virtual int GetInputLevel() = 0;
-  // Starts or stops the local microphone. Useful if local mic info is needed
-  // prior to a call being connected; the mic will be started automatically
-  // when a VoiceMediaChannel starts sending.
-  virtual bool SetLocalMonitor(bool enable) = 0;
-  // Installs a callback for raw frames from the local camera.
-  virtual bool SetLocalRenderer(VideoRenderer* renderer) = 0;
-  // Starts/stops local camera.
-  virtual CaptureResult SetVideoCapture(bool capture) = 0;
-
-  virtual const std::vector<AudioCodec>& audio_codecs() = 0;
-  virtual const std::vector<VideoCodec>& video_codecs() = 0;
-
-  // Logging control
-  virtual void SetVoiceLogging(int min_sev, const char* filter) = 0;
-  virtual void SetVideoLogging(int min_sev, const char* filter) = 0;
-
-  // media processors for effects
-  virtual bool RegisterVideoProcessor(VideoProcessor* video_processor) = 0;
-  virtual bool UnregisterVideoProcessor(VideoProcessor* video_processor) = 0;
-  virtual bool RegisterVoiceProcessor(uint32 ssrc,
-                                      VoiceProcessor* video_processor,
-                                      MediaProcessorDirection direction) = 0;
-  virtual bool UnregisterVoiceProcessor(uint32 ssrc,
-                                        VoiceProcessor* video_processor,
-                                        MediaProcessorDirection direction) = 0;
-
-  sigslot::repeater2<VideoCapturer*, CaptureResult>
-      SignalVideoCaptureResult;
-};
-
-
-class MediaEngineFactory {
- public:
-  static MediaEngineInterface* Create();
-};
-
-
-// CompositeMediaEngine constructs a MediaEngine from separate
-// voice and video engine classes.
-template<class VOICE, class VIDEO>
-class CompositeMediaEngine : public MediaEngineInterface {
- public:
-  CompositeMediaEngine() {}
-  virtual ~CompositeMediaEngine() {}
-  virtual bool Init() {
-    if (!voice_.Init())
-      return false;
-    if (!video_.Init()) {
-      voice_.Terminate();
-      return false;
-    }
-    SignalVideoCaptureResult.repeat(video_.SignalCaptureResult);
-    return true;
-  }
-  virtual void Terminate() {
-    video_.Terminate();
-    voice_.Terminate();
-  }
-
-  virtual int GetCapabilities() {
-    return (voice_.GetCapabilities() | video_.GetCapabilities());
-  }
-  virtual VoiceMediaChannel *CreateChannel() {
-    return voice_.CreateChannel();
-  }
-  virtual VideoMediaChannel *CreateVideoChannel(VoiceMediaChannel* channel) {
-    return video_.CreateChannel(channel);
-  }
-  virtual SoundclipMedia *CreateSoundclip() {
-    return voice_.CreateSoundclip();
-  }
-
-  virtual bool SetAudioOptions(int o) {
-    return voice_.SetOptions(o);
-  }
-  virtual bool SetVideoOptions(int o) {
-    return video_.SetOptions(o);
-  }
-  virtual bool SetDefaultVideoEncoderConfig(const VideoEncoderConfig& config) {
-    return video_.SetDefaultEncoderConfig(config);
-  }
-
-  virtual bool SetSoundDevices(const Device* in_device,
-                               const Device* out_device) {
-    return voice_.SetDevices(in_device, out_device);
-  }
-  virtual bool SetVideoCaptureDevice(const Device* cam_device) {
-    return video_.SetCaptureDevice(cam_device);
-  }
-  virtual bool SetVideoCapturer(VideoCapturer* capturer, uint32 ssrc) {
-    return video_.SetVideoCapturer(capturer, ssrc);
-  }
-
-  virtual bool GetOutputVolume(int* level) {
-    return voice_.GetOutputVolume(level);
-  }
-  virtual bool SetOutputVolume(int level) {
-    return voice_.SetOutputVolume(level);
-  }
-
-  virtual int GetInputLevel() {
-    return voice_.GetInputLevel();
-  }
-  virtual bool SetLocalMonitor(bool enable) {
-    return voice_.SetLocalMonitor(enable);
-  }
-  virtual bool SetLocalRenderer(VideoRenderer* renderer) {
-    return video_.SetLocalRenderer(renderer);
-  }
-  virtual CaptureResult SetVideoCapture(bool capture) {
-    return video_.SetCapture(capture);
-  }
-
-  virtual const std::vector<AudioCodec>& audio_codecs() {
-    return voice_.codecs();
-  }
-  virtual const std::vector<VideoCodec>& video_codecs() {
-    return video_.codecs();
-  }
-
-  virtual void SetVoiceLogging(int min_sev, const char* filter) {
-    return voice_.SetLogging(min_sev, filter);
-  }
-  virtual void SetVideoLogging(int min_sev, const char* filter) {
-    return video_.SetLogging(min_sev, filter);
-  }
-
-  virtual bool RegisterVideoProcessor(VideoProcessor* processor) {
-    return video_.RegisterProcessor(processor);
-  }
-  virtual bool UnregisterVideoProcessor(VideoProcessor* processor) {
-    return video_.UnregisterProcessor(processor);
-  }
-  virtual bool RegisterVoiceProcessor(uint32 ssrc,
-                                      VoiceProcessor* processor,
-                                      MediaProcessorDirection direction) {
-    return voice_.RegisterProcessor(ssrc, processor, direction);
-  }
-  virtual bool UnregisterVoiceProcessor(uint32 ssrc,
-                                        VoiceProcessor* processor,
-                                        MediaProcessorDirection direction) {
-    return voice_.UnregisterProcessor(ssrc, processor, direction);
-  }
-
- protected:
-  VOICE voice_;
-  VIDEO video_;
-};
-
-// NullVoiceEngine can be used with CompositeMediaEngine in the case where only
-// a video engine is desired.
-class NullVoiceEngine {
- public:
-  bool Init() { return true; }
-  void Terminate() {}
-  int GetCapabilities() { return 0; }
-  // If you need this to return an actual channel, use FakeMediaEngine instead.
-  VoiceMediaChannel* CreateChannel() {
-    return NULL;
-  }
-  SoundclipMedia* CreateSoundclip() {
-    return NULL;
-  }
-  bool SetOptions(int opts) { return true; }
-  bool SetDevices(const Device* in_device, const Device* out_device) {
-    return true;
-  }
-  bool GetOutputVolume(int* level) {
-    *level = 0;
-    return true;
-  }
-  bool SetOutputVolume(int level) { return true; }
-  int GetInputLevel() { return 0; }
-  bool SetLocalMonitor(bool enable) { return true; }
-  const std::vector<AudioCodec>& codecs() { return codecs_; }
-  void SetLogging(int min_sev, const char* filter) {}
-  bool RegisterProcessor(uint32 ssrc,
-                         VoiceProcessor* voice_processor,
-                         MediaProcessorDirection direction) { return true; }
-  bool UnregisterProcessor(uint32 ssrc,
-                           VoiceProcessor* voice_processor,
-                           MediaProcessorDirection direction) { return true; }
-
- private:
-  std::vector<AudioCodec> codecs_;
-};
-
-// NullVideoEngine can be used with CompositeMediaEngine in the case where only
-// a voice engine is desired.
-class NullVideoEngine {
- public:
-  bool Init() { return true; }
-  void Terminate() {}
-  int GetCapabilities() { return 0; }
-  // If you need this to return an actual channel, use FakeMediaEngine instead.
-  VideoMediaChannel* CreateChannel(
-      VoiceMediaChannel* voice_media_channel) {
-    return NULL;
-  }
-  bool SetOptions(int opts) { return true; }
-  bool SetDefaultEncoderConfig(const VideoEncoderConfig& config) {
-    return true;
-  }
-  bool SetCaptureDevice(const Device* cam_device) { return true; }
-  bool SetLocalRenderer(VideoRenderer* renderer) { return true; }
-  CaptureResult SetCapture(bool capture) { return CR_SUCCESS;  }
-  const std::vector<VideoCodec>& codecs() { return codecs_; }
-  void SetLogging(int min_sev, const char* filter) {}
-  bool RegisterProcessor(VideoProcessor* video_processor) { return true; }
-  bool UnregisterProcessor(VideoProcessor* video_processor) { return true; }
-  bool SetVideoCapturer(VideoCapturer* capturer, uint32 ssrc) { return true; }
-
-  sigslot::signal2<VideoCapturer*, CaptureResult> SignalCaptureResult;
- private:
-  std::vector<VideoCodec> codecs_;
-};
-
-typedef CompositeMediaEngine<NullVoiceEngine, NullVideoEngine> NullMediaEngine;
-
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_MEDIAENGINE_H_
diff --git a/third_party/libjingle/source/talk/session/phone/mediamessages.cc b/third_party/libjingle/source/talk/session/phone/mediamessages.cc
deleted file mode 100644
index c40b03f..0000000
--- a/third_party/libjingle/source/talk/session/phone/mediamessages.cc
+++ /dev/null
@@ -1,453 +0,0 @@
-/*
- * libjingle
- * Copyright 2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Documentation is in mediamessages.h.
- */
-
-#include "talk/session/phone/mediamessages.h"
-
-#include "talk/base/logging.h"
-#include "talk/base/stringencode.h"
-#include "talk/p2p/base/constants.h"
-#include "talk/p2p/base/parsing.h"
-#include "talk/session/phone/mediasessionclient.h"
-#include "talk/session/phone/streamparams.h"
-#include "talk/xmllite/xmlelement.h"
-
-namespace cricket {
-
-namespace {
-
-bool GetFirstSourceByNick(const NamedSources& sources,
-                          const std::string& nick,
-                          NamedSource* source_out) {
-  for (NamedSources::const_iterator source = sources.begin();
-       source != sources.end(); ++source) {
-    if (source->nick == nick) {
-      *source_out = *source;
-      return true;
-    }
-  }
-  return false;
-}
-
-bool GetSourceBySsrc(const NamedSources& sources, uint32 ssrc,
-                     NamedSource* source_out) {
-  for (NamedSources::const_iterator source = sources.begin();
-       source != sources.end(); ++source) {
-    if (source->ssrc == ssrc) {
-      *source_out = *source;
-      return true;
-    }
-  }
-  return false;
-}
-
-// NOTE: There is no check here for duplicate sources, so check before
-// adding.
-void AddSource(NamedSources* sources, const NamedSource& source) {
-  sources->push_back(source);
-}
-
-void RemoveSourceBySsrc(uint32 ssrc, NamedSources* sources) {
-  for (NamedSources::iterator source = sources->begin();
-       source != sources->end(); ) {
-    if (source->ssrc == ssrc) {
-      source = sources->erase(source);
-    } else {
-      ++source;
-    }
-  }
-}
-
-bool ParseSsrc(const std::string& string, uint32* ssrc) {
-  return talk_base::FromString(string, ssrc);
-}
-
-bool ParseSsrc(const buzz::XmlElement* element, uint32* ssrc) {
-  if (element == NULL) {
-    return false;
-  }
-  return ParseSsrc(element->BodyText(), ssrc);
-}
-
-bool ParseNamedSource(const buzz::XmlElement* source_elem,
-                      NamedSource* named_source,
-                      ParseError* error) {
-  named_source->nick = source_elem->Attr(QN_NICK);
-  if (named_source->nick.empty()) {
-    return BadParse("Missing or invalid nick.", error);
-  }
-
-  named_source->name = source_elem->Attr(QN_NAME);
-
-  const buzz::XmlElement* ssrc_elem =
-      source_elem->FirstNamed(QN_JINGLE_DRAFT_SSRC);
-  if (ssrc_elem != NULL && !ssrc_elem->BodyText().empty()) {
-    uint32 ssrc;
-    if (!ParseSsrc(ssrc_elem->BodyText(), &ssrc)) {
-      return BadParse("Missing or invalid ssrc.", error);
-    }
-    named_source->SetSsrc(ssrc);
-  }
-
-  return true;
-}
-
-// Builds a <view> element according to the following spec:
-// goto/jinglemuc
-buzz::XmlElement* CreateViewElem(const std::string& name,
-                                 const std::string& type) {
-  buzz::XmlElement* view_elem =
-      new buzz::XmlElement(QN_JINGLE_DRAFT_VIEW, true);
-  view_elem->AddAttr(QN_NAME, name);
-  view_elem->SetAttr(QN_TYPE, type);
-  return view_elem;
-}
-
-buzz::XmlElement* CreateVideoViewElem(const std::string& content_name,
-                                      const std::string& type) {
-  return CreateViewElem(content_name, type);
-}
-
-buzz::XmlElement* CreateNoneVideoViewElem(const std::string& content_name) {
-  return CreateVideoViewElem(content_name, STR_JINGLE_DRAFT_VIEW_TYPE_NONE);
-}
-
-buzz::XmlElement* CreateStaticVideoViewElem(const std::string& content_name,
-                                            const StaticVideoView& view) {
-  buzz::XmlElement* view_elem =
-      CreateVideoViewElem(content_name, STR_JINGLE_DRAFT_VIEW_TYPE_STATIC);
-  AddXmlAttr(view_elem, QN_SSRC, view.ssrc);
-
-  buzz::XmlElement* params_elem = new buzz::XmlElement(QN_JINGLE_DRAFT_PARAMS);
-  AddXmlAttr(params_elem, QN_WIDTH, view.width);
-  AddXmlAttr(params_elem, QN_HEIGHT, view.height);
-  AddXmlAttr(params_elem, QN_FRAMERATE, view.framerate);
-  AddXmlAttr(params_elem, QN_PREFERENCE, view.preference);
-  view_elem->AddElement(params_elem);
-
-  return view_elem;
-}
-
-}  //  namespace
-
-bool MediaSources::GetFirstAudioSourceByNick(
-    const std::string& nick, NamedSource* source) {
-  return GetFirstSourceByNick(audio_, nick, source);
-}
-
-bool MediaSources::GetFirstVideoSourceByNick(
-    const std::string& nick, NamedSource* source) {
-  return GetFirstSourceByNick(video_, nick, source);
-}
-
-void MediaSources::CopyFrom(const MediaSources& sources) {
-  audio_ = sources.audio_;
-  video_ = sources.video_;
-}
-
-bool MediaSources::GetAudioSourceBySsrc(uint32 ssrc, NamedSource* source) {
-  return GetSourceBySsrc(audio_, ssrc, source);
-}
-
-bool MediaSources::GetVideoSourceBySsrc(uint32 ssrc, NamedSource* source) {
-  return GetSourceBySsrc(video_, ssrc, source);
-}
-
-void MediaSources::AddAudioSource(const NamedSource& source) {
-  AddSource(&audio_, source);
-}
-
-void MediaSources::AddVideoSource(const NamedSource& source) {
-  AddSource(&video_, source);
-}
-
-void MediaSources::RemoveAudioSourceBySsrc(uint32 ssrc) {
-  RemoveSourceBySsrc(ssrc, &audio_);
-}
-
-void MediaSources::RemoveVideoSourceBySsrc(uint32 ssrc) {
-  RemoveSourceBySsrc(ssrc, &video_);
-}
-
-bool IsJingleViewRequest(const XmlElements& action_elems) {
-  return GetXmlElement(action_elems, QN_JINGLE_DRAFT_VIEW) != NULL;
-}
-
-bool ParseStaticVideoView(const buzz::XmlElement* view_elem,
-                          StaticVideoView* view,
-                          ParseError* error) {
-  if (!ParseSsrc(view_elem->Attr(QN_SSRC), &(view->ssrc))) {
-    return BadParse("Invalid or missing view ssrc.", error);
-  }
-
-  const buzz::XmlElement* params_elem =
-      view_elem->FirstNamed(QN_JINGLE_DRAFT_PARAMS);
-  if (params_elem) {
-    view->width = GetXmlAttr(params_elem, QN_WIDTH, 0);
-    view->height = GetXmlAttr(params_elem, QN_HEIGHT, 0);
-    view->framerate = GetXmlAttr(params_elem, QN_FRAMERATE, 0);
-    view->preference = GetXmlAttr(params_elem, QN_PREFERENCE, 0);
-  } else {
-    return BadParse("Missing view params.", error);
-  }
-
-  return true;
-}
-
-bool ParseJingleViewRequest(const XmlElements& action_elems,
-                            ViewRequest* view_request,
-                            ParseError* error) {
-  for (XmlElements::const_iterator iter = action_elems.begin();
-       iter != action_elems.end(); ++iter) {
-    const buzz::XmlElement* view_elem = *iter;
-    if (view_elem->Name() == QN_JINGLE_DRAFT_VIEW) {
-      std::string type = view_elem->Attr(QN_TYPE);
-      if (STR_JINGLE_DRAFT_VIEW_TYPE_NONE == type) {
-        view_request->static_video_views.clear();
-        return true;
-      } else if (STR_JINGLE_DRAFT_VIEW_TYPE_STATIC == type) {
-        StaticVideoView static_video_view(0, 0, 0, 0);
-        if (!ParseStaticVideoView(view_elem, &static_video_view, error)) {
-          return false;
-        }
-        view_request->static_video_views.push_back(static_video_view);
-      } else {
-        LOG(LS_INFO) << "Ingnoring unknown view type: " << type;
-      }
-    }
-  }
-  return true;
-}
-
-bool WriteJingleViewRequest(const std::string& content_name,
-                            const ViewRequest& request,
-                            XmlElements* elems,
-                            WriteError* error) {
-  if (request.static_video_views.empty()) {
-    elems->push_back(CreateNoneVideoViewElem(content_name));
-  } else {
-    for (StaticVideoViews::const_iterator view =
-             request.static_video_views.begin();
-         view != request.static_video_views.end(); ++view) {
-      elems->push_back(CreateStaticVideoViewElem(content_name, *view));
-    }
-  }
-  return true;
-}
-
-bool IsSourcesNotify(const buzz::XmlElement* action_elem) {
-  return action_elem->FirstNamed(QN_JINGLE_LEGACY_NOTIFY) != NULL;
-}
-
-bool ParseSourcesNotify(const buzz::XmlElement* action_elem,
-                        const SessionDescription* session_description,
-                        MediaSources* sources,
-                        ParseError* error) {
-  for (const buzz::XmlElement* notify_elem =
-           action_elem->FirstNamed(QN_JINGLE_LEGACY_NOTIFY);
-       notify_elem != NULL;
-       notify_elem = notify_elem->NextNamed(QN_JINGLE_LEGACY_NOTIFY)) {
-    std::string content_name = notify_elem->Attr(QN_NAME);
-    for (const buzz::XmlElement* source_elem =
-             notify_elem->FirstNamed(QN_JINGLE_LEGACY_SOURCE);
-         source_elem != NULL;
-         source_elem = source_elem->NextNamed(QN_JINGLE_LEGACY_SOURCE)) {
-      NamedSource named_source;
-      if (!ParseNamedSource(source_elem, &named_source, error)) {
-        return false;
-      }
-
-      if (session_description == NULL) {
-        return BadParse("Unknown content name: " + content_name, error);
-      }
-      const ContentInfo* content =
-          FindContentInfoByName(session_description->contents(), content_name);
-      if (content == NULL) {
-        return BadParse("Unknown content name: " + content_name, error);
-      }
-
-      if (IsAudioContent(content)) {
-        sources->mutable_audio()->push_back(named_source);
-      } else if (IsVideoContent(content)) {
-        sources->mutable_video()->push_back(named_source);
-      }
-    }
-  }
-
-  return true;
-}
-
-bool ParseSsrcAsLegacyStream(const buzz::XmlElement* desc_elem,
-                             std::vector<StreamParams>* streams,
-                             ParseError* error) {
-  const std::string ssrc_str = desc_elem->Attr(QN_SSRC);
-  if (!ssrc_str.empty()) {
-    uint32 ssrc;
-    if (!ParseSsrc(ssrc_str, &ssrc)) {
-      return BadParse("Missing or invalid ssrc.", error);
-    }
-
-    streams->push_back(StreamParams::CreateLegacy(ssrc));
-  }
-  return true;
-}
-
-bool ParseSsrcs(const buzz::XmlElement* parent_elem,
-                std::vector<uint32>* ssrcs,
-                ParseError* error) {
-  for (const buzz::XmlElement* ssrc_elem =
-           parent_elem->FirstNamed(QN_JINGLE_DRAFT_SSRC);
-       ssrc_elem != NULL;
-       ssrc_elem = ssrc_elem->NextNamed(QN_JINGLE_DRAFT_SSRC)) {
-    uint32 ssrc;
-    if (!ParseSsrc(ssrc_elem->BodyText(), &ssrc)) {
-      return BadParse("Missing or invalid ssrc.", error);
-    }
-
-    ssrcs->push_back(ssrc);
-  }
-  return true;
-}
-
-bool ParseSsrcGroups(const buzz::XmlElement* parent_elem,
-                     std::vector<SsrcGroup>* ssrc_groups,
-                     ParseError* error) {
-  for (const buzz::XmlElement* group_elem =
-           parent_elem->FirstNamed(QN_JINGLE_DRAFT_SSRC_GROUP);
-       group_elem != NULL;
-       group_elem = group_elem->NextNamed(QN_JINGLE_DRAFT_SSRC_GROUP)) {
-    std::string semantics = group_elem->Attr(QN_SEMANTICS);
-    std::vector<uint32> ssrcs;
-    if (!ParseSsrcs(group_elem, &ssrcs, error)) {
-      return false;
-    }
-    ssrc_groups->push_back(SsrcGroup(semantics, ssrcs));
-  }
-  return true;
-}
-
-bool ParseJingleStream(const buzz::XmlElement* stream_elem,
-                       std::vector<StreamParams>* streams,
-                       ParseError* error) {
-  StreamParams stream;
-  stream.nick = stream_elem->Attr(QN_NICK);
-  stream.name = stream_elem->Attr(QN_NAME);
-  stream.type = stream_elem->Attr(QN_TYPE);
-  stream.display = stream_elem->Attr(QN_DISPLAY);
-  stream.cname = stream_elem->Attr(QN_CNAME);
-  if (!ParseSsrcs(stream_elem, &(stream.ssrcs), error)) {
-    return false;
-  }
-  std::vector<SsrcGroup> ssrc_groups;
-  if (!ParseSsrcGroups(stream_elem, &(stream.ssrc_groups), error)) {
-    return false;
-  }
-  streams->push_back(stream);
-  return true;
-}
-
-bool HasJingleStreams(const buzz::XmlElement* desc_elem) {
-  const buzz::XmlElement* streams_elem =
-      desc_elem->FirstNamed(QN_JINGLE_DRAFT_STREAMS);
-  return (streams_elem != NULL);
-}
-
-bool ParseJingleStreams(const buzz::XmlElement* desc_elem,
-                        std::vector<StreamParams>* streams,
-                        ParseError* error) {
-  const buzz::XmlElement* streams_elem =
-      desc_elem->FirstNamed(QN_JINGLE_DRAFT_STREAMS);
-  if (streams_elem == NULL) {
-    return BadParse("Missing streams element.", error);
-  }
-  for (const buzz::XmlElement* stream_elem =
-           streams_elem->FirstNamed(QN_JINGLE_DRAFT_STREAM);
-       stream_elem != NULL;
-       stream_elem = stream_elem->NextNamed(QN_JINGLE_DRAFT_STREAM)) {
-    if (!ParseJingleStream(stream_elem, streams, error)) {
-      return false;
-    }
-  }
-  return true;
-}
-
-void WriteSsrcs(const std::vector<uint32>& ssrcs,
-                buzz::XmlElement* parent_elem) {
-  for (std::vector<uint32>::const_iterator ssrc = ssrcs.begin();
-       ssrc != ssrcs.end(); ++ssrc) {
-    buzz::XmlElement* ssrc_elem =
-        new buzz::XmlElement(QN_JINGLE_DRAFT_SSRC, false);
-    SetXmlBody(ssrc_elem, *ssrc);
-
-    parent_elem->AddElement(ssrc_elem);
-  }
-}
-
-void WriteSsrcGroups(const std::vector<SsrcGroup>& groups,
-                     buzz::XmlElement* parent_elem) {
-  for (std::vector<SsrcGroup>::const_iterator group = groups.begin();
-       group != groups.end(); ++group) {
-    buzz::XmlElement* group_elem =
-        new buzz::XmlElement(QN_JINGLE_DRAFT_SSRC_GROUP, false);
-    AddXmlAttrIfNonEmpty(group_elem, QN_SEMANTICS, group->semantics);
-    WriteSsrcs(group->ssrcs, group_elem);
-
-    parent_elem->AddElement(group_elem);
-  }
-}
-
-void WriteJingleStream(const StreamParams& stream,
-                       buzz::XmlElement* parent_elem) {
-  buzz::XmlElement* stream_elem =
-      new buzz::XmlElement(QN_JINGLE_DRAFT_STREAM, false);
-  AddXmlAttrIfNonEmpty(stream_elem, QN_NICK, stream.nick);
-  AddXmlAttrIfNonEmpty(stream_elem, QN_NAME, stream.name);
-  AddXmlAttrIfNonEmpty(stream_elem, QN_TYPE, stream.type);
-  AddXmlAttrIfNonEmpty(stream_elem, QN_DISPLAY, stream.display);
-  AddXmlAttrIfNonEmpty(stream_elem, QN_CNAME, stream.cname);
-  WriteSsrcs(stream.ssrcs, stream_elem);
-  WriteSsrcGroups(stream.ssrc_groups, stream_elem);
-
-  parent_elem->AddElement(stream_elem);
-}
-
-void WriteJingleStreams(const std::vector<StreamParams>& streams,
-                        buzz::XmlElement* parent_elem) {
-  buzz::XmlElement* streams_elem =
-      new buzz::XmlElement(QN_JINGLE_DRAFT_STREAMS, true);
-  for (std::vector<StreamParams>::const_iterator stream = streams.begin();
-       stream != streams.end(); ++stream) {
-    WriteJingleStream(*stream, streams_elem);
-  }
-
-  parent_elem->AddElement(streams_elem);
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/session/phone/mediamessages.h b/third_party/libjingle/source/talk/session/phone/mediamessages.h
deleted file mode 100644
index 11b9e89..0000000
--- a/third_party/libjingle/source/talk/session/phone/mediamessages.h
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * libjingle
- * Copyright 2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * A collection of functions and types for serializing and
- * deserializing Jingle session messages related to media.
- * Specificially, the <notify> and <view> messages.  They are not yet
- * standardized, but their current documentation can be found at:
- * goto/jinglemuc
- */
-
-#ifndef TALK_SESSION_PHONE_MEDIAMESSAGES_H_
-#define TALK_SESSION_PHONE_MEDIAMESSAGES_H_
-
-#include <string>
-#include <vector>
-
-#include "talk/base/basictypes.h"
-#include "talk/p2p/base/parsing.h"
-#include "talk/p2p/base/sessiondescription.h"
-
-namespace cricket {
-
-struct StreamParams;
-
-// In a <notify> message, there are number of sources with names.
-// This represents one such named source.
-struct NamedSource {
-  NamedSource() : ssrc(0), ssrc_set(false), removed(false) {}
-
-  void SetSsrc(uint32 ssrc) {
-    this->ssrc = ssrc;
-    this->ssrc_set = true;
-  }
-
-  std::string nick;
-  std::string name;
-  uint32 ssrc;
-  bool ssrc_set;
-  bool removed;
-};
-
-// TODO: Remove this, according to c++ readability.
-typedef std::vector<NamedSource> NamedSources;
-
-// A collection of named audio sources and named video sources, as
-// would be found in a typical <notify> message.  Most of the methods
-// are merely for convenience. Many of these methods are keyed by
-// ssrc, which is the source identifier in the RTP spec
-// (http://tools.ietf.org/html/rfc3550).
-struct MediaSources {
- public:
-  MediaSources() {}
-  void CopyFrom(const MediaSources& sources);
-
-  NamedSources* mutable_audio() { return &audio_; }
-  NamedSources* mutable_video() { return &video_; }
-  const NamedSources& audio() const { return audio_; }
-  const NamedSources& video() const { return video_; }
-
-  // Get the source with the given ssrc.  Returns true if found.
-  bool GetAudioSourceBySsrc(uint32 ssrc, NamedSource* source);
-  bool GetVideoSourceBySsrc(uint32 ssrc, NamedSource* source);
-  // Get the first source with the given nick.  Returns true if found.
-  // TODO: Remove the following two methods once all
-  // senders use explicit-remove by ssrc.
-  bool GetFirstAudioSourceByNick(const std::string& nick, NamedSource* source);
-  bool GetFirstVideoSourceByNick(const std::string& nick, NamedSource* source);
-  // Add a source.
-  void AddAudioSource(const NamedSource& source);
-  void AddVideoSource(const NamedSource& source);
-  // Remove the source with the given ssrc.
-  void RemoveAudioSourceBySsrc(uint32 ssrc);
-  void RemoveVideoSourceBySsrc(uint32 ssrc);
-
- private:
-  NamedSources audio_;
-  NamedSources video_;
-
-  DISALLOW_COPY_AND_ASSIGN(MediaSources);
-};
-
-// In a <view> message, there are a number of views specified.  This
-// represents one such view.  We currently only support "static"
-// views.
-struct StaticVideoView {
-  StaticVideoView(uint32 ssrc, int width, int height, int framerate)
-      : ssrc(ssrc),
-        width(width),
-        height(height),
-        framerate(framerate),
-        preference(0) {}
-
-  uint32 ssrc;
-  int width;
-  int height;
-  int framerate;
-  int preference;
-};
-
-typedef std::vector<StaticVideoView> StaticVideoViews;
-
-// Represents a whole view request message, which contains many views.
-struct ViewRequest {
-  StaticVideoViews static_video_views;
-};
-
-// If the elems of a parent (usually <jingle>) constitute a view request.
-bool IsJingleViewRequest(const XmlElements& elems);
-
-// Parses a view request from jingle contents (<view>s).  If it
-// fails, returns false and fills an error message.
-bool ParseJingleViewRequest(const XmlElements& elems,
-                            ViewRequest* view_request,
-                            ParseError* error);
-
-// Serializes a view request to XML.  If it fails, returns false and
-// fills in an error message.
-bool WriteJingleViewRequest(const std::string& content_name,
-                            const ViewRequest& view,
-                            XmlElements* elems,
-                            WriteError* error);
-
-// TODO: Get rid of legacy source notify and replace with
-// description-info as soon as reflector is capable of sending it.
-bool IsSourcesNotify(const buzz::XmlElement* action_elem);
-
-// Parses a notify message from XML.  If it fails, returns false and
-// fills in an error message.
-// The session_description is needed to map content_name => media type.
-bool ParseSourcesNotify(const buzz::XmlElement* action_elem,
-                        const SessionDescription* session_description,
-                        MediaSources* sources,
-                        ParseError* error);
-
-// If the given elem has <streams>.
-bool HasJingleStreams(const buzz::XmlElement* desc_elem);
-
-// Parses streams from a jingle <description>.  If it fails, returns
-// false and fills an error message.
-bool ParseJingleStreams(const buzz::XmlElement* desc_elem,
-                        std::vector<StreamParams>* streams,
-                        ParseError* error);
-
-// Write a <streams> element to the parent_elem.
-void WriteJingleStreams(const std::vector<StreamParams>& streams,
-                        buzz::XmlElement* parent_elem);
-
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_MEDIAMESSAGES_H_
diff --git a/third_party/libjingle/source/talk/session/phone/mediamessages_unittest.cc b/third_party/libjingle/source/talk/session/phone/mediamessages_unittest.cc
deleted file mode 100644
index 0290c02..0000000
--- a/third_party/libjingle/source/talk/session/phone/mediamessages_unittest.cc
+++ /dev/null
@@ -1,441 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/session/phone/mediamessages.h"
-
-#include <string>
-#include <vector>
-
-#include "talk/base/gunit.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/p2p/base/constants.h"
-#include "talk/session/phone/mediasessionclient.h"
-#include "talk/xmllite/xmlelement.h"
-
-// Unit tests for mediamessages.cc.
-
-namespace cricket {
-
-namespace {
-
-static const char kViewVideoNoneXml[] =
-    "<view xmlns='google:jingle'"
-    "  name='video1'"
-    "  type='none'"
-    "/>";
-
-static const char kNotifyEmptyXml[] =
-    "<notify xmlns='google:jingle'"
-    "  name='video1'"
-    "/>";
-
-class MediaMessagesTest : public testing::Test {
- public:
-  // CreateMediaSessionDescription uses a static variable cricket::NS_JINGLE_RTP
-  // defined in another file and cannot be used to initialize another static
-  // variable (http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.14)
-  MediaMessagesTest()
-      : remote_description_(CreateMediaSessionDescription("audio1", "video1")) {
-  }
-
- protected:
-  static std::string ViewVideoStaticVgaXml(const std::string& ssrc) {
-      return "<view xmlns='google:jingle'"
-             "  name='video1'"
-             "  type='static'"
-             "  ssrc='" + ssrc + "'"
-             ">"
-             "<params"
-             "    width='640'"
-             "    height='480'"
-             "    framerate='30'"
-             "    preference='0'"
-             "  />"
-             "</view>";
-  }
-
-  static std::string NotifyAddXml(const std::string& content_name,
-                                  const std::string& nick,
-                                  const std::string& name,
-                                  const std::string& ssrc) {
-    return "<notify xmlns='google:jingle'"
-           "  name='" + content_name + "'"
-           ">"
-           "  <source"
-           "    nick='" + nick + "'"
-           "    name='" + name + "'"
-           "  >"
-           "    <ssrc>" + ssrc + "</ssrc>"
-           "  </source>"
-           "</notify>";
-  }
-
-  static std::string NotifyTwoSourceXml(const std::string& name,
-                                        const std::string& nick1,
-                                        const std::string& ssrc1,
-                                        const std::string& nick2,
-                                        const std::string& ssrc2) {
-    return "<notify xmlns='google:jingle'"
-           "  name='" + name + "'"
-           ">"
-           "  <source"
-           "    nick='" + nick1 + "'"
-           "  >"
-           "    <ssrc>" + ssrc1 + "</ssrc>"
-           "  </source>"
-           "  <source"
-           "    nick='" + nick2 + "'"
-           "  >"
-           "    <ssrc>" + ssrc2 + "</ssrc>"
-           "  </source>"
-           "</notify>";
-  }
-
-  static std::string NotifyImplicitRemoveXml(const std::string& content_name,
-                                             const std::string& nick) {
-    return "<notify xmlns='google:jingle'"
-           "  name='" + content_name + "'"
-           ">"
-           "  <source"
-           "    nick='" + nick + "'"
-           "  >"
-           "  </source>"
-           "</notify>";
-  }
-
-  static cricket::StreamParams CreateStream(const std::string& nick,
-                                            const std::string& name,
-                                            uint32 ssrc1,
-                                            uint32 ssrc2,
-                                            const std::string& semantics,
-                                            const std::string& type,
-                                            const std::string& display) {
-    StreamParams stream;
-    stream.nick = nick;
-    stream.name = name;
-    stream.ssrcs.push_back(ssrc1);
-    stream.ssrcs.push_back(ssrc2);
-    stream.ssrc_groups.push_back(
-        cricket::SsrcGroup(semantics, stream.ssrcs));
-    stream.type = type;
-    stream.display = display;
-    return stream;
-  }
-
-  static std::string StreamsXml(const std::string& stream1,
-                               const std::string& stream2) {
-    return "<streams xmlns='google:jingle'>"
-           + stream1
-           + stream2 +
-           "</streams>";
-  }
-
-
-  static std::string StreamXml(const std::string& nick,
-                               const std::string& name,
-                               const std::string& ssrc1,
-                               const std::string& ssrc2,
-                               const std::string& semantics,
-                               const std::string& type,
-                               const std::string& display) {
-    return "<stream"
-           " nick='" + nick + "'"
-           " name='" + name + "'"
-           " type='" + type + "'"
-           " display='" + display + "'"
-           ">"
-           "<ssrc>" + ssrc1 + "</ssrc>"
-           "<ssrc>" + ssrc2 + "</ssrc>"
-           "<ssrc-group"
-           "  semantics='" + semantics + "'"
-           ">"
-           "<ssrc>" + ssrc1 + "</ssrc>"
-           "<ssrc>" + ssrc2 + "</ssrc>"
-           "</ssrc-group>"
-           "</stream>";
-  }
-
-  static cricket::SessionDescription* CreateMediaSessionDescription(
-      const std::string& audio_content_name,
-      const std::string& video_content_name) {
-    cricket::SessionDescription* desc = new cricket::SessionDescription();
-    desc->AddContent(audio_content_name, cricket::NS_JINGLE_RTP,
-                     new cricket::AudioContentDescription());
-    desc->AddContent(video_content_name, cricket::NS_JINGLE_RTP,
-                     new cricket::VideoContentDescription());
-    return desc;
-  }
-
-  talk_base::scoped_ptr<cricket::SessionDescription> remote_description_;
-};
-
-}  // anonymous namespace
-
-// Test serializing/deserializing an empty <view> message.
-TEST_F(MediaMessagesTest, ViewNoneToFromXml) {
-  talk_base::scoped_ptr<buzz::XmlElement> expected_view_elem(
-      buzz::XmlElement::ForStr(kViewVideoNoneXml));
-
-  cricket::ViewRequest view_request;
-  cricket::XmlElements actual_view_elems;
-  cricket::WriteError error;
-
-  EXPECT_FALSE(cricket::IsJingleViewRequest(actual_view_elems));
-  ASSERT_TRUE(cricket::WriteJingleViewRequest(
-      "video1", view_request, &actual_view_elems, &error));
-
-  ASSERT_EQ(1U, actual_view_elems.size());
-  EXPECT_EQ(expected_view_elem->Str(), actual_view_elems[0]->Str());
-
-  cricket::ParseError parse_error;
-  EXPECT_TRUE(cricket::IsJingleViewRequest(actual_view_elems));
-  ASSERT_TRUE(cricket::ParseJingleViewRequest(
-      actual_view_elems, &view_request, &parse_error));
-  EXPECT_EQ(0U, view_request.static_video_views.size());
-}
-
-// Test serializing/deserializing an a simple vga <view> message.
-TEST_F(MediaMessagesTest, ViewVgaToFromXml) {
-  talk_base::scoped_ptr<buzz::XmlElement> expected_view_elem1(
-      buzz::XmlElement::ForStr(ViewVideoStaticVgaXml("1234")));
-  talk_base::scoped_ptr<buzz::XmlElement> expected_view_elem2(
-      buzz::XmlElement::ForStr(ViewVideoStaticVgaXml("2468")));
-
-  cricket::ViewRequest view_request;
-  cricket::XmlElements actual_view_elems;
-  cricket::WriteError error;
-
-  view_request.static_video_views.push_back(
-      cricket::StaticVideoView(1234, 640, 480, 30));
-  view_request.static_video_views.push_back(
-      cricket::StaticVideoView(2468, 640, 480, 30));
-
-  ASSERT_TRUE(cricket::WriteJingleViewRequest(
-      "video1", view_request, &actual_view_elems, &error));
-
-  ASSERT_EQ(2U, actual_view_elems.size());
-  EXPECT_EQ(expected_view_elem1->Str(), actual_view_elems[0]->Str());
-  EXPECT_EQ(expected_view_elem2->Str(), actual_view_elems[1]->Str());
-
-  view_request.static_video_views.clear();
-  cricket::ParseError parse_error;
-  EXPECT_TRUE(cricket::IsJingleViewRequest(actual_view_elems));
-  ASSERT_TRUE(cricket::ParseJingleViewRequest(
-      actual_view_elems, &view_request, &parse_error));
-  EXPECT_EQ(2U, view_request.static_video_views.size());
-  EXPECT_EQ(1234U, view_request.static_video_views[0].ssrc);
-  EXPECT_EQ(640, view_request.static_video_views[0].width);
-  EXPECT_EQ(480, view_request.static_video_views[0].height);
-  EXPECT_EQ(30, view_request.static_video_views[0].framerate);
-  EXPECT_EQ(2468U, view_request.static_video_views[1].ssrc);
-}
-
-// Test deserializing bad view XML.
-TEST_F(MediaMessagesTest, ParseBadViewXml) {
-  talk_base::scoped_ptr<buzz::XmlElement> view_elem(
-      buzz::XmlElement::ForStr(ViewVideoStaticVgaXml("not-an-ssrc")));
-  XmlElements view_elems;
-  view_elems.push_back(view_elem.get());
-
-  cricket::ViewRequest view_request;
-  cricket::ParseError parse_error;
-  ASSERT_FALSE(cricket::ParseJingleViewRequest(
-      view_elems, &view_request, &parse_error));
-}
-
-// Test serializing/deserializing an empty session-info message.
-TEST_F(MediaMessagesTest, NotifyFromEmptyXml) {
-  talk_base::scoped_ptr<buzz::XmlElement> action_elem(
-      new buzz::XmlElement(cricket::QN_JINGLE));
-  EXPECT_FALSE(cricket::IsSourcesNotify(action_elem.get()));
-}
-
-// Test serializing/deserializing an empty <notify> message.
-TEST_F(MediaMessagesTest, NotifyEmptyFromXml) {
-  talk_base::scoped_ptr<buzz::XmlElement> action_elem(
-      new buzz::XmlElement(cricket::QN_JINGLE));
-  action_elem->AddElement(
-      buzz::XmlElement::ForStr(kNotifyEmptyXml));
-
-  cricket::MediaSources sources;
-  cricket::ParseError error;
-
-  EXPECT_TRUE(cricket::IsSourcesNotify(action_elem.get()));
-  ASSERT_TRUE(cricket::ParseSourcesNotify(action_elem.get(),
-                                          remote_description_.get(),
-                                          &sources, &error));
-
-  EXPECT_EQ(0U, sources.audio().size());
-  EXPECT_EQ(0U, sources.video().size());
-}
-
-// Test serializing/deserializing a complex <notify> message.
-TEST_F(MediaMessagesTest, NotifyFromXml) {
-  talk_base::scoped_ptr<buzz::XmlElement> action_elem(
-      new buzz::XmlElement(cricket::QN_JINGLE));
-  action_elem->AddElement(
-      buzz::XmlElement::ForStr(NotifyAddXml(
-          "video1", "Joe", "Facetime", "1234")));
-  action_elem->AddElement(
-      buzz::XmlElement::ForStr(NotifyAddXml(
-          "video1", "Bob", "Microsoft Word", "2468")));
-  action_elem->AddElement(
-      buzz::XmlElement::ForStr(NotifyAddXml(
-          "video1", "Bob", "", "3692")));
-  action_elem->AddElement(
-      buzz::XmlElement::ForStr(NotifyImplicitRemoveXml(
-          "audio1", "Joe")));
-  action_elem->AddElement(
-      buzz::XmlElement::ForStr(NotifyAddXml(
-          "audio1", "Bob", "", "3692")));
-  action_elem->AddElement(
-      buzz::XmlElement::ForStr(NotifyTwoSourceXml(
-          "video1", "Joe", "1234", "Bob", "2468")));
-
-  cricket::MediaSources sources;
-  cricket::ParseError error;
-
-  EXPECT_TRUE(cricket::IsSourcesNotify(action_elem.get()));
-  ASSERT_TRUE(cricket::ParseSourcesNotify(action_elem.get(),
-                                          remote_description_.get(),
-                                          &sources, &error));
-
-  ASSERT_EQ(5U, sources.video().size());
-  ASSERT_EQ(2U, sources.audio().size());
-
-  EXPECT_EQ("Joe", sources.video()[0].nick);
-  EXPECT_EQ("Facetime", sources.video()[0].name);
-  EXPECT_EQ(1234U, sources.video()[0].ssrc);
-  EXPECT_TRUE(sources.video()[0].ssrc_set);
-  EXPECT_FALSE(sources.video()[0].removed);
-
-  EXPECT_EQ("Bob", sources.video()[1].nick);
-  EXPECT_EQ("Microsoft Word", sources.video()[1].name);
-  EXPECT_EQ(2468U, sources.video()[1].ssrc);
-  EXPECT_TRUE(sources.video()[1].ssrc_set);
-  EXPECT_FALSE(sources.video()[0].removed);
-
-  EXPECT_EQ("Bob", sources.video()[2].nick);
-  EXPECT_EQ(3692U, sources.video()[2].ssrc);
-  EXPECT_TRUE(sources.video()[2].ssrc_set);
-  EXPECT_EQ("", sources.video()[2].name);
-  EXPECT_FALSE(sources.video()[0].removed);
-
-  EXPECT_EQ("Joe", sources.video()[3].nick);
-  EXPECT_EQ(1234U, sources.video()[3].ssrc);
-
-  EXPECT_EQ("Bob", sources.video()[4].nick);
-  EXPECT_EQ(2468U, sources.video()[4].ssrc);
-
-  EXPECT_EQ("Joe", sources.audio()[0].nick);
-  EXPECT_FALSE(sources.audio()[0].ssrc_set);
-  EXPECT_FALSE(sources.video()[0].removed);
-}
-
-// Test serializing/deserializing a malformed <notify> message.
-TEST_F(MediaMessagesTest, NotifyFromBadXml) {
-  MediaSources sources;
-  ParseError error;
-
-  // Bad ssrc
-  talk_base::scoped_ptr<buzz::XmlElement> action_elem(
-      new buzz::XmlElement(cricket::QN_JINGLE));
-  action_elem->AddElement(
-      buzz::XmlElement::ForStr(NotifyAddXml("video1", "Joe", "", "XYZ")));
-  EXPECT_TRUE(cricket::IsSourcesNotify(action_elem.get()));
-  EXPECT_FALSE(cricket::ParseSourcesNotify(
-      action_elem.get(), remote_description_.get(), &sources, &error));
-
-  // Bad nick
-  action_elem.reset(new buzz::XmlElement(cricket::QN_JINGLE));
-  action_elem->AddElement(
-      buzz::XmlElement::ForStr(NotifyAddXml("video1", "", "", "1234")));
-  EXPECT_TRUE(cricket::IsSourcesNotify(action_elem.get()));
-  EXPECT_FALSE(cricket::ParseSourcesNotify(
-      action_elem.get(), remote_description_.get(), &sources, &error));
-}
-
-// Test serializing/deserializing typical streams xml.
-TEST_F(MediaMessagesTest, StreamsToFromXml) {
-  talk_base::scoped_ptr<buzz::XmlElement> expected_streams_elem(
-      buzz::XmlElement::ForStr(
-          StreamsXml(
-              StreamXml("nick1", "name1", "101", "102",
-                        "semantics1", "type1", "display1"),
-              StreamXml("nick2", "name2", "201", "202",
-                        "semantics2", "type2", "display2"))));
-
-  std::vector<cricket::StreamParams> expected_streams;
-  expected_streams.push_back(CreateStream("nick1", "name1", 101U, 102U,
-                                          "semantics1", "type1", "display1"));
-  expected_streams.push_back(CreateStream("nick2", "name2", 201U, 202U,
-                                          "semantics2", "type2", "display2"));
-
-  talk_base::scoped_ptr<buzz::XmlElement> actual_desc_elem(
-      new buzz::XmlElement(QN_JINGLE_RTP_CONTENT));
-  cricket::WriteJingleStreams(expected_streams, actual_desc_elem.get());
-
-  const buzz::XmlElement* actual_streams_elem =
-      actual_desc_elem->FirstNamed(QN_JINGLE_DRAFT_STREAMS);
-  ASSERT_TRUE(actual_streams_elem != NULL);
-  EXPECT_EQ(expected_streams_elem->Str(), actual_streams_elem->Str());
-
-  talk_base::scoped_ptr<buzz::XmlElement> expected_desc_elem(
-      new buzz::XmlElement(QN_JINGLE_RTP_CONTENT));
-  expected_desc_elem->AddElement(new buzz::XmlElement(
-      *expected_streams_elem));
-  std::vector<cricket::StreamParams> actual_streams;
-  cricket::ParseError parse_error;
-
-  EXPECT_TRUE(cricket::HasJingleStreams(expected_desc_elem.get()));
-  ASSERT_TRUE(cricket::ParseJingleStreams(
-      expected_desc_elem.get(), &actual_streams, &parse_error));
-  EXPECT_EQ(2U, actual_streams.size());
-  EXPECT_EQ(expected_streams[0], actual_streams[0]);
-  EXPECT_EQ(expected_streams[1], actual_streams[1]);
-}
-
-// Test deserializing bad streams xml.
-TEST_F(MediaMessagesTest, StreamsFromBadXml) {
-  talk_base::scoped_ptr<buzz::XmlElement> streams_elem(
-      buzz::XmlElement::ForStr(
-          StreamsXml(
-              StreamXml("nick1", "name1", "101", "not-an-ssrc",
-                        "semantics1", "type1", "display1"),
-              StreamXml("nick2", "name2", "202", "not-an-ssrc",
-                        "semantics2", "type2", "display2"))));
-  talk_base::scoped_ptr<buzz::XmlElement> desc_elem(
-      new buzz::XmlElement(QN_JINGLE_RTP_CONTENT));
-  desc_elem->AddElement(new buzz::XmlElement(*streams_elem));
-
-  std::vector<cricket::StreamParams> actual_streams;
-  cricket::ParseError parse_error;
-  ASSERT_FALSE(cricket::ParseJingleStreams(
-      desc_elem.get(), &actual_streams, &parse_error));
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/session/phone/mediamonitor.cc b/third_party/libjingle/source/talk/session/phone/mediamonitor.cc
deleted file mode 100644
index 0160077..0000000
--- a/third_party/libjingle/source/talk/session/phone/mediamonitor.cc
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * libjingle
- * Copyright 2005--2007, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/common.h"
-#include "talk/session/phone/mediamonitor.h"
-#include "talk/session/phone/channelmanager.h"
-
-namespace cricket {
-
-enum {
-  MSG_MONITOR_POLL = 1,
-  MSG_MONITOR_START = 2,
-  MSG_MONITOR_STOP = 3,
-  MSG_MONITOR_SIGNAL = 4
-};
-
-MediaMonitor::MediaMonitor(talk_base::Thread* worker_thread,
-                           talk_base::Thread* monitor_thread)
-    : worker_thread_(worker_thread),
-      monitor_thread_(monitor_thread), monitoring_(false), rate_(0) {
-}
-
-MediaMonitor::~MediaMonitor() {
-  monitoring_ = false;
-  monitor_thread_->Clear(this);
-  worker_thread_->Clear(this);
-}
-
-void MediaMonitor::Start(uint32 milliseconds) {
-  rate_ = milliseconds;
-  if (rate_ < 100)
-    rate_ = 100;
-  worker_thread_->Post(this, MSG_MONITOR_START);
-}
-
-void MediaMonitor::Stop() {
-  worker_thread_->Post(this, MSG_MONITOR_STOP);
-  rate_ = 0;
-}
-
-void MediaMonitor::OnMessage(talk_base::Message* message) {
-  talk_base::CritScope cs(&crit_);
-
-  switch (message->message_id) {
-  case MSG_MONITOR_START:
-    ASSERT(talk_base::Thread::Current() == worker_thread_);
-    if (!monitoring_) {
-      monitoring_ = true;
-      PollMediaChannel();
-    }
-    break;
-
-  case MSG_MONITOR_STOP:
-    ASSERT(talk_base::Thread::Current() == worker_thread_);
-    if (monitoring_) {
-      monitoring_ = false;
-      worker_thread_->Clear(this);
-    }
-    break;
-
-  case MSG_MONITOR_POLL:
-    ASSERT(talk_base::Thread::Current() == worker_thread_);
-    PollMediaChannel();
-    break;
-
-  case MSG_MONITOR_SIGNAL:
-    ASSERT(talk_base::Thread::Current() == monitor_thread_);
-    Update();
-    break;
-  }
-}
-
-void MediaMonitor::PollMediaChannel() {
-  talk_base::CritScope cs(&crit_);
-  ASSERT(talk_base::Thread::Current() == worker_thread_);
-
-  GetStats();
-
-  // Signal the monitoring thread, start another poll timer
-  monitor_thread_->Post(this, MSG_MONITOR_SIGNAL);
-  worker_thread_->PostDelayed(rate_, this, MSG_MONITOR_POLL);
-}
-
-}
diff --git a/third_party/libjingle/source/talk/session/phone/mediamonitor.h b/third_party/libjingle/source/talk/session/phone/mediamonitor.h
deleted file mode 100644
index 6b964aa..0000000
--- a/third_party/libjingle/source/talk/session/phone/mediamonitor.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * libjingle
- * Copyright 2005--2008, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// Class to collect statistics from a media channel
-
-#ifndef TALK_SESSION_PHONE_MEDIAMONITOR_H_
-#define TALK_SESSION_PHONE_MEDIAMONITOR_H_
-
-#include "talk/base/thread.h"
-#include "talk/base/sigslot.h"
-#include "talk/base/criticalsection.h"
-#include "talk/session/phone/mediachannel.h"
-
-namespace cricket {
-
-// The base MediaMonitor class, independent of voice and video.
-class MediaMonitor : public talk_base::MessageHandler,
-    public sigslot::has_slots<> {
- public:
-  MediaMonitor(talk_base::Thread* worker_thread,
-               talk_base::Thread* monitor_thread);
-  ~MediaMonitor();
-
-  void Start(uint32 milliseconds);
-  void Stop();
-
- protected:
-  void OnMessage(talk_base::Message *message);
-  void PollMediaChannel();
-  virtual void GetStats() = 0;
-  virtual void Update() = 0;
-
-  talk_base::CriticalSection crit_;
-  talk_base::Thread* worker_thread_;
-  talk_base::Thread* monitor_thread_;
-  bool monitoring_;
-  uint32 rate_;
-};
-
-// Templatized MediaMonitor that can deal with different kinds of media.
-template<class MC, class MI>
-class MediaMonitorT : public MediaMonitor {
- public:
-  MediaMonitorT(MC* media_channel, talk_base::Thread* worker_thread,
-                talk_base::Thread* monitor_thread)
-      : MediaMonitor(worker_thread, monitor_thread),
-        media_channel_(media_channel) {}
-  sigslot::signal2<MC*, const MI&> SignalUpdate;
-
- protected:
-  // These routines assume the crit_ lock is held by the calling thread.
-  virtual void GetStats() {
-    media_info_.Clear();
-    media_channel_->GetStats(&media_info_);
-  }
-  virtual void Update() {
-    MI stats(media_info_);
-    crit_.Leave();
-    SignalUpdate(media_channel_, stats);
-    crit_.Enter();
-  }
-
- private:
-  MC* media_channel_;
-  MI media_info_;
-};
-
-typedef MediaMonitorT<VoiceMediaChannel, VoiceMediaInfo> VoiceMediaMonitor;
-typedef MediaMonitorT<VideoMediaChannel, VideoMediaInfo> VideoMediaMonitor;
-
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_MEDIAMONITOR_H_
-
diff --git a/third_party/libjingle/source/talk/session/phone/mediaprocessorinterface.h b/third_party/libjingle/source/talk/session/phone/mediaprocessorinterface.h
deleted file mode 100644
index 2f8d02a..0000000
--- a/third_party/libjingle/source/talk/session/phone/mediaprocessorinterface.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-#ifndef TALK_SESSION_PHONE_MEDIAPROCESSORINTERFACE_H_
-#define TALK_SESSION_PHONE_MEDIAPROCESSORINTERFACE_H_
-
-#include "talk/base/basictypes.h"
-#include "talk/base/sigslot.h"
-#include "talk/session/phone/videoframe.h"
-
-namespace cricket {
-
-enum MediaProcessorDirection {
-    MPD_RX = 1 << 0,
-    MPD_TX = 1 << 1,
-    MPD_RX_AND_TX = MPD_RX | MPD_TX,
-};
-
-struct AudioFrame {
-  AudioFrame()
-      : audio10ms(NULL),
-        length(0),
-        sampling_freq(8000),
-        is_stereo(false) {
-  }
-
-  AudioFrame(int16* audio, size_t audio_length, int sample_freq, bool stereo)
-      : audio10ms(audio),
-        length(audio_length),
-        sampling_freq(sample_freq),
-        is_stereo(stereo) {
-  }
-
-  int16* audio10ms;
-  size_t length;
-  int sampling_freq;
-  bool is_stereo;
-};
-
-class VoiceProcessor : public sigslot::has_slots<> {
- public:
-  virtual ~VoiceProcessor() {}
-  // Contents of frame may be manipulated by the processor.
-  // The processed data is expected to be the same size as the
-  // original data
-  virtual void OnFrame(uint32 ssrc, AudioFrame* frame) = 0;
-};
-
-class VideoProcessor : public sigslot::has_slots<> {
- public:
-  virtual ~VideoProcessor() {}
-  // Contents of frame may be manipulated by the processor.
-  // The processed data is expected to be the same size as the
-  // original data
-  virtual void OnFrame(uint32 ssrc, VideoFrame* frame) = 0;
-};
-
-}  // namespace cricket
-#endif  // TALK_SESSION_PHONE_MEDIAPROCESSORINTERFACE_H_
diff --git a/third_party/libjingle/source/talk/session/phone/mediarecorder.cc b/third_party/libjingle/source/talk/session/phone/mediarecorder.cc
deleted file mode 100644
index 7b06e48..0000000
--- a/third_party/libjingle/source/talk/session/phone/mediarecorder.cc
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * libjingle
- * Copyright 2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/session/phone/mediarecorder.h"
-
-#include <limits.h>
-
-#include <string>
-
-#include "talk/base/fileutils.h"
-#include "talk/base/logging.h"
-#include "talk/base/pathutils.h"
-#include "talk/session/phone/channel.h"
-#include "talk/session/phone/rtpdump.h"
-
-
-namespace cricket {
-
-///////////////////////////////////////////////////////////////////////////
-// Implementation of RtpDumpSink.
-///////////////////////////////////////////////////////////////////////////
-RtpDumpSink::RtpDumpSink(const std::string& filename)
-    : max_size_(INT_MAX),
-      recording_(false),
-      packet_filter_(PF_NONE),
-      filename_(filename) {
-}
-
-RtpDumpSink::~RtpDumpSink() {}
-
-void RtpDumpSink::SetMaxSize(size_t size) {
-  talk_base::CritScope cs(&critical_section_);
-  max_size_ = size;
-}
-
-bool RtpDumpSink::Enable(bool enable) {
-  talk_base::CritScope cs(&critical_section_);
-
-  recording_ = enable;
-
-  // Create a file and the RTP writer if we have not done yet.
-  if (recording_ && !writer_.get()) {
-    stream_.reset(talk_base::Filesystem::OpenFile(
-        talk_base::Pathname(filename_), "wb"));
-    if (!stream_.get()) {
-      return false;
-    }
-    writer_.reset(new RtpDumpWriter(stream_.get()));
-    writer_->set_packet_filter(packet_filter_);
-  } else if (!recording_ && stream_.get()) {
-    stream_->Flush();
-  }
-  return true;
-}
-
-void RtpDumpSink::OnPacket(const void* data, size_t size, bool rtcp) {
-  talk_base::CritScope cs(&critical_section_);
-
-  if (recording_ && writer_.get()) {
-    size_t current_size;
-    if (writer_->GetDumpSize(&current_size) &&
-        current_size + RtpDumpPacket::kHeaderLength + size <= max_size_) {
-      if (!rtcp) {
-        writer_->WriteRtpPacket(data, size);
-      } else {
-        // TODO: Enable recording RTCP.
-      }
-    }
-  }
-}
-
-void RtpDumpSink::set_packet_filter(int filter) {
-  talk_base::CritScope cs(&critical_section_);
-  packet_filter_ = filter;
-  if (writer_.get()) {
-    writer_->set_packet_filter(packet_filter_);
-  }
-}
-
-void RtpDumpSink::Flush() {
-  talk_base::CritScope cs(&critical_section_);
-  if (stream_.get()) {
-    stream_->Flush();
-  }
-}
-
-///////////////////////////////////////////////////////////////////////////
-// Implementation of MediaRecorder.
-///////////////////////////////////////////////////////////////////////////
-MediaRecorder::MediaRecorder() {}
-
-MediaRecorder::~MediaRecorder() {
-  talk_base::CritScope cs(&critical_section_);
-  std::map<BaseChannel*, SinkPair*>::iterator itr;
-  for (itr = sinks_.begin(); itr != sinks_.end(); ++itr) {
-    delete itr->second;
-  }
-}
-
-bool MediaRecorder::AddChannel(VoiceChannel* channel,
-                               const std::string& send_filename,
-                               const std::string& recv_filename,
-                               int filter) {
-  return InternalAddChannel(channel, false, send_filename, recv_filename,
-                            filter);
-}
-bool MediaRecorder::AddChannel(VideoChannel* channel,
-                               const std::string& send_filename,
-                               const std::string& recv_filename,
-                               int filter) {
-  return InternalAddChannel(channel, true, send_filename, recv_filename,
-                            filter);
-}
-
-bool MediaRecorder::InternalAddChannel(BaseChannel* channel,
-                                       bool video_channel,
-                                       const std::string& send_filename,
-                                       const std::string& recv_filename,
-                                       int filter) {
-  if (!channel) {
-    return false;
-  }
-
-  talk_base::CritScope cs(&critical_section_);
-  if (sinks_.end() != sinks_.find(channel)) {
-    return false;  // The channel was added already.
-  }
-
-  SinkPair* sink_pair = new SinkPair;
-  sink_pair->video_channel = video_channel;
-  sink_pair->filter = filter;
-  sink_pair->send_sink.reset(new RtpDumpSink(send_filename));
-  sink_pair->send_sink->set_packet_filter(filter);
-  sink_pair->recv_sink.reset(new RtpDumpSink(recv_filename));
-  sink_pair->recv_sink->set_packet_filter(filter);
-  sinks_[channel] = sink_pair;
-
-  return true;
-}
-
-void MediaRecorder::RemoveChannel(BaseChannel* channel) {
-  talk_base::CritScope cs(&critical_section_);
-  std::map<BaseChannel*, SinkPair*>::iterator itr = sinks_.find(channel);
-  if (sinks_.end() != itr) {
-    channel->UnregisterSendSink(itr->second->send_sink.get());
-    channel->UnregisterRecvSink(itr->second->recv_sink.get());
-    delete itr->second;
-    sinks_.erase(itr);
-  }
-}
-
-bool MediaRecorder::EnableChannel(
-    BaseChannel* channel, bool enable_send, bool enable_recv) {
-  talk_base::CritScope cs(&critical_section_);
-  std::map<BaseChannel*, SinkPair*>::iterator itr = sinks_.find(channel);
-  if (sinks_.end() == itr) {
-    return false;
-  }
-
-  SinkPair* sink_pair = itr->second;
-  RtpDumpSink* sink = sink_pair->send_sink.get();
-  sink->Enable(enable_send);
-  if (enable_send) {
-    channel->RegisterSendSink(sink, &RtpDumpSink::OnPacket);
-  } else {
-    channel->UnregisterSendSink(sink);
-  }
-
-  sink = sink_pair->recv_sink.get();
-  sink->Enable(enable_recv);
-  if (enable_recv) {
-    channel->RegisterRecvSink(sink, &RtpDumpSink::OnPacket);
-  } else {
-    channel->UnregisterRecvSink(sink);
-  }
-
-  if (sink_pair->video_channel &&
-      (sink_pair->filter & PF_RTPPACKET) == PF_RTPPACKET) {
-    // Request a full intra frame.
-    VideoChannel* video_channel = static_cast<VideoChannel*>(channel);
-    if (enable_send) {
-      video_channel->SendIntraFrame();
-    }
-    if (enable_recv) {
-      video_channel->RequestIntraFrame();
-    }
-  }
-
-  return true;
-}
-
-void MediaRecorder::FlushSinks() {
-  talk_base::CritScope cs(&critical_section_);
-  std::map<BaseChannel*, SinkPair*>::iterator itr;
-  for (itr = sinks_.begin(); itr != sinks_.end(); ++itr) {
-    itr->second->send_sink->Flush();
-    itr->second->recv_sink->Flush();
-  }
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/session/phone/mediarecorder.h b/third_party/libjingle/source/talk/session/phone/mediarecorder.h
deleted file mode 100644
index fa77e6d..0000000
--- a/third_party/libjingle/source/talk/session/phone/mediarecorder.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * libjingle
- * Copyright 2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SESSION_PHONE_MEDIARECORDER_H_
-#define TALK_SESSION_PHONE_MEDIARECORDER_H_
-
-#include <map>
-#include <string>
-
-#include "talk/base/criticalsection.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/base/sigslot.h"
-#include "talk/session/phone/mediasink.h"
-
-namespace talk_base {
-class Pathname;
-class FileStream;
-}
-
-namespace cricket {
-
-class BaseChannel;
-class VideoChannel;
-class VoiceChannel;
-class RtpDumpWriter;
-
-// RtpDumpSink implements MediaSinkInterface by dumping the RTP/RTCP packets to
-// a file.
-class RtpDumpSink : public MediaSinkInterface, public sigslot::has_slots<> {
- public:
-  explicit RtpDumpSink(const std::string& filename);
-  virtual ~RtpDumpSink();
-
-  virtual void SetMaxSize(size_t size);
-  virtual bool Enable(bool enable);
-  virtual bool IsEnabled() const { return recording_; }
-  virtual void OnPacket(const void* data, size_t size, bool rtcp);
-  virtual void set_packet_filter(int filter);
-  int packet_filter() const { return packet_filter_; }
-  void Flush();
-
- private:
-  size_t max_size_;
-  bool recording_;
-  int packet_filter_;
-  std::string filename_;
-  talk_base::scoped_ptr<talk_base::FileStream> stream_;
-  talk_base::scoped_ptr<RtpDumpWriter> writer_;
-  talk_base::CriticalSection critical_section_;
-
-  DISALLOW_COPY_AND_ASSIGN(RtpDumpSink);
-};
-
-class MediaRecorder {
- public:
-  MediaRecorder();
-  virtual ~MediaRecorder();
-
-  bool AddChannel(VoiceChannel* channel,
-                  const std::string& send_filename,
-                  const std::string& recv_filename,
-                  int filter);
-  bool AddChannel(VideoChannel* channel,
-                  const std::string& send_filename,
-                  const std::string& recv_filename,
-                  int filter);
-  void RemoveChannel(BaseChannel* channel);
-  bool EnableChannel(BaseChannel* channel, bool enable_send, bool enable_recv);
-  void FlushSinks();
-
- private:
-  struct SinkPair {
-    bool video_channel;
-    int filter;
-    talk_base::scoped_ptr<RtpDumpSink> send_sink;
-    talk_base::scoped_ptr<RtpDumpSink> recv_sink;
-  };
-
-  bool InternalAddChannel(BaseChannel* channel,
-                          bool video_channel,
-                          const std::string& send_filename,
-                          const std::string& recv_filename,
-                          int filter);
-
-  std::map<BaseChannel*, SinkPair*> sinks_;
-  talk_base::CriticalSection critical_section_;
-
-  DISALLOW_COPY_AND_ASSIGN(MediaRecorder);
-};
-
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_MEDIARECORDER_H_
diff --git a/third_party/libjingle/source/talk/session/phone/mediarecorder_unittest.cc b/third_party/libjingle/source/talk/session/phone/mediarecorder_unittest.cc
deleted file mode 100644
index 59d1afe..0000000
--- a/third_party/libjingle/source/talk/session/phone/mediarecorder_unittest.cc
+++ /dev/null
@@ -1,344 +0,0 @@
-// libjingle
-// Copyright 2010 Google Inc.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-//  1. Redistributions of source code must retain the above copyright notice,
-//     this list of conditions and the following disclaimer.
-//  2. Redistributions in binary form must reproduce the above copyright notice,
-//     this list of conditions and the following disclaimer in the documentation
-//     and/or other materials provided with the distribution.
-//  3. The name of the author may not be used to endorse or promote products
-//     derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include <string>
-
-#include "talk/base/bytebuffer.h"
-#include "talk/base/fileutils.h"
-#include "talk/base/gunit.h"
-#include "talk/base/pathutils.h"
-#include "talk/base/thread.h"
-#include "talk/p2p/base/fakesession.h"
-#include "talk/session/phone/channel.h"
-#include "talk/session/phone/fakemediaengine.h"
-#include "talk/session/phone/mediarecorder.h"
-#include "talk/session/phone/rtpdump.h"
-#include "talk/session/phone/testutils.h"
-
-namespace cricket {
-
-/////////////////////////////////////////////////////////////////////////
-// Test RtpDumpSink
-/////////////////////////////////////////////////////////////////////////
-class RtpDumpSinkTest : public testing::Test {
- public:
-  virtual void SetUp() {
-    EXPECT_TRUE(talk_base::Filesystem::GetTemporaryFolder(path_, true, NULL));
-    path_.SetFilename("sink-test.rtpdump");
-    sink_.reset(new RtpDumpSink(path_.pathname()));
-
-    for (int i = 0; i < ARRAY_SIZE(rtp_buf_); ++i) {
-      RtpTestUtility::kTestRawRtpPackets[i].WriteToByteBuffer(
-          RtpTestUtility::kDefaultSsrc, &rtp_buf_[i]);
-    }
-  }
-
-  virtual void TearDown() {
-    stream_.reset();
-    EXPECT_TRUE(talk_base::Filesystem::DeleteFile(path_));
-  }
-
- protected:
-  void OnRtpPacket(const RawRtpPacket& raw) {
-    talk_base::ByteBuffer buf;
-    raw.WriteToByteBuffer(RtpTestUtility::kDefaultSsrc, &buf);
-    sink_->OnPacket(buf.Data(), buf.Length(), false);
-  }
-
-  talk_base::StreamResult ReadPacket(RtpDumpPacket* packet) {
-    if (!stream_.get()) {
-      sink_.reset();  // This will close the file. So we can read it.
-      stream_.reset(talk_base::Filesystem::OpenFile(path_, "rb"));
-      reader_.reset(new RtpDumpReader(stream_.get()));
-    }
-    return reader_->ReadPacket(packet);
-  }
-
-  talk_base::Pathname path_;
-  talk_base::scoped_ptr<RtpDumpSink> sink_;
-  talk_base::ByteBuffer rtp_buf_[3];
-  talk_base::scoped_ptr<talk_base::StreamInterface> stream_;
-  talk_base::scoped_ptr<RtpDumpReader> reader_;
-};
-
-TEST_F(RtpDumpSinkTest, TestRtpDumpSink) {
-  // By default, the sink is disabled. The 1st packet is not written.
-  EXPECT_FALSE(sink_->IsEnabled());
-  sink_->set_packet_filter(PF_ALL);
-  OnRtpPacket(RtpTestUtility::kTestRawRtpPackets[0]);
-
-  // Enable the sink. The 2nd packet is written.
-  EXPECT_TRUE(sink_->Enable(true));
-  EXPECT_TRUE(sink_->IsEnabled());
-  EXPECT_TRUE(talk_base::Filesystem::IsFile(path_.pathname()));
-  OnRtpPacket(RtpTestUtility::kTestRawRtpPackets[1]);
-
-  // Disable the sink. The 3rd packet is not written.
-  EXPECT_TRUE(sink_->Enable(false));
-  EXPECT_FALSE(sink_->IsEnabled());
-  OnRtpPacket(RtpTestUtility::kTestRawRtpPackets[2]);
-
-  // Read the recorded file and verify it contains only the 2nd packet.
-  RtpDumpPacket packet;
-  EXPECT_EQ(talk_base::SR_SUCCESS, ReadPacket(&packet));
-  EXPECT_TRUE(RtpTestUtility::VerifyPacket(
-      &packet, &RtpTestUtility::kTestRawRtpPackets[1], false));
-  EXPECT_EQ(talk_base::SR_EOS, ReadPacket(&packet));
-}
-
-TEST_F(RtpDumpSinkTest, TestRtpDumpSinkMaxSize) {
-  EXPECT_TRUE(sink_->Enable(true));
-  sink_->set_packet_filter(PF_ALL);
-  sink_->SetMaxSize(strlen(RtpDumpFileHeader::kFirstLine) +
-                    RtpDumpFileHeader::kHeaderLength +
-                    RtpDumpPacket::kHeaderLength +
-                    RtpTestUtility::kTestRawRtpPackets[0].size());
-  OnRtpPacket(RtpTestUtility::kTestRawRtpPackets[0]);
-
-  // Exceed the limit size: the 2nd and 3rd packets are not written.
-  OnRtpPacket(RtpTestUtility::kTestRawRtpPackets[1]);
-  OnRtpPacket(RtpTestUtility::kTestRawRtpPackets[2]);
-
-  // Read the recorded file and verify that it contains only the first packet.
-  RtpDumpPacket packet;
-  EXPECT_EQ(talk_base::SR_SUCCESS, ReadPacket(&packet));
-  EXPECT_TRUE(RtpTestUtility::VerifyPacket(
-      &packet, &RtpTestUtility::kTestRawRtpPackets[0], false));
-  EXPECT_EQ(talk_base::SR_EOS, ReadPacket(&packet));
-}
-
-TEST_F(RtpDumpSinkTest, TestRtpDumpSinkFilter) {
-  // The default filter is PF_NONE.
-  EXPECT_EQ(PF_NONE, sink_->packet_filter());
-
-  // Set to PF_RTPHEADER before enable.
-  sink_->set_packet_filter(PF_RTPHEADER);
-  EXPECT_EQ(PF_RTPHEADER, sink_->packet_filter());
-  EXPECT_TRUE(sink_->Enable(true));
-  // We dump only the header of the first packet.
-  OnRtpPacket(RtpTestUtility::kTestRawRtpPackets[0]);
-
-  // Set the filter to PF_RTPPACKET. We dump all the second packet.
-  sink_->set_packet_filter(PF_RTPPACKET);
-  EXPECT_EQ(PF_RTPPACKET, sink_->packet_filter());
-  OnRtpPacket(RtpTestUtility::kTestRawRtpPackets[1]);
-
-  // Set the filter to PF_NONE. We do not dump the third packet.
-  sink_->set_packet_filter(PF_NONE);
-  EXPECT_EQ(PF_NONE, sink_->packet_filter());
-  OnRtpPacket(RtpTestUtility::kTestRawRtpPackets[2]);
-
-  // Read the recorded file and verify the header of the first packet and
-  // the whole packet for the second packet.
-  RtpDumpPacket packet;
-  EXPECT_EQ(talk_base::SR_SUCCESS, ReadPacket(&packet));
-  EXPECT_TRUE(RtpTestUtility::VerifyPacket(
-      &packet, &RtpTestUtility::kTestRawRtpPackets[0], true));
-  EXPECT_EQ(talk_base::SR_SUCCESS, ReadPacket(&packet));
-  EXPECT_TRUE(RtpTestUtility::VerifyPacket(
-      &packet, &RtpTestUtility::kTestRawRtpPackets[1], false));
-  EXPECT_EQ(talk_base::SR_EOS, ReadPacket(&packet));
-}
-
-/////////////////////////////////////////////////////////////////////////
-// Test MediaRecorder
-/////////////////////////////////////////////////////////////////////////
-void TestMediaRecorder(BaseChannel* channel,
-                       FakeVideoMediaChannel* video_media_channel,
-                       int filter) {
-  // Create media recorder.
-  talk_base::scoped_ptr<MediaRecorder> recorder(new MediaRecorder);
-  // Fail to EnableChannel before AddChannel.
-  EXPECT_FALSE(recorder->EnableChannel(channel, true, true));
-  EXPECT_FALSE(channel->HasSendSinks());
-  EXPECT_FALSE(channel->HasRecvSinks());
-
-  // Add the channel to the recorder.
-  talk_base::Pathname path;
-  EXPECT_TRUE(talk_base::Filesystem::GetTemporaryFolder(path, true, NULL));
-  path.SetFilename("send.rtpdump");
-  std::string send_file = path.pathname();
-  path.SetFilename("recv.rtpdump");
-  std::string recv_file = path.pathname();
-  if (video_media_channel) {
-    EXPECT_TRUE(recorder->AddChannel(static_cast<VideoChannel*>(channel),
-                                     send_file, recv_file, filter));
-  } else {
-    EXPECT_TRUE(recorder->AddChannel(static_cast<VoiceChannel*>(channel),
-                                     send_file, recv_file, filter));
-  }
-
-  // Enable recording only the sent media.
-  EXPECT_TRUE(recorder->EnableChannel(channel, true, false));
-  EXPECT_TRUE(channel->HasSendSinks());
-  EXPECT_FALSE(channel->HasRecvSinks());
-  if (video_media_channel) {
-    EXPECT_TRUE_WAIT(video_media_channel->sent_intra_frame(), 100);
-  }
-
-  // Enable recording only the received meida.
-  EXPECT_TRUE(recorder->EnableChannel(channel, false, true));
-  EXPECT_FALSE(channel->HasSendSinks());
-  EXPECT_TRUE(channel->HasRecvSinks());
-  if (video_media_channel) {
-    EXPECT_TRUE(video_media_channel->requested_intra_frame());
-  }
-
-  // Enable recording both the sent and the received video.
-  EXPECT_TRUE(recorder->EnableChannel(channel, true, true));
-  EXPECT_TRUE(channel->HasSendSinks());
-  EXPECT_TRUE(channel->HasRecvSinks());
-
-  // Enable recording only headers.
-  if (video_media_channel) {
-    video_media_channel->set_sent_intra_frame(false);
-    video_media_channel->set_requested_intra_frame(false);
-  }
-  EXPECT_TRUE(recorder->EnableChannel(channel, true, true));
-  EXPECT_TRUE(channel->HasSendSinks());
-  EXPECT_TRUE(channel->HasRecvSinks());
-  if (video_media_channel) {
-    if ((filter & PF_RTPPACKET) == PF_RTPPACKET) {
-      // If record the whole RTP packet, trigers FIR.
-      EXPECT_TRUE(video_media_channel->requested_intra_frame());
-      EXPECT_TRUE(video_media_channel->sent_intra_frame());
-    } else {
-      // If record only the RTP header, does not triger FIR.
-      EXPECT_FALSE(video_media_channel->requested_intra_frame());
-      EXPECT_FALSE(video_media_channel->sent_intra_frame());
-    }
-  }
-
-  // Remove the voice channel from the recorder.
-  recorder->RemoveChannel(channel);
-  EXPECT_FALSE(channel->HasSendSinks());
-  EXPECT_FALSE(channel->HasRecvSinks());
-
-  // Delete all files.
-  recorder.reset();
-  EXPECT_TRUE(talk_base::Filesystem::DeleteFile(send_file));
-  EXPECT_TRUE(talk_base::Filesystem::DeleteFile(recv_file));
-}
-
-// Fisrt start recording header and then start recording media. Verify that
-// differnt files are created for header and media.
-void TestRecordHeaderAndMedia(BaseChannel* channel,
-                              FakeVideoMediaChannel* video_media_channel) {
-  // Create RTP header recorder.
-  talk_base::scoped_ptr<MediaRecorder> header_recorder(new MediaRecorder);
-
-  talk_base::Pathname path;
-  EXPECT_TRUE(talk_base::Filesystem::GetTemporaryFolder(path, true, NULL));
-  path.SetFilename("send-header.rtpdump");
-  std::string send_header_file = path.pathname();
-  path.SetFilename("recv-header.rtpdump");
-  std::string recv_header_file = path.pathname();
-  if (video_media_channel) {
-    EXPECT_TRUE(header_recorder->AddChannel(
-        static_cast<VideoChannel*>(channel),
-        send_header_file, recv_header_file, PF_RTPHEADER));
-  } else {
-    EXPECT_TRUE(header_recorder->AddChannel(
-        static_cast<VoiceChannel*>(channel),
-        send_header_file, recv_header_file, PF_RTPHEADER));
-  }
-
-  // Enable recording both sent and received.
-  EXPECT_TRUE(header_recorder->EnableChannel(channel, true, true));
-  EXPECT_TRUE(channel->HasSendSinks());
-  EXPECT_TRUE(channel->HasRecvSinks());
-  if (video_media_channel) {
-    EXPECT_FALSE(video_media_channel->sent_intra_frame());
-    EXPECT_FALSE(video_media_channel->requested_intra_frame());
-  }
-
-  // Verify that header files are created.
-  EXPECT_TRUE(talk_base::Filesystem::IsFile(send_header_file));
-  EXPECT_TRUE(talk_base::Filesystem::IsFile(recv_header_file));
-
-  // Create RTP header recorder.
-  talk_base::scoped_ptr<MediaRecorder> recorder(new MediaRecorder);
-  path.SetFilename("send.rtpdump");
-  std::string send_file = path.pathname();
-  path.SetFilename("recv.rtpdump");
-  std::string recv_file = path.pathname();
-  if (video_media_channel) {
-    EXPECT_TRUE(recorder->AddChannel(
-        static_cast<VideoChannel*>(channel),
-        send_file, recv_file, PF_RTPPACKET));
-  } else {
-    EXPECT_TRUE(recorder->AddChannel(
-        static_cast<VoiceChannel*>(channel),
-        send_file, recv_file, PF_RTPPACKET));
-  }
-
-  // Enable recording both sent and received.
-  EXPECT_TRUE(recorder->EnableChannel(channel, true, true));
-  EXPECT_TRUE(channel->HasSendSinks());
-  EXPECT_TRUE(channel->HasRecvSinks());
-  if (video_media_channel) {
-    EXPECT_TRUE_WAIT(video_media_channel->sent_intra_frame(), 100);
-    EXPECT_TRUE(video_media_channel->requested_intra_frame());
-  }
-
-  // Verify that media files are created.
-  EXPECT_TRUE(talk_base::Filesystem::IsFile(send_file));
-  EXPECT_TRUE(talk_base::Filesystem::IsFile(recv_file));
-
-  // Delete all files.
-  header_recorder.reset();
-  recorder.reset();
-  EXPECT_TRUE(talk_base::Filesystem::DeleteFile(send_header_file));
-  EXPECT_TRUE(talk_base::Filesystem::DeleteFile(recv_header_file));
-  EXPECT_TRUE(talk_base::Filesystem::DeleteFile(send_file));
-  EXPECT_TRUE(talk_base::Filesystem::DeleteFile(recv_file));
-}
-
-TEST(MediaRecorderTest, TestMediaRecorderVoiceChannel) {
-  // Create the voice channel.
-  cricket::FakeSession session;
-  cricket::FakeMediaEngine media_engine;
-  VoiceChannel channel(talk_base::Thread::Current(), &media_engine,
-                       new FakeVoiceMediaChannel(NULL), &session, "", false);
-  EXPECT_TRUE(channel.Init());
-  TestMediaRecorder(&channel, NULL, PF_RTPPACKET);
-  TestMediaRecorder(&channel, NULL, PF_RTPHEADER);
-  TestRecordHeaderAndMedia(&channel, NULL);
-}
-
-TEST(MediaRecorderTest, TestMediaRecorderVideoChannel) {
-  // Create the video channel.
-  cricket::FakeSession session;
-  cricket::FakeMediaEngine media_engine;
-  FakeVideoMediaChannel* media_channel = new FakeVideoMediaChannel(NULL);
-  VideoChannel channel(talk_base::Thread::Current(), &media_engine,
-                       media_channel, &session, "", false, NULL);
-  EXPECT_TRUE(channel.Init());
-  TestMediaRecorder(&channel, media_channel, PF_RTPPACKET);
-  TestMediaRecorder(&channel, media_channel, PF_RTPHEADER);
-  TestRecordHeaderAndMedia(&channel, media_channel);
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/session/phone/mediasession.cc b/third_party/libjingle/source/talk/session/phone/mediasession.cc
deleted file mode 100644
index 4e66872..0000000
--- a/third_party/libjingle/source/talk/session/phone/mediasession.cc
+++ /dev/null
@@ -1,586 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/session/phone/mediasession.h"
-
-#include "talk/base/helpers.h"
-#include "talk/base/logging.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/p2p/base/constants.h"
-#include "talk/session/phone/channelmanager.h"
-#include "talk/session/phone/cryptoparams.h"
-#include "talk/session/phone/srtpfilter.h"
-#include "talk/xmpp/constants.h"
-
-namespace {
-const char kInline[] = "inline:";
-}
-
-namespace cricket {
-
-using talk_base::scoped_ptr;
-
-static bool CreateCryptoParams(int tag, const std::string& cipher,
-                               CryptoParams *out) {
-  std::string key;
-  key.reserve(SRTP_MASTER_KEY_BASE64_LEN);
-
-  if (!talk_base::CreateRandomString(SRTP_MASTER_KEY_BASE64_LEN, &key)) {
-    return false;
-  }
-  out->tag = tag;
-  out->cipher_suite = cipher;
-  out->key_params = kInline;
-  out->key_params += key;
-  return true;
-}
-
-#ifdef HAVE_SRTP
-static bool AddCryptoParams(const std::string& cipher_suite,
-                            CryptoParamsVec *out) {
-  int size = out->size();
-
-  out->resize(size + 1);
-  return CreateCryptoParams(size, cipher_suite, &out->at(size));
-}
-#endif
-
-// For audio, HMAC 32 is prefered because of the low overhead.
-static bool GetSupportedAudioCryptos(CryptoParamsVec* cryptos) {
-#ifdef HAVE_SRTP
-  return AddCryptoParams(CS_AES_CM_128_HMAC_SHA1_32, cryptos) &&
-      AddCryptoParams(CS_AES_CM_128_HMAC_SHA1_80, cryptos);
-#else
-  return false;
-#endif
-}
-
-static bool GetSupportedVideoCryptos(CryptoParamsVec* cryptos) {
-#ifdef HAVE_SRTP
-  return AddCryptoParams(CS_AES_CM_128_HMAC_SHA1_80, cryptos);
-#else
-  return false;
-#endif
-}
-
-// For video support only 80-bit SHA1 HMAC. For audio 32-bit HMAC is
-// tolerated because it is low overhead. Pick the crypto in the list
-// that is supported.
-static bool SelectCrypto(const MediaContentDescription* offer,
-                         CryptoParams *crypto) {
-  bool audio = offer->type() == MEDIA_TYPE_AUDIO;
-  const CryptoParamsVec& cryptos = offer->cryptos();
-
-  for (CryptoParamsVec::const_iterator i = cryptos.begin();
-       i != cryptos.end(); ++i) {
-    if (CS_AES_CM_128_HMAC_SHA1_80 == i->cipher_suite ||
-        (CS_AES_CM_128_HMAC_SHA1_32 == i->cipher_suite && audio)) {
-      return CreateCryptoParams(i->tag, i->cipher_suite, crypto);
-    }
-  }
-  return false;
-}
-
-static const StreamParams* FindStreamParamsByName(
-    const StreamParamsVec& params_vec,
-    const std::string& name) {
-  for (StreamParamsVec::const_iterator it = params_vec.begin();
-       it != params_vec.end(); ++it) {
-    if (it->name == name)
-      return &*it;
-  }
-  return NULL;
-}
-
-static const StreamParams* FindFirstStreamParamsByCname(
-    const StreamParamsVec& params_vec,
-    const std::string& cname) {
-  for (StreamParamsVec::const_iterator it = params_vec.begin();
-       it != params_vec.end(); ++it) {
-    if (cname == it->cname)
-      return &*it;
-  }
-  return NULL;
-}
-
-static const StreamParams* FindStreamParamsBySsrc(
-    const StreamParamsVec& params_vec,
-    uint32 ssrc) {
-  for (StreamParamsVec::const_iterator stream_it = params_vec.begin();
-       stream_it != params_vec.end(); ++stream_it) {
-    const std::vector<uint32>& ssrcs = stream_it->ssrcs;
-    for (std::vector<uint32>::const_iterator ssrc_it = ssrcs.begin();
-         ssrc_it !=  ssrcs.end(); ++ssrc_it) {
-      if (ssrc == *ssrc_it)
-        return &*stream_it;
-    }
-  }
-  return NULL;
-}
-
-// Generates a new CNAME or the CNAME of an already existing StreamParams
-// if a StreamParams exist for another Stream in streams with sync_label
-// sync_label.
-static bool GenerateCname(const StreamParamsVec& params_vec,
-                          const MediaSessionOptions::Streams& streams,
-                          const std::string& synch_label,
-                          std::string* cname) {
-  ASSERT(cname != NULL);
-  if (!cname)
-    return false;
-
-  // Check if a CNAME exist for any of the other synched streams.
-  for (MediaSessionOptions::Streams::const_iterator stream_it = streams.begin();
-       stream_it != streams.end() ; ++stream_it) {
-    if (synch_label != stream_it->sync_label)
-      continue;
-    const StreamParams* param = FindStreamParamsByName(params_vec,
-                                                       stream_it->name);
-    if (param) {
-      *cname = param->cname;
-      return true;
-    }
-  }
-  // No other stream seems to exist that we should sync with.
-  // Generate a random string for the RTCP CNAME, as stated in RFC 6222.
-  // This string is only used for synchronization, and therefore is opaque.
-  do {
-    if (!talk_base::CreateRandomString(16, cname)) {
-      ASSERT(false);
-      return false;
-    }
-  } while (FindFirstStreamParamsByCname(params_vec, *cname));
-
-  return true;
-}
-
-// Generate a new SSRC and make sure it does not exist in params_vec.
-static uint32 GenerateSsrc(const StreamParamsVec& params_vec) {
-  uint32 ssrc = 0;
-  do {
-    ssrc = talk_base::CreateRandomNonZeroId();
-  } while (FindStreamParamsBySsrc(params_vec, ssrc));
-  return ssrc;
-}
-
-// Finds all StreamParams of all media types and attach them to stream_params.
-static void GetCurrentStreamParams(const SessionDescription* sdesc,
-                                   StreamParamsVec* stream_params) {
-  if (!sdesc)
-    return;
-
-  const ContentInfos& contents = sdesc->contents();
-  for (ContentInfos::const_iterator content = contents.begin();
-       content != contents.end(); content++) {
-    if (!IsAudioContent(&*content) && !IsVideoContent(&*content))
-      continue;
-    const MediaContentDescription* media =
-        static_cast<const MediaContentDescription*>(
-            content->description);
-    const StreamParamsVec& streams = media->streams();
-    for (StreamParamsVec::const_iterator it = streams.begin();
-         it != streams.end(); ++it) {
-      stream_params->push_back(*it);
-    }
-  }
-}
-
-// Adds a StreamParams for each Stream in Streams with media type
-// media_type to content_description.
-// current_parms - All currently known StreamParams of any media type.
-static bool AddStreamParams(
-    MediaType media_type,
-    const MediaSessionOptions::Streams& streams,
-    StreamParamsVec* current_params,
-    MediaContentDescription* content_description) {
-  for (MediaSessionOptions::Streams::const_iterator stream_it = streams.begin();
-       stream_it != streams.end(); ++stream_it) {
-    if (stream_it->type != media_type)
-      continue;  // Wrong media type.
-    const StreamParams* params = FindStreamParamsByName(*current_params,
-                                                        stream_it->name);
-    if (!params) {
-      // This is a new stream.
-      // Get a CNAME. Either new or same as one of the other synched streams.
-      std::string cname;
-      if (!GenerateCname(*current_params, streams, stream_it->sync_label,
-                         &cname)) {
-        return false;
-      }
-      uint32 ssrc = GenerateSsrc(*current_params);
-      // TODO: Generate the more complex types of stream_params.
-
-      StreamParams stream_param;
-      stream_param.name = stream_it->name;
-      stream_param.ssrcs.push_back(ssrc);
-      stream_param.cname = cname;
-      stream_param.sync_label = stream_it->sync_label;
-      content_description->AddStream(stream_param);
-
-      // Store the new StreamParams in current_params.
-      // This is necessary so that we can use the CNAME for other media types.
-      current_params->push_back(stream_param);
-    } else {
-      content_description->AddStream(*params);
-    }
-  }
-  return true;
-}
-
-void MediaSessionOptions::AddStream(MediaType type,
-                                    const std::string& name,
-                                    const std::string& sync_label) {
-  streams.push_back(Stream(type, name, sync_label));
-
-  if (type == MEDIA_TYPE_VIDEO)
-    has_video = true;
-  else if (type == MEDIA_TYPE_AUDIO)
-    has_audio = true;
-}
-
-void MediaSessionOptions::RemoveStream(MediaType type,
-                                       const std::string& name) {
-  Streams::iterator stream_it = streams.begin();
-  for (; stream_it != streams.end(); ++stream_it) {
-    if (stream_it->type == type && stream_it->name == name) {
-      streams.erase(stream_it);
-      return;
-    }
-  }
-  ASSERT(false);
-}
-
-MediaSessionDescriptionFactory::MediaSessionDescriptionFactory()
-    : secure_(SEC_DISABLED) {
-}
-
-MediaSessionDescriptionFactory::MediaSessionDescriptionFactory(
-    ChannelManager* channel_manager)
-    : secure_(SEC_DISABLED) {
-  channel_manager->GetSupportedAudioCodecs(&audio_codecs_);
-  channel_manager->GetSupportedVideoCodecs(&video_codecs_);
-}
-
-SessionDescription* MediaSessionDescriptionFactory::CreateOffer(
-    const MediaSessionOptions& options,
-    const SessionDescription* current_description) {
-  scoped_ptr<SessionDescription> offer(new SessionDescription());
-
-  StreamParamsVec current_params;
-  GetCurrentStreamParams(current_description, &current_params);
-
-  if (options.has_audio) {
-    scoped_ptr<AudioContentDescription> audio(new AudioContentDescription());
-    for (AudioCodecs::const_iterator codec = audio_codecs_.begin();
-         codec != audio_codecs_.end(); ++codec) {
-      audio->AddCodec(*codec);
-    }
-    audio->SortCodecs();
-    if (!AddStreamParams(MEDIA_TYPE_AUDIO, options.streams, &current_params,
-                         audio.get())) {
-      return NULL;  // Abort, something went seriously wrong.
-    }
-
-    if (options.streams.empty()) {
-      // TODO: Remove this legacy stream when all apps use StreamParams.
-      audio->AddLegacyStream(talk_base::CreateRandomNonZeroId());
-    }
-    audio->set_rtcp_mux(options.rtcp_mux_enabled);
-    audio->set_lang(lang_);
-
-    if (secure() != SEC_DISABLED) {
-      CryptoParamsVec audio_cryptos;
-      if (current_description) {
-        // Copy crypto parameters from the previous offer.
-        const ContentInfo* info =
-            GetFirstAudioContent(current_description);
-        if (info) {
-          const AudioContentDescription* desc =
-              static_cast<const AudioContentDescription*>(info->description);
-          audio_cryptos = desc->cryptos();
-        }
-      }
-      if (audio_cryptos.empty())
-        GetSupportedAudioCryptos(&audio_cryptos);  // Generate new cryptos.
-
-      for (CryptoParamsVec::const_iterator crypto = audio_cryptos.begin();
-           crypto != audio_cryptos.end(); ++crypto) {
-        audio->AddCrypto(*crypto);
-      }
-
-      if (secure() == SEC_REQUIRED) {
-        if (audio->cryptos().empty()) {
-          return NULL;  // Abort, crypto required but none found.
-        }
-        audio->set_crypto_required(true);
-      }
-    }
-
-    offer->AddContent(CN_AUDIO, NS_JINGLE_RTP, audio.release());
-  }
-
-  // add video codecs, if this is a video call
-  if (options.has_video) {
-    scoped_ptr<VideoContentDescription> video(new VideoContentDescription());
-    for (VideoCodecs::const_iterator codec = video_codecs_.begin();
-         codec != video_codecs_.end(); ++codec) {
-      video->AddCodec(*codec);
-    }
-
-    video->SortCodecs();
-    if (!AddStreamParams(MEDIA_TYPE_VIDEO, options.streams, &current_params,
-                         video.get())) {
-      return NULL;  // Abort, something went seriously wrong.
-    }
-
-    if (options.streams.empty()) {
-      // TODO: Remove this legacy stream when all apps use StreamParams.
-      video->AddLegacyStream(talk_base::CreateRandomNonZeroId());
-    }
-    video->set_bandwidth(options.video_bandwidth);
-    video->set_rtcp_mux(options.rtcp_mux_enabled);
-
-    if (secure() != SEC_DISABLED) {
-      CryptoParamsVec video_cryptos;
-      if (current_description) {
-        // Copy crypto parameters from the previous offer.
-        const ContentInfo* info =
-            GetFirstVideoContent(current_description);
-        if (info) {
-          const VideoContentDescription* desc =
-              static_cast<const VideoContentDescription*>(info->description);
-          video_cryptos = desc->cryptos();
-        }
-      }
-      if (video_cryptos.empty())
-        GetSupportedVideoCryptos(&video_cryptos);  // Generate new crypto.
-      for (CryptoParamsVec::const_iterator crypto = video_cryptos.begin();
-           crypto != video_cryptos.end(); ++crypto) {
-        video->AddCrypto(*crypto);
-      }
-      if (secure() == SEC_REQUIRED) {
-        if (video->cryptos().empty()) {
-          return NULL;  // Abort, crypto required but none found.
-        }
-        video->set_crypto_required(true);
-      }
-    }
-
-    offer->AddContent(CN_VIDEO, NS_JINGLE_RTP, video.release());
-  }
-
-  return offer.release();
-}
-
-SessionDescription* MediaSessionDescriptionFactory::CreateAnswer(
-    const SessionDescription* offer, const MediaSessionOptions& options,
-    const SessionDescription* current_description) {
-  // The answer contains the intersection of the codecs in the offer with the
-  // codecs we support, ordered by our local preference. As indicated by
-  // XEP-0167, we retain the same payload ids from the offer in the answer.
-  scoped_ptr<SessionDescription> accept(new SessionDescription());
-
-  StreamParamsVec current_params;
-  GetCurrentStreamParams(current_description, &current_params);
-
-  const ContentInfo* audio_content = GetFirstAudioContent(offer);
-  if (audio_content && options.has_audio) {
-    const AudioContentDescription* audio_offer =
-        static_cast<const AudioContentDescription*>(audio_content->description);
-    scoped_ptr<AudioContentDescription> audio_accept(
-        new AudioContentDescription());
-    for (AudioCodecs::const_iterator ours = audio_codecs_.begin();
-        ours != audio_codecs_.end(); ++ours) {
-      for (AudioCodecs::const_iterator theirs = audio_offer->codecs().begin();
-          theirs != audio_offer->codecs().end(); ++theirs) {
-        if (ours->Matches(*theirs)) {
-          AudioCodec negotiated(*ours);
-          negotiated.id = theirs->id;
-          audio_accept->AddCodec(negotiated);
-        }
-      }
-    }
-
-    audio_accept->SortCodecs();
-    if (!AddStreamParams(MEDIA_TYPE_AUDIO, options.streams, &current_params,
-                         audio_accept.get())) {
-      return NULL;  // Abort, something went seriously wrong.
-    }
-
-    if (options.streams.empty()) {
-      // TODO: Remove this legacy stream when all apps use StreamParams.
-      audio_accept->AddLegacyStream(talk_base::CreateRandomNonZeroId());
-    }
-    audio_accept->set_rtcp_mux(
-        options.rtcp_mux_enabled && audio_offer->rtcp_mux());
-
-    if (secure() != SEC_DISABLED) {
-      CryptoParams crypto;
-
-      if (SelectCrypto(audio_offer, &crypto)) {
-        if (current_description) {
-          // Check if this crypto already exist in the previous
-          // session description. Use it in that case.
-          const ContentInfo* info =
-              GetFirstAudioContent(current_description);
-          if (info) {
-            const AudioContentDescription* desc =
-                static_cast<const AudioContentDescription*>(info->description);
-            const CryptoParamsVec& cryptos = desc->cryptos();
-            for (CryptoParamsVec::const_iterator it = cryptos.begin();
-                it != cryptos.end(); ++it) {
-              if (crypto.Matches(*it)) {
-                crypto = *it;
-                break;
-              }
-            }
-          }
-        }
-        audio_accept->AddCrypto(crypto);
-      }
-    }
-
-    if (audio_accept->cryptos().empty() &&
-        (audio_offer->crypto_required() || secure() == SEC_REQUIRED)) {
-      return NULL;  // Fails the session setup.
-    }
-    accept->AddContent(audio_content->name, audio_content->type,
-                       audio_accept.release());
-  } else {
-    LOG(LS_INFO) << "Audio is not supported in answer";
-  }
-
-  const ContentInfo* video_content = GetFirstVideoContent(offer);
-  if (video_content && options.has_video) {
-    const VideoContentDescription* video_offer =
-        static_cast<const VideoContentDescription*>(video_content->description);
-    scoped_ptr<VideoContentDescription> video_accept(
-        new VideoContentDescription());
-    for (VideoCodecs::const_iterator ours = video_codecs_.begin();
-        ours != video_codecs_.end(); ++ours) {
-      for (VideoCodecs::const_iterator theirs = video_offer->codecs().begin();
-          theirs != video_offer->codecs().end(); ++theirs) {
-        if (ours->Matches(*theirs)) {
-          VideoCodec negotiated(*ours);
-          negotiated.id = theirs->id;
-          video_accept->AddCodec(negotiated);
-        }
-      }
-    }
-    if (!AddStreamParams(MEDIA_TYPE_VIDEO, options.streams, &current_params,
-                         video_accept.get())) {
-      return NULL;  // Abort, something went seriously wrong.
-    }
-
-    if (options.streams.empty()) {
-      // TODO: Remove this legacy stream when all apps use StreamParams.
-      video_accept->AddLegacyStream(talk_base::CreateRandomNonZeroId());
-    }
-    video_accept->set_bandwidth(options.video_bandwidth);
-    video_accept->set_rtcp_mux(
-        options.rtcp_mux_enabled && video_offer->rtcp_mux());
-    video_accept->SortCodecs();
-
-    if (secure() != SEC_DISABLED) {
-      CryptoParams crypto;
-
-      if (SelectCrypto(video_offer, &crypto)) {
-        if (current_description) {
-          // Check if this crypto already exist in the previous
-          // session description. Use it in that case.
-          const ContentInfo* info = GetFirstVideoContent(current_description);
-          if (info) {
-            const VideoContentDescription* desc =
-                static_cast<const VideoContentDescription*>(info->description);
-            const CryptoParamsVec& cryptos = desc->cryptos();
-            for (CryptoParamsVec::const_iterator it = cryptos.begin();
-                 it != cryptos.end(); ++it) {
-              if (crypto.Matches(*it)) {
-                crypto = *it;
-                break;
-              }
-            }
-          }
-        }
-        video_accept->AddCrypto(crypto);
-      }
-    }
-
-    if (video_accept->cryptos().empty() &&
-        (video_offer->crypto_required() || secure() == SEC_REQUIRED)) {
-      return NULL;  // Fails the session setup.
-    }
-    accept->AddContent(video_content->name, video_content->type,
-                       video_accept.release());
-  } else {
-    LOG(LS_INFO) << "Video is not supported in answer";
-  }
-  return accept.release();
-}
-
-static bool IsMediaContent(const ContentInfo* content, MediaType media_type) {
-  if (content == NULL || content->type != NS_JINGLE_RTP) {
-    return false;
-  }
-
-  const MediaContentDescription* media =
-      static_cast<const MediaContentDescription*>(content->description);
-  return media->type() == media_type;
-}
-
-bool IsAudioContent(const ContentInfo* content) {
-  return IsMediaContent(content, MEDIA_TYPE_AUDIO);
-}
-
-bool IsVideoContent(const ContentInfo* content) {
-  return IsMediaContent(content, MEDIA_TYPE_VIDEO);
-}
-
-static const ContentInfo* GetFirstMediaContent(const SessionDescription* sdesc,
-                                               MediaType media_type) {
-  if (sdesc == NULL)
-    return NULL;
-
-  const ContentInfos& contents = sdesc->contents();
-  for (ContentInfos::const_iterator content = contents.begin();
-       content != contents.end(); content++) {
-    if (IsMediaContent(&*content, media_type)) {
-      return &*content;
-    }
-  }
-  return NULL;
-}
-
-const ContentInfo* GetFirstAudioContent(const SessionDescription* sdesc) {
-  return GetFirstMediaContent(sdesc, MEDIA_TYPE_AUDIO);
-}
-
-const ContentInfo* GetFirstVideoContent(const SessionDescription* sdesc) {
-  return GetFirstMediaContent(sdesc, MEDIA_TYPE_VIDEO);
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/session/phone/mediasession.h b/third_party/libjingle/source/talk/session/phone/mediasession.h
deleted file mode 100644
index 49df26a..0000000
--- a/third_party/libjingle/source/talk/session/phone/mediasession.h
+++ /dev/null
@@ -1,305 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// Types and classes used in media session descriptions.
-
-#ifndef TALK_SESSION_PHONE_MEDIASESSION_H_
-#define TALK_SESSION_PHONE_MEDIASESSION_H_
-
-#include <string>
-#include <vector>
-#include <algorithm>
-
-#include "talk/session/phone/codec.h"
-#include "talk/session/phone/cryptoparams.h"
-#include "talk/session/phone/mediachannel.h"
-#include "talk/session/phone/streamparams.h"
-#include "talk/p2p/base/sessiondescription.h"
-
-namespace cricket {
-
-class ChannelManager;
-typedef std::vector<AudioCodec> AudioCodecs;
-typedef std::vector<VideoCodec> VideoCodecs;
-typedef std::vector<CryptoParams> CryptoParamsVec;
-typedef std::vector<StreamParams> StreamParamsVec;
-
-// SEC_ENABLED and SEC_REQUIRED should only be used if the session
-// was negotiated over TLS, to protect the inline crypto material
-// exchange.
-// SEC_DISABLED: No crypto in outgoing offer and answer. Fail any
-//               offer with crypto required.
-// SEC_ENABLED: Crypto in outgoing offer and answer. Fail any offer
-//              with unsupported required crypto. Crypto set but not
-//              required in outgoing offer.
-// SEC_REQUIRED: Crypto in outgoing offer and answer with
-//               required='true'. Fail any offer with no or
-//               unsupported crypto (implicit crypto required='true'
-//               in the offer.)
-enum SecureMediaPolicy {
-  SEC_DISABLED,
-  SEC_ENABLED,
-  SEC_REQUIRED
-};
-
-enum MediaType {
-  MEDIA_TYPE_AUDIO,
-  MEDIA_TYPE_VIDEO
-};
-
-// Options to control how session descriptions are generated.
-const int kAutoBandwidth = -1;
-struct MediaSessionOptions {
-  MediaSessionOptions() :
-      has_audio(true),  // Audio enabled by default.
-      has_video(false),
-      is_muc(false),
-      rtcp_mux_enabled(true),
-      video_bandwidth(kAutoBandwidth) {
-  }
-
-  // Add a stream with MediaType type and id name.
-  // All streams with the same sync_label will get the same CNAME.
-  // All names must be unique.
-  void AddStream(MediaType type,
-                 const std::string& name,
-                 const std::string& sync_label);
-  void RemoveStream(MediaType type, const std::string& name);
-
-  bool has_audio;
-  bool has_video;
-  bool is_muc;
-  bool rtcp_mux_enabled;
-  // bps. -1 == auto.
-  int video_bandwidth;
-
-  struct Stream {
-    Stream(MediaType type,
-           const std::string& name,
-           const std::string& sync_label)
-        : type(type), name(name), sync_label(sync_label) {
-    }
-    MediaType type;
-    std::string name;
-    std::string sync_label;
-  };
-
-  typedef std::vector<Stream> Streams;
-  Streams streams;
-};
-
-// "content" (as used in XEP-0166) descriptions for voice and video.
-class MediaContentDescription : public ContentDescription {
- public:
-  MediaContentDescription()
-      : rtcp_mux_(false),
-        bandwidth_(kAutoBandwidth),
-        crypto_required_(false),
-        rtp_header_extensions_set_(false),
-        multistream_(false) {
-  }
-
-  virtual MediaType type() const = 0;
-
-  bool rtcp_mux() const { return rtcp_mux_; }
-  void set_rtcp_mux(bool mux) { rtcp_mux_ = mux; }
-
-  int bandwidth() const { return bandwidth_; }
-  void set_bandwidth(int bandwidth) { bandwidth_ = bandwidth; }
-
-  const std::vector<CryptoParams>& cryptos() const { return cryptos_; }
-  void AddCrypto(const CryptoParams& params) {
-    cryptos_.push_back(params);
-  }
-  bool crypto_required() const { return crypto_required_; }
-  void set_crypto_required(bool crypto) {
-    crypto_required_ = crypto;
-  }
-
-  const std::vector<RtpHeaderExtension>& rtp_header_extensions() const {
-    return rtp_header_extensions_;
-  }
-  void AddRtpHeaderExtension(const RtpHeaderExtension& ext) {
-    rtp_header_extensions_.push_back(ext);
-    rtp_header_extensions_set_ = true;
-  }
-  void ClearRtpHeaderExtensions() {
-    rtp_header_extensions_.clear();
-    rtp_header_extensions_set_ = true;
-  }
-  // We can't always tell if an empty list of header extensions is
-  // because the other side doesn't support them, or just isn't hooked up to
-  // signal them. For now we assume an empty list means no signaling, but
-  // provide the ClearRtpHeaderExtensions method to allow "no support" to be
-  // clearly indicated (i.e. when derived from other information).
-  bool rtp_header_extensions_set() const {
-    return rtp_header_extensions_set_;
-  }
-  // True iff the client supports multiple streams.
-  void set_multistream(bool multistream) { multistream_ = multistream; }
-  bool multistream() const { return multistream_;  }
-  const StreamParamsVec& streams() const {
-    return streams_;
-  }
-  // TODO: Remove this by giving mediamessage.cc access
-  // to MediaContentDescription
-  StreamParamsVec& mutable_streams() {
-    return streams_;
-  }
-  void AddStream(const StreamParams& stream) {
-    streams_.push_back(stream);
-  }
-  // Legacy streams have an ssrc, but nothing else.
-  void AddLegacyStream(uint32 ssrc) {
-    streams_.push_back(StreamParams::CreateLegacy(ssrc));
-  }
-
-  uint32 first_ssrc() const {
-    if (streams_.empty()) {
-      return 0;
-    }
-    return streams_[0].first_ssrc();
-  }
-  bool has_ssrcs() const {
-    if (streams_.empty()) {
-      return false;
-    }
-    return streams_[0].has_ssrcs();
-  }
-
- protected:
-  bool rtcp_mux_;
-  int bandwidth_;
-  std::vector<CryptoParams> cryptos_;
-  bool crypto_required_;
-  std::vector<RtpHeaderExtension> rtp_header_extensions_;
-  bool rtp_header_extensions_set_;
-  bool multistream_;
-  StreamParamsVec streams_;
-};
-
-template <class C>
-class MediaContentDescriptionImpl : public MediaContentDescription {
- public:
-  struct PreferenceSort {
-    bool operator()(C a, C b) { return a.preference > b.preference; }
-  };
-
-  const std::vector<C>& codecs() const { return codecs_; }
-  void AddCodec(const C& codec) {
-    codecs_.push_back(codec);
-  }
-  void SortCodecs() {
-    std::sort(codecs_.begin(), codecs_.end(), PreferenceSort());
-  }
-
- private:
-  std::vector<C> codecs_;
-};
-
-class AudioContentDescription : public MediaContentDescriptionImpl<AudioCodec> {
- public:
-  AudioContentDescription() :
-      agc_minus_10db_(false),
-      conference_mode_(false) {}
-
-  virtual MediaType type() const { return MEDIA_TYPE_AUDIO; }
-
-  bool conference_mode() const { return conference_mode_; }
-  void set_conference_mode(bool enable) {
-    conference_mode_ = enable;
-  }
-
-  const std::string &lang() const { return lang_; }
-  void set_lang(const std::string &lang) { lang_ = lang; }
-
-  bool agc_minus_10db() const { return agc_minus_10db_; }
-  void set_agc_minus_10db(bool enable) {
-    agc_minus_10db_ = enable;
-  }
-
- private:
-  bool agc_minus_10db_;
-
- private:
-  bool conference_mode_;
-  std::string lang_;
-};
-
-class VideoContentDescription : public MediaContentDescriptionImpl<VideoCodec> {
- public:
-  virtual MediaType type() const { return MEDIA_TYPE_VIDEO; }
-};
-
-// Creates media session descriptions according to the supplied codecs and
-// other fields, as well as the supplied per-call options.
-// When creating answers, performs the appropriate negotiation
-// of the various fields to determine the proper result.
-class MediaSessionDescriptionFactory {
- public:
-  // Default ctor; use methods below to set configuration.
-  MediaSessionDescriptionFactory();
-  // Helper, to allow configuration to be loaded from a ChannelManager.
-  explicit MediaSessionDescriptionFactory(ChannelManager* manager);
-
-  const AudioCodecs& audio_codecs() const { return audio_codecs_; }
-  void set_audio_codecs(const AudioCodecs& codecs) { audio_codecs_ = codecs; }
-  const VideoCodecs& video_codecs() const { return video_codecs_; }
-  void set_video_codecs(const VideoCodecs& codecs) { video_codecs_ = codecs; }
-  SecureMediaPolicy secure() const { return secure_; }
-  void set_secure(SecureMediaPolicy s) { secure_ = s; }
-
-
-  SessionDescription* CreateOffer(
-      const MediaSessionOptions& options,
-      const SessionDescription* current_description);
-
-
-
-
-
-  SessionDescription* CreateAnswer(
-        const SessionDescription* offer,
-        const MediaSessionOptions& options,
-        const SessionDescription* current_description);
-
- private:
-  AudioCodecs audio_codecs_;
-  VideoCodecs video_codecs_;
-  SecureMediaPolicy secure_;
-  std::string lang_;
-};
-
-// Convenience functions.
-bool IsAudioContent(const ContentInfo* content);
-bool IsVideoContent(const ContentInfo* content);
-const ContentInfo* GetFirstAudioContent(const SessionDescription* sdesc);
-const ContentInfo* GetFirstVideoContent(const SessionDescription* sdesc);
-
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_MEDIASESSION_H_
diff --git a/third_party/libjingle/source/talk/session/phone/mediasession_unittest.cc b/third_party/libjingle/source/talk/session/phone/mediasession_unittest.cc
deleted file mode 100644
index d2c1695..0000000
--- a/third_party/libjingle/source/talk/session/phone/mediasession_unittest.cc
+++ /dev/null
@@ -1,574 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string>
-#include <vector>
-
-#include "talk/base/gunit.h"
-#include "talk/p2p/base/constants.h"
-#include "talk/session/phone/codec.h"
-#include "talk/session/phone/mediasession.h"
-#include "talk/session/phone/srtpfilter.h"
-#include "talk/session/phone/testutils.h"
-
-#ifdef HAVE_SRTP
-#define ASSERT_CRYPTO(cd, r, s, cs) \
-    ASSERT_EQ(r, cd->crypto_required()); \
-    ASSERT_EQ(s, cd->cryptos().size()); \
-    ASSERT_EQ(std::string(cs), cd->cryptos()[0].cipher_suite)
-#else
-#define ASSERT_CRYPTO(c, r, s, cs) \
-  ASSERT_EQ(false, cd->crypto_required()); \
-  ASSERT_EQ(0U, cd->cryptos().size());
-#endif
-
-using cricket::MediaSessionDescriptionFactory;
-using cricket::MediaSessionOptions;
-using cricket::MediaType;
-using cricket::SessionDescription;
-using cricket::SsrcGroup;
-using cricket::StreamParams;
-using cricket::StreamParamsVec;
-using cricket::ContentInfo;
-using cricket::CryptoParamsVec;
-using cricket::AudioContentDescription;
-using cricket::MediaContentDescription;
-using cricket::VideoContentDescription;
-using cricket::kAutoBandwidth;
-using cricket::AudioCodec;
-using cricket::VideoCodec;
-using cricket::NS_JINGLE_RTP;
-using cricket::MEDIA_TYPE_AUDIO;
-using cricket::MEDIA_TYPE_VIDEO;
-using cricket::SEC_ENABLED;
-using cricket::CS_AES_CM_128_HMAC_SHA1_32;
-using cricket::CS_AES_CM_128_HMAC_SHA1_80;
-
-static const AudioCodec kAudioCodecs1[] = {
-  AudioCodec(103, "ISAC",   16000, -1,    1, 5),
-  AudioCodec(102, "iLBC",   8000,  13300, 1, 4),
-  AudioCodec(0,   "PCMU",   8000,  64000, 1, 3),
-  AudioCodec(8,   "PCMA",   8000,  64000, 1, 2),
-  AudioCodec(117, "red",    8000,  0,     1, 1),
-};
-
-static const AudioCodec kAudioCodecs2[] = {
-  AudioCodec(126, "speex",  16000, 22000, 1, 3),
-  AudioCodec(127, "iLBC",   8000,  13300, 1, 2),
-  AudioCodec(0,   "PCMU",   8000,  64000, 1, 1),
-};
-
-static const AudioCodec kAudioCodecsAnswer[] = {
-  AudioCodec(102, "iLBC",   8000,  13300, 1, 2),
-  AudioCodec(0,   "PCMU",   8000,  64000, 1, 1),
-};
-
-static const VideoCodec kVideoCodecs1[] = {
-  VideoCodec(96, "H264-SVC", 320, 200, 30, 2),
-  VideoCodec(97, "H264", 320, 200, 30, 1)
-};
-
-static const VideoCodec kVideoCodecs2[] = {
-  VideoCodec(126, "H264", 320, 200, 30, 2),
-  VideoCodec(127, "H263", 320, 200, 30, 1)
-};
-
-static const VideoCodec kVideoCodecsAnswer[] = {
-  VideoCodec(97, "H264", 320, 200, 30, 2)
-};
-
-static const uint32 kSimulcastParamsSsrc[] = {10, 11, 20, 21, 30, 31};
-static const uint32 kSimSsrc[] = {10, 20, 30};
-static const uint32 kFec1Ssrc[] = {10, 11};
-static const uint32 kFec2Ssrc[] = {20, 21};
-static const uint32 kFec3Ssrc[] = {30, 31};
-
-static const char kMediaStream1[] = "stream_1";
-static const char kMediaStream2[] = "stream_2";
-static const char kVideoTrack1[] = "video_1";
-static const char kVideoTrack2[] = "video_2";
-static const char kAudioTrack1[] = "audio_1";
-static const char kAudioTrack2[] = "audio_2";
-static const char kAudioTrack3[] = "audio_3";
-
-class MediaSessionDescriptionFactoryTest : public testing::Test {
- public:
-  MediaSessionDescriptionFactoryTest() {
-    f1_.set_audio_codecs(MAKE_VECTOR(kAudioCodecs1));
-    f1_.set_video_codecs(MAKE_VECTOR(kVideoCodecs1));
-    f2_.set_audio_codecs(MAKE_VECTOR(kAudioCodecs2));
-    f2_.set_video_codecs(MAKE_VECTOR(kVideoCodecs2));
-  }
-
-  // Create a video StreamParamsVec object with:
-  // - one video stream with 3 simulcast streams and FEC,
-  StreamParamsVec CreateComplexVideoStreamParamsVec() {
-    SsrcGroup sim_group("SIM", MAKE_VECTOR(kSimSsrc));
-    SsrcGroup fec_group1("FEC", MAKE_VECTOR(kFec1Ssrc));
-    SsrcGroup fec_group2("FEC", MAKE_VECTOR(kFec2Ssrc));
-    SsrcGroup fec_group3("FEC", MAKE_VECTOR(kFec3Ssrc));
-
-    std::vector<SsrcGroup> ssrc_groups;
-    ssrc_groups.push_back(sim_group);
-    ssrc_groups.push_back(fec_group1);
-    ssrc_groups.push_back(fec_group2);
-    ssrc_groups.push_back(fec_group3);
-
-    StreamParams simulcast_params;
-    simulcast_params.name = kVideoTrack1;
-    simulcast_params.ssrcs = MAKE_VECTOR(kSimulcastParamsSsrc);
-    simulcast_params.ssrc_groups = ssrc_groups;
-    simulcast_params.cname = "Video_SIM_FEC";
-    simulcast_params.sync_label = kMediaStream1;
-
-    StreamParamsVec video_streams;
-    video_streams.push_back(simulcast_params);
-
-    return video_streams;
-  }
-  bool CompareCryptoParams(const CryptoParamsVec& c1,
-                           const CryptoParamsVec& c2) {
-    if (c1.size() != c2.size())
-      return false;
-    for (size_t i = 0; i < c1.size(); ++i)
-      if (c1[i].tag != c2[i].tag || c1[i].cipher_suite != c2[i].cipher_suite ||
-          c1[i].key_params != c2[i].key_params ||
-          c1[i].session_params != c2[i].session_params)
-        return false;
-    return true;
-  }
-
- protected:
-  const MediaContentDescription*  GetMediaDescription(
-      const SessionDescription* sdesc,
-      const std::string& content_name) {
-    const ContentInfo* content = sdesc->GetContentByName(content_name);
-    if (content == NULL) {
-      return NULL;
-    }
-    return static_cast<const MediaContentDescription*>(
-        content->description);
-  }
-
-  const AudioContentDescription*  GetAudioDescription(
-      const SessionDescription* sdesc) {
-    return static_cast<const AudioContentDescription*>(
-        GetMediaDescription(sdesc, "audio"));
-  }
-
-  const VideoContentDescription*  GetVideoDescription(
-      const SessionDescription* sdesc) {
-    return static_cast<const VideoContentDescription*>(
-        GetMediaDescription(sdesc, "video"));
-  }
-
-  MediaSessionDescriptionFactory f1_;
-  MediaSessionDescriptionFactory f2_;
-};
-
-// Create a typical audio offer, and ensure it matches what we expect.
-TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAudioOffer) {
-  f1_.set_secure(SEC_ENABLED);
-  talk_base::scoped_ptr<SessionDescription> offer(
-      f1_.CreateOffer(MediaSessionOptions(), NULL));
-  ASSERT_TRUE(offer.get() != NULL);
-  const ContentInfo* ac = offer->GetContentByName("audio");
-  const ContentInfo* vc = offer->GetContentByName("video");
-  ASSERT_TRUE(ac != NULL);
-  ASSERT_TRUE(vc == NULL);
-  EXPECT_EQ(std::string(NS_JINGLE_RTP), ac->type);
-  const AudioContentDescription* acd =
-      static_cast<const AudioContentDescription*>(ac->description);
-  EXPECT_EQ(MEDIA_TYPE_AUDIO, acd->type());
-  EXPECT_EQ(f1_.audio_codecs(), acd->codecs());
-  EXPECT_NE(0U, acd->first_ssrc());             // a random nonzero ssrc
-  EXPECT_EQ(kAutoBandwidth, acd->bandwidth());  // default bandwidth (auto)
-  EXPECT_TRUE(acd->rtcp_mux());                 // rtcp-mux defaults on
-  ASSERT_CRYPTO(acd, false, 2U, CS_AES_CM_128_HMAC_SHA1_32);
-}
-
-// Create a typical video offer, and ensure it matches what we expect.
-TEST_F(MediaSessionDescriptionFactoryTest, TestCreateVideoOffer) {
-  MediaSessionOptions opts;
-  opts.has_video = true;
-  f1_.set_secure(SEC_ENABLED);
-  talk_base::scoped_ptr<SessionDescription>
-      offer(f1_.CreateOffer(opts, NULL));
-  ASSERT_TRUE(offer.get() != NULL);
-  const ContentInfo* ac = offer->GetContentByName("audio");
-  const ContentInfo* vc = offer->GetContentByName("video");
-  ASSERT_TRUE(ac != NULL);
-  ASSERT_TRUE(vc != NULL);
-  EXPECT_EQ(std::string(NS_JINGLE_RTP), ac->type);
-  EXPECT_EQ(std::string(NS_JINGLE_RTP), vc->type);
-  const AudioContentDescription* acd =
-      static_cast<const AudioContentDescription*>(ac->description);
-  const VideoContentDescription* vcd =
-      static_cast<const VideoContentDescription*>(vc->description);
-  EXPECT_EQ(MEDIA_TYPE_AUDIO, acd->type());
-  EXPECT_EQ(f1_.audio_codecs(), acd->codecs());
-  EXPECT_NE(0U, acd->first_ssrc());             // a random nonzero ssrc
-  EXPECT_EQ(kAutoBandwidth, acd->bandwidth());  // default bandwidth (auto)
-  EXPECT_TRUE(acd->rtcp_mux());                 // rtcp-mux defaults on
-  ASSERT_CRYPTO(acd, false, 2U, CS_AES_CM_128_HMAC_SHA1_32);
-  EXPECT_EQ(MEDIA_TYPE_VIDEO, vcd->type());
-  EXPECT_EQ(f1_.video_codecs(), vcd->codecs());
-  EXPECT_NE(0U, vcd->first_ssrc());             // a random nonzero ssrc
-  EXPECT_EQ(kAutoBandwidth, vcd->bandwidth());  // default bandwidth (auto)
-  EXPECT_TRUE(vcd->rtcp_mux());                 // rtcp-mux defaults on
-  ASSERT_CRYPTO(vcd, false, 1U, CS_AES_CM_128_HMAC_SHA1_80);
-}
-
-// Create a typical audio answer, and ensure it matches what we expect.
-TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAudioAnswer) {
-  f1_.set_secure(SEC_ENABLED);
-  f2_.set_secure(SEC_ENABLED);
-  talk_base::scoped_ptr<SessionDescription> offer(
-      f1_.CreateOffer(MediaSessionOptions(), NULL));
-  ASSERT_TRUE(offer.get() != NULL);
-  talk_base::scoped_ptr<SessionDescription> answer(
-      f2_.CreateAnswer(offer.get(), MediaSessionOptions(), NULL));
-  const ContentInfo* ac = answer->GetContentByName("audio");
-  const ContentInfo* vc = answer->GetContentByName("video");
-  ASSERT_TRUE(ac != NULL);
-  ASSERT_TRUE(vc == NULL);
-  EXPECT_EQ(std::string(NS_JINGLE_RTP), ac->type);
-  const AudioContentDescription* acd =
-      static_cast<const AudioContentDescription*>(ac->description);
-  EXPECT_EQ(MEDIA_TYPE_AUDIO, acd->type());
-  EXPECT_EQ(MAKE_VECTOR(kAudioCodecsAnswer), acd->codecs());
-  EXPECT_NE(0U, acd->first_ssrc());             // a random nonzero ssrc
-  EXPECT_EQ(kAutoBandwidth, acd->bandwidth());  // negotiated auto bw
-  EXPECT_TRUE(acd->rtcp_mux());                 // negotiated rtcp-mux
-  ASSERT_CRYPTO(acd, false, 1U, CS_AES_CM_128_HMAC_SHA1_32);
-}
-
-// Create a typical video answer, and ensure it matches what we expect.
-TEST_F(MediaSessionDescriptionFactoryTest, TestCreateVideoAnswer) {
-  MediaSessionOptions opts;
-  opts.has_video = true;
-  f1_.set_secure(SEC_ENABLED);
-  f2_.set_secure(SEC_ENABLED);
-  talk_base::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL));
-  ASSERT_TRUE(offer.get() != NULL);
-  talk_base::scoped_ptr<SessionDescription> answer(
-      f2_.CreateAnswer(offer.get(), opts, NULL));
-  const ContentInfo* ac = answer->GetContentByName("audio");
-  const ContentInfo* vc = answer->GetContentByName("video");
-  ASSERT_TRUE(ac != NULL);
-  ASSERT_TRUE(vc != NULL);
-  EXPECT_EQ(std::string(NS_JINGLE_RTP), ac->type);
-  EXPECT_EQ(std::string(NS_JINGLE_RTP), vc->type);
-  const AudioContentDescription* acd =
-      static_cast<const AudioContentDescription*>(ac->description);
-  const VideoContentDescription* vcd =
-      static_cast<const VideoContentDescription*>(vc->description);
-  EXPECT_EQ(MEDIA_TYPE_AUDIO, acd->type());
-  EXPECT_EQ(MAKE_VECTOR(kAudioCodecsAnswer), acd->codecs());
-  EXPECT_EQ(kAutoBandwidth, acd->bandwidth());  // negotiated auto bw
-  EXPECT_NE(0U, acd->first_ssrc());             // a random nonzero ssrc
-  EXPECT_TRUE(acd->rtcp_mux());                 // negotiated rtcp-mux
-  ASSERT_CRYPTO(acd, false, 1U, CS_AES_CM_128_HMAC_SHA1_32);
-  EXPECT_EQ(MEDIA_TYPE_VIDEO, vcd->type());
-  EXPECT_EQ(MAKE_VECTOR(kVideoCodecsAnswer), vcd->codecs());
-  EXPECT_NE(0U, vcd->first_ssrc());             // a random nonzero ssrc
-  EXPECT_TRUE(vcd->rtcp_mux());                 // negotiated rtcp-mux
-  ASSERT_CRYPTO(vcd, false, 1U, CS_AES_CM_128_HMAC_SHA1_80);
-}
-
-
-// Create a typical video answer, and ensure it matches what we expect.
-TEST_F(MediaSessionDescriptionFactoryTest, TestCreateVideoAnswerRtcpMux) {
-  MediaSessionOptions offer_opts;
-  MediaSessionOptions answer_opts;
-  answer_opts.has_video = true;
-  offer_opts.has_video = true;
-
-  talk_base::scoped_ptr<SessionDescription> offer(NULL);
-  talk_base::scoped_ptr<SessionDescription> answer(NULL);
-
-  offer_opts.rtcp_mux_enabled = true;
-  answer_opts.rtcp_mux_enabled = true;
-
-  offer.reset(f1_.CreateOffer(offer_opts, NULL));
-  answer.reset(f2_.CreateAnswer(offer.get(), answer_opts, NULL));
-  ASSERT_TRUE(NULL != GetAudioDescription(offer.get()));
-  ASSERT_TRUE(NULL != GetVideoDescription(offer.get()));
-  ASSERT_TRUE(NULL != GetAudioDescription(answer.get()));
-  ASSERT_TRUE(NULL != GetVideoDescription(answer.get()));
-  EXPECT_TRUE(GetAudioDescription(offer.get())->rtcp_mux());
-  EXPECT_TRUE(GetVideoDescription(offer.get())->rtcp_mux());
-  EXPECT_TRUE(GetAudioDescription(answer.get())->rtcp_mux());
-  EXPECT_TRUE(GetVideoDescription(answer.get())->rtcp_mux());
-
-  offer_opts.rtcp_mux_enabled = true;
-  answer_opts.rtcp_mux_enabled = false;
-
-  offer.reset(f1_.CreateOffer(offer_opts, NULL));
-  answer.reset(f2_.CreateAnswer(offer.get(), answer_opts, NULL));
-  ASSERT_TRUE(NULL != GetAudioDescription(offer.get()));
-  ASSERT_TRUE(NULL != GetVideoDescription(offer.get()));
-  ASSERT_TRUE(NULL != GetAudioDescription(answer.get()));
-  ASSERT_TRUE(NULL != GetVideoDescription(answer.get()));
-  EXPECT_TRUE(GetAudioDescription(offer.get())->rtcp_mux());
-  EXPECT_TRUE(GetVideoDescription(offer.get())->rtcp_mux());
-  EXPECT_FALSE(GetAudioDescription(answer.get())->rtcp_mux());
-  EXPECT_FALSE(GetVideoDescription(answer.get())->rtcp_mux());
-
-  offer_opts.rtcp_mux_enabled = false;
-  answer_opts.rtcp_mux_enabled = true;
-
-  offer.reset(f1_.CreateOffer(offer_opts, NULL));
-  answer.reset(f2_.CreateAnswer(offer.get(), answer_opts, NULL));
-  ASSERT_TRUE(NULL != GetAudioDescription(offer.get()));
-  ASSERT_TRUE(NULL != GetVideoDescription(offer.get()));
-  ASSERT_TRUE(NULL != GetAudioDescription(answer.get()));
-  ASSERT_TRUE(NULL != GetVideoDescription(answer.get()));
-  EXPECT_FALSE(GetAudioDescription(offer.get())->rtcp_mux());
-  EXPECT_FALSE(GetVideoDescription(offer.get())->rtcp_mux());
-  EXPECT_FALSE(GetAudioDescription(answer.get())->rtcp_mux());
-  EXPECT_FALSE(GetVideoDescription(answer.get())->rtcp_mux());
-
-  offer_opts.rtcp_mux_enabled = false;
-  answer_opts.rtcp_mux_enabled = false;
-
-  offer.reset(f1_.CreateOffer(offer_opts, NULL));
-  answer.reset(f2_.CreateAnswer(offer.get(), answer_opts, NULL));
-  ASSERT_TRUE(NULL != GetAudioDescription(offer.get()));
-  ASSERT_TRUE(NULL != GetVideoDescription(offer.get()));
-  ASSERT_TRUE(NULL != GetAudioDescription(answer.get()));
-  ASSERT_TRUE(NULL != GetVideoDescription(answer.get()));
-  EXPECT_FALSE(GetAudioDescription(offer.get())->rtcp_mux());
-  EXPECT_FALSE(GetVideoDescription(offer.get())->rtcp_mux());
-  EXPECT_FALSE(GetAudioDescription(answer.get())->rtcp_mux());
-  EXPECT_FALSE(GetVideoDescription(answer.get())->rtcp_mux());
-}
-
-// Create an audio-only answer to a video offer.
-TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAudioAnswerToVideo) {
-  MediaSessionOptions opts;
-  opts.has_video = true;
-  talk_base::scoped_ptr<SessionDescription>
-      offer(f1_.CreateOffer(opts, NULL));
-  ASSERT_TRUE(offer.get() != NULL);
-  talk_base::scoped_ptr<SessionDescription> answer(
-      f2_.CreateAnswer(offer.get(), MediaSessionOptions(), NULL));
-  const ContentInfo* ac = answer->GetContentByName("audio");
-  const ContentInfo* vc = answer->GetContentByName("video");
-  ASSERT_TRUE(ac != NULL);
-  ASSERT_TRUE(vc == NULL);
-}
-
-// Create an audio and video offer with:
-// - one video track,
-// - two audio tracks.
-// and ensure it matches what we expect. Also updates the initial offer by
-// adding a new video track and replaces one of the audio tracks.
-TEST_F(MediaSessionDescriptionFactoryTest, TestCreateMultiStreamVideoOffer) {
-  MediaSessionOptions opts;
-  opts.AddStream(MEDIA_TYPE_VIDEO, kVideoTrack1, kMediaStream1);
-  opts.AddStream(MEDIA_TYPE_AUDIO, kAudioTrack1, kMediaStream1);
-  opts.AddStream(MEDIA_TYPE_AUDIO, kAudioTrack2, kMediaStream1);
-
-  f1_.set_secure(SEC_ENABLED);
-  talk_base::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(opts, NULL));
-
-  ASSERT_TRUE(offer.get() != NULL);
-  const ContentInfo* ac = offer->GetContentByName("audio");
-  const ContentInfo* vc = offer->GetContentByName("video");
-  ASSERT_TRUE(ac != NULL);
-  ASSERT_TRUE(vc != NULL);
-  const AudioContentDescription* acd =
-      static_cast<const AudioContentDescription*>(ac->description);
-  const VideoContentDescription* vcd =
-      static_cast<const VideoContentDescription*>(vc->description);
-  EXPECT_EQ(MEDIA_TYPE_AUDIO, acd->type());
-  EXPECT_EQ(f1_.audio_codecs(), acd->codecs());
-
-  const StreamParamsVec& audio_streams = acd->streams();
-  ASSERT_EQ(2U, audio_streams.size());
-  EXPECT_EQ(audio_streams[0].cname , audio_streams[1].cname);
-  EXPECT_EQ(kAudioTrack1, audio_streams[0].name);
-  ASSERT_EQ(1U, audio_streams[0].ssrcs.size());
-  EXPECT_NE(0U, audio_streams[0].ssrcs[0]);
-  EXPECT_EQ(kAudioTrack2, audio_streams[1].name);
-  ASSERT_EQ(1U, audio_streams[1].ssrcs.size());
-  EXPECT_NE(0U, audio_streams[1].ssrcs[0]);
-
-  EXPECT_EQ(kAutoBandwidth, acd->bandwidth());  // default bandwidth (auto)
-  EXPECT_TRUE(acd->rtcp_mux());                 // rtcp-mux defaults on
-  ASSERT_CRYPTO(acd, false, 2U, CS_AES_CM_128_HMAC_SHA1_32);
-
-  EXPECT_EQ(MEDIA_TYPE_VIDEO, vcd->type());
-  EXPECT_EQ(f1_.video_codecs(), vcd->codecs());
-  ASSERT_CRYPTO(vcd, false, 1U, CS_AES_CM_128_HMAC_SHA1_80);
-
-  const StreamParamsVec& video_streams = vcd->streams();
-  ASSERT_EQ(1U, video_streams.size());
-  EXPECT_EQ(video_streams[0].cname, audio_streams[0].cname);
-  EXPECT_EQ(kVideoTrack1, video_streams[0].name);
-  EXPECT_EQ(kAutoBandwidth, vcd->bandwidth());  // default bandwidth (auto)
-  EXPECT_TRUE(vcd->rtcp_mux());                 // rtcp-mux defaults on
-
-
-  // Update the offer. Add a new video track that is not synched to the
-  // other tracks and replace audio track 2 with audio track 3.
-  opts.AddStream(MEDIA_TYPE_VIDEO, kVideoTrack2, kMediaStream2);
-  opts.RemoveStream(MEDIA_TYPE_AUDIO, kAudioTrack2);
-  opts.AddStream(MEDIA_TYPE_AUDIO, kAudioTrack3, kMediaStream1);
-  talk_base::scoped_ptr<SessionDescription>
-      updated_offer(f1_.CreateOffer(opts, offer.get()));
-
-  ASSERT_TRUE(updated_offer.get() != NULL);
-  ac = updated_offer->GetContentByName("audio");
-  vc = updated_offer->GetContentByName("video");
-  ASSERT_TRUE(ac != NULL);
-  ASSERT_TRUE(vc != NULL);
-  const AudioContentDescription* updated_acd =
-      static_cast<const AudioContentDescription*>(ac->description);
-  const VideoContentDescription* updated_vcd =
-      static_cast<const VideoContentDescription*>(vc->description);
-
-  EXPECT_EQ(acd->type(), updated_acd->type());
-  EXPECT_EQ(acd->codecs(), updated_acd->codecs());
-  EXPECT_EQ(vcd->type(), updated_vcd->type());
-  EXPECT_EQ(vcd->codecs(), updated_vcd->codecs());
-  ASSERT_CRYPTO(updated_acd, false, 2U, CS_AES_CM_128_HMAC_SHA1_32);
-  EXPECT_TRUE(CompareCryptoParams(acd->cryptos(), updated_acd->cryptos()));
-  ASSERT_CRYPTO(updated_vcd, false, 1U, CS_AES_CM_128_HMAC_SHA1_80);
-  EXPECT_TRUE(CompareCryptoParams(vcd->cryptos(), updated_vcd->cryptos()));
-
-  const StreamParamsVec& updated_audio_streams = updated_acd->streams();
-  ASSERT_EQ(2U, updated_audio_streams.size());
-  EXPECT_EQ(audio_streams[0], updated_audio_streams[0]);
-  EXPECT_EQ(kAudioTrack3, updated_audio_streams[1].name);  // New audio track.
-  ASSERT_EQ(1U, updated_audio_streams[1].ssrcs.size());
-  EXPECT_NE(0U, updated_audio_streams[1].ssrcs[0]);
-  EXPECT_EQ(updated_audio_streams[0].cname, updated_audio_streams[1].cname);
-
-  const StreamParamsVec& updated_video_streams = updated_vcd->streams();
-  ASSERT_EQ(2U, updated_video_streams.size());
-  EXPECT_EQ(video_streams[0], updated_video_streams[0]);
-  EXPECT_EQ(kVideoTrack2, updated_video_streams[1].name);
-  EXPECT_NE(updated_video_streams[1].cname, updated_video_streams[0].cname);
-}
-
-// Create an audio and video answer to a standard video offer with:
-// - one video track,
-// - two audio tracks.
-// and ensure it matches what we expect. Also updates the initial answer by
-// adding a new video track and removes one of the audio tracks.
-TEST_F(MediaSessionDescriptionFactoryTest, TestCreateMultiStreamVideoAnswer) {
-  MediaSessionOptions offer_opts;
-  offer_opts.has_video = true;
-  f1_.set_secure(SEC_ENABLED);
-  f2_.set_secure(SEC_ENABLED);
-  talk_base::scoped_ptr<SessionDescription> offer(f1_.CreateOffer(offer_opts,
-                                                                  NULL));
-
-  MediaSessionOptions opts;
-  opts.AddStream(MEDIA_TYPE_VIDEO, kVideoTrack1, kMediaStream1);
-  opts.AddStream(MEDIA_TYPE_AUDIO, kAudioTrack1, kMediaStream1);
-  opts.AddStream(MEDIA_TYPE_AUDIO, kAudioTrack2, kMediaStream1);
-
-  talk_base::scoped_ptr<SessionDescription>
-      answer(f2_.CreateAnswer(offer.get(), opts, NULL));
-
-  ASSERT_TRUE(answer.get() != NULL);
-  const ContentInfo* ac = answer->GetContentByName("audio");
-  const ContentInfo* vc = answer->GetContentByName("video");
-  ASSERT_TRUE(ac != NULL);
-  ASSERT_TRUE(vc != NULL);
-  const AudioContentDescription* acd =
-      static_cast<const AudioContentDescription*>(ac->description);
-  const VideoContentDescription* vcd =
-      static_cast<const VideoContentDescription*>(vc->description);
-  EXPECT_EQ(MEDIA_TYPE_AUDIO, acd->type());
-  EXPECT_EQ(MAKE_VECTOR(kAudioCodecsAnswer), acd->codecs());
-  ASSERT_CRYPTO(acd, false, 1U, CS_AES_CM_128_HMAC_SHA1_32);
-  ASSERT_CRYPTO(vcd, false, 1U, CS_AES_CM_128_HMAC_SHA1_80);
-
-  const StreamParamsVec& audio_streams = acd->streams();
-  ASSERT_EQ(2U, audio_streams.size());
-  EXPECT_TRUE(audio_streams[0].cname ==  audio_streams[1].cname);
-  EXPECT_EQ(kAudioTrack1, audio_streams[0].name);
-  ASSERT_EQ(1U, audio_streams[0].ssrcs.size());
-  EXPECT_NE(0U, audio_streams[0].ssrcs[0]);
-  EXPECT_EQ(kAudioTrack2, audio_streams[1].name);
-  ASSERT_EQ(1U, audio_streams[1].ssrcs.size());
-  EXPECT_NE(0U, audio_streams[1].ssrcs[0]);
-
-  EXPECT_EQ(kAutoBandwidth, acd->bandwidth());  // default bandwidth (auto)
-  EXPECT_TRUE(acd->rtcp_mux());                 // rtcp-mux defaults on
-
-  EXPECT_EQ(MEDIA_TYPE_VIDEO, vcd->type());
-  EXPECT_EQ(MAKE_VECTOR(kVideoCodecsAnswer), vcd->codecs());
-
-  const StreamParamsVec& video_streams = vcd->streams();
-  ASSERT_EQ(1U, video_streams.size());
-  EXPECT_EQ(video_streams[0].cname, audio_streams[0].cname);
-  EXPECT_EQ(kVideoTrack1, video_streams[0].name);
-  EXPECT_EQ(kAutoBandwidth, vcd->bandwidth());  // default bandwidth (auto)
-  EXPECT_TRUE(vcd->rtcp_mux());                 // rtcp-mux defaults on
-
-  // Update the answer. Add a new video track that is not synched to the
-  // other traacks and remove 1 audio track.
-  opts.AddStream(MEDIA_TYPE_VIDEO, kVideoTrack2, kMediaStream2);
-  opts.RemoveStream(MEDIA_TYPE_AUDIO, kAudioTrack2);
-  talk_base::scoped_ptr<SessionDescription>
-      updated_answer(f2_.CreateAnswer(offer.get(), opts, answer.get()));
-
-  ASSERT_TRUE(updated_answer.get() != NULL);
-  ac = updated_answer->GetContentByName("audio");
-  vc = updated_answer->GetContentByName("video");
-  ASSERT_TRUE(ac != NULL);
-  ASSERT_TRUE(vc != NULL);
-  const AudioContentDescription* updated_acd =
-      static_cast<const AudioContentDescription*>(ac->description);
-  const VideoContentDescription* updated_vcd =
-      static_cast<const VideoContentDescription*>(vc->description);
-
-  ASSERT_CRYPTO(updated_acd, false, 1U, CS_AES_CM_128_HMAC_SHA1_32);
-  EXPECT_TRUE(CompareCryptoParams(acd->cryptos(), updated_acd->cryptos()));
-  ASSERT_CRYPTO(updated_vcd, false, 1U, CS_AES_CM_128_HMAC_SHA1_80);
-  EXPECT_TRUE(CompareCryptoParams(vcd->cryptos(), updated_vcd->cryptos()));
-
-  EXPECT_EQ(acd->type(), updated_acd->type());
-  EXPECT_EQ(acd->codecs(), updated_acd->codecs());
-  EXPECT_EQ(vcd->type(), updated_vcd->type());
-  EXPECT_EQ(vcd->codecs(), updated_vcd->codecs());
-
-  const StreamParamsVec& updated_audio_streams = updated_acd->streams();
-  ASSERT_EQ(1U, updated_audio_streams.size());
-  EXPECT_TRUE(audio_streams[0] ==  updated_audio_streams[0]);
-
-  const StreamParamsVec& updated_video_streams = updated_vcd->streams();
-  ASSERT_EQ(2U, updated_video_streams.size());
-  EXPECT_EQ(video_streams[0], updated_video_streams[0]);
-  EXPECT_EQ(kVideoTrack2, updated_video_streams[1].name);
-  EXPECT_NE(updated_video_streams[1].cname, updated_video_streams[0].cname);
-}
diff --git a/third_party/libjingle/source/talk/session/phone/mediasessionclient.cc b/third_party/libjingle/source/talk/session/phone/mediasessionclient.cc
deleted file mode 100644
index 31bd1f7..0000000
--- a/third_party/libjingle/source/talk/session/phone/mediasessionclient.cc
+++ /dev/null
@@ -1,849 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string>
-
-#include "talk/session/phone/mediasessionclient.h"
-
-#include "talk/base/helpers.h"
-#include "talk/base/logging.h"
-#include "talk/base/stringutils.h"
-#include "talk/base/stringencode.h"
-#include "talk/p2p/base/constants.h"
-#include "talk/p2p/base/parsing.h"
-#include "talk/session/phone/cryptoparams.h"
-#include "talk/session/phone/mediamessages.h"
-#include "talk/session/phone/srtpfilter.h"
-#include "talk/xmpp/constants.h"
-#include "talk/xmllite/qname.h"
-#include "talk/xmllite/xmlconstants.h"
-
-namespace cricket {
-
-MediaSessionClient::MediaSessionClient(
-    const buzz::Jid& jid, SessionManager *manager)
-    : jid_(jid),
-      session_manager_(manager),
-      focus_call_(NULL),
-      channel_manager_(new ChannelManager(session_manager_->worker_thread())),
-      desc_factory_(channel_manager_) {
-  Construct();
-}
-
-MediaSessionClient::MediaSessionClient(
-    const buzz::Jid& jid, SessionManager *manager,
-    MediaEngineInterface* media_engine, DeviceManagerInterface* device_manager)
-    : jid_(jid),
-      session_manager_(manager),
-      focus_call_(NULL),
-      channel_manager_(new ChannelManager(
-          media_engine, device_manager, session_manager_->worker_thread())),
-      desc_factory_(channel_manager_) {
-  Construct();
-}
-
-void MediaSessionClient::Construct() {
-  // Register ourselves as the handler of audio and video sessions.
-  session_manager_->AddClient(NS_JINGLE_RTP, this);
-  // Forward device notifications.
-  SignalDevicesChange.repeat(channel_manager_->SignalDevicesChange);
-  // Bring up the channel manager.
-  // In previous versions of ChannelManager, this was done automatically
-  // in the constructor.
-  channel_manager_->Init();
-}
-
-MediaSessionClient::~MediaSessionClient() {
-  // Destroy all calls
-  std::map<uint32, Call *>::iterator it;
-  while (calls_.begin() != calls_.end()) {
-    std::map<uint32, Call *>::iterator it = calls_.begin();
-    DestroyCall((*it).second);
-  }
-
-  // Delete channel manager. This will wait for the channels to exit
-  delete channel_manager_;
-
-  // Remove ourselves from the client map.
-  session_manager_->RemoveClient(NS_JINGLE_RTP);
-}
-
-Call *MediaSessionClient::CreateCall() {
-  Call *call = new Call(this);
-  calls_[call->id()] = call;
-  SignalCallCreate(call);
-  return call;
-}
-
-void MediaSessionClient::OnSessionCreate(Session *session,
-                                         bool received_initiate) {
-  if (received_initiate) {
-    session->SignalState.connect(this, &MediaSessionClient::OnSessionState);
-  }
-}
-
-void MediaSessionClient::OnSessionState(BaseSession* base_session,
-                                        BaseSession::State state) {
-  // MediaSessionClient can only be used with a Session*, so it's
-  // safe to cast here.
-  Session* session = static_cast<Session*>(base_session);
-
-  if (state == Session::STATE_RECEIVEDINITIATE) {
-    // The creation of the call must happen after the session has
-    // processed the initiate message because we need the
-    // remote_description to know what content names to use in the
-    // call.
-
-    // If our accept would have no codecs, then we must reject this call.
-    const SessionDescription* offer = session->remote_description();
-    const SessionDescription* accept = CreateAnswer(offer, CallOptions());
-    const ContentInfo* audio_content = GetFirstAudioContent(accept);
-    const AudioContentDescription* audio_accept = (!audio_content) ? NULL :
-        static_cast<const AudioContentDescription*>(audio_content->description);
-
-    // For some reason, we need to create the call even when we
-    // reject.
-    Call *call = CreateCall();
-    session_map_[session->id()] = call;
-    call->IncomingSession(session, offer);
-
-    if (!audio_accept || audio_accept->codecs().size() == 0) {
-      session->Reject(STR_TERMINATE_INCOMPATIBLE_PARAMETERS);
-    }
-    delete accept;
-  }
-}
-
-void MediaSessionClient::DestroyCall(Call *call) {
-  // Change focus away, signal destruction
-
-  if (call == focus_call_)
-    SetFocus(NULL);
-  SignalCallDestroy(call);
-
-  // Remove it from calls_ map and delete
-
-  std::map<uint32, Call *>::iterator it = calls_.find(call->id());
-  if (it != calls_.end())
-    calls_.erase(it);
-
-  delete call;
-}
-
-void MediaSessionClient::OnSessionDestroy(Session *session) {
-  // Find the call this session is in, remove it
-
-  std::map<std::string, Call *>::iterator it = session_map_.find(session->id());
-  ASSERT(it != session_map_.end());
-  if (it != session_map_.end()) {
-    Call *call = (*it).second;
-    session_map_.erase(it);
-    call->RemoveSession(session);
-  }
-}
-
-Call *MediaSessionClient::GetFocus() {
-  return focus_call_;
-}
-
-void MediaSessionClient::SetFocus(Call *call) {
-  Call *old_focus_call = focus_call_;
-  if (focus_call_ != call) {
-    if (focus_call_ != NULL)
-      focus_call_->EnableChannels(false);
-    focus_call_ = call;
-    if (focus_call_ != NULL)
-      focus_call_->EnableChannels(true);
-    SignalFocus(focus_call_, old_focus_call);
-  }
-}
-
-void MediaSessionClient::JoinCalls(Call *call_to_join, Call *call) {
-  // Move all sessions from call to call_to_join, delete call.
-  // If call_to_join has focus, added sessions should have enabled channels.
-
-  if (focus_call_ == call)
-    SetFocus(NULL);
-  call_to_join->Join(call, focus_call_ == call_to_join);
-  DestroyCall(call);
-}
-
-Session *MediaSessionClient::CreateSession(Call *call) {
-  const std::string& type = NS_JINGLE_RTP;
-  Session *session = session_manager_->CreateSession(jid().Str(), type);
-  session_map_[session->id()] = call;
-  return session;
-}
-
-// TODO: Move all of the parsing and writing functions into
-// mediamessages.cc, with unit tests.
-bool ParseGingleAudioCodec(const buzz::XmlElement* element, AudioCodec* out) {
-  int id = GetXmlAttr(element, QN_ID, -1);
-  if (id < 0)
-    return false;
-
-  std::string name = GetXmlAttr(element, QN_NAME, buzz::STR_EMPTY);
-  int clockrate = GetXmlAttr(element, QN_CLOCKRATE, 0);
-  int bitrate = GetXmlAttr(element, QN_BITRATE, 0);
-  int channels = GetXmlAttr(element, QN_CHANNELS, 1);
-  *out = AudioCodec(id, name, clockrate, bitrate, channels, 0);
-  return true;
-}
-
-bool ParseGingleVideoCodec(const buzz::XmlElement* element, VideoCodec* out) {
-  int id = GetXmlAttr(element, QN_ID, -1);
-  if (id < 0)
-    return false;
-
-  std::string name = GetXmlAttr(element, QN_NAME, buzz::STR_EMPTY);
-  int width = GetXmlAttr(element, QN_WIDTH, 0);
-  int height = GetXmlAttr(element, QN_HEIGHT, 0);
-  int framerate = GetXmlAttr(element, QN_FRAMERATE, 0);
-
-  *out = VideoCodec(id, name, width, height, framerate, 0);
-  return true;
-}
-
-// Parses an ssrc string as a legacy stream.  If it fails, returns
-// false and fills an error message.
-bool ParseSsrcAsLegacyStream(const std::string& ssrc_str,
-                             std::vector<StreamParams>* streams,
-                             ParseError* error) {
-  if (!ssrc_str.empty()) {
-    uint32 ssrc;
-    if (!talk_base::FromString(ssrc_str, &ssrc)) {
-      return BadParse("Missing or invalid ssrc.", error);
-    }
-
-    streams->push_back(StreamParams::CreateLegacy(ssrc));
-  }
-  return true;
-}
-
-void ParseGingleSsrc(const buzz::XmlElement* parent_elem,
-                     const buzz::QName& name,
-                     MediaContentDescription* media) {
-  const buzz::XmlElement* ssrc_elem = parent_elem->FirstNamed(name);
-  if (ssrc_elem) {
-    ParseError error;
-    ParseSsrcAsLegacyStream(
-        ssrc_elem->BodyText(), &(media->mutable_streams()), &error);
-  }
-}
-
-bool ParseCryptoParams(const buzz::XmlElement* element,
-                       CryptoParams* out,
-                       ParseError* error) {
-  if (!element->HasAttr(QN_CRYPTO_SUITE)) {
-    return BadParse("crypto: crypto-suite attribute missing ", error);
-  } else if (!element->HasAttr(QN_CRYPTO_KEY_PARAMS)) {
-    return BadParse("crypto: key-params attribute missing ", error);
-  } else if (!element->HasAttr(QN_CRYPTO_TAG)) {
-    return BadParse("crypto: tag attribute missing ", error);
-  }
-
-  const std::string& crypto_suite = element->Attr(QN_CRYPTO_SUITE);
-  const std::string& key_params = element->Attr(QN_CRYPTO_KEY_PARAMS);
-  const int tag = GetXmlAttr(element, QN_CRYPTO_TAG, 0);
-  const std::string& session_params =
-      element->Attr(QN_CRYPTO_SESSION_PARAMS);  // Optional.
-
-  *out = CryptoParams(tag, crypto_suite, key_params, session_params);
-  return true;
-}
-
-
-// Parse the first encryption element found with a matching 'usage'
-// element.
-// <usage/> is specific to Gingle. In Jingle, <crypto/> is already
-// scoped to a content.
-// Return false if there was an encryption element and it could not be
-// parsed.
-bool ParseGingleEncryption(const buzz::XmlElement* desc,
-                           const buzz::QName& usage,
-                           MediaContentDescription* media,
-                           ParseError* error) {
-  for (const buzz::XmlElement* encryption = desc->FirstNamed(QN_ENCRYPTION);
-       encryption != NULL;
-       encryption = encryption->NextNamed(QN_ENCRYPTION)) {
-    if (encryption->FirstNamed(usage) != NULL) {
-      media->set_crypto_required(
-          GetXmlAttr(encryption, QN_ENCRYPTION_REQUIRED, false));
-      for (const buzz::XmlElement* crypto = encryption->FirstNamed(QN_CRYPTO);
-           crypto != NULL;
-           crypto = crypto->NextNamed(QN_CRYPTO)) {
-        CryptoParams params;
-        if (!ParseCryptoParams(crypto, &params, error)) {
-          return false;
-        }
-        media->AddCrypto(params);
-      }
-      break;
-    }
-  }
-  return true;
-}
-
-void ParseBandwidth(const buzz::XmlElement* parent_elem,
-                    MediaContentDescription* media) {
-  const buzz::XmlElement* bw_elem = GetXmlChild(parent_elem, LN_BANDWIDTH);
-  int bandwidth_kbps;
-  if (bw_elem && talk_base::FromString(bw_elem->BodyText(), &bandwidth_kbps)) {
-    if (bandwidth_kbps >= 0) {
-      media->set_bandwidth(bandwidth_kbps * 1000);
-    }
-  }
-}
-
-bool ParseGingleAudioContent(const buzz::XmlElement* content_elem,
-                             const ContentDescription** content,
-                             ParseError* error) {
-  AudioContentDescription* audio = new AudioContentDescription();
-
-  if (content_elem->FirstElement()) {
-    for (const buzz::XmlElement* codec_elem =
-             content_elem->FirstNamed(QN_GINGLE_AUDIO_PAYLOADTYPE);
-         codec_elem != NULL;
-         codec_elem = codec_elem->NextNamed(QN_GINGLE_AUDIO_PAYLOADTYPE)) {
-      AudioCodec codec;
-      if (ParseGingleAudioCodec(codec_elem, &codec)) {
-        audio->AddCodec(codec);
-      }
-    }
-  } else {
-    // For backward compatibility, we can assume the other client is
-    // an old version of Talk if it has no audio payload types at all.
-    audio->AddCodec(AudioCodec(103, "ISAC", 16000, -1, 1, 1));
-    audio->AddCodec(AudioCodec(0, "PCMU", 8000, 64000, 1, 0));
-  }
-
-  ParseGingleSsrc(content_elem, QN_GINGLE_AUDIO_SRCID, audio);
-
-  if (!ParseGingleEncryption(content_elem, QN_GINGLE_AUDIO_CRYPTO_USAGE,
-                             audio, error)) {
-    return false;
-  }
-
-  *content = audio;
-  return true;
-}
-
-bool ParseGingleVideoContent(const buzz::XmlElement* content_elem,
-                             const ContentDescription** content,
-                             ParseError* error) {
-  VideoContentDescription* video = new VideoContentDescription();
-
-  for (const buzz::XmlElement* codec_elem =
-           content_elem->FirstNamed(QN_GINGLE_VIDEO_PAYLOADTYPE);
-       codec_elem != NULL;
-       codec_elem = codec_elem->NextNamed(QN_GINGLE_VIDEO_PAYLOADTYPE)) {
-    VideoCodec codec;
-    if (ParseGingleVideoCodec(codec_elem, &codec)) {
-      video->AddCodec(codec);
-    }
-  }
-
-  ParseGingleSsrc(content_elem, QN_GINGLE_VIDEO_SRCID, video);
-  ParseBandwidth(content_elem, video);
-
-  if (!ParseGingleEncryption(content_elem, QN_GINGLE_VIDEO_CRYPTO_USAGE,
-                             video, error)) {
-    return false;
-  }
-
-  *content = video;
-  return true;
-}
-
-void ParsePayloadTypeParameters(const buzz::XmlElement* element,
-                                std::map<std::string, std::string>* paramap) {
-  for (const buzz::XmlElement* param = element->FirstNamed(QN_PARAMETER);
-       param != NULL; param = param->NextNamed(QN_PARAMETER)) {
-    std::string name  = GetXmlAttr(param, QN_PAYLOADTYPE_PARAMETER_NAME,
-                                   buzz::STR_EMPTY);
-    std::string value = GetXmlAttr(param, QN_PAYLOADTYPE_PARAMETER_VALUE,
-                                   buzz::STR_EMPTY);
-    if (!name.empty() && !value.empty()) {
-      paramap->insert(make_pair(name, value));
-    }
-  }
-}
-
-int FindWithDefault(const std::map<std::string, std::string>& map,
-                    const std::string& key, const int def) {
-  std::map<std::string, std::string>::const_iterator iter = map.find(key);
-  return (iter == map.end()) ? def : atoi(iter->second.c_str());
-}
-
-
-// Parse the first encryption element found.
-// Return false if there was an encryption element and it could not be
-// parsed.
-bool ParseJingleEncryption(const buzz::XmlElement* content_elem,
-                           MediaContentDescription* media,
-                           ParseError* error) {
-  const buzz::XmlElement* encryption =
-          content_elem->FirstNamed(QN_ENCRYPTION);
-  if (encryption == NULL) {
-      return true;
-  }
-
-  media->set_crypto_required(
-      GetXmlAttr(encryption, QN_ENCRYPTION_REQUIRED, false));
-
-  for (const buzz::XmlElement* crypto = encryption->FirstNamed(QN_CRYPTO);
-       crypto != NULL;
-       crypto = crypto->NextNamed(QN_CRYPTO)) {
-    CryptoParams params;
-    if (!ParseCryptoParams(crypto, &params, error)) {
-      return false;
-    }
-    media->AddCrypto(params);
-  }
-  return true;
-}
-
-bool ParseJingleAudioCodec(const buzz::XmlElement* elem, AudioCodec* codec) {
-  int id = GetXmlAttr(elem, QN_ID, -1);
-  if (id < 0)
-    return false;
-
-  std::string name = GetXmlAttr(elem, QN_NAME, buzz::STR_EMPTY);
-  int clockrate = GetXmlAttr(elem, QN_CLOCKRATE, 0);
-  int channels = GetXmlAttr(elem, QN_CHANNELS, 1);
-
-  std::map<std::string, std::string> paramap;
-  ParsePayloadTypeParameters(elem, &paramap);
-  int bitrate = FindWithDefault(paramap, PAYLOADTYPE_PARAMETER_BITRATE, 0);
-
-  *codec = AudioCodec(id, name, clockrate, bitrate, channels, 0);
-  return true;
-}
-
-bool ParseJingleVideoCodec(const buzz::XmlElement* elem, VideoCodec* codec) {
-  int id = GetXmlAttr(elem, QN_ID, -1);
-  if (id < 0)
-    return false;
-
-  std::string name = GetXmlAttr(elem, QN_NAME, buzz::STR_EMPTY);
-
-  std::map<std::string, std::string> paramap;
-  ParsePayloadTypeParameters(elem, &paramap);
-  int width = FindWithDefault(paramap, PAYLOADTYPE_PARAMETER_WIDTH, 0);
-  int height = FindWithDefault(paramap, PAYLOADTYPE_PARAMETER_HEIGHT, 0);
-  int framerate = FindWithDefault(paramap, PAYLOADTYPE_PARAMETER_FRAMERATE, 0);
-
-  *codec = VideoCodec(id, name, width, height, framerate, 0);
-  return true;
-}
-
-bool ParseJingleStreamsOrLegacySsrc(const buzz::XmlElement* desc_elem,
-                                    MediaContentDescription* media,
-                                    ParseError* error) {
-  if (HasJingleStreams(desc_elem)) {
-    if (!ParseJingleStreams(desc_elem, &(media->mutable_streams()), error)) {
-      return false;
-    }
-  } else {
-    const std::string ssrc_str = desc_elem->Attr(QN_SSRC);
-    if (!ParseSsrcAsLegacyStream(
-            ssrc_str, &(media->mutable_streams()), error)) {
-      return false;
-    }
-  }
-  return true;
-}
-
-bool ParseJingleAudioContent(const buzz::XmlElement* content_elem,
-                             const ContentDescription** content,
-                             ParseError* error) {
-  AudioContentDescription* audio = new AudioContentDescription();
-
-  for (const buzz::XmlElement* payload_elem =
-           content_elem->FirstNamed(QN_JINGLE_RTP_PAYLOADTYPE);
-      payload_elem != NULL;
-      payload_elem = payload_elem->NextNamed(QN_JINGLE_RTP_PAYLOADTYPE)) {
-    AudioCodec codec;
-    if (ParseJingleAudioCodec(payload_elem, &codec)) {
-      audio->AddCodec(codec);
-    }
-  }
-
-  if (!ParseJingleStreamsOrLegacySsrc(content_elem, audio, error)) {
-    return false;
-  }
-
-  if (!ParseJingleEncryption(content_elem, audio, error)) {
-    return false;
-  }
-
-  audio->set_rtcp_mux(content_elem->FirstNamed(QN_JINGLE_RTCP_MUX) != NULL);
-
-  *content = audio;
-  return true;
-}
-
-bool ParseJingleVideoContent(const buzz::XmlElement* content_elem,
-                             const ContentDescription** content,
-                             ParseError* error) {
-  VideoContentDescription* video = new VideoContentDescription();
-
-  for (const buzz::XmlElement* payload_elem =
-           content_elem->FirstNamed(QN_JINGLE_RTP_PAYLOADTYPE);
-      payload_elem != NULL;
-      payload_elem = payload_elem->NextNamed(QN_JINGLE_RTP_PAYLOADTYPE)) {
-    VideoCodec codec;
-    if (ParseJingleVideoCodec(payload_elem, &codec)) {
-      video->AddCodec(codec);
-    }
-  }
-
-  if (!ParseJingleStreamsOrLegacySsrc(content_elem, video, error)) {
-    return false;
-  }
-  ParseBandwidth(content_elem, video);
-
-  if (!ParseJingleEncryption(content_elem, video, error)) {
-    return false;
-  }
-
-  video->set_rtcp_mux(content_elem->FirstNamed(QN_JINGLE_RTCP_MUX) != NULL);
-
-  *content = video;
-  return true;
-}
-
-bool MediaSessionClient::ParseContent(SignalingProtocol protocol,
-                                     const buzz::XmlElement* content_elem,
-                                     const ContentDescription** content,
-                                     ParseError* error) {
-  if (protocol == PROTOCOL_GINGLE) {
-    const std::string& content_type = content_elem->Name().Namespace();
-    if (NS_GINGLE_AUDIO == content_type) {
-      return ParseGingleAudioContent(content_elem, content, error);
-    } else if (NS_GINGLE_VIDEO == content_type) {
-      return ParseGingleVideoContent(content_elem, content, error);
-    } else {
-      return BadParse("Unknown content type: " + content_type, error);
-    }
-  } else {
-    std::string media;
-    if (!RequireXmlAttr(content_elem, QN_JINGLE_CONTENT_MEDIA, &media, error))
-      return false;
-
-    if (media == JINGLE_CONTENT_MEDIA_AUDIO) {
-      return ParseJingleAudioContent(content_elem, content, error);
-    } else if (media == JINGLE_CONTENT_MEDIA_VIDEO) {
-      return ParseJingleVideoContent(content_elem, content, error);
-    } else {
-      return BadParse("Unknown media: " + media, error);
-    }
-  }
-}
-
-buzz::XmlElement* CreateGingleAudioCodecElem(const AudioCodec& codec) {
-  buzz::XmlElement* payload_type =
-      new buzz::XmlElement(QN_GINGLE_AUDIO_PAYLOADTYPE, true);
-  AddXmlAttr(payload_type, QN_ID, codec.id);
-  payload_type->AddAttr(QN_NAME, codec.name);
-  if (codec.clockrate > 0)
-    AddXmlAttr(payload_type, QN_CLOCKRATE, codec.clockrate);
-  if (codec.bitrate > 0)
-    AddXmlAttr(payload_type, QN_BITRATE, codec.bitrate);
-  if (codec.channels > 1)
-    AddXmlAttr(payload_type, QN_CHANNELS, codec.channels);
-  return payload_type;
-}
-
-buzz::XmlElement* CreateGingleVideoCodecElem(const VideoCodec& codec) {
-  buzz::XmlElement* payload_type =
-      new buzz::XmlElement(QN_GINGLE_VIDEO_PAYLOADTYPE, true);
-  AddXmlAttr(payload_type, QN_ID, codec.id);
-  payload_type->AddAttr(QN_NAME, codec.name);
-  AddXmlAttr(payload_type, QN_WIDTH, codec.width);
-  AddXmlAttr(payload_type, QN_HEIGHT, codec.height);
-  AddXmlAttr(payload_type, QN_FRAMERATE, codec.framerate);
-  return payload_type;
-}
-
-buzz::XmlElement* CreateGingleSsrcElem(const buzz::QName& name, uint32 ssrc) {
-  buzz::XmlElement* elem = new buzz::XmlElement(name, true);
-  if (ssrc) {
-    SetXmlBody(elem, ssrc);
-  }
-  return elem;
-}
-
-buzz::XmlElement* CreateBandwidthElem(const buzz::QName& name, int bps) {
-  int kbps = bps / 1000;
-  buzz::XmlElement* elem = new buzz::XmlElement(name);
-  elem->AddAttr(buzz::QN_TYPE, "AS");
-  SetXmlBody(elem, kbps);
-  return elem;
-}
-
-// For Jingle, usage_qname is empty.
-buzz::XmlElement* CreateJingleEncryptionElem(const CryptoParamsVec& cryptos,
-                                             bool required) {
-  buzz::XmlElement* encryption_elem = new buzz::XmlElement(QN_ENCRYPTION);
-
-  if (required) {
-    encryption_elem->SetAttr(QN_ENCRYPTION_REQUIRED, "true");
-  }
-
-  for (CryptoParamsVec::const_iterator i = cryptos.begin();
-       i != cryptos.end();
-       ++i) {
-    buzz::XmlElement* crypto_elem = new buzz::XmlElement(QN_CRYPTO);
-
-    AddXmlAttr(crypto_elem, QN_CRYPTO_TAG, i->tag);
-    crypto_elem->AddAttr(QN_CRYPTO_SUITE, i->cipher_suite);
-    crypto_elem->AddAttr(QN_CRYPTO_KEY_PARAMS, i->key_params);
-    if (!i->session_params.empty()) {
-      crypto_elem->AddAttr(QN_CRYPTO_SESSION_PARAMS, i->session_params);
-    }
-    encryption_elem->AddElement(crypto_elem);
-  }
-  return encryption_elem;
-}
-
-buzz::XmlElement* CreateGingleEncryptionElem(const CryptoParamsVec& cryptos,
-                                             const buzz::QName& usage_qname,
-                                             bool required) {
-  buzz::XmlElement* encryption_elem =
-      CreateJingleEncryptionElem(cryptos, required);
-
-  if (required) {
-    encryption_elem->SetAttr(QN_ENCRYPTION_REQUIRED, "true");
-  }
-
-  buzz::XmlElement* usage_elem = new buzz::XmlElement(usage_qname);
-  encryption_elem->AddElement(usage_elem);
-
-  return encryption_elem;
-}
-
-buzz::XmlElement* CreateGingleAudioContentElem(
-    const AudioContentDescription* audio,
-    bool crypto_required) {
-  buzz::XmlElement* elem =
-      new buzz::XmlElement(QN_GINGLE_AUDIO_CONTENT, true);
-
-  for (AudioCodecs::const_iterator codec = audio->codecs().begin();
-       codec != audio->codecs().end(); ++codec) {
-    elem->AddElement(CreateGingleAudioCodecElem(*codec));
-  }
-  if (audio->has_ssrcs()) {
-    elem->AddElement(CreateGingleSsrcElem(
-        QN_GINGLE_AUDIO_SRCID, audio->first_ssrc()));
-  }
-
-  const CryptoParamsVec& cryptos = audio->cryptos();
-  if (!cryptos.empty()) {
-    elem->AddElement(CreateGingleEncryptionElem(cryptos,
-                                                QN_GINGLE_AUDIO_CRYPTO_USAGE,
-                                                crypto_required));
-  }
-  return elem;
-}
-
-buzz::XmlElement* CreateGingleVideoContentElem(
-    const VideoContentDescription* video,
-    bool crypto_required) {
-  buzz::XmlElement* elem =
-      new buzz::XmlElement(QN_GINGLE_VIDEO_CONTENT, true);
-
-  for (VideoCodecs::const_iterator codec = video->codecs().begin();
-       codec != video->codecs().end(); ++codec) {
-    elem->AddElement(CreateGingleVideoCodecElem(*codec));
-  }
-  if (video->has_ssrcs()) {
-    elem->AddElement(CreateGingleSsrcElem(
-        QN_GINGLE_VIDEO_SRCID, video->first_ssrc()));
-  }
-  if (video->bandwidth() != kAutoBandwidth) {
-    elem->AddElement(CreateBandwidthElem(QN_GINGLE_VIDEO_BANDWIDTH,
-                                         video->bandwidth()));
-  }
-
-  const CryptoParamsVec& cryptos = video->cryptos();
-  if (!cryptos.empty()) {
-    elem->AddElement(CreateGingleEncryptionElem(cryptos,
-                                                QN_GINGLE_VIDEO_CRYPTO_USAGE,
-                                                crypto_required));
-  }
-
-  return elem;
-}
-
-buzz::XmlElement* CreatePayloadTypeParameterElem(
-    const std::string& name, int value) {
-  buzz::XmlElement* elem = new buzz::XmlElement(QN_PARAMETER);
-
-  elem->AddAttr(QN_PAYLOADTYPE_PARAMETER_NAME, name);
-  AddXmlAttr(elem, QN_PAYLOADTYPE_PARAMETER_VALUE, value);
-
-  return elem;
-}
-
-buzz::XmlElement* CreateJingleAudioCodecElem(const AudioCodec& codec) {
-  buzz::XmlElement* elem = new buzz::XmlElement(QN_JINGLE_RTP_PAYLOADTYPE);
-
-  AddXmlAttr(elem, QN_ID, codec.id);
-  elem->AddAttr(QN_NAME, codec.name);
-  if (codec.clockrate > 0) {
-    AddXmlAttr(elem, QN_CLOCKRATE, codec.clockrate);
-  }
-  if (codec.bitrate > 0) {
-    elem->AddElement(CreatePayloadTypeParameterElem(
-        PAYLOADTYPE_PARAMETER_BITRATE, codec.bitrate));
-  }
-  if (codec.channels > 1) {
-    AddXmlAttr(elem, QN_CHANNELS, codec.channels);
-  }
-
-  return elem;
-}
-
-buzz::XmlElement* CreateJingleVideoCodecElem(const VideoCodec& codec) {
-  buzz::XmlElement* elem = new buzz::XmlElement(QN_JINGLE_RTP_PAYLOADTYPE);
-
-  AddXmlAttr(elem, QN_ID, codec.id);
-  elem->AddAttr(QN_NAME, codec.name);
-  elem->AddElement(CreatePayloadTypeParameterElem(
-      PAYLOADTYPE_PARAMETER_WIDTH, codec.width));
-  elem->AddElement(CreatePayloadTypeParameterElem(
-      PAYLOADTYPE_PARAMETER_HEIGHT, codec.height));
-  elem->AddElement(CreatePayloadTypeParameterElem(
-      PAYLOADTYPE_PARAMETER_FRAMERATE, codec.framerate));
-
-  return elem;
-}
-
-void WriteLegacyJingleSsrc(const MediaContentDescription* media,
-                           buzz::XmlElement* elem) {
-  if (media->has_ssrcs()) {
-    AddXmlAttr(elem, QN_SSRC, media->first_ssrc());
-  }
-}
-
-void WriteJingleStreamsOrLegacySsrc(const MediaContentDescription* media,
-                                    buzz::XmlElement* desc_elem) {
-  if (!media->multistream()) {
-    WriteLegacyJingleSsrc(media, desc_elem);
-  } else {
-    WriteJingleStreams(media->streams(), desc_elem);
-  }
-}
-
-buzz::XmlElement* CreateJingleAudioContentElem(
-    const AudioContentDescription* audio, bool crypto_required) {
-  buzz::XmlElement* elem =
-      new buzz::XmlElement(QN_JINGLE_RTP_CONTENT, true);
-
-  elem->SetAttr(QN_JINGLE_CONTENT_MEDIA, JINGLE_CONTENT_MEDIA_AUDIO);
-  WriteJingleStreamsOrLegacySsrc(audio, elem);
-
-  for (AudioCodecs::const_iterator codec = audio->codecs().begin();
-       codec != audio->codecs().end(); ++codec) {
-    elem->AddElement(CreateJingleAudioCodecElem(*codec));
-  }
-
-  const CryptoParamsVec& cryptos = audio->cryptos();
-  if (!cryptos.empty()) {
-    elem->AddElement(CreateJingleEncryptionElem(cryptos, crypto_required));
-  }
-
-  if (audio->rtcp_mux()) {
-    elem->AddElement(new buzz::XmlElement(QN_JINGLE_RTCP_MUX));
-  }
-
-  return elem;
-}
-
-buzz::XmlElement* CreateJingleVideoContentElem(
-    const VideoContentDescription* video, bool crypto_required) {
-  buzz::XmlElement* elem =
-      new buzz::XmlElement(QN_JINGLE_RTP_CONTENT, true);
-
-  elem->SetAttr(QN_JINGLE_CONTENT_MEDIA, JINGLE_CONTENT_MEDIA_VIDEO);
-  WriteJingleStreamsOrLegacySsrc(video, elem);
-
-  for (VideoCodecs::const_iterator codec = video->codecs().begin();
-       codec != video->codecs().end(); ++codec) {
-    elem->AddElement(CreateJingleVideoCodecElem(*codec));
-  }
-
-  const CryptoParamsVec& cryptos = video->cryptos();
-  if (!cryptos.empty()) {
-    elem->AddElement(CreateJingleEncryptionElem(cryptos, crypto_required));
-  }
-
-  if (video->rtcp_mux()) {
-    elem->AddElement(new buzz::XmlElement(QN_JINGLE_RTCP_MUX));
-  }
-
-  if (video->bandwidth() != kAutoBandwidth) {
-    elem->AddElement(CreateBandwidthElem(QN_JINGLE_RTP_BANDWIDTH,
-                                         video->bandwidth()));
-  }
-
-  return elem;
-}
-
-bool MediaSessionClient::WriteContent(SignalingProtocol protocol,
-                                      const ContentDescription* content,
-                                      buzz::XmlElement** elem,
-                                      WriteError* error) {
-  const MediaContentDescription* media =
-      static_cast<const MediaContentDescription*>(content);
-  bool crypto_required = secure() == SEC_REQUIRED;
-
-  if (media->type() == MEDIA_TYPE_AUDIO) {
-    const AudioContentDescription* audio =
-        static_cast<const AudioContentDescription*>(media);
-    if (protocol == PROTOCOL_GINGLE) {
-      *elem = CreateGingleAudioContentElem(audio, crypto_required);
-    } else {
-      *elem = CreateJingleAudioContentElem(audio, crypto_required);
-    }
-  } else if (media->type() == MEDIA_TYPE_VIDEO) {
-    const VideoContentDescription* video =
-        static_cast<const VideoContentDescription*>(media);
-    if (protocol == PROTOCOL_GINGLE) {
-      *elem = CreateGingleVideoContentElem(video, crypto_required);
-    } else {
-      *elem = CreateJingleVideoContentElem(video, crypto_required);
-    }
-  } else {
-    return BadWrite("Unknown content type: " + media->type(), error);
-  }
-
-  return true;
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/session/phone/mediasessionclient.h b/third_party/libjingle/source/talk/session/phone/mediasessionclient.h
deleted file mode 100644
index 893e95f..0000000
--- a/third_party/libjingle/source/talk/session/phone/mediasessionclient.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SESSION_PHONE_MEDIASESSIONCLIENT_H_
-#define TALK_SESSION_PHONE_MEDIASESSIONCLIENT_H_
-
-#include <string>
-#include <vector>
-#include <map>
-#include <algorithm>
-#include "talk/session/phone/call.h"
-#include "talk/session/phone/channelmanager.h"
-#include "talk/session/phone/cryptoparams.h"
-#include "talk/session/phone/mediasession.h"
-#include "talk/base/sigslot.h"
-#include "talk/base/sigslotrepeater.h"
-#include "talk/base/messagequeue.h"
-#include "talk/base/thread.h"
-#include "talk/p2p/base/sessionmanager.h"
-#include "talk/p2p/base/session.h"
-#include "talk/p2p/base/sessionclient.h"
-#include "talk/p2p/base/sessiondescription.h"
-
-namespace cricket {
-
-class Call;
-
-class MediaSessionClient : public SessionClient, public sigslot::has_slots<> {
- public:
-  MediaSessionClient(const buzz::Jid& jid, SessionManager *manager);
-  // Alternative constructor, allowing injection of media_engine
-  // and device_manager.
-  MediaSessionClient(const buzz::Jid& jid, SessionManager *manager,
-                     MediaEngineInterface* media_engine,
-                     DeviceManagerInterface* device_manager);
-  ~MediaSessionClient();
-
-  const buzz::Jid &jid() const { return jid_; }
-  SessionManager* session_manager() const { return session_manager_; }
-  ChannelManager* channel_manager() const { return channel_manager_; }
-
-  SecureMediaPolicy secure() const { return desc_factory_.secure(); }
-  void set_secure(SecureMediaPolicy s) { desc_factory_.set_secure(s); }
-
-  int GetCapabilities() { return channel_manager_->GetCapabilities(); }
-
-  Call *CreateCall();
-  void DestroyCall(Call *call);
-
-  Call *GetFocus();
-  void SetFocus(Call *call);
-
-  void JoinCalls(Call *call_to_join, Call *call);
-
-  bool GetAudioInputDevices(std::vector<std::string>* names) {
-    return channel_manager_->GetAudioInputDevices(names);
-  }
-  bool GetAudioOutputDevices(std::vector<std::string>* names) {
-    return channel_manager_->GetAudioOutputDevices(names);
-  }
-  bool GetVideoCaptureDevices(std::vector<std::string>* names) {
-    return channel_manager_->GetVideoCaptureDevices(names);
-  }
-
-  bool SetAudioOptions(const std::string& in_name, const std::string& out_name,
-                       int opts) {
-    return channel_manager_->SetAudioOptions(in_name, out_name, opts);
-  }
-  bool SetOutputVolume(int level) {
-    return channel_manager_->SetOutputVolume(level);
-  }
-  bool SetVideoOptions(const std::string& cam_device) {
-    return channel_manager_->SetVideoOptions(cam_device);
-  }
-
-  SessionDescription* CreateOffer(const CallOptions& options) {
-    return desc_factory_.CreateOffer(options, NULL);
-  }
-  SessionDescription* CreateAnswer(const SessionDescription* offer,
-                                   const CallOptions& options) {
-    return desc_factory_.CreateAnswer(offer, options, NULL);
-  }
-
-  sigslot::signal2<Call *, Call *> SignalFocus;
-  sigslot::signal1<Call *> SignalCallCreate;
-  sigslot::signal1<Call *> SignalCallDestroy;
-  sigslot::repeater0<> SignalDevicesChange;
-
- private:
-  void Construct();
-  void OnSessionCreate(Session *session, bool received_initiate);
-  void OnSessionState(BaseSession *session, BaseSession::State state);
-  void OnSessionDestroy(Session *session);
-  virtual bool ParseContent(SignalingProtocol protocol,
-                            const buzz::XmlElement* elem,
-                            const ContentDescription** content,
-                            ParseError* error);
-  virtual bool WriteContent(SignalingProtocol protocol,
-                            const ContentDescription* content,
-                            buzz::XmlElement** elem,
-                            WriteError* error);
-  Session *CreateSession(Call *call);
-
-  buzz::Jid jid_;
-  SessionManager* session_manager_;
-  Call *focus_call_;
-  ChannelManager *channel_manager_;
-  MediaSessionDescriptionFactory desc_factory_;
-  std::map<uint32, Call *> calls_;
-  std::map<std::string, Call *> session_map_;
-  friend class Call;
-};
-
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_MEDIASESSIONCLIENT_H_
diff --git a/third_party/libjingle/source/talk/session/phone/mediasessionclient_unittest.cc b/third_party/libjingle/source/talk/session/phone/mediasessionclient_unittest.cc
deleted file mode 100644
index 574b052..0000000
--- a/third_party/libjingle/source/talk/session/phone/mediasessionclient_unittest.cc
+++ /dev/null
@@ -1,2696 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string>
-#include <vector>
-
-#include "talk/base/gunit.h"
-#include "talk/base/logging.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/p2p/base/constants.h"
-#include "talk/p2p/client/basicportallocator.h"
-#include "talk/session/phone/fakedevicemanager.h"
-#include "talk/session/phone/fakemediaengine.h"
-#include "talk/session/phone/mediasessionclient.h"
-#include "talk/xmllite/xmlelement.h"
-#include "talk/xmllite/xmlbuilder.h"
-#include "talk/xmllite/xmlprinter.h"
-#include "talk/xmpp/constants.h"
-
-// The codecs that our FakeMediaEngine will support. Order is important, since
-// the tests check that our messages have codecs in the correct order.
-static const cricket::AudioCodec kAudioCodecs[] = {
-  cricket::AudioCodec(103, "ISAC",   16000, -1,    1, 18),
-  cricket::AudioCodec(104, "ISAC",   32000, -1,    1, 17),
-  cricket::AudioCodec(119, "ISACLC", 16000, 40000, 1, 16),
-  cricket::AudioCodec(99,  "speex",  16000, 22000, 1, 15),
-  cricket::AudioCodec(97,  "IPCMWB", 16000, 80000, 1, 14),
-  cricket::AudioCodec(9,   "G722",   16000, 64000, 1, 13),
-  cricket::AudioCodec(102, "iLBC",   8000,  13300, 1, 12),
-  cricket::AudioCodec(98,  "speex",  8000,  11000, 1, 11),
-  cricket::AudioCodec(3,   "GSM",    8000,  13000, 1, 10),
-  cricket::AudioCodec(100, "EG711U", 8000,  64000, 1, 9),
-  cricket::AudioCodec(101, "EG711A", 8000,  64000, 1, 8),
-  cricket::AudioCodec(0,   "PCMU",   8000,  64000, 1, 7),
-  cricket::AudioCodec(8,   "PCMA",   8000,  64000, 1, 6),
-  cricket::AudioCodec(126, "CN",     32000, 0,     1, 5),
-  cricket::AudioCodec(105, "CN",     16000, 0,     1, 4),
-  cricket::AudioCodec(13,  "CN",     8000,  0,     1, 3),
-  cricket::AudioCodec(117, "red",    8000,  0,     1, 2),
-  cricket::AudioCodec(106, "telephone-event", 8000, 0, 1, 1)
-};
-
-static const cricket::VideoCodec kVideoCodecs[] = {
-  cricket::VideoCodec(96, "H264-SVC", 320, 200, 30, 1)
-};
-
-const std::string kGingleCryptoOffer = \
-    "<rtp:encryption xmlns:rtp='urn:xmpp:jingle:apps:rtp:1'>   "  \
-    "  <usage/>                                                "  \
-    "  <rtp:crypto tag='145' crypto-suite='AES_CM_128_HMAC_SHA1_32'" \
-    "  key-params='inline:hsWuSQJxx7przmb8HM+ZkeNcG3HezSNID7LmfDa9'/>" \
-    "  <rtp:crypto tag='51' crypto-suite='AES_CM_128_HMAC_SHA1_80'" \
-    "  key-params='inline:J4lfdUL8W1F7TNJKcbuygaQuA429SJy2e9JctPUy'/>" \
-    "</rtp:encryption>                                         ";
-
-// Jingle offer does not have any <usage> element.
-const std::string kJingleCryptoOffer = \
-    "<rtp:encryption xmlns:rtp='urn:xmpp:jingle:apps:rtp:1'>   "  \
-    "  <rtp:crypto tag='145' crypto-suite='AES_CM_128_HMAC_SHA1_32'" \
-    "  key-params='inline:hsWuSQJxx7przmb8HM+ZkeNcG3HezSNID7LmfDa9'/>" \
-    "  <rtp:crypto tag='51' crypto-suite='AES_CM_128_HMAC_SHA1_80'" \
-    "  key-params='inline:J4lfdUL8W1F7TNJKcbuygaQuA429SJy2e9JctPUy'/>" \
-    "</rtp:encryption>                                         ";
-
-
-const std::string kGingleRequiredCryptoOffer = \
-    "<rtp:encryption xmlns:rtp='urn:xmpp:jingle:apps:rtp:1' required='true'> "\
-    "  <usage/>                                                "  \
-    "  <rtp:crypto tag='145' crypto-suite='AES_CM_128_HMAC_SHA1_32'" \
-    "  key-params='inline:hsWuSQJxx7przmb8HM+ZkeNcG3HezSNID7LmfDa9'/>" \
-    "  <rtp:crypto tag='51' crypto-suite='AES_CM_128_HMAC_SHA1_80'" \
-    "  key-params='inline:J4lfdUL8W1F7TNJKcbuygaQuA429SJy2e9JctPUy'/>" \
-    "</rtp:encryption>                                         ";
-
-const std::string kJingleRequiredCryptoOffer = \
-    "<rtp:encryption xmlns:rtp='urn:xmpp:jingle:apps:rtp:1' required='true'> "\
-    "  <rtp:crypto tag='145' crypto-suite='AES_CM_128_HMAC_SHA1_32'" \
-    "  key-params='inline:hsWuSQJxx7przmb8HM+ZkeNcG3HezSNID7LmfDa9'/>" \
-    "  <rtp:crypto tag='51' crypto-suite='AES_CM_128_HMAC_SHA1_80'" \
-    "  key-params='inline:J4lfdUL8W1F7TNJKcbuygaQuA429SJy2e9JctPUy'/>" \
-    "</rtp:encryption>                                         ";
-
-
-const std::string kGingleUnsupportedCryptoOffer = \
-    "<rtp:encryption xmlns:rtp='urn:xmpp:jingle:apps:rtp:1'>   "  \
-    "  <usage/>                                                "  \
-    "  <rtp:crypto tag='145' crypto-suite='NOT_SUPPORTED_1'" \
-    "  key-params='inline:hsWuSQJxx7przmb8HM+ZkeNcG3HezSNID7LmfDa9'/>" \
-    "  <rtp:crypto tag='51' crypto-suite='NOT_SUPPORTED_2'" \
-    "  key-params='inline:J4lfdUL8W1F7TNJKcbuygaQuA429SJy2e9JctPUy'/>" \
-    "</rtp:encryption>                                         ";
-
-const std::string kJingleUnsupportedCryptoOffer =                 \
-    "<rtp:encryption xmlns:rtp='urn:xmpp:jingle:apps:rtp:1'>   "  \
-    "  <rtp:crypto tag='145' crypto-suite='NOT_SUPPORTED_1'" \
-    "  key-params='inline:hsWuSQJxx7przmb8HM+ZkeNcG3HezSNID7LmfDa9'/>" \
-    "  <rtp:crypto tag='51' crypto-suite='NOT_SUPPORTED_2'" \
-    "  key-params='inline:J4lfdUL8W1F7TNJKcbuygaQuA429SJy2e9JctPUy'/>" \
-    "</rtp:encryption>                                         ";
-
-
-// With unsupported but with required="true"
-const std::string kGingleRequiredUnsupportedCryptoOffer =         \
-    "<rtp:encryption xmlns:rtp='urn:xmpp:jingle:apps:rtp:1' required='true'>" \
-    "  <usage/>                                                "  \
-    "  <rtp:crypto tag='145' crypto-suite='NOT_SUPPORTED_1'"      \
-    "  key-params='inline:hsWuSQJxx7przmb8HM+ZkeNcG3HezSNID7LmfDa9'/>" \
-    "  <rtp:crypto tag='51' crypto-suite='NOT_SUPPORTED_2'" \
-    "  key-params='inline:J4lfdUL8W1F7TNJKcbuygaQuA429SJy2e9JctPUy'/>" \
-    "</rtp:encryption>                                         ";
-
-const std::string kJingleRequiredUnsupportedCryptoOffer =                     \
-    "<rtp:encryption xmlns:rtp='urn:xmpp:jingle:apps:rtp:1' required='true'>" \
-    "  <rtp:crypto tag='145' crypto-suite='NOT_SUPPORTED_1'                 " \
-    "  key-params='inline:hsWuSQJxx7przmb8HM+ZkeNcG3HezSNID7LmfDa9'/>       " \
-    "  <rtp:crypto tag='51' crypto-suite='NOT_SUPPORTED_2'                  " \
-    "  key-params='inline:J4lfdUL8W1F7TNJKcbuygaQuA429SJy2e9JctPUy'/>"        \
-    "</rtp:encryption>                                         ";
-
-const std::string kGingleInitiate(
-     "<iq xmlns='jabber:client' from='me@domain.com/resource'         " \
-     "    to='user@domain.com/resource' type='set' id='123'>          " \
-     "  <session xmlns='http://www.google.com/session' type='initiate'" \
-     "    id='abcdef' initiator='me@domain.com/resource'>             " \
-     "    <description xmlns='http://www.google.com/session/phone'>   " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='103' name='ISAC' clockrate='16000' />               " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='104' name='ISAC' clockrate='32000' />               " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='119' name='ISACLC' clockrate='16000' bitrate='40000' />  " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='99' name='speex' clockrate='16000' bitrate='22000' />    " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='97' name='IPCMWB' clockrate='16000' bitrate='80000' />   " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='9' name='G722' clockrate='16000' bitrate='64000' /> " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='102' name='iLBC' clockrate='8000' bitrate='13300' />" \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='98' name='speex' clockrate='8000' bitrate='11000' />" \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='3' name='GSM' clockrate='8000' bitrate='13000' />   " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='100' name='EG711U' clockrate='8000' bitrate='64000' />   " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='101' name='EG711A' clockrate='8000' bitrate='64000' />   " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='0' name='PCMU' clockrate='8000' bitrate='64000' />  " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='8' name='PCMA' clockrate='8000' bitrate='64000' />  " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='126' name='CN' clockrate='32000' />                 " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='105' name='CN' clockrate='16000' />                 " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='13' name='CN' clockrate='8000' />                   " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='117' name='red' clockrate='8000' />                 " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='106' name='telephone-event' clockrate='8000' />     " \
-     "    </description>                                              " \
-     "  </session>                                                    " \
-     "</iq>                                                           ");
-
-const std::string kJingleInitiate(
-     "<iq xmlns='jabber:client' from='me@domain.com/resource'           " \
-     "    to='user@domain.com/resource' type='set' id='123'>            " \
-     "  <jingle xmlns='urn:xmpp:jingle:1' action='session-initiate'     " \
-     "          sid='abcdef' initiator='me@domain.com/resource'>        " \
-     "    <content name='test audio'>                                   " \
-     "      <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'> " \
-     "        <payload-type id='103' name='ISAC' clockrate='16000'/>    " \
-     "        <payload-type id='104' name='ISAC' clockrate='32000'/>    " \
-     "        <payload-type                                             " \
-     "          id='119' name='ISACLC' clockrate='16000'>               " \
-     "          <parameter name='bitrate' value='40000'/>               " \
-     "        </payload-type>                                           " \
-     "        <payload-type                                             " \
-     "          id='99' name='speex' clockrate='16000'>                 " \
-     "          <parameter name='bitrate' value='22000'/>               " \
-     "        </payload-type>                                           " \
-     "        <payload-type                                             " \
-     "          id='97' name='IPCMWB' clockrate='16000'>                " \
-     "          <parameter name='bitrate' value='80000'/>               " \
-     "        </payload-type>                                           " \
-     "        <payload-type                                             " \
-     "          id='9' name='G722' clockrate='16000'>                   " \
-     "          <parameter name='bitrate' value='64000'/>               " \
-     "        </payload-type>                                           " \
-     "        <payload-type                                             " \
-     "          id='102' name='iLBC' clockrate='8000'>                  " \
-     "          <parameter name='bitrate' value='13300'/>               " \
-     "        </payload-type>                                           " \
-     "        <payload-type                                             " \
-     "          id='98' name='speex' clockrate='8000'>                  " \
-     "          <parameter name='bitrate' value='11000'/>               " \
-     "        </payload-type>                                           " \
-     "        <payload-type                                             " \
-     "          id='3' name='GSM' clockrate='8000'>                     " \
-     "          <parameter name='bitrate' value='13000'/>               " \
-     "        </payload-type>                                           " \
-     "        <payload-type                                             " \
-     "          id='100' name='EG711U' clockrate='8000'>                " \
-     "          <parameter name='bitrate' value='64000'/>               " \
-     "        </payload-type>                                           " \
-     "        <payload-type                                             " \
-     "          id='101' name='EG711A' clockrate='8000'>                " \
-     "          <parameter name='bitrate' value='64000'/>               " \
-     "        </payload-type>                                           " \
-     "        <payload-type                                             " \
-     "          id='0' name='PCMU' clockrate='8000'>                    " \
-     "          <parameter name='bitrate' value='64000'/>               " \
-     "        </payload-type>                                           " \
-     "        <payload-type                                             " \
-     "          id='8' name='PCMA' clockrate='8000'>                    " \
-     "          <parameter name='bitrate' value='64000'/>               " \
-     "        </payload-type>                                           " \
-     "        <payload-type                                             " \
-     "          id='126' name='CN' clockrate='32000' />                 " \
-     "        <payload-type                                             " \
-     "          id='105' name='CN' clockrate='16000' />                 " \
-     "        <payload-type                                             " \
-     "          id='13' name='CN' clockrate='8000' />                   " \
-     "        <payload-type                                             " \
-     "          id='117' name='red' clockrate='8000' />                 " \
-     "        <payload-type                                             " \
-     "          id='106' name='telephone-event' clockrate='8000' />     " \
-     "      </description>                                              " \
-     "     <transport xmlns=\"http://www.google.com/transport/p2p\"/>   " \
-     "    </content>                                                    " \
-     "  </jingle>                                                       " \
-     "</iq>                                                             ");
-
-// Initiate string with a different order of supported codecs.
-// Should accept the supported ones, but with our desired order.
-const std::string kGingleInitiateDifferentPreference(
-     "<iq xmlns='jabber:client' from='me@domain.com/resource'         " \
-     "    to='user@domain.com/resource' type='set' id='123'>          " \
-     "  <session xmlns='http://www.google.com/session' type='initiate'" \
-     "    id='abcdef' initiator='me@domain.com/resource'>             " \
-     "    <description xmlns='http://www.google.com/session/phone'>   " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='104' name='ISAC' clockrate='32000' />               " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='97' name='IPCMWB' clockrate='16000' bitrate='80000' />   " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='9' name='G722' clockrate='16000' bitrate='64000' /> " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='119' name='ISACLC' clockrate='16000' bitrate='40000' />  " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='103' name='ISAC' clockrate='16000' />               " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='99' name='speex' clockrate='16000' bitrate='22000' />    " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='100' name='EG711U' clockrate='8000' bitrate='64000' />   " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='101' name='EG711A' clockrate='8000' bitrate='64000' />   " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='0' name='PCMU' clockrate='8000' bitrate='64000' />  " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='8' name='PCMA' clockrate='8000' bitrate='64000' />  " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='102' name='iLBC' clockrate='8000' bitrate='13300' />" \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='3' name='GSM' clockrate='8000' bitrate='13000' />   " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='98' name='speex' clockrate='8000' bitrate='11000' />" \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='126' name='CN' clockrate='32000' />                 " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='105' name='CN' clockrate='16000' />                 " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='13' name='CN' clockrate='8000' />                   " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='117' name='red' clockrate='8000' />                 " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='106' name='telephone-event' clockrate='8000' />     " \
-     "    </description>                                              " \
-     "  </session>                                                    " \
-     "</iq>                                                           ");
-
-const std::string kJingleInitiateDifferentPreference(
-     "<iq xmlns='jabber:client' from='me@domain.com/resource'           " \
-     "    to='user@domain.com/resource' type='set' id='123'>            " \
-     "  <jingle xmlns='urn:xmpp:jingle:1' action='session-initiate'     " \
-     "          sid='abcdef' initiator='me@domain.com/resource'>        " \
-     "    <content name='test audio'>                                   " \
-     "      <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'> " \
-     "        <payload-type id='104' name='ISAC' clockrate='32000'/>    " \
-     "        <payload-type                                             " \
-     "          id='97' name='IPCMWB' clockrate='16000'>                " \
-     "          <parameter name='bitrate' value='80000'/>               " \
-     "        </payload-type>                                           " \
-     "        <payload-type                                             " \
-     "          id='9' name='G722' clockrate='16000'>                   " \
-     "          <parameter name='bitrate' value='64000'/>               " \
-     "        </payload-type>                                           " \
-     "        <payload-type                                             " \
-     "          id='119' name='ISACLC' clockrate='16000'>               " \
-     "          <parameter name='bitrate' value='40000'/>               " \
-     "        </payload-type>                                           " \
-     "        <payload-type id='103' name='ISAC' clockrate='16000'/>    " \
-     "        <payload-type                                             " \
-     "          id='99' name='speex' clockrate='16000'>                 " \
-     "          <parameter name='bitrate' value='22000'/>               " \
-     "        </payload-type>                                           " \
-     "        <payload-type                                             " \
-     "          id='100' name='EG711U' clockrate='8000'>                " \
-     "          <parameter name='bitrate' value='64000'/>               " \
-     "        </payload-type>                                           " \
-     "        <payload-type                                             " \
-     "          id='101' name='EG711A' clockrate='8000'>                " \
-     "          <parameter name='bitrate' value='64000'/>               " \
-     "        </payload-type>                                           " \
-     "        <payload-type                                             " \
-     "          id='0' name='PCMU' clockrate='8000'>                    " \
-     "          <parameter name='bitrate' value='64000'/>               " \
-     "        </payload-type>                                           " \
-     "        <payload-type                                             " \
-     "          id='8' name='PCMA' clockrate='8000'>                    " \
-     "          <parameter name='bitrate' value='64000'/>               " \
-     "        </payload-type>                                           " \
-     "        <payload-type                                             " \
-     "          id='102' name='iLBC' clockrate='8000'>                  " \
-     "          <parameter name='bitrate' value='13300'/>               " \
-     "        </payload-type>                                           " \
-     "        <payload-type                                             " \
-     "          id='3' name='GSM' clockrate='8000'>                     " \
-     "          <parameter name='bitrate' value='13000'/>               " \
-     "        </payload-type>                                           " \
-     "        <payload-type                                             " \
-     "          id='98' name='speex' clockrate='8000'>                  " \
-     "          <parameter name='bitrate' value='11000'/>               " \
-     "        </payload-type>                                           " \
-     "        <payload-type                                             " \
-     "          id='126' name='CN' clockrate='32000' />                 " \
-     "        <payload-type                                             " \
-     "          id='105' name='CN' clockrate='16000' />                 " \
-     "        <payload-type                                             " \
-     "          id='13' name='CN' clockrate='8000' />                   " \
-     "        <payload-type                                             " \
-     "          id='117' name='red' clockrate='8000' />                 " \
-     "        <payload-type                                             " \
-     "          id='106' name='telephone-event' clockrate='8000' />     " \
-     "      </description>                                              " \
-     "     <transport xmlns=\"http://www.google.com/transport/p2p\"/>   " \
-     "    </content>                                                    " \
-     "  </jingle>                                                       " \
-     "</iq>                                                             ");
-
-const std::string kGingleVideoInitiate(
-     "<iq xmlns='jabber:client' from='me@domain.com/resource'         " \
-     "    to='user@domain.com/resource' type='set' id='123'>          " \
-     "  <session xmlns='http://www.google.com/session' type='initiate'" \
-     "    id='abcdef' initiator='me@domain.com/resource'>             " \
-     "    <description xmlns='http://www.google.com/session/video'>   " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='103' name='ISAC' clockrate='16000' />               " \
-     "      <payload-type xmlns='http://www.google.com/session/video' " \
-     "        id='99' name='H264-SVC' framerate='30'                  " \
-     "        height='200' width='320'/>                              " \
-     "    </description>                                              " \
-     "  </session>                                                    " \
-     "</iq>                                                           ");
-
-const std::string kJingleVideoInitiate(
-     "<iq xmlns='jabber:client' from='me@domain.com/resource'           " \
-     "    to='user@domain.com/resource' type='set' id='123'>            " \
-     "  <jingle xmlns='urn:xmpp:jingle:1' action='session-initiate'     " \
-     "          sid='abcdef' initiator='me@domain.com/resource'>        " \
-     "    <content name='test audio'>                                   " \
-     "      <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'> " \
-     "        <payload-type id='103' name='ISAC' clockrate='16000'/>    " \
-     "      </description>                                              " \
-     "     <transport xmlns=\"http://www.google.com/transport/p2p\"/>   " \
-     "    </content>                                                    " \
-     "    <content name='test video'>                                   " \
-     "      <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='video'> " \
-     "        <payload-type id='99' name='H264-SVC'>                    " \
-     "          <parameter name='height' value='200'/>                  " \
-     "          <parameter name='width' value='320'/>                   " \
-     "          <parameter name='framerate' value='30'/>                " \
-     "        </payload-type>                                           " \
-     "      </description>                                              " \
-     "     <transport xmlns=\"http://www.google.com/transport/p2p\"/>   " \
-     "    </content>                                                    " \
-     "  </jingle>                                                       " \
-     "</iq>                                                             ");
-
-const std::string kJingleVideoInitiateWithBandwidth(
-     "<iq xmlns='jabber:client' from='me@domain.com/resource'           " \
-     "    to='user@domain.com/resource' type='set' id='123'>            " \
-     "  <jingle xmlns='urn:xmpp:jingle:1' action='session-initiate'     " \
-     "         sid='abcdef' initiator='me@domain.com/resource'>         " \
-     "    <content name='test audio'>                                   " \
-     "      <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'> " \
-     "        <payload-type id='103' name='ISAC' clockrate='16000'/>    " \
-     "      </description>                                              " \
-     "     <transport xmlns=\"http://www.google.com/transport/p2p\"/>   " \
-     "    </content>                                                    " \
-     "    <content name='test video'>                                   " \
-     "      <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='video'> " \
-     "        <payload-type id='99' name='H264-SVC'>                    " \
-     "          <parameter name='height' value='200'/>                  " \
-     "          <parameter name='width' value='320'/>                   " \
-     "          <parameter name='framerate' value='30'/>                " \
-     "        </payload-type>                                           " \
-     "        <bandwidth type='AS'>42</bandwidth>                       " \
-     "      </description>                                              " \
-     "     <transport xmlns=\"http://www.google.com/transport/p2p\"/>   " \
-     "    </content>                                                    " \
-     "  </jingle>                                                       " \
-     "</iq>                                                             ");
-
-const std::string kJingleVideoInitiateWithRtcpMux(
-     "<iq xmlns='jabber:client' from='me@domain.com/resource'           " \
-     "    to='user@domain.com/resource' type='set' id='123'>            " \
-     "  <jingle xmlns='urn:xmpp:jingle:1' action='session-initiate'     " \
-     "         sid='abcdef' initiator='me@domain.com/resource'>         " \
-     "    <content name='test audio'>                                   " \
-     "      <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'> " \
-     "        <payload-type id='103' name='ISAC' clockrate='16000'/>    " \
-     "      </description>                                              " \
-     "     <transport xmlns=\"http://www.google.com/transport/p2p\"/>   " \
-     "    </content>                                                    " \
-     "    <content name='test video'>                                   " \
-     "      <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='video'> " \
-     "        <payload-type id='99' name='H264-SVC'>                    " \
-     "          <parameter name='height' value='200'/>                  " \
-     "          <parameter name='width' value='320'/>                   " \
-     "          <parameter name='framerate' value='30'/>                " \
-     "        </payload-type>                                           " \
-     "        <rtcp-mux/>                                               " \
-     "      </description>                                              " \
-     "     <transport xmlns=\"http://www.google.com/transport/p2p\"/>   " \
-     "    </content>                                                    " \
-     "  </jingle>                                                       " \
-     "</iq>                                                             ");
-
-// Initiate string with a combination of supported and unsupported codecs
-// Should accept the supported ones
-const std::string kGingleInitiateSomeUnsupported(
-     "<iq xmlns='jabber:client' from='me@domain.com/resource'         " \
-     "    to='user@domain.com/resource' type='set' id='123'>          " \
-     "  <session xmlns='http://www.google.com/session' type='initiate'" \
-     "    id='abcdef' initiator='me@domain.com/resource'>             " \
-     "    <description xmlns='http://www.google.com/session/phone'>   " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='103' name='ISAC' clockrate='16000' />               " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='97' name='ASDFDS' />                                " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='102' name='1010' />                                 " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='107' name='DFAS' />                                 " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='100' name='EG711U' />                               " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='101' name='EG711A' />                               " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='0' name='PCMU' />                                   " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='110' name=':)' />                                   " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='13' name='CN' />                                    " \
-     "    </description>                                              " \
-     "  </session>                                                    " \
-     "</iq>                                                           ");
-
-const std::string kJingleInitiateSomeUnsupported(
-     "<iq xmlns='jabber:client' from='me@domain.com/resource'         " \
-     "    to='user@domain.com/resource' type='set' id='123'>          " \
-     "  <jingle xmlns='urn:xmpp:jingle:1' action='session-initiate'   " \
-     "          sid='abcdef' initiator='me@domain.com/resource'>      " \
-     "    <content name='test audio'>                                 " \
-     "      <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'> " \
-     "        <payload-type                                           " \
-     "          id='103' name='ISAC' clockrate='16000' />             " \
-     "        <payload-type                                           " \
-     "          id='97' name='ASDFDS' />                              " \
-     "        <payload-type                                           " \
-     "          id='102' name='1010' />                               " \
-     "        <payload-type                                           " \
-     "          id='107' name='DFAS' />                               " \
-     "        <payload-type                                           " \
-     "          id='100' name='EG711U' />                             " \
-     "        <payload-type                                           " \
-     "          id='101' name='EG711A' />                             " \
-     "        <payload-type                                           " \
-     "          id='0' name='PCMU' />                                 " \
-     "        <payload-type                                           " \
-     "          id='110' name=':)' />                                 " \
-     "        <payload-type                                           " \
-     "          id='13' name='CN' />                                  " \
-     "      </description>                                            " \
-     "     <transport xmlns=\"http://www.google.com/transport/p2p\"/> " \
-     "    </content>                                                  " \
-     "  </jingle>                                                     " \
-     "</iq>                                                           ");
-
-const std::string kGingleVideoInitiateWithBandwidth(
-     "<iq xmlns='jabber:client' from='me@domain.com/resource'         " \
-     "    to='user@domain.com/resource' type='set' id='123'>          " \
-     "  <session xmlns='http://www.google.com/session' type='initiate'" \
-     "    id='abcdef' initiator='me@domain.com/resource'>             " \
-     "    <description xmlns='http://www.google.com/session/video'>   " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='103' name='ISAC' clockrate='16000' />               " \
-     "      <payload-type xmlns='http://www.google.com/session/video' " \
-     "        id='99' name='H264-SVC' framerate='30'                  " \
-     "        height='200' width='320'/>                              " \
-     "      <bandwidth type='AS'>42</bandwidth>                       " \
-     "    </description>                                              " \
-     "  </session>                                                    " \
-     "</iq>                                                           ");
-
-// Initiate string without any supported codecs. Should send a reject.
-const std::string kGingleInitiateNoSupportedAudioCodecs(
-     "<iq xmlns='jabber:client' from='me@domain.com/resource'         " \
-     "    to='user@domain.com/resource' type='set' id='123'>          " \
-     "  <session xmlns='http://www.google.com/session' type='initiate'" \
-     "    id='abcdef' initiator='me@domain.com/resource'>             " \
-     "    <description xmlns='http://www.google.com/session/phone'>   " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='123' name='Supercodec6000' />                       " \
-     "    </description>                                              " \
-     "  </session>                                                    " \
-     "</iq>                                                           ");
-
-const std::string kJingleInitiateNoSupportedAudioCodecs(
-     "<iq xmlns='jabber:client' from='me@domain.com/resource'         " \
-     "    to='user@domain.com/resource' type='set' id='123'>          " \
-     "  <jingle xmlns='urn:xmpp:jingle:1' action='session-initiate'   " \
-     "          sid='abcdef' initiator='me@domain.com/resource'>      " \
-     "    <content name='test audio'>                                 " \
-     "      <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'>" \
-     "        <payload-type                                           " \
-     "          id='123' name='Supercodec6000' />                     " \
-     "      </description>                                            " \
-     "     <transport xmlns=\"http://www.google.com/transport/p2p\"/>  " \
-     "    </content>                                                  " \
-     "  </jingle>                                                     " \
-     "</iq>                                                           ");
-
-// Initiate string without any codecs. Assumes ancient version of Cricket
-// and tries a session with ISAC and PCMU
-const std::string kGingleInitiateNoAudioCodecs(
-     "<iq xmlns='jabber:client' from='me@domain.com/resource'         " \
-     "    to='user@domain.com/resource' type='set' id='123'>          " \
-     "  <session xmlns='http://www.google.com/session' type='initiate'" \
-     "    id='abcdef' initiator='me@domain.com/resource'>             " \
-     "    <description xmlns='http://www.google.com/session/phone'>   " \
-     "    </description>                                              " \
-     "  </session>                                                    " \
-     "</iq>                                                           ");
-
-const std::string kJingleInitiateNoAudioCodecs(
-     "<iq xmlns='jabber:client' from='me@domain.com/resource'         " \
-     "    to='user@domain.com/resource' type='set' id='123'>          " \
-     "  <jingle xmlns='urn:xmpp:jingle:1' action='session-initiate'   " \
-     "          sid='abcdef' initiator='me@domain.com/resource'>      " \
-     "    <content name='test audio'>                                 " \
-     "      <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'>" \
-     "      </description>                                            " \
-     "     <transport xmlns=\"http://www.google.com/transport/p2p\"/>  " \
-     "    </content>                                                  " \
-     "  </jingle>                                                     " \
-     "</iq>                                                           ");
-
-// The codecs are supported, but not at the given clockrates. Should send
-// a reject.
-const std::string kGingleInitiateWrongClockrates(
-     "<iq xmlns='jabber:client' from='me@domain.com/resource'         " \
-     "    to='user@domain.com/resource' type='set' id='123'>          " \
-     "  <session xmlns='http://www.google.com/session' type='initiate'" \
-     "    id='abcdef' initiator='me@domain.com/resource'>             " \
-     "    <description xmlns='http://www.google.com/session/phone'>   " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='103' name='ISAC' clockrate='8000'/>                 " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='97' name='IPCMWB' clockrate='1337'/>                " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='102' name='iLBC' clockrate='1982' />                " \
-     "    </description>                                              " \
-     "  </session>                                                    " \
-     "</iq>                                                           ");
-
-const std::string kJingleInitiateWrongClockrates(
-     "<iq xmlns='jabber:client' from='me@domain.com/resource'           " \
-     "    to='user@domain.com/resource' type='set' id='123'>            " \
-     "  <jingle xmlns='urn:xmpp:jingle:1' action='session-initiate'     " \
-     "          sid='abcdef' initiator='me@domain.com/resource'>        " \
-     "    <content name='test audio'>                                   " \
-     "      <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'>" \
-     "        <payload-type                                             " \
-     "          id='103' name='ISAC' clockrate='8000'/>                 " \
-     "        <payload-type                                             " \
-     "          id='97' name='IPCMWB' clockrate='1337'/>                " \
-     "       <payload-type                                              " \
-     "          id='102' name='iLBC' clockrate='1982' />                " \
-     "      </description>                                              " \
-     "     <transport xmlns=\"http://www.google.com/transport/p2p\"/>  " \
-     "    </content>                                                    " \
-     "  </jingle>                                                       " \
-     "</iq>                                                             ");
-
-// The codecs are supported, but not with the given number of channels.
-// Should send a reject.
-const std::string kGingleInitiateWrongChannels(
-     "<iq xmlns='jabber:client' from='me@domain.com/resource'         " \
-     "    to='user@domain.com/resource' type='set' id='123'>          " \
-     "  <session xmlns='http://www.google.com/session' type='initiate'" \
-     "    id='abcdef' initiator='me@domain.com/resource'>             " \
-     "    <description xmlns='http://www.google.com/session/phone'>   " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='103' name='ISAC' channels='2'/>                     " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='97' name='IPCMWB' channels='3'/>                    " \
-     "    </description>                                              " \
-     "  </session>                                                    " \
-     "</iq>                                                           ");
-
-const std::string kJingleInitiateWrongChannels(
-     "<iq xmlns='jabber:client' from='me@domain.com/resource'           " \
-     "    to='user@domain.com/resource' type='set' id='123'>            " \
-     "  <jingle xmlns='urn:xmpp:jingle:1' action='session-initiate'>    " \
-     "    <content name='test audio'>                                   " \
-     "      <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'>" \
-     "        <payload-type                                             " \
-     "          id='103' name='ISAC' channels='2'/>                     " \
-     "        <payload-type                                             " \
-     "          id='97' name='IPCMWB' channels='3'/>                    " \
-     "      </description>                                              " \
-     "     <transport xmlns=\"http://www.google.com/transport/p2p\"/>   " \
-     "    </content>                                                    " \
-     "  </jingle>                                                       " \
-     "</iq>                                                             ");
-
-// Initiate with a dynamic codec not using GIPS default payload id. Should
-// accept with provided payload id.
-const std::string kGingleInitiateDynamicAudioCodecs(
-     "<iq xmlns='jabber:client' from='me@domain.com/resource'         " \
-     "    to='user@domain.com/resource' type='set' id='123'>          " \
-     "  <session xmlns='http://www.google.com/session' type='initiate'" \
-     "    id='abcdef' initiator='me@domain.com/resource'>             " \
-     "    <description xmlns='http://www.google.com/session/phone'>   " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='123' name='speex' clockrate='16000'/>               " \
-     "    </description>                                              " \
-     "  </session>                                                    " \
-     "</iq>                                                           ");
-
-const std::string kJingleInitiateDynamicAudioCodecs(
-     "<iq xmlns='jabber:client' from='me@domain.com/resource'           " \
-     "    to='user@domain.com/resource' type='set' id='123'>            " \
-     "  <jingle xmlns='urn:xmpp:jingle:1' action='session-initiate'     " \
-     "          sid='abcdef' initiator='me@domain.com/resource'>        " \
-     "    <content name='test audio'>                                   " \
-     "      <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'>" \
-     "        <payload-type                                             " \
-     "          id='123' name='speex' clockrate='16000'/>               " \
-     "      </description>                                              " \
-     "     <transport xmlns=\"http://www.google.com/transport/p2p\"/>   " \
-     "    </content>                                                    " \
-     "  </jingle>                                                       " \
-     "</iq>                                                             ");
-
-// Initiate string with nothing but static codec id's. Should accept.
-const std::string kGingleInitiateStaticAudioCodecs(
-     "<iq xmlns='jabber:client' from='me@domain.com/resource'         " \
-     "    to='user@domain.com/resource' type='set' id='123'>          " \
-     "  <session xmlns='http://www.google.com/session' type='initiate'" \
-     "    id='abcdef' initiator='me@domain.com/resource'>             " \
-     "    <description xmlns='http://www.google.com/session/phone'>   " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='3' />                                               " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='0' />                                               " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='8' />                                               " \
-     "    </description>                                              " \
-     "  </session>                                                    " \
-     "</iq>                                                           ");
-
-const std::string kJingleInitiateStaticAudioCodecs(
-     "<iq xmlns='jabber:client' from='me@domain.com/resource'         " \
-     "    to='user@domain.com/resource' type='set' id='123'>          " \
-     "  <jingle xmlns='urn:xmpp:jingle:1' action='session-initiate'   " \
-     "          sid='abcdef' initiator='me@domain.com/resource'>      " \
-     "    <content name='test audio'>                                 " \
-     "      <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'>" \
-     "        <payload-type id='3' />                                 " \
-     "        <payload-type id='0' />                                 " \
-     "        <payload-type id='8' />                                 " \
-     "      </description>                                            " \
-     "     <transport xmlns=\"http://www.google.com/transport/p2p\"/> " \
-     "    </content>                                                  " \
-     "  </jingle>                                                     " \
-     "</iq>                                                           ");
-
-// Initiate with payload type-less codecs. Should reject.
-const std::string kGingleInitiateNoPayloadTypes(
-     "<iq xmlns='jabber:client' from='me@domain.com/resource'         " \
-     "    to='user@domain.com/resource' type='set' id='123'>          " \
-     "  <session xmlns='http://www.google.com/session' type='initiate'" \
-     "    id='abcdef' initiator='me@domain.com/resource'>             " \
-     "    <description xmlns='http://www.google.com/session/phone'>   " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "       name='ISAC' clockrate='16000'/>                          " \
-     "    </description>                                              " \
-     "  </session>                                                    " \
-     "</iq>                                                           ");
-
-const std::string kJingleInitiateNoPayloadTypes(
-     "<iq xmlns='jabber:client' from='me@domain.com/resource'         " \
-     "    to='user@domain.com/resource' type='set' id='123'>          " \
-     "  <jingle xmlns='urn:xmpp:jingle:1' action='session-initiate'>  " \
-     "          sid='abcdef' initiator='me@domain.com/resource'>      " \
-     "    <content name='test audio'>                                 " \
-     "      <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'>" \
-     "        <payload-type  name='ISAC' clockrate='16000'/>          " \
-     "      </description>                                            " \
-     "     <transport xmlns=\"http://www.google.com/transport/p2p\"/> " \
-     "    </content>                                                  " \
-     "  </jingle>                                                     " \
-     "</iq>                                                           ");
-
-// Initiate with unnamed dynamic codces. Should reject.
-const std::string kGingleInitiateDynamicWithoutNames(
-     "<iq xmlns='jabber:client' from='me@domain.com/resource'         " \
-     "    to='user@domain.com/resource' type='set' id='123'>          " \
-     "  <session xmlns='http://www.google.com/session' type='initiate'" \
-     "    id='abcdef' initiator='me@domain.com/resource'>             " \
-     "    <description xmlns='http://www.google.com/session/phone'>   " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "       id='100' clockrate='16000'/>                             " \
-     "    </description>                                              " \
-     "  </session>                                                    " \
-     "</iq>                                                           ");
-
-const std::string kJingleInitiateDynamicWithoutNames(
-     "<iq xmlns='jabber:client' from='me@domain.com/resource'         " \
-     "    to='user@domain.com/resource' type='set' id='123'>          " \
-     "  <jingle xmlns='urn:xmpp:jingle:1' action='session-initiate'>  " \
-     "          sid='abcdef' initiator='me@domain.com/resource'>      " \
-     "    <content name='test audio'>                                 " \
-     "      <description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'>" \
-     "        <payload-type id='100' clockrate='16000'/>              " \
-     "      </description>                                            " \
-     "     <transport xmlns=\"http://www.google.com/transport/p2p\"/>  " \
-     "    </content>                                                  " \
-     "  </jingle>                                                     " \
-     "</iq>                                                           ");
-
-const uint32 kAudioSsrc = 4294967295U;
-const uint32 kVideoSsrc = 87654321;
-// Note that this message does not specify a session ID. It must be populated
-// before use.
-const std::string kGingleAcceptWithSsrcs(
-     "<iq xmlns='jabber:client' from='me@mydomain.com'                " \
-     "    to='user@domain.com/resource' type='set' id='150'>          " \
-     "  <session xmlns='http://www.google.com/session' type='accept'  " \
-     "    initiator='me@domain.com/resource'>                         " \
-     "    <description xmlns='http://www.google.com/session/video'>   " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='103' name='ISAC' clockrate='16000' />               " \
-     "      <payload-type xmlns='http://www.google.com/session/phone' " \
-     "        id='104' name='ISAC' clockrate='32000' />               " \
-     "      <src-id xmlns='http://www.google.com/session/phone'>      " \
-     "        4294967295</src-id>                                       " \
-     "      <src-id>87654321</src-id>                                 " \
-     "    </description>                                              " \
-     "  </session>                                                    " \
-     "</iq>                                                           ");
-
-const std::string kJingleAcceptWithSsrcs(
-     "<iq xmlns='jabber:client' from='me@mydomain.com'                " \
-     "    to='user@domain.com/resource' type='set' id='150'>          " \
-     "  <jingle xmlns='urn:xmpp:jingle:1' action='session-accept'     " \
-     "          initiator='me@domain.com/resource'>                   " \
-     "    <content name='audio'>                                      " \
-     "      <description xmlns='urn:xmpp:jingle:apps:rtp:1'           " \
-     "          media='audio' ssrc='4294967295'>                      " \
-     "        <payload-type id='103' name='ISAC' clockrate='16000'/>  " \
-     "        <payload-type id='104' name='ISAC' clockrate='32000'/>  " \
-     "      </description>                                            " \
-     "     <transport xmlns='http://www.google.com/transport/p2p'/>   " \
-     "    </content>                                                  " \
-     "    <content name='video'>                                      " \
-     "      <description xmlns='urn:xmpp:jingle:apps:rtp:1'           " \
-     "          media='video' ssrc='87654321'>                        " \
-     "      </description>                                            " \
-     "     <transport xmlns='http://www.google.com/transport/p2p'/>   " \
-     "    </content>                                                  " \
-     "  </jingle>                                                     " \
-     "</iq>                                                           ");
-
-std::string JingleView(const std::string& ssrc,
-                       const std::string& width,
-                       const std::string& height,
-                       const std::string& framerate) {
-  // We have some slightly weird whitespace formatting to make the
-  // actual XML generated match the expected XML here.
-  return \
-      "<cli:iq"
-      "  to='me@mydomain.com'"
-      "  type='set'"
-      "  xmlns:cli='jabber:client'>"
-        "<jingle"
-      "    xmlns='urn:xmpp:jingle:1'"
-      "    action='session-info'"
-      "    sid=''>"
-          "<view xmlns='google:jingle'"
-      "      name='video'"
-      "      type='static'"
-      "      ssrc='" + ssrc + "'>"
-            "<params"
-      "        width='" + width + "'"
-      "        height='" + height + "'"
-      "        framerate='" + framerate + "'"
-      "        preference='0'/>"
-          "</view>"
-        "</jingle>"
-      "</cli:iq>";
-}
-
-std::string JingleNotifyAdd(const std::string& content_name,
-                            const std::string& nick,
-                            const std::string& ssrc) {
-  return \
-      "<iq"
-      "  xmlns='jabber:client'"
-      "  from='me@mydomain.com'"
-      "  to='user@domain.com/resource'"
-      "  type='set'"
-      "  id='150'>"
-      "  <jingle"
-      "    xmlns='urn:xmpp:jingle:1'"
-      "    action='session-info'>"
-      "    <notify"
-      "      xmlns='google:jingle'"
-      "      name='" + content_name + "'>"
-      "      <source"
-      "        nick='" + nick + "'>"
-      "        <ssrc>"  + ssrc + "</ssrc>"
-      "      </source>"
-      "    </notify>"
-      "  </jingle>"
-      "</iq>";
-}
-
-std::string JingleNotifyImplicitRemove(const std::string& content_name,
-                                       const std::string& nick) {
-  return \
-      "<iq"
-      "  xmlns='jabber:client'"
-      "  from='me@mydomain.com'"
-      "  to='user@domain.com/resource'"
-      "  type='set'"
-      "  id='150'>"
-      "  <jingle"
-      "    xmlns='urn:xmpp:jingle:1'"
-      "    action='session-info'>"
-      "    <notify"
-      "      xmlns='google:jingle'"
-      "      name='" + content_name + "'>"
-      "      <source"
-      "        nick='" + nick + "'>"
-       "      </source>"
-      "    </notify>"
-      "  </jingle>"
-      "</iq>";
-}
-
-buzz::XmlElement* CopyElement(const buzz::XmlElement* elem) {
-  return new buzz::XmlElement(*elem);
-}
-
-static std::string AddEncryption(std::string stanza, std::string encryption) {
-  std::string::size_type pos = stanza.find("</description>");
-  while (pos != std::string::npos) {
-      stanza = stanza.insert(pos, encryption);
-      pos = stanza.find("</description>", pos + encryption.length() + 1);
-  }
-  return stanza;
-}
-
-
-int IntFromJingleCodecParameter(const buzz::XmlElement* parameter,
-                                const std::string& expected_name) {
-  if (parameter) {
-    const std::string& actual_name =
-        parameter->Attr(cricket::QN_PAYLOADTYPE_PARAMETER_NAME);
-
-    EXPECT_EQ(expected_name, actual_name)
-        << "wrong parameter name.  Expected '"
-        << expected_name << "'. Actually '"
-        << actual_name << "'.";
-
-    return atoi(parameter->Attr(
-        cricket::QN_PAYLOADTYPE_PARAMETER_VALUE).c_str());
-  }
-  return 0;
-}
-
-// Parses and extracts payload and codec info from test XML.  Since
-// that XML will be in various contents (Gingle and Jingle), we need an
-// abstract parser with one concrete implementation per XML content.
-class MediaSessionTestParser {
- public:
-  virtual buzz::XmlElement* ActionFromStanza(buzz::XmlElement* stanza) = 0;
-  virtual buzz::XmlElement* ContentFromAction(buzz::XmlElement* action) = 0;
-  virtual buzz::XmlElement* NextContent(buzz::XmlElement* content) = 0;
-  virtual buzz::XmlElement* PayloadTypeFromContent(
-      buzz::XmlElement* content) = 0;
-  virtual buzz::XmlElement* NextFromPayloadType(
-      buzz::XmlElement* payload_type) = 0;
-  virtual cricket::AudioCodec AudioCodecFromPayloadType(
-      const buzz::XmlElement* payload_type) = 0;
-  virtual cricket::VideoCodec VideoCodecFromPayloadType(
-      const buzz::XmlElement* payload_type) = 0;
-  virtual buzz::XmlElement* EncryptionFromContent(
-      buzz::XmlElement* content) = 0;
-  virtual buzz::XmlElement* NextFromEncryption(
-      buzz::XmlElement* encryption) = 0;
-  virtual const buzz::XmlElement* BandwidthFromContent(
-      buzz::XmlElement* content) = 0;
-  virtual const buzz::XmlElement* RtcpMuxFromContent(
-      buzz::XmlElement* content) = 0;
-  virtual bool ActionIsTerminate(const buzz::XmlElement* action) = 0;
-  virtual ~MediaSessionTestParser() {}
-};
-
-class JingleSessionTestParser : public MediaSessionTestParser {
- public:
-  JingleSessionTestParser() : action_(NULL) {}
-
-  ~JingleSessionTestParser() {
-    delete action_;
-  }
-
-  buzz::XmlElement* ActionFromStanza(buzz::XmlElement* stanza) {
-    return stanza->FirstNamed(cricket::QN_JINGLE);
-  }
-
-  buzz::XmlElement* ContentFromAction(buzz::XmlElement* action) {
-    // We need to be able to use multiple contents, but the action
-    // gets deleted before we can call NextContent, so we need to
-    // stash away a copy.
-    action_ = CopyElement(action);
-    return action_->FirstNamed(cricket::QN_JINGLE_CONTENT);
-  }
-
-  buzz::XmlElement* NextContent(buzz::XmlElement* content) {
-    // For some reason, content->NextNamed(cricket::QN_JINGLE_CONTENT)
-    // doesn't work.
-    return action_->FirstNamed(cricket::QN_JINGLE_CONTENT)
-        ->NextNamed(cricket::QN_JINGLE_CONTENT);
-  }
-
-  buzz::XmlElement* PayloadTypeFromContent(buzz::XmlElement* content) {
-    buzz::XmlElement* content_desc =
-        content->FirstNamed(cricket::QN_JINGLE_RTP_CONTENT);
-    if (!content_desc)
-      return NULL;
-
-    return content_desc->FirstNamed(cricket::QN_JINGLE_RTP_PAYLOADTYPE);
-  }
-
-  buzz::XmlElement* NextFromPayloadType(buzz::XmlElement* payload_type) {
-    return payload_type->NextNamed(cricket::QN_JINGLE_RTP_PAYLOADTYPE);
-  }
-
-  cricket::AudioCodec AudioCodecFromPayloadType(
-      const buzz::XmlElement* payload_type) {
-    int id = 0;
-    if (payload_type->HasAttr(cricket::QN_ID))
-      id = atoi(payload_type->Attr(cricket::QN_ID).c_str());
-
-    std::string name = "";
-    if (payload_type->HasAttr(cricket::QN_NAME))
-      name = payload_type->Attr(cricket::QN_NAME);
-
-    int clockrate = 0;
-    if (payload_type->HasAttr(cricket::QN_CLOCKRATE))
-      clockrate = atoi(payload_type->Attr(cricket::QN_CLOCKRATE).c_str());
-
-    int bitrate = IntFromJingleCodecParameter(
-        payload_type->FirstNamed(cricket::QN_PARAMETER), "bitrate");
-
-    int channels = 1;
-    if (payload_type->HasAttr(cricket::QN_CHANNELS))
-      channels = atoi(payload_type->Attr(
-          cricket::QN_CHANNELS).c_str());
-
-    return cricket::AudioCodec(id, name, clockrate, bitrate, channels, 0);
-  }
-
-  cricket::VideoCodec VideoCodecFromPayloadType(
-      const buzz::XmlElement* payload_type) {
-    int id = 0;
-    if (payload_type->HasAttr(cricket::QN_ID))
-      id = atoi(payload_type->Attr(cricket::QN_ID).c_str());
-
-    std::string name = "";
-    if (payload_type->HasAttr(cricket::QN_NAME))
-      name = payload_type->Attr(cricket::QN_NAME);
-
-    int width = 0;
-    int height = 0;
-    int framerate = 0;
-    const buzz::XmlElement* param =
-        payload_type->FirstNamed(cricket::QN_PARAMETER);
-    if (param) {
-      width = IntFromJingleCodecParameter(param, "width");
-      param = param->NextNamed(cricket::QN_PARAMETER);
-      if (param) {
-        height = IntFromJingleCodecParameter(param, "height");
-        param = param->NextNamed(cricket::QN_PARAMETER);
-        if (param) {
-          framerate = IntFromJingleCodecParameter(param, "framerate");
-        }
-      }
-    }
-
-    return cricket::VideoCodec(id, name, width, height, framerate, 0);
-  }
-
-  bool ActionIsTerminate(const buzz::XmlElement* action) {
-    return (action->HasAttr(cricket::QN_ACTION) &&
-            action->Attr(cricket::QN_ACTION) == "session-terminate");
-  }
-
-  buzz::XmlElement* EncryptionFromContent(buzz::XmlElement* content) {
-    buzz::XmlElement* content_desc =
-        content->FirstNamed(cricket::QN_JINGLE_RTP_CONTENT);
-    if (!content_desc)
-      return NULL;
-
-    return content_desc->FirstNamed(cricket::QN_ENCRYPTION);
-  }
-
-  buzz::XmlElement* NextFromEncryption(buzz::XmlElement* encryption) {
-    return encryption->NextNamed(cricket::QN_ENCRYPTION);
-  }
-
-  const buzz::XmlElement* BandwidthFromContent(buzz::XmlElement* content) {
-    buzz::XmlElement* content_desc =
-        content->FirstNamed(cricket::QN_JINGLE_RTP_CONTENT);
-    if (!content_desc)
-      return NULL;
-
-    return content_desc->FirstNamed(cricket::QN_JINGLE_RTP_BANDWIDTH);
-  }
-
-  const buzz::XmlElement* RtcpMuxFromContent(buzz::XmlElement* content) {
-    return content->FirstNamed(cricket::QN_JINGLE_RTCP_MUX);
-  }
-
- private:
-  buzz::XmlElement* action_;
-};
-
-class GingleSessionTestParser : public MediaSessionTestParser {
- public:
-  GingleSessionTestParser() : found_content_count_(0) {}
-
-  buzz::XmlElement* ActionFromStanza(buzz::XmlElement* stanza) {
-    return stanza->FirstNamed(cricket::QN_GINGLE_SESSION);
-  }
-
-  buzz::XmlElement* ContentFromAction(buzz::XmlElement* session) {
-    buzz::XmlElement* content =
-        session->FirstNamed(cricket::QN_GINGLE_AUDIO_CONTENT);
-    if (content == NULL)
-      content = session->FirstNamed(cricket::QN_GINGLE_VIDEO_CONTENT);
-    return content;
-  }
-
-  // Assumes contents are in order of audio, and then video.
-  buzz::XmlElement* NextContent(buzz::XmlElement* content) {
-    found_content_count_++;
-    return content;
-  }
-
-  buzz::XmlElement* PayloadTypeFromContent(buzz::XmlElement* content) {
-    if (found_content_count_ > 0) {
-      return content->FirstNamed(cricket::QN_GINGLE_VIDEO_PAYLOADTYPE);
-    } else {
-      return content->FirstNamed(cricket::QN_GINGLE_AUDIO_PAYLOADTYPE);
-    }
-  }
-
-  buzz::XmlElement* NextFromPayloadType(buzz::XmlElement* payload_type) {
-    if (found_content_count_ > 0) {
-      return payload_type->NextNamed(cricket::QN_GINGLE_VIDEO_PAYLOADTYPE);
-    } else {
-      return payload_type->NextNamed(cricket::QN_GINGLE_AUDIO_PAYLOADTYPE);
-    }
-  }
-
-  cricket::AudioCodec AudioCodecFromPayloadType(
-      const buzz::XmlElement* payload_type) {
-    int id = 0;
-    if (payload_type->HasAttr(cricket::QN_ID))
-      id = atoi(payload_type->Attr(cricket::QN_ID).c_str());
-
-    std::string name;
-    if (payload_type->HasAttr(cricket::QN_NAME))
-      name = payload_type->Attr(cricket::QN_NAME);
-
-    int clockrate = 0;
-    if (payload_type->HasAttr(cricket::QN_CLOCKRATE))
-      clockrate = atoi(payload_type->Attr(cricket::QN_CLOCKRATE).c_str());
-
-    int bitrate = 0;
-    if (payload_type->HasAttr(cricket::QN_BITRATE))
-      bitrate = atoi(payload_type->Attr(cricket::QN_BITRATE).c_str());
-
-    int channels = 1;
-    if (payload_type->HasAttr(cricket::QN_CHANNELS))
-      channels = atoi(payload_type->Attr(cricket::QN_CHANNELS).c_str());
-
-    return cricket::AudioCodec(id, name, clockrate, bitrate, channels, 0);
-  }
-
-  cricket::VideoCodec VideoCodecFromPayloadType(
-      const buzz::XmlElement* payload_type) {
-    int id = 0;
-    if (payload_type->HasAttr(cricket::QN_ID))
-      id = atoi(payload_type->Attr(cricket::QN_ID).c_str());
-
-    std::string name;
-    if (payload_type->HasAttr(cricket::QN_NAME))
-      name = payload_type->Attr(cricket::QN_NAME);
-
-    int width = 0;
-    if (payload_type->HasAttr(cricket::QN_WIDTH))
-      width = atoi(payload_type->Attr(cricket::QN_WIDTH).c_str());
-
-    int height = 0;
-    if (payload_type->HasAttr(cricket::QN_HEIGHT))
-      height = atoi(payload_type->Attr(cricket::QN_HEIGHT).c_str());
-
-    int framerate = 1;
-    if (payload_type->HasAttr(cricket::QN_FRAMERATE))
-      framerate = atoi(payload_type->Attr(cricket::QN_FRAMERATE).c_str());
-
-    return cricket::VideoCodec(id, name, width, height, framerate, 0);
-  }
-
-  buzz::XmlElement* EncryptionFromContent(
-      buzz::XmlElement* content) {
-    return content->FirstNamed(cricket::QN_ENCRYPTION);
-  }
-
-  buzz::XmlElement* NextFromEncryption(buzz::XmlElement* encryption) {
-    return encryption->NextNamed(cricket::QN_ENCRYPTION);
-  }
-
-  const buzz::XmlElement* BandwidthFromContent(buzz::XmlElement* content) {
-    return content->FirstNamed(cricket::QN_GINGLE_VIDEO_BANDWIDTH);
-  }
-
-  const buzz::XmlElement* RtcpMuxFromContent(buzz::XmlElement* content) {
-    return NULL;
-  }
-
-  bool ActionIsTerminate(const buzz::XmlElement* session) {
-    return (session->HasAttr(buzz::QN_TYPE) &&
-            session->Attr(buzz::QN_TYPE) == "terminate");
-  }
-
-  int found_content_count_;
-};
-
-class MediaSessionClientTest : public sigslot::has_slots<> {
- public:
-  explicit MediaSessionClientTest(MediaSessionTestParser* parser,
-                                  cricket::SignalingProtocol initial_protocol) {
-    nm_ = new talk_base::BasicNetworkManager();
-    pa_ = new cricket::BasicPortAllocator(nm_);
-    sm_ = new cricket::SessionManager(pa_, NULL);
-    fme_ = new cricket::FakeMediaEngine();
-
-    std::vector<cricket::AudioCodec>
-        audio_codecs(kAudioCodecs, kAudioCodecs + ARRAY_SIZE(kAudioCodecs));
-    fme_->SetAudioCodecs(audio_codecs);
-    std::vector<cricket::VideoCodec>
-        video_codecs(kVideoCodecs, kVideoCodecs + ARRAY_SIZE(kVideoCodecs));
-    fme_->SetVideoCodecs(video_codecs);
-
-    client_ = new cricket::MediaSessionClient(
-        buzz::Jid("user@domain.com/resource"), sm_,
-        fme_, new cricket::FakeDeviceManager());
-    client_->session_manager()->SignalOutgoingMessage.connect(
-        this, &MediaSessionClientTest::OnSendStanza);
-    client_->session_manager()->SignalSessionCreate.connect(
-        this, &MediaSessionClientTest::OnSessionCreate);
-    client_->SignalCallCreate.connect(
-        this, &MediaSessionClientTest::OnCallCreate);
-    client_->SignalCallDestroy.connect(
-        this, &MediaSessionClientTest::OnCallDestroy);
-
-    call_ = NULL;
-    parser_ = parser;
-    initial_protocol_ = initial_protocol;
-    expect_incoming_crypto_ = false;
-    expect_outgoing_crypto_ = false;
-    expected_video_bandwidth_ = cricket::kAutoBandwidth;
-    expected_video_rtcp_mux_ = false;
-  }
-
-  ~MediaSessionClientTest() {
-    delete client_;
-    delete sm_;
-    delete pa_;
-    delete nm_;
-    delete parser_;
-  }
-
-  buzz::XmlElement* ActionFromStanza(buzz::XmlElement* stanza) {
-    return parser_->ActionFromStanza(stanza);
-  }
-
-  buzz::XmlElement* ContentFromAction(buzz::XmlElement* action) {
-    return parser_->ContentFromAction(action);
-  }
-
-  buzz::XmlElement* PayloadTypeFromContent(buzz::XmlElement* payload) {
-    return parser_->PayloadTypeFromContent(payload);
-  }
-
-  buzz::XmlElement* NextFromPayloadType(buzz::XmlElement* payload_type) {
-    return parser_->NextFromPayloadType(payload_type);
-  }
-
-  buzz::XmlElement* EncryptionFromContent(buzz::XmlElement* content) {
-    return parser_->EncryptionFromContent(content);
-  }
-
-  buzz::XmlElement* NextFromEncryption(buzz::XmlElement* encryption) {
-    return parser_->NextFromEncryption(encryption);
-  }
-
-  cricket::AudioCodec AudioCodecFromPayloadType(
-      const buzz::XmlElement* payload_type) {
-    return parser_->AudioCodecFromPayloadType(payload_type);
-  }
-
-  const cricket::AudioContentDescription* GetFirstAudioContentDescription(
-      const cricket::SessionDescription* sdesc) {
-    const cricket::ContentInfo* content =
-        cricket::GetFirstAudioContent(sdesc);
-    if (content == NULL)
-      return NULL;
-    return static_cast<const cricket::AudioContentDescription*>(
-        content->description);
-  }
-
-  const cricket::VideoContentDescription* GetFirstVideoContentDescription(
-      const cricket::SessionDescription* sdesc) {
-    const cricket::ContentInfo* content =
-        cricket::GetFirstVideoContent(sdesc);
-    if (content == NULL)
-      return NULL;
-    return static_cast<const cricket::VideoContentDescription*>(
-        content->description);
-  }
-
-  void CheckCryptoFromGoodIncomingInitiate(const cricket::Session* session) {
-    ASSERT_TRUE(session != NULL);
-    const cricket::AudioContentDescription* content =
-        GetFirstAudioContentDescription(session->remote_description());
-    ASSERT_TRUE(content != NULL);
-    ASSERT_EQ(2U, content->cryptos().size());
-    ASSERT_EQ(145, content->cryptos()[0].tag);
-    ASSERT_EQ("AES_CM_128_HMAC_SHA1_32", content->cryptos()[0].cipher_suite);
-    ASSERT_EQ("inline:hsWuSQJxx7przmb8HM+ZkeNcG3HezSNID7LmfDa9",
-              content->cryptos()[0].key_params);
-    ASSERT_EQ(51, content->cryptos()[1].tag);
-    ASSERT_EQ("AES_CM_128_HMAC_SHA1_80", content->cryptos()[1].cipher_suite);
-    ASSERT_EQ("inline:J4lfdUL8W1F7TNJKcbuygaQuA429SJy2e9JctPUy",
-              content->cryptos()[1].key_params);
-  }
-
-  void CheckCryptoForGoodOutgoingAccept(const cricket::Session* session) {
-    const cricket::AudioContentDescription* content =
-        GetFirstAudioContentDescription(session->local_description());
-    ASSERT_EQ(1U, content->cryptos().size());
-    ASSERT_EQ(145, content->cryptos()[0].tag);
-    ASSERT_EQ("AES_CM_128_HMAC_SHA1_32", content->cryptos()[0].cipher_suite);
-    ASSERT_EQ(47U, content->cryptos()[0].key_params.size());
-  }
-
-  void CheckBadCryptoFromIncomingInitiate(const cricket::Session* session) {
-    const cricket::AudioContentDescription* content =
-        GetFirstAudioContentDescription(session->remote_description());
-    ASSERT_EQ(1U, content->cryptos().size());
-    ASSERT_EQ(145, content->cryptos()[0].tag);
-    ASSERT_EQ("NOT_SUPPORTED", content->cryptos()[0].cipher_suite);
-    ASSERT_EQ("inline:hsWuSQJxx7przmb8HM+ZkeNcG3HezSNID7LmfDa9",
-              content->cryptos()[0].key_params);
-  }
-
-  void CheckNoCryptoForOutgoingAccept(const cricket::Session* session) {
-    const cricket::AudioContentDescription* content =
-        GetFirstAudioContentDescription(session->local_description());
-    ASSERT_TRUE(content->cryptos().empty());
-  }
-
-  void CheckVideoBandwidth(int expected_bandwidth,
-                           const cricket::SessionDescription* sdesc) {
-    const cricket::VideoContentDescription* video =
-        GetFirstVideoContentDescription(sdesc);
-    if (video != NULL) {
-      ASSERT_EQ(expected_bandwidth, video->bandwidth());
-    }
-  }
-
-  void CheckVideoRtcpMux(bool expected_video_rtcp_mux,
-                         const cricket::SessionDescription* sdesc) {
-    const cricket::VideoContentDescription* video =
-        GetFirstVideoContentDescription(sdesc);
-    if (video != NULL) {
-      ASSERT_EQ(expected_video_rtcp_mux, video->rtcp_mux());
-    }
-  }
-
-  void CheckAudioSsrcForIncomingAccept(const cricket::Session* session) {
-    const cricket::AudioContentDescription* audio =
-        GetFirstAudioContentDescription(session->remote_description());
-    ASSERT_TRUE(audio != NULL);
-    ASSERT_EQ(kAudioSsrc, audio->first_ssrc());
-  }
-
-  void CheckVideoSsrcForIncomingAccept(const cricket::Session* session) {
-    const cricket::VideoContentDescription* video =
-        GetFirstVideoContentDescription(session->remote_description());
-    ASSERT_TRUE(video != NULL);
-    ASSERT_EQ(kVideoSsrc, video->first_ssrc());
-  }
-
-  void TestGoodIncomingInitiate(const std::string &initiate_string,
-                                buzz::XmlElement** element) {
-    *element = NULL;
-
-    buzz::XmlElement* el = buzz::XmlElement::ForStr(initiate_string);
-    client_->session_manager()->OnIncomingMessage(el);
-    ASSERT_TRUE(call_ != NULL);
-    ASSERT_TRUE(call_->sessions()[0] != NULL);
-    ASSERT_EQ(cricket::Session::STATE_RECEIVEDINITIATE,
-              call_->sessions()[0]->state());
-    ASSERT_EQ(1U, stanzas_.size());
-    ASSERT_TRUE(buzz::QN_IQ == stanzas_[0]->Name());
-    ASSERT_TRUE(stanzas_[0]->HasAttr(buzz::QN_TYPE));
-    ASSERT_EQ(std::string(buzz::STR_RESULT), stanzas_[0]->Attr(buzz::QN_TYPE));
-    delete stanzas_[0];
-    stanzas_.clear();
-    CheckVideoBandwidth(expected_video_bandwidth_,
-                        call_->sessions()[0]->remote_description());
-    CheckVideoRtcpMux(expected_video_rtcp_mux_,
-                      call_->sessions()[0]->remote_description());
-    if (expect_incoming_crypto_) {
-      CheckCryptoFromGoodIncomingInitiate(call_->sessions()[0]);
-    }
-
-    // TODO: Add tests for sending <bandwidth> in accept.
-    cricket::CallOptions opts;
-    opts.has_video = (GetFirstVideoContentDescription(
-        call_->sessions()[0]->remote_description()) != NULL);
-    call_->AcceptSession(call_->sessions()[0], opts);
-    ASSERT_EQ(cricket::Session::STATE_SENTACCEPT,
-              call_->sessions()[0]->state());
-    ASSERT_EQ(1U, stanzas_.size());
-    ASSERT_TRUE(buzz::QN_IQ == stanzas_[0]->Name());
-    ASSERT_TRUE(stanzas_[0]->HasAttr(buzz::QN_TYPE));
-    ASSERT_EQ(std::string(buzz::STR_SET), stanzas_[0]->Attr(buzz::QN_TYPE));
-
-    buzz::XmlElement* e = ActionFromStanza(stanzas_[0]);
-    ASSERT_TRUE(e != NULL);
-    ASSERT_TRUE(ContentFromAction(e) != NULL);
-    *element = CopyElement(ContentFromAction(e));
-    ASSERT_TRUE(*element != NULL);
-    delete stanzas_[0];
-    stanzas_.clear();
-    if (expect_outgoing_crypto_) {
-      CheckCryptoForGoodOutgoingAccept(call_->sessions()[0]);
-    }
-
-    call_->Terminate();
-    ASSERT_EQ(cricket::Session::STATE_SENTTERMINATE,
-              call_->sessions()[0]->state());
-    ASSERT_EQ(1U, stanzas_.size());
-    ASSERT_TRUE(buzz::QN_IQ == stanzas_[0]->Name());
-    ASSERT_TRUE(stanzas_[0]->HasAttr(buzz::QN_TYPE));
-    ASSERT_EQ(std::string(buzz::STR_SET), stanzas_[0]->Attr(buzz::QN_TYPE));
-    e = ActionFromStanza(stanzas_[0]);
-    ASSERT_TRUE(e != NULL);
-    ASSERT_TRUE(parser_->ActionIsTerminate(e));
-    delete stanzas_[0];
-    stanzas_.clear();
-  }
-
-  void TestBadIncomingInitiate(const std::string& initiate_string) {
-    buzz::XmlElement* el = buzz::XmlElement::ForStr(initiate_string);
-    client_->session_manager()->OnIncomingMessage(el);
-    ASSERT_TRUE(call_ != NULL);
-    ASSERT_TRUE(call_->sessions()[0] != NULL);
-    ASSERT_EQ(cricket::Session::STATE_SENTREJECT,
-              call_->sessions()[0]->state());
-    ASSERT_EQ(2U, stanzas_.size());
-    ASSERT_TRUE(buzz::QN_IQ == stanzas_[0]->Name());
-    ASSERT_TRUE(stanzas_[1]->HasAttr(buzz::QN_TYPE));
-    ASSERT_EQ(std::string(buzz::STR_RESULT), stanzas_[1]->Attr(buzz::QN_TYPE));
-    delete stanzas_[0];
-    stanzas_.clear();
-  }
-
-  void TestGoodOutgoingInitiate() {
-    cricket::CallOptions options;
-    TestGoodOutgoingInitiate(options);
-  }
-
-  void TestGoodOutgoingInitiate(const cricket::CallOptions& options) {
-    client_->CreateCall();
-    ASSERT_TRUE(call_ != NULL);
-    call_->InitiateSession(buzz::Jid("me@mydomain.com"), options);
-    ASSERT_TRUE(call_->sessions()[0] != NULL);
-    ASSERT_EQ(cricket::Session::STATE_SENTINITIATE,
-              call_->sessions()[0]->state());
-    ASSERT_EQ(1U, stanzas_.size());
-    ASSERT_TRUE(buzz::QN_IQ == stanzas_[0]->Name());
-    ASSERT_TRUE(stanzas_[0]->HasAttr(buzz::QN_TYPE));
-    ASSERT_EQ(std::string(buzz::STR_SET), stanzas_[0]->Attr(buzz::QN_TYPE));
-    buzz::XmlElement* action = ActionFromStanza(stanzas_[0]);
-    ASSERT_TRUE(action != NULL);
-    buzz::XmlElement* content = ContentFromAction(action);
-    ASSERT_TRUE(content != NULL);
-
-    buzz::XmlElement* e = PayloadTypeFromContent(content);
-    ASSERT_TRUE(e != NULL);
-    cricket::AudioCodec codec = AudioCodecFromPayloadType(e);
-    ASSERT_EQ(103, codec.id);
-    ASSERT_EQ("ISAC", codec.name);
-    ASSERT_EQ(16000, codec.clockrate);
-    ASSERT_EQ(0, codec.bitrate);
-    ASSERT_EQ(1, codec.channels);
-
-    e = NextFromPayloadType(e);
-    ASSERT_TRUE(e != NULL);
-    codec = AudioCodecFromPayloadType(e);
-    ASSERT_EQ(104, codec.id);
-    ASSERT_EQ("ISAC", codec.name);
-    ASSERT_EQ(32000, codec.clockrate);
-    ASSERT_EQ(0, codec.bitrate);
-    ASSERT_EQ(1, codec.channels);
-
-    e = NextFromPayloadType(e);
-    ASSERT_TRUE(e != NULL);
-    codec = AudioCodecFromPayloadType(e);
-    ASSERT_EQ(119, codec.id);
-    ASSERT_EQ("ISACLC", codec.name);
-    ASSERT_EQ(16000, codec.clockrate);
-    ASSERT_EQ(40000, codec.bitrate);
-    ASSERT_EQ(1, codec.channels);
-
-    e = NextFromPayloadType(e);
-    ASSERT_TRUE(e != NULL);
-    codec = AudioCodecFromPayloadType(e);
-    ASSERT_EQ(99, codec.id);
-    ASSERT_EQ("speex", codec.name);
-    ASSERT_EQ(16000, codec.clockrate);
-    ASSERT_EQ(22000, codec.bitrate);
-    ASSERT_EQ(1, codec.channels);
-
-    e = NextFromPayloadType(e);
-    ASSERT_TRUE(e != NULL);
-    codec = AudioCodecFromPayloadType(e);
-    ASSERT_EQ(97, codec.id);
-    ASSERT_EQ("IPCMWB", codec.name);
-    ASSERT_EQ(16000, codec.clockrate);
-    ASSERT_EQ(80000, codec.bitrate);
-    ASSERT_EQ(1, codec.channels);
-
-     e = NextFromPayloadType(e);
-    ASSERT_TRUE(e != NULL);
-    codec = AudioCodecFromPayloadType(e);
-    ASSERT_EQ(9, codec.id);
-    ASSERT_EQ("G722", codec.name);
-    ASSERT_EQ(16000, codec.clockrate);
-    ASSERT_EQ(64000, codec.bitrate);
-    ASSERT_EQ(1, codec.channels);
-
-    e = NextFromPayloadType(e);
-    ASSERT_TRUE(e != NULL);
-    codec = AudioCodecFromPayloadType(e);
-    ASSERT_EQ(102, codec.id);
-    ASSERT_EQ("iLBC", codec.name);
-    ASSERT_EQ(8000, codec.clockrate);
-    ASSERT_EQ(13300, codec.bitrate);
-    ASSERT_EQ(1, codec.channels);
-
-    e = NextFromPayloadType(e);
-    ASSERT_TRUE(e != NULL);
-    codec = AudioCodecFromPayloadType(e);
-    ASSERT_EQ(98, codec.id);
-    ASSERT_EQ("speex", codec.name);
-    ASSERT_EQ(8000, codec.clockrate);
-    ASSERT_EQ(11000, codec.bitrate);
-    ASSERT_EQ(1, codec.channels);
-
-    e = NextFromPayloadType(e);
-    ASSERT_TRUE(e != NULL);
-    codec = AudioCodecFromPayloadType(e);
-    ASSERT_EQ(3, codec.id);
-    ASSERT_EQ("GSM", codec.name);
-    ASSERT_EQ(8000, codec.clockrate);
-    ASSERT_EQ(13000, codec.bitrate);
-    ASSERT_EQ(1, codec.channels);
-
-    e = NextFromPayloadType(e);
-    ASSERT_TRUE(e != NULL);
-    codec = AudioCodecFromPayloadType(e);
-    ASSERT_EQ(100, codec.id);
-    ASSERT_EQ("EG711U", codec.name);
-    ASSERT_EQ(8000, codec.clockrate);
-    ASSERT_EQ(64000, codec.bitrate);
-    ASSERT_EQ(1, codec.channels);
-
-    e = NextFromPayloadType(e);
-    ASSERT_TRUE(e != NULL);
-    codec = AudioCodecFromPayloadType(e);
-    ASSERT_EQ(101, codec.id);
-    ASSERT_EQ("EG711A", codec.name);
-    ASSERT_EQ(8000, codec.clockrate);
-    ASSERT_EQ(64000, codec.bitrate);
-    ASSERT_EQ(1, codec.channels);
-
-    e = NextFromPayloadType(e);
-    ASSERT_TRUE(e != NULL);
-    codec = AudioCodecFromPayloadType(e);
-    ASSERT_EQ(0, codec.id);
-    ASSERT_EQ("PCMU", codec.name);
-    ASSERT_EQ(8000, codec.clockrate);
-    ASSERT_EQ(64000, codec.bitrate);
-    ASSERT_EQ(1, codec.channels);
-
-    e = NextFromPayloadType(e);
-    ASSERT_TRUE(e != NULL);
-    codec = AudioCodecFromPayloadType(e);
-    ASSERT_EQ(8, codec.id);
-    ASSERT_EQ("PCMA", codec.name);
-    ASSERT_EQ(8000, codec.clockrate);
-    ASSERT_EQ(64000, codec.bitrate);
-    ASSERT_EQ(1, codec.channels);
-
-    e = NextFromPayloadType(e);
-    ASSERT_TRUE(e != NULL);
-    codec = AudioCodecFromPayloadType(e);
-    ASSERT_EQ(126, codec.id);
-    ASSERT_EQ("CN", codec.name);
-    ASSERT_EQ(32000, codec.clockrate);
-    ASSERT_EQ(1, codec.channels);
-
-    e = NextFromPayloadType(e);
-    ASSERT_TRUE(e != NULL);
-    codec = AudioCodecFromPayloadType(e);
-    ASSERT_EQ(105, codec.id);
-    ASSERT_EQ("CN", codec.name);
-    ASSERT_EQ(16000, codec.clockrate);
-    ASSERT_EQ(1, codec.channels);
-
-    e = NextFromPayloadType(e);
-    ASSERT_TRUE(e != NULL);
-    codec = AudioCodecFromPayloadType(e);
-    ASSERT_EQ(13, codec.id);
-    ASSERT_EQ("CN", codec.name);
-    ASSERT_EQ(8000, codec.clockrate);
-    ASSERT_EQ(1, codec.channels);
-
-    e = NextFromPayloadType(e);
-    ASSERT_TRUE(e != NULL);
-    codec = AudioCodecFromPayloadType(e);
-    ASSERT_EQ(117, codec.id);
-    ASSERT_EQ("red", codec.name);
-    ASSERT_EQ(8000, codec.clockrate);
-    ASSERT_EQ(1, codec.channels);
-
-    e = NextFromPayloadType(e);
-    ASSERT_TRUE(e != NULL);
-    codec = AudioCodecFromPayloadType(e);
-    ASSERT_EQ(106, codec.id);
-    ASSERT_EQ("telephone-event", codec.name);
-    ASSERT_EQ(8000, codec.clockrate);
-    ASSERT_EQ(1, codec.channels);
-
-    e = NextFromPayloadType(e);
-    ASSERT_TRUE(e == NULL);
-
-    if (expect_outgoing_crypto_) {
-      buzz::XmlElement* encryption = EncryptionFromContent(content);
-      ASSERT_TRUE(encryption != NULL);
-
-      if (client_->secure() == cricket::SEC_REQUIRED) {
-        ASSERT_TRUE(cricket::GetXmlAttr(
-            encryption, cricket::QN_ENCRYPTION_REQUIRED, false));
-      }
-
-      if (content->Name().Namespace() == cricket::NS_GINGLE_AUDIO) {
-        e = encryption->FirstNamed(cricket::QN_GINGLE_AUDIO_CRYPTO_USAGE);
-        ASSERT_TRUE(e != NULL);
-        ASSERT_TRUE(
-            e->NextNamed(cricket::QN_GINGLE_AUDIO_CRYPTO_USAGE) == NULL);
-        ASSERT_TRUE(
-            e->FirstNamed(cricket::QN_GINGLE_VIDEO_CRYPTO_USAGE) == NULL);
-      }
-
-      e = encryption->FirstNamed(cricket::QN_CRYPTO);
-      ASSERT_TRUE(e != NULL);
-      ASSERT_EQ("0", e->Attr(cricket::QN_CRYPTO_TAG));
-      ASSERT_EQ("AES_CM_128_HMAC_SHA1_32", e->Attr(cricket::QN_CRYPTO_SUITE));
-      std::string key_0 = e->Attr(cricket::QN_CRYPTO_KEY_PARAMS);
-      ASSERT_EQ(47U, key_0.length());
-      ASSERT_EQ("inline:", key_0.substr(0, 7));
-
-      e = e->NextNamed(cricket::QN_CRYPTO);
-      ASSERT_TRUE(e != NULL);
-      ASSERT_EQ("1", e->Attr(cricket::QN_CRYPTO_TAG));
-      ASSERT_EQ("AES_CM_128_HMAC_SHA1_80", e->Attr(cricket::QN_CRYPTO_SUITE));
-      std::string key_1 = e->Attr(cricket::QN_CRYPTO_KEY_PARAMS);
-      ASSERT_EQ(47U, key_1.length());
-      ASSERT_EQ("inline:", key_1.substr(0, 7));
-      ASSERT_NE(key_0, key_1);
-
-      encryption = NextFromEncryption(encryption);
-      ASSERT_TRUE(encryption == NULL);
-    }
-
-    if (options.has_video) {
-      CheckVideoBandwidth(options.video_bandwidth,
-                          call_->sessions()[0]->local_description());
-      CheckVideoRtcpMux(expected_video_rtcp_mux_,
-                        call_->sessions()[0]->remote_description());
-      content = parser_->NextContent(content);
-      const buzz::XmlElement* bandwidth =
-          parser_->BandwidthFromContent(content);
-      if (options.video_bandwidth == cricket::kAutoBandwidth) {
-        ASSERT_TRUE(bandwidth == NULL);
-      } else {
-        ASSERT_TRUE(bandwidth != NULL);
-        ASSERT_EQ("AS", bandwidth->Attr(buzz::QName("", "type")));
-        ASSERT_EQ(talk_base::ToString(options.video_bandwidth / 1000),
-                  bandwidth->BodyText());
-      }
-    }
-
-    delete stanzas_[0];
-    stanzas_.clear();
-  }
-
-  void TestHasAllSupportedAudioCodecs(buzz::XmlElement* e) {
-    ASSERT_TRUE(e != NULL);
-
-    e = PayloadTypeFromContent(e);
-    ASSERT_TRUE(e != NULL);
-    cricket::AudioCodec codec = AudioCodecFromPayloadType(e);
-    ASSERT_EQ(103, codec.id);
-    ASSERT_EQ("ISAC", codec.name);
-    ASSERT_EQ(16000, codec.clockrate);
-    ASSERT_EQ(1, codec.channels);
-
-    e = NextFromPayloadType(e);
-    ASSERT_TRUE(e != NULL);
-    codec = AudioCodecFromPayloadType(e);
-    ASSERT_EQ(104, codec.id);
-    ASSERT_EQ("ISAC", codec.name);
-    ASSERT_EQ(32000, codec.clockrate);
-    ASSERT_EQ(1, codec.channels);
-
-    e = NextFromPayloadType(e);
-    ASSERT_TRUE(e != NULL);
-    codec = AudioCodecFromPayloadType(e);
-    ASSERT_EQ(119, codec.id);
-    ASSERT_EQ("ISACLC", codec.name);
-    ASSERT_EQ(16000, codec.clockrate);
-    ASSERT_EQ(40000, codec.bitrate);
-    ASSERT_EQ(1, codec.channels);
-
-    e = NextFromPayloadType(e);
-    ASSERT_TRUE(e != NULL);
-    codec = AudioCodecFromPayloadType(e);
-    ASSERT_EQ(99, codec.id);
-    ASSERT_EQ("speex", codec.name);
-    ASSERT_EQ(16000, codec.clockrate);
-    ASSERT_EQ(22000, codec.bitrate);
-    ASSERT_EQ(1, codec.channels);
-
-    e = NextFromPayloadType(e);
-    ASSERT_TRUE(e != NULL);
-    codec = AudioCodecFromPayloadType(e);
-    ASSERT_EQ(97, codec.id);
-    ASSERT_EQ("IPCMWB", codec.name);
-    ASSERT_EQ(16000, codec.clockrate);
-    ASSERT_EQ(80000, codec.bitrate);
-    ASSERT_EQ(1, codec.channels);
-
-    e = NextFromPayloadType(e);
-    ASSERT_TRUE(e != NULL);
-    codec = AudioCodecFromPayloadType(e);
-    ASSERT_EQ(9, codec.id);
-    ASSERT_EQ("G722", codec.name);
-    ASSERT_EQ(16000, codec.clockrate);
-    ASSERT_EQ(64000, codec.bitrate);
-    ASSERT_EQ(1, codec.channels);
-
-    e = NextFromPayloadType(e);
-    ASSERT_TRUE(e != NULL);
-    codec = AudioCodecFromPayloadType(e);
-    ASSERT_EQ(102, codec.id);
-    ASSERT_EQ("iLBC", codec.name);
-    ASSERT_EQ(8000, codec.clockrate);
-    ASSERT_EQ(13300, codec.bitrate);
-    ASSERT_EQ(1, codec.channels);
-
-    e = NextFromPayloadType(e);
-    ASSERT_TRUE(e != NULL);
-    codec = AudioCodecFromPayloadType(e);
-    ASSERT_EQ(98, codec.id);
-    ASSERT_EQ("speex", codec.name);
-    ASSERT_EQ(8000, codec.clockrate);
-    ASSERT_EQ(11000, codec.bitrate);
-    ASSERT_EQ(1, codec.channels);
-
-    e = NextFromPayloadType(e);
-    ASSERT_TRUE(e != NULL);
-    codec = AudioCodecFromPayloadType(e);
-    ASSERT_EQ(3, codec.id);
-    ASSERT_EQ("GSM", codec.name);
-    ASSERT_EQ(8000, codec.clockrate);
-    ASSERT_EQ(13000, codec.bitrate);
-    ASSERT_EQ(1, codec.channels);
-
-    e = NextFromPayloadType(e);
-    ASSERT_TRUE(e != NULL);
-    codec = AudioCodecFromPayloadType(e);
-    ASSERT_EQ(100, codec.id);
-    ASSERT_EQ("EG711U", codec.name);
-    ASSERT_EQ(8000, codec.clockrate);
-    ASSERT_EQ(64000, codec.bitrate);
-    ASSERT_EQ(1, codec.channels);
-
-    e = NextFromPayloadType(e);
-    ASSERT_TRUE(e != NULL);
-    codec = AudioCodecFromPayloadType(e);
-    ASSERT_EQ(101, codec.id);
-    ASSERT_EQ("EG711A", codec.name);
-    ASSERT_EQ(8000, codec.clockrate);
-    ASSERT_EQ(64000, codec.bitrate);
-    ASSERT_EQ(1, codec.channels);
-
-    e = NextFromPayloadType(e);
-    ASSERT_TRUE(e != NULL);
-    codec = AudioCodecFromPayloadType(e);
-    ASSERT_EQ(0, codec.id);
-    ASSERT_EQ("PCMU", codec.name);
-    ASSERT_EQ(8000, codec.clockrate);
-    ASSERT_EQ(64000, codec.bitrate);
-    ASSERT_EQ(1, codec.channels);
-
-    e = NextFromPayloadType(e);
-    ASSERT_TRUE(e != NULL);
-    codec = AudioCodecFromPayloadType(e);
-    ASSERT_EQ(8, codec.id);
-    ASSERT_EQ("PCMA", codec.name);
-    ASSERT_EQ(8000, codec.clockrate);
-    ASSERT_EQ(64000, codec.bitrate);
-    ASSERT_EQ(1, codec.channels);
-
-    e = NextFromPayloadType(e);
-    ASSERT_TRUE(e != NULL);
-    codec = AudioCodecFromPayloadType(e);
-    ASSERT_EQ(126, codec.id);
-    ASSERT_EQ("CN", codec.name);
-    ASSERT_EQ(32000, codec.clockrate);
-    ASSERT_EQ(1, codec.channels);
-
-    e = NextFromPayloadType(e);
-    ASSERT_TRUE(e != NULL);
-    codec = AudioCodecFromPayloadType(e);
-    ASSERT_EQ(105, codec.id);
-    ASSERT_EQ("CN", codec.name);
-    ASSERT_EQ(16000, codec.clockrate);
-    ASSERT_EQ(1, codec.channels);
-
-    e = NextFromPayloadType(e);
-    ASSERT_TRUE(e != NULL);
-    codec = AudioCodecFromPayloadType(e);
-    ASSERT_EQ(13, codec.id);
-    ASSERT_EQ("CN", codec.name);
-    ASSERT_EQ(8000, codec.clockrate);
-    ASSERT_EQ(1, codec.channels);
-
-    e = NextFromPayloadType(e);
-    ASSERT_TRUE(e != NULL);
-    codec = AudioCodecFromPayloadType(e);
-    ASSERT_EQ(117, codec.id);
-    ASSERT_EQ("red", codec.name);
-    ASSERT_EQ(8000, codec.clockrate);
-    ASSERT_EQ(1, codec.channels);
-
-    e = NextFromPayloadType(e);
-    ASSERT_TRUE(e != NULL);
-    codec = AudioCodecFromPayloadType(e);
-    ASSERT_EQ(106, codec.id);
-    ASSERT_EQ("telephone-event", codec.name);
-    ASSERT_EQ(8000, codec.clockrate);
-    ASSERT_EQ(1, codec.channels);
-
-    e = NextFromPayloadType(e);
-    ASSERT_TRUE(e == NULL);
-  }
-
-  void TestCodecsOfVideoInitiate(buzz::XmlElement* content) {
-    ASSERT_TRUE(content != NULL);
-    buzz::XmlElement* payload_type = PayloadTypeFromContent(content);
-    ASSERT_TRUE(payload_type != NULL);
-    cricket::AudioCodec codec = AudioCodecFromPayloadType(payload_type);
-    ASSERT_EQ(103, codec.id);
-    ASSERT_EQ("ISAC", codec.name);
-    ASSERT_EQ(16000, codec.clockrate);
-    ASSERT_EQ(1, codec.channels);
-
-    content = parser_->NextContent(content);
-    ASSERT_TRUE(content != NULL);
-    payload_type = PayloadTypeFromContent(content);
-    ASSERT_TRUE(payload_type != NULL);
-    cricket::VideoCodec vcodec =
-        parser_->VideoCodecFromPayloadType(payload_type);
-    ASSERT_EQ(99, vcodec.id);
-    ASSERT_EQ("H264-SVC", vcodec.name);
-    ASSERT_EQ(320, vcodec.width);
-    ASSERT_EQ(200, vcodec.height);
-    ASSERT_EQ(30, vcodec.framerate);
-  }
-
-  void TestHasAudioCodecsFromInitiateSomeUnsupported(buzz::XmlElement* e) {
-    ASSERT_TRUE(e != NULL);
-    e = PayloadTypeFromContent(e);
-    ASSERT_TRUE(e != NULL);
-
-    cricket::AudioCodec codec = AudioCodecFromPayloadType(e);
-    ASSERT_EQ(103, codec.id);
-    ASSERT_EQ("ISAC", codec.name);
-    ASSERT_EQ(16000, codec.clockrate);
-    ASSERT_EQ(1, codec.channels);
-
-    e = NextFromPayloadType(e);
-    ASSERT_TRUE(e != NULL);
-    codec = AudioCodecFromPayloadType(e);
-    ASSERT_EQ(100, codec.id);
-    ASSERT_EQ("EG711U", codec.name);
-
-    e = NextFromPayloadType(e);
-    ASSERT_TRUE(e != NULL);
-    codec = AudioCodecFromPayloadType(e);
-    ASSERT_EQ(101, codec.id);
-    ASSERT_EQ("EG711A", codec.name);
-
-    e = NextFromPayloadType(e);
-    ASSERT_TRUE(e != NULL);
-    codec = AudioCodecFromPayloadType(e);
-    ASSERT_EQ(0, codec.id);
-    ASSERT_EQ("PCMU", codec.name);
-
-    e = NextFromPayloadType(e);
-    ASSERT_TRUE(e != NULL);
-    codec = AudioCodecFromPayloadType(e);
-    ASSERT_EQ(13, codec.id);
-    ASSERT_EQ("CN", codec.name);
-
-    e = NextFromPayloadType(e);
-    ASSERT_TRUE(e == NULL);
-  }
-
-  void TestHasAudioCodecsFromInitiateDynamicAudioCodecs(
-      buzz::XmlElement* e) {
-    ASSERT_TRUE(e != NULL);
-    e = PayloadTypeFromContent(e);
-    ASSERT_TRUE(e != NULL);
-
-    cricket::AudioCodec codec = AudioCodecFromPayloadType(e);
-    ASSERT_EQ(123, codec.id);
-    ASSERT_EQ(16000, codec.clockrate);
-    ASSERT_EQ(1, codec.channels);
-
-    e = NextFromPayloadType(e);
-    ASSERT_TRUE(e == NULL);
-  }
-
-  void TestHasDefaultAudioCodecs(buzz::XmlElement* e) {
-    ASSERT_TRUE(e != NULL);
-    e = PayloadTypeFromContent(e);
-    ASSERT_TRUE(e != NULL);
-
-    cricket::AudioCodec codec = AudioCodecFromPayloadType(e);
-    ASSERT_EQ(103, codec.id);
-    ASSERT_EQ("ISAC", codec.name);
-
-    e = NextFromPayloadType(e);
-    ASSERT_TRUE(e != NULL);
-    codec = AudioCodecFromPayloadType(e);
-    ASSERT_EQ(0, codec.id);
-    ASSERT_EQ("PCMU", codec.name);
-
-    e = NextFromPayloadType(e);
-    ASSERT_TRUE(e == NULL);
-  }
-
-  void TestHasAudioCodecsFromInitiateStaticAudioCodecs(
-      buzz::XmlElement* e) {
-    ASSERT_TRUE(e != NULL);
-    e = PayloadTypeFromContent(e);
-    ASSERT_TRUE(e != NULL);
-
-    cricket::AudioCodec codec = AudioCodecFromPayloadType(e);
-    ASSERT_EQ(3, codec.id);
-
-    e = NextFromPayloadType(e);
-    ASSERT_TRUE(e != NULL);
-    codec = AudioCodecFromPayloadType(e);
-    ASSERT_EQ(0, codec.id);
-
-    e = NextFromPayloadType(e);
-    ASSERT_TRUE(e != NULL);
-    codec = AudioCodecFromPayloadType(e);
-    ASSERT_EQ(8, codec.id);
-
-    e = NextFromPayloadType(e);
-    ASSERT_TRUE(e == NULL);
-  }
-
-  void TestGingleInitiateWithUnsupportedCrypto(
-      const std::string &initiate_string,
-      buzz::XmlElement** element) {
-    *element = NULL;
-
-    buzz::XmlElement* el = buzz::XmlElement::ForStr(initiate_string);
-    client_->session_manager()->OnIncomingMessage(el);
-
-    ASSERT_EQ(cricket::Session::STATE_RECEIVEDINITIATE,
-              call_->sessions()[0]->state());
-    delete stanzas_[0];
-    stanzas_.clear();
-    CheckBadCryptoFromIncomingInitiate(call_->sessions()[0]);
-
-    call_->AcceptSession(call_->sessions()[0], cricket::CallOptions());
-    delete stanzas_[0];
-    stanzas_.clear();
-    CheckNoCryptoForOutgoingAccept(call_->sessions()[0]);
-
-    call_->Terminate();
-    ASSERT_EQ(cricket::Session::STATE_SENTTERMINATE,
-              call_->sessions()[0]->state());
-    delete stanzas_[0];
-    stanzas_.clear();
-  }
-
-  void TestIncomingAcceptWithSsrcs(const std::string& accept_string) {
-    client_->CreateCall();
-    ASSERT_TRUE(call_ != NULL);
-
-    cricket::CallOptions options;
-    options.has_video = true;
-    options.is_muc = true;
-
-    call_->InitiateSession(buzz::Jid("me@mydomain.com"), options);
-    ASSERT_TRUE(call_->sessions()[0] != NULL);
-    ASSERT_EQ(cricket::Session::STATE_SENTINITIATE,
-              call_->sessions()[0]->state());
-    ASSERT_EQ(1U, stanzas_.size());
-    ASSERT_TRUE(buzz::QN_IQ == stanzas_[0]->Name());
-    ASSERT_TRUE(stanzas_[0]->HasAttr(buzz::QN_TYPE));
-    ASSERT_EQ(std::string(buzz::STR_SET), stanzas_[0]->Attr(buzz::QN_TYPE));
-    buzz::XmlElement* action = ActionFromStanza(stanzas_[0]);
-    ASSERT_TRUE(action != NULL);
-    buzz::XmlElement* content = ContentFromAction(action);
-    ASSERT_TRUE(content != NULL);
-    if (initial_protocol_ == cricket::PROTOCOL_JINGLE) {
-      buzz::XmlElement* content_desc =
-          content->FirstNamed(cricket::QN_JINGLE_RTP_CONTENT);
-      ASSERT_TRUE(content_desc != NULL);
-      // TODO: Allow option for intiator to select ssrc.
-      // Right now, for MUC, we set it to a random value.
-      ASSERT_NE("", content_desc->Attr(cricket::QN_SSRC));
-    }
-    delete stanzas_[0];
-    stanzas_.clear();
-
-    // We need to insert the session ID into the session accept message.
-    buzz::XmlElement* el = buzz::XmlElement::ForStr(accept_string);
-    const std::string sid = call_->sessions()[0]->id();
-    if (initial_protocol_ == cricket::PROTOCOL_JINGLE) {
-      buzz::XmlElement* jingle = el->FirstNamed(cricket::QN_JINGLE);
-      jingle->SetAttr(cricket::QN_SID, sid);
-    } else {
-      buzz::XmlElement* session = el->FirstNamed(cricket::QN_GINGLE_SESSION);
-      session->SetAttr(cricket::QN_ID, sid);
-    }
-
-    client_->session_manager()->OnIncomingMessage(el);
-
-    ASSERT_EQ(cricket::Session::STATE_RECEIVEDACCEPT,
-              call_->sessions()[0]->state());
-    ASSERT_EQ(1U, stanzas_.size());
-    ASSERT_TRUE(buzz::QN_IQ == stanzas_[0]->Name());
-    ASSERT_TRUE(stanzas_[0]->HasAttr(buzz::QN_TYPE));
-    ASSERT_EQ(std::string(buzz::STR_RESULT), stanzas_[0]->Attr(buzz::QN_TYPE));
-    delete stanzas_[0];
-    stanzas_.clear();
-
-    CheckAudioSsrcForIncomingAccept(call_->sessions()[0]);
-    CheckVideoSsrcForIncomingAccept(call_->sessions()[0]);
-  }
-
-  size_t ClearStanzas() {
-    size_t size = stanzas_.size();
-    for (size_t i = 0; i < size; i++) {
-      delete stanzas_[i];
-    }
-    stanzas_.clear();
-    return size;
-  }
-
-  void SetJingleSid(buzz::XmlElement* stanza) {
-    buzz::XmlElement* jingle =
-        stanza->FirstNamed(cricket::QN_JINGLE);
-    jingle->SetAttr(cricket::QN_SID, call_->sessions()[0]->id());
-  }
-
-  void TestSourceNotifiesAndViewRequests() {
-    cricket::CallOptions options;
-    options.has_video = true;
-    options.is_muc = true;
-
-    client_->CreateCall();
-    call_->InitiateSession(buzz::Jid("me@mydomain.com"), options);
-    ASSERT_EQ(1U, ClearStanzas());
-    ASSERT_EQ(0U, last_sources_update_.audio().size());
-    ASSERT_EQ(0U, last_sources_update_.video().size());
-
-    talk_base::scoped_ptr<buzz::XmlElement> accept_stanza(
-        buzz::XmlElement::ForStr(kJingleAcceptWithSsrcs));
-    SetJingleSid(accept_stanza.get());
-    client_->session_manager()->OnIncomingMessage(accept_stanza.get());
-    ASSERT_EQ(cricket::Session::STATE_RECEIVEDACCEPT,
-              call_->sessions()[0]->state());
-    ASSERT_EQ(1U, stanzas_.size());
-    ASSERT_EQ(std::string(buzz::STR_RESULT), stanzas_[0]->Attr(buzz::QN_TYPE));
-    ClearStanzas();
-
-    talk_base::scoped_ptr<buzz::XmlElement> notify_stanza(
-        buzz::XmlElement::ForStr(JingleNotifyAdd("video", "Bob", "ABC")));
-    SetJingleSid(notify_stanza.get());
-    client_->session_manager()->OnIncomingMessage(notify_stanza.get());
-    // First one is ignored because of bad syntax.
-    ASSERT_EQ(1U, stanzas_.size());
-    // TODO: Figure out how to make this an ERROR rather than RESULT.
-    ASSERT_EQ(std::string(buzz::STR_RESULT), stanzas_[0]->Attr(buzz::QN_TYPE));
-    ClearStanzas();
-    ASSERT_EQ(0U, last_sources_update_.audio().size());
-    ASSERT_EQ(0U, last_sources_update_.video().size());
-
-    notify_stanza.reset(
-        buzz::XmlElement::ForStr(JingleNotifyAdd("audio", "Bob", "1234")));
-    SetJingleSid(notify_stanza.get());
-    client_->session_manager()->OnIncomingMessage(notify_stanza.get());
-    ASSERT_EQ(1U, last_sources_update_.audio().size());
-    ASSERT_EQ("Bob", last_sources_update_.audio()[0].nick);
-    ASSERT_TRUE(last_sources_update_.audio()[0].ssrc_set);
-    ASSERT_EQ(1234U, last_sources_update_.audio()[0].ssrc);
-
-    notify_stanza.reset(
-        buzz::XmlElement::ForStr(JingleNotifyAdd("audio", "Joe", "2468")));
-    SetJingleSid(notify_stanza.get());
-    client_->session_manager()->OnIncomingMessage(notify_stanza.get());
-    ASSERT_EQ(1U, last_sources_update_.audio().size());
-    ASSERT_EQ("Joe", last_sources_update_.audio()[0].nick);
-    ASSERT_TRUE(last_sources_update_.audio()[0].ssrc_set);
-    ASSERT_EQ(2468U, last_sources_update_.audio()[0].ssrc);
-
-    notify_stanza.reset(
-        buzz::XmlElement::ForStr(JingleNotifyAdd("video", "Bob", "5678")));
-    SetJingleSid(notify_stanza.get());
-    client_->session_manager()->OnIncomingMessage(notify_stanza.get());
-    ASSERT_EQ(1U, last_sources_update_.video().size());
-    ASSERT_EQ("Bob", last_sources_update_.video()[0].nick);
-    ASSERT_TRUE(last_sources_update_.video()[0].ssrc_set);
-    ASSERT_EQ(5678U, last_sources_update_.video()[0].ssrc);
-
-    // We're testing that a "duplicate" is effectively ignored.
-    last_sources_update_.mutable_video()->clear();
-    notify_stanza.reset(
-        buzz::XmlElement::ForStr(JingleNotifyAdd("video", "Bob", "5678")));
-    SetJingleSid(notify_stanza.get());
-    client_->session_manager()->OnIncomingMessage(notify_stanza.get());
-    ASSERT_EQ(0U, last_sources_update_.video().size());
-
-    cricket::FakeVoiceMediaChannel* voice_channel = fme_->GetVoiceChannel(0);
-    ASSERT_TRUE(voice_channel != NULL);
-    ASSERT_TRUE(
-        voice_channel->streams().find(1234U) != voice_channel->streams().end());
-    ASSERT_TRUE(
-        voice_channel->streams().find(2468U) != voice_channel->streams().end());
-    cricket::FakeVideoMediaChannel* video_channel = fme_->GetVideoChannel(0);
-    ASSERT_TRUE(video_channel != NULL);
-    ASSERT_TRUE(
-        video_channel->streams().find(5678U) != video_channel->streams().end());
-    ClearStanzas();
-
-    cricket::ViewRequest viewRequest;
-    cricket::StaticVideoView staticVideoView(5678U, 640, 480, 30);
-    viewRequest.static_video_views.push_back(staticVideoView);
-    talk_base::scoped_ptr<buzz::XmlElement> expected_view_elem(
-        buzz::XmlElement::ForStr(JingleView("5678", "640", "480", "30")));
-    SetJingleSid(expected_view_elem.get());
-
-    ASSERT_TRUE(
-        call_->SendViewRequest(call_->sessions()[0], viewRequest));
-    ASSERT_EQ(1U, stanzas_.size());
-    ASSERT_EQ(expected_view_elem->Str(), stanzas_[0]->Str());
-    ClearStanzas();
-
-    // Implicit removal of audio ssrc.
-    notify_stanza.reset(
-        buzz::XmlElement::ForStr(JingleNotifyImplicitRemove("audio", "Bob")));
-    SetJingleSid(notify_stanza.get());
-    client_->session_manager()->OnIncomingMessage(notify_stanza.get());
-    ASSERT_EQ(1U, last_sources_update_.audio().size());
-    ASSERT_TRUE(last_sources_update_.audio()[0].removed);
-    ASSERT_TRUE(last_sources_update_.audio()[0].ssrc_set);
-    ASSERT_EQ(1234U, last_sources_update_.audio()[0].ssrc);
-
-    // Implicit removal of video ssrc.
-    notify_stanza.reset(
-        buzz::XmlElement::ForStr(JingleNotifyImplicitRemove("video", "Bob")));
-    SetJingleSid(notify_stanza.get());
-    client_->session_manager()->OnIncomingMessage(notify_stanza.get());
-    ASSERT_EQ(1U, last_sources_update_.video().size());
-    ASSERT_TRUE(last_sources_update_.video()[0].removed);
-    ASSERT_TRUE(last_sources_update_.video()[0].ssrc_set);
-    ASSERT_EQ(5678U, last_sources_update_.video()[0].ssrc);
-
-    // Implicit removal of non-existent audio ssrc: should be ignored.
-    last_sources_update_.mutable_audio()->clear();
-    notify_stanza.reset(
-        buzz::XmlElement::ForStr(JingleNotifyImplicitRemove("audio", "Bob")));
-    SetJingleSid(notify_stanza.get());
-    client_->session_manager()->OnIncomingMessage(notify_stanza.get());
-    ASSERT_EQ(0U, last_sources_update_.audio().size());
-
-    // Implicit removal of non-existent video ssrc: should be ignored.
-    last_sources_update_.mutable_video()->clear();
-    notify_stanza.reset(
-        buzz::XmlElement::ForStr(JingleNotifyImplicitRemove("video", "Bob")));
-    SetJingleSid(notify_stanza.get());
-    client_->session_manager()->OnIncomingMessage(notify_stanza.get());
-    ASSERT_EQ(0U, last_sources_update_.video().size());
-
-    voice_channel = fme_->GetVoiceChannel(0);
-    ASSERT_TRUE(voice_channel != NULL);
-    ASSERT_FALSE(
-        voice_channel->streams().find(1234U) != voice_channel->streams().end());
-    ASSERT_TRUE(
-        voice_channel->streams().find(2468U) != voice_channel->streams().end());
-    video_channel = fme_->GetVideoChannel(0);
-    ASSERT_TRUE(video_channel != NULL);
-    ASSERT_FALSE(
-        video_channel->streams().find(5678U) != video_channel->streams().end());
-
-    // Fails because ssrc is now invalid.
-    ASSERT_FALSE(
-        call_->SendViewRequest(call_->sessions()[0], viewRequest));
-
-    ClearStanzas();
-  }
-
-  void MakeSignalingSecure(cricket::SecureMediaPolicy secure) {
-    client_->set_secure(secure);
-  }
-
-  void ExpectCrypto(cricket::SecureMediaPolicy secure) {
-    MakeSignalingSecure(secure);
-    expect_incoming_crypto_ = true;
-#ifdef HAVE_SRTP
-    expect_outgoing_crypto_ = true;
-#endif
-  }
-
-  void ExpectVideoBandwidth(int bandwidth) {
-    expected_video_bandwidth_ = bandwidth;
-  }
-
-  void ExpectVideoRtcpMux(bool rtcp_mux) {
-    expected_video_rtcp_mux_ = rtcp_mux;
-  }
-
- private:
-  void OnSendStanza(cricket::SessionManager* manager,
-                    const buzz::XmlElement* stanza) {
-    LOG(LS_INFO) << stanza->Str();
-    stanzas_.push_back(new buzz::XmlElement(*stanza));
-  }
-
-  void OnSessionCreate(cricket::Session* session, bool initiate) {
-    session->set_current_protocol(initial_protocol_);
-  }
-
-  void OnCallCreate(cricket::Call *call) {
-    call_ = call;
-    call->SignalMediaSourcesUpdate.connect(
-        this, &MediaSessionClientTest::OnMediaSourcesUpdate);
-  }
-
-  void OnCallDestroy(cricket::Call *call) {
-    call_ = NULL;
-  }
-
-  void OnMediaSourcesUpdate(cricket::Call *call,
-                            cricket::Session *session,
-                            const cricket::MediaSources& sources) {
-    last_sources_update_.CopyFrom(sources);
-  }
-
-  talk_base::NetworkManager* nm_;
-  cricket::PortAllocator* pa_;
-  cricket::SessionManager* sm_;
-  cricket::FakeMediaEngine* fme_;
-  cricket::MediaSessionClient* client_;
-
-  cricket::Call* call_;
-  std::vector<buzz::XmlElement* > stanzas_;
-  MediaSessionTestParser* parser_;
-  cricket::SignalingProtocol initial_protocol_;
-  bool expect_incoming_crypto_;
-  bool expect_outgoing_crypto_;
-  int expected_video_bandwidth_;
-  bool expected_video_rtcp_mux_;
-  cricket::MediaSources last_sources_update_;
-};
-
-MediaSessionClientTest* GingleTest() {
-  return new MediaSessionClientTest(new GingleSessionTestParser(),
-                                    cricket::PROTOCOL_GINGLE);
-}
-
-MediaSessionClientTest* JingleTest() {
-  return new MediaSessionClientTest(new JingleSessionTestParser(),
-                                    cricket::PROTOCOL_JINGLE);
-}
-
-TEST(MediaSessionTest, JingleGoodVideoInitiate) {
-  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
-  talk_base::scoped_ptr<buzz::XmlElement> elem;
-  test->TestGoodIncomingInitiate(kJingleVideoInitiate, elem.use());
-  test->TestCodecsOfVideoInitiate(elem.get());
-}
-
-TEST(MediaSessionTest, JingleGoodVideoInitiateWithBandwidth) {
-  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
-  talk_base::scoped_ptr<buzz::XmlElement> elem;
-  test->ExpectVideoBandwidth(42000);
-  test->TestGoodIncomingInitiate(kJingleVideoInitiateWithBandwidth, elem.use());
-}
-
-TEST(MediaSessionTest, JingleGoodVideoInitiateWithRtcpMux) {
-  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
-  talk_base::scoped_ptr<buzz::XmlElement> elem;
-  test->ExpectVideoRtcpMux(true);
-  test->TestGoodIncomingInitiate(kJingleVideoInitiateWithRtcpMux, elem.use());
-}
-
-TEST(MediaSessionTest, JingleGoodInitiateAllSupportedAudioCodecs) {
-  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
-  talk_base::scoped_ptr<buzz::XmlElement> elem;
-  test->TestGoodIncomingInitiate(kJingleInitiate, elem.use());
-  test->TestHasAllSupportedAudioCodecs(elem.get());
-}
-
-TEST(MediaSessionTest, JingleGoodInitiateDifferentPreferenceAudioCodecs) {
-  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
-  talk_base::scoped_ptr<buzz::XmlElement> elem;
-  test->TestGoodIncomingInitiate(kJingleInitiateDifferentPreference,
-      elem.use());
-  test->TestHasAllSupportedAudioCodecs(elem.get());
-}
-
-TEST(MediaSessionTest, JingleGoodInitiateSomeUnsupportedAudioCodecs) {
-  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
-  talk_base::scoped_ptr<buzz::XmlElement> elem;
-  test->TestGoodIncomingInitiate(kJingleInitiateSomeUnsupported, elem.use());
-  test->TestHasAudioCodecsFromInitiateSomeUnsupported(elem.get());
-}
-
-TEST(MediaSessionTest, JingleGoodInitiateDynamicAudioCodecs) {
-  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
-  talk_base::scoped_ptr<buzz::XmlElement> elem;
-  test->TestGoodIncomingInitiate(kJingleInitiateDynamicAudioCodecs, elem.use());
-  test->TestHasAudioCodecsFromInitiateDynamicAudioCodecs(elem.get());
-}
-
-TEST(MediaSessionTest, JingleGoodInitiateStaticAudioCodecs) {
-  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
-  talk_base::scoped_ptr<buzz::XmlElement> elem;
-  test->TestGoodIncomingInitiate(kJingleInitiateStaticAudioCodecs, elem.use());
-  test->TestHasAudioCodecsFromInitiateStaticAudioCodecs(elem.get());
-}
-
-TEST(MediaSessionTest, JingleBadInitiateNoAudioCodecs) {
-  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
-  test->TestBadIncomingInitiate(kJingleInitiateNoAudioCodecs);
-}
-
-TEST(MediaSessionTest, JingleBadInitiateNoSupportedAudioCodecs) {
-  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
-  test->TestBadIncomingInitiate(kJingleInitiateNoSupportedAudioCodecs);
-}
-
-TEST(MediaSessionTest, JingleBadInitiateWrongClockrates) {
-  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
-  test->TestBadIncomingInitiate(kJingleInitiateWrongClockrates);
-}
-
-TEST(MediaSessionTest, JingleBadInitiateWrongChannels) {
-  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
-  test->TestBadIncomingInitiate(kJingleInitiateWrongChannels);
-}
-
-TEST(MediaSessionTest, JingleBadInitiateNoPayloadTypes) {
-  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
-  test->TestBadIncomingInitiate(kJingleInitiateNoPayloadTypes);
-}
-
-TEST(MediaSessionTest, JingleBadInitiateDynamicWithoutNames) {
-  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
-  test->TestBadIncomingInitiate(kJingleInitiateDynamicWithoutNames);
-}
-
-TEST(MediaSessionTest, JingleGoodOutgoingInitiate) {
-  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
-  test->TestGoodOutgoingInitiate();
-}
-
-TEST(MediaSessionTest, JingleGoodOutgoingInitiateWithBandwidth) {
-  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
-  cricket::CallOptions options;
-  options.has_video = true;
-  options.video_bandwidth = 42000;
-  test->TestGoodOutgoingInitiate(options);
-}
-
-TEST(MediaSessionTest, JingleGoodOutgoingInitiateWithRtcpMux) {
-  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
-  cricket::CallOptions options;
-  options.has_video = true;
-  options.rtcp_mux_enabled = true;
-  test->TestGoodOutgoingInitiate(options);
-}
-
-// Crypto related tests.
-
-// Offer has crypto but the session is not secured, just ignore it.
-TEST(MediaSessionTest, JingleInitiateWithCryptoIsIgnoredWhenNotSecured) {
-  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
-  talk_base::scoped_ptr<buzz::XmlElement> elem;
-  test->TestGoodIncomingInitiate(AddEncryption(kJingleVideoInitiate,
-                                              kJingleCryptoOffer), elem.use());
-}
-
-// Offer has crypto required but the session is not secure, fail.
-TEST(MediaSessionTest, JingleInitiateWithCryptoRequiredWhenNotSecured) {
-  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
-  test->TestBadIncomingInitiate(AddEncryption(kJingleVideoInitiate,
-                                             kJingleRequiredCryptoOffer));
-}
-
-// Offer has no crypto but the session is secure required, fail.
-TEST(MediaSessionTest, JingleInitiateWithNoCryptoFailsWhenSecureRequired) {
-  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
-  test->ExpectCrypto(cricket::SEC_REQUIRED);
-  test->TestBadIncomingInitiate(kJingleInitiate);
-}
-
-// Offer has crypto and session is secure, expect crypto in the answer.
-TEST(MediaSessionTest, JingleInitiateWithCryptoWhenSecureEnabled) {
-  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
-  talk_base::scoped_ptr<buzz::XmlElement> elem;
-  test->ExpectCrypto(cricket::SEC_ENABLED);
-  test->TestGoodIncomingInitiate(AddEncryption(kJingleVideoInitiate,
-                                              kJingleCryptoOffer), elem.use());
-}
-
-// Offer has crypto and session is secure required, expect crypto in
-// the answer.
-TEST(MediaSessionTest, JingleInitiateWithCryptoWhenSecureRequired) {
-  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
-  talk_base::scoped_ptr<buzz::XmlElement> elem;
-  test->ExpectCrypto(cricket::SEC_REQUIRED);
-  test->TestGoodIncomingInitiate(AddEncryption(kJingleVideoInitiate,
-                                              kJingleCryptoOffer), elem.use());
-}
-
-// Offer has unsupported crypto and session is secure, no crypto in
-// the answer.
-TEST(MediaSessionTest, JingleInitiateWithUnsupportedCrypto) {
-  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
-  talk_base::scoped_ptr<buzz::XmlElement> elem;
-  test->MakeSignalingSecure(cricket::SEC_ENABLED);
-  test->TestGoodIncomingInitiate(
-      AddEncryption(kJingleInitiate, kJingleUnsupportedCryptoOffer),
-      elem.use());
-}
-
-// Offer has unsupported REQUIRED crypto and session is not secure, fail.
-TEST(MediaSessionTest, JingleInitiateWithRequiredUnsupportedCrypto) {
-  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
-  test->TestBadIncomingInitiate(
-      AddEncryption(kJingleInitiate, kJingleRequiredUnsupportedCryptoOffer));
-}
-
-// Offer has unsupported REQUIRED crypto and session is secure, fail.
-TEST(MediaSessionTest, JingleInitiateWithRequiredUnsupportedCryptoWhenSecure) {
-  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
-  test->MakeSignalingSecure(cricket::SEC_ENABLED);
-  test->TestBadIncomingInitiate(
-      AddEncryption(kJingleInitiate, kJingleRequiredUnsupportedCryptoOffer));
-}
-
-// Offer has unsupported REQUIRED crypto and session is required secure, fail.
-TEST(MediaSessionTest,
-     JingleInitiateWithRequiredUnsupportedCryptoWhenSecureRequired) {
-  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
-  test->MakeSignalingSecure(cricket::SEC_REQUIRED);
-  test->TestBadIncomingInitiate(
-      AddEncryption(kJingleInitiate, kJingleRequiredUnsupportedCryptoOffer));
-}
-
-
-TEST(MediaSessionTest, JingleGoodOutgoingInitiateWithCrypto) {
-  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
-  test->ExpectCrypto(cricket::SEC_ENABLED);
-  test->TestGoodOutgoingInitiate();
-}
-
-TEST(MediaSessionTest, JingleGoodOutgoingInitiateWithCryptoRequired) {
-  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
-  test->ExpectCrypto(cricket::SEC_REQUIRED);
-  test->TestGoodOutgoingInitiate();
-}
-
-TEST(MediaSessionTest, JingleIncomingAcceptWithSsrcs) {
-  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
-  test->TestIncomingAcceptWithSsrcs(kJingleAcceptWithSsrcs);
-}
-
-TEST(MediaSessionTest, JingleNotifyAndView) {
-  talk_base::scoped_ptr<MediaSessionClientTest> test(JingleTest());
-  test->TestSourceNotifiesAndViewRequests();
-}
-
-// Gingle tests
-
-TEST(MediaSessionTest, GingleGoodVideoInitiate) {
-  talk_base::scoped_ptr<buzz::XmlElement> elem;
-  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
-  test->TestGoodIncomingInitiate(kGingleVideoInitiate, elem.use());
-  test->TestCodecsOfVideoInitiate(elem.get());
-}
-
-TEST(MediaSessionTest, GingleGoodVideoInitiateWithBandwidth) {
-  talk_base::scoped_ptr<buzz::XmlElement> elem;
-  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
-  test->ExpectVideoBandwidth(42000);
-  test->TestGoodIncomingInitiate(kGingleVideoInitiateWithBandwidth, elem.use());
-}
-
-TEST(MediaSessionTest, GingleGoodInitiateAllSupportedAudioCodecs) {
-  talk_base::scoped_ptr<buzz::XmlElement> elem;
-  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
-  test->TestGoodIncomingInitiate(kGingleInitiate, elem.use());
-  test->TestHasAllSupportedAudioCodecs(elem.get());
-}
-
-TEST(MediaSessionTest, GingleGoodInitiateAllSupportedAudioCodecsWithCrypto) {
-  talk_base::scoped_ptr<buzz::XmlElement> elem;
-  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
-  test->ExpectCrypto(cricket::SEC_ENABLED);
-  test->TestGoodIncomingInitiate(AddEncryption(kGingleInitiate,
-                                              kGingleCryptoOffer), elem.use());
-  test->TestHasAllSupportedAudioCodecs(elem.get());
-}
-
-TEST(MediaSessionTest, GingleGoodInitiateDifferentPreferenceAudioCodecs) {
-  talk_base::scoped_ptr<buzz::XmlElement> elem;
-  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
-  test->TestGoodIncomingInitiate(kGingleInitiateDifferentPreference,
-      elem.use());
-  test->TestHasAllSupportedAudioCodecs(elem.get());
-}
-
-TEST(MediaSessionTest, GingleGoodInitiateSomeUnsupportedAudioCodecs) {
-  talk_base::scoped_ptr<buzz::XmlElement> elem;
-  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
-  test->TestGoodIncomingInitiate(kGingleInitiateSomeUnsupported, elem.use());
-  test->TestHasAudioCodecsFromInitiateSomeUnsupported(elem.get());
-}
-
-TEST(MediaSessionTest, GingleGoodInitiateDynamicAudioCodecs) {
-  talk_base::scoped_ptr<buzz::XmlElement> elem;
-  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
-  test->TestGoodIncomingInitiate(kGingleInitiateDynamicAudioCodecs, elem.use());
-  test->TestHasAudioCodecsFromInitiateDynamicAudioCodecs(elem.get());
-}
-
-TEST(MediaSessionTest, GingleGoodInitiateStaticAudioCodecs) {
-  talk_base::scoped_ptr<buzz::XmlElement> elem;
-  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
-  test->TestGoodIncomingInitiate(kGingleInitiateStaticAudioCodecs, elem.use());
-  test->TestHasAudioCodecsFromInitiateStaticAudioCodecs(elem.get());
-}
-
-TEST(MediaSessionTest, GingleGoodInitiateNoAudioCodecs) {
-  talk_base::scoped_ptr<buzz::XmlElement> elem;
-  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
-  test->TestGoodIncomingInitiate(kGingleInitiateNoAudioCodecs, elem.use());
-  test->TestHasDefaultAudioCodecs(elem.get());
-}
-
-TEST(MediaSessionTest, GingleBadInitiateNoSupportedAudioCodecs) {
-  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
-  test->TestBadIncomingInitiate(kGingleInitiateNoSupportedAudioCodecs);
-}
-
-TEST(MediaSessionTest, GingleBadInitiateWrongClockrates) {
-  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
-  test->TestBadIncomingInitiate(kGingleInitiateWrongClockrates);
-}
-
-TEST(MediaSessionTest, GingleBadInitiateWrongChannels) {
-  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
-  test->TestBadIncomingInitiate(kGingleInitiateWrongChannels);
-}
-
-
-TEST(MediaSessionTest, GingleBadInitiateNoPayloadTypes) {
-  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
-  test->TestBadIncomingInitiate(kGingleInitiateNoPayloadTypes);
-}
-
-TEST(MediaSessionTest, GingleBadInitiateDynamicWithoutNames) {
-  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
-  test->TestBadIncomingInitiate(kGingleInitiateDynamicWithoutNames);
-}
-
-TEST(MediaSessionTest, GingleGoodOutgoingInitiate) {
-  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
-  test->TestGoodOutgoingInitiate();
-}
-
-TEST(MediaSessionTest, GingleGoodOutgoingInitiateWithBandwidth) {
-  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
-  cricket::CallOptions options;
-  options.has_video = true;
-  options.video_bandwidth = 42000;
-  test->TestGoodOutgoingInitiate(options);
-}
-
-// Crypto related tests.
-
-// Offer has crypto but the session is not secured, just ignore it.
-TEST(MediaSessionTest, GingleInitiateWithCryptoIsIgnoredWhenNotSecured) {
-  talk_base::scoped_ptr<buzz::XmlElement> elem;
-  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
-  test->TestGoodIncomingInitiate(AddEncryption(kGingleInitiate,
-                                              kGingleCryptoOffer), elem.use());
-}
-
-// Offer has crypto required but the session is not secure, fail.
-TEST(MediaSessionTest, GingleInitiateWithCryptoRequiredWhenNotSecured) {
-  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
-  test->TestBadIncomingInitiate(AddEncryption(kGingleInitiate,
-                                             kGingleRequiredCryptoOffer));
-}
-
-// Offer has no crypto but the session is secure required, fail.
-TEST(MediaSessionTest, GingleInitiateWithNoCryptoFailsWhenSecureRequired) {
-  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
-  test->ExpectCrypto(cricket::SEC_REQUIRED);
-  test->TestBadIncomingInitiate(kGingleInitiate);
-}
-
-// Offer has crypto and session is secure, expect crypto in the answer.
-TEST(MediaSessionTest, GingleInitiateWithCryptoWhenSecureEnabled) {
-  talk_base::scoped_ptr<buzz::XmlElement> elem;
-  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
-  test->ExpectCrypto(cricket::SEC_ENABLED);
-  test->TestGoodIncomingInitiate(AddEncryption(kGingleInitiate,
-                                              kGingleCryptoOffer), elem.use());
-}
-
-// Offer has crypto and session is secure required, expect crypto in
-// the answer.
-TEST(MediaSessionTest, GingleInitiateWithCryptoWhenSecureRequired) {
-  talk_base::scoped_ptr<buzz::XmlElement> elem;
-  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
-  test->ExpectCrypto(cricket::SEC_REQUIRED);
-  test->TestGoodIncomingInitiate(AddEncryption(kGingleInitiate,
-                                              kGingleCryptoOffer), elem.use());
-}
-
-// Offer has unsupported crypto and session is secure, no crypto in
-// the answer.
-TEST(MediaSessionTest, GingleInitiateWithUnsupportedCrypto) {
-  talk_base::scoped_ptr<buzz::XmlElement> elem;
-  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
-  test->MakeSignalingSecure(cricket::SEC_ENABLED);
-  test->TestGoodIncomingInitiate(
-      AddEncryption(kGingleInitiate, kGingleUnsupportedCryptoOffer),
-      elem.use());
-}
-
-// Offer has unsupported REQUIRED crypto and session is not secure, fail.
-TEST(MediaSessionTest, GingleInitiateWithRequiredUnsupportedCrypto) {
-  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
-  test->TestBadIncomingInitiate(
-      AddEncryption(kGingleInitiate, kGingleRequiredUnsupportedCryptoOffer));
-}
-
-// Offer has unsupported REQUIRED crypto and session is secure, fail.
-TEST(MediaSessionTest, GingleInitiateWithRequiredUnsupportedCryptoWhenSecure) {
-  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
-  test->MakeSignalingSecure(cricket::SEC_ENABLED);
-  test->TestBadIncomingInitiate(
-      AddEncryption(kGingleInitiate, kGingleRequiredUnsupportedCryptoOffer));
-}
-
-// Offer has unsupported REQUIRED crypto and session is required secure, fail.
-TEST(MediaSessionTest,
-     GingleInitiateWithRequiredUnsupportedCryptoWhenSecureRequired) {
-  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
-  test->MakeSignalingSecure(cricket::SEC_REQUIRED);
-  test->TestBadIncomingInitiate(
-      AddEncryption(kGingleInitiate, kGingleRequiredUnsupportedCryptoOffer));
-}
-
-TEST(MediaSessionTest, GingleGoodOutgoingInitiateWithCrypto) {
-  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
-  test->ExpectCrypto(cricket::SEC_ENABLED);
-  test->TestGoodOutgoingInitiate();
-}
-
-TEST(MediaSessionTest, GingleGoodOutgoingInitiateWithCryptoRequired) {
-  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
-  test->ExpectCrypto(cricket::SEC_REQUIRED);
-  test->TestGoodOutgoingInitiate();
-}
-
-TEST(MediaSessionTest, GingleIncomingAcceptWithSsrcs) {
-  talk_base::scoped_ptr<MediaSessionClientTest> test(GingleTest());
-  test->TestIncomingAcceptWithSsrcs(kGingleAcceptWithSsrcs);
-}
diff --git a/third_party/libjingle/source/talk/session/phone/mediasink.h b/third_party/libjingle/source/talk/session/phone/mediasink.h
deleted file mode 100644
index 3bc12bc..0000000
--- a/third_party/libjingle/source/talk/session/phone/mediasink.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SESSION_PHONE_MEDIASINK_H_
-#define TALK_SESSION_PHONE_MEDIASINK_H_
-
-namespace cricket {
-
-// MediaSinkInterface is a sink to handle RTP and RTCP packets that are sent or
-// received by a channel.
-class MediaSinkInterface {
- public:
-  virtual ~MediaSinkInterface() {}
-
-  virtual void SetMaxSize(size_t size) = 0;
-  virtual bool Enable(bool enable) = 0;
-  virtual bool IsEnabled() const = 0;
-  virtual void OnPacket(const void* data, size_t size, bool rtcp) = 0;
-  virtual void set_packet_filter(int filter) = 0;
-};
-
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_MEDIASINK_H_
diff --git a/third_party/libjingle/source/talk/session/phone/nullvideorenderer.h b/third_party/libjingle/source/talk/session/phone/nullvideorenderer.h
deleted file mode 100644
index aa48205..0000000
--- a/third_party/libjingle/source/talk/session/phone/nullvideorenderer.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * libjingle
- * Copyright 2004, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SESSION_PHONE_NULLVIDEORENDERER_H_
-#define TALK_SESSION_PHONE_NULLVIDEORENDERER_H_
-
-#include "talk/session/phone/videorenderer.h"
-
-namespace cricket {
-
-// Simple implementation for use in tests.
-class NullVideoRenderer : public VideoRenderer {
-  virtual bool SetSize(int width, int height, int reserved) {
-    return true;
-  }
-  // Called when a new frame is available for display.
-  virtual bool RenderFrame(const VideoFrame *frame) {
-    return true;
-  }
-};
-
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_NULLVIDEORENDERER_H_
diff --git a/third_party/libjingle/source/talk/session/phone/rtcpmuxfilter.cc b/third_party/libjingle/source/talk/session/phone/rtcpmuxfilter.cc
deleted file mode 100644
index 7ec095d..0000000
--- a/third_party/libjingle/source/talk/session/phone/rtcpmuxfilter.cc
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/session/phone/rtcpmuxfilter.h"
-
-#include "talk/base/logging.h"
-
-namespace cricket {
-
-RtcpMuxFilter::RtcpMuxFilter() : state_(ST_INIT), offer_enable_(false) {
-}
-
-bool RtcpMuxFilter::IsActive() const {
-  return state_ == ST_ACTIVE;
-}
-
-bool RtcpMuxFilter::SetOffer(bool offer_enable, ContentSource source) {
-  bool ret = false;
-  if (state_ == ST_INIT) {
-    offer_enable_ = offer_enable;
-    state_ = (source == CS_LOCAL) ? ST_SENTOFFER : ST_RECEIVEDOFFER;
-    ret = true;
-  } else {
-    LOG(LS_ERROR) << "Invalid state for RTCP mux offer";
-  }
-  return ret;
-}
-
-bool RtcpMuxFilter::SetAnswer(bool answer_enable, ContentSource source) {
-  bool ret = false;
-  if ((state_ == ST_SENTOFFER && source == CS_REMOTE) ||
-      (state_ == ST_RECEIVEDOFFER && source == CS_LOCAL)) {
-    if (offer_enable_) {
-      state_ = (answer_enable) ? ST_ACTIVE : ST_INIT;
-      ret = true;
-    } else {
-      // If the offer didn't specify RTCP mux, the answer shouldn't either.
-      if (!answer_enable) {
-        ret = true;
-        state_ = ST_INIT;
-      } else {
-        LOG(LS_WARNING) << "Invalid parameters in RTCP mux answer";
-      }
-    }
-  } else {
-    LOG(LS_ERROR) << "Invalid state for RTCP mux answer";
-  }
-  return ret;
-}
-
-bool RtcpMuxFilter::DemuxRtcp(const char* data, int len) {
-  // If we're muxing RTP/RTCP, we must inspect each packet delivered and
-  // determine whether it is RTP or RTCP. We do so by checking the packet type,
-  // and assuming RTP if type is 0-63 or 96-127. For additional details, see
-  // http://tools.ietf.org/html/rfc5761.
-  // Note that if we offer RTCP mux, we may receive muxed RTCP before we
-  // receive the answer, so we operate in that state too.
-  if (state_ != ST_SENTOFFER && state_ != ST_ACTIVE) {
-    return false;
-  }
-
-  int type = (len >= 2) ? (static_cast<uint8>(data[1]) & 0x7F) : 0;
-  return (type >= 64 && type < 96);
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/session/phone/rtcpmuxfilter.h b/third_party/libjingle/source/talk/session/phone/rtcpmuxfilter.h
deleted file mode 100644
index 0224e9f..0000000
--- a/third_party/libjingle/source/talk/session/phone/rtcpmuxfilter.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SESSION_PHONE_RTCPMUXFILTER_H_
-#define TALK_SESSION_PHONE_RTCPMUXFILTER_H_
-
-#include "talk/base/basictypes.h"
-#include "talk/p2p/base/sessiondescription.h"
-
-namespace cricket {
-
-// RTCP Muxer, as defined in RFC 5761 (http://tools.ietf.org/html/rfc5761)
-class RtcpMuxFilter {
- public:
-  RtcpMuxFilter();
-
-  // Whether the filter is active, i.e. has RTCP mux been properly negotiated.
-  bool IsActive() const;
-
-  // Specifies whether the offer indicates the use of RTCP mux.
-  bool SetOffer(bool offer_enable, ContentSource src);
-
-  // Specifies whether the answer indicates the use of RTCP mux.
-  bool SetAnswer(bool answer_enable, ContentSource src);
-
-  // Determines whether the specified packet is RTCP.
-  bool DemuxRtcp(const char* data, int len);
-
- private:
-  enum State { ST_INIT, ST_SENTOFFER, ST_RECEIVEDOFFER, ST_ACTIVE };
-  State state_;
-  bool offer_enable_;
-};
-
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_RTCPMUXFILTER_H_
diff --git a/third_party/libjingle/source/talk/session/phone/rtcpmuxfilter_unittest.cc b/third_party/libjingle/source/talk/session/phone/rtcpmuxfilter_unittest.cc
deleted file mode 100644
index 518330f..0000000
--- a/third_party/libjingle/source/talk/session/phone/rtcpmuxfilter_unittest.cc
+++ /dev/null
@@ -1,83 +0,0 @@
-// libjingle
-// Copyright 2011 Google Inc.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-//  1. Redistributions of source code must retain the above copyright notice,
-//     this list of conditions and the following disclaimer.
-//  2. Redistributions in binary form must reproduce the above copyright notice,
-//     this list of conditions and the following disclaimer in the documentation
-//     and/or other materials provided with the distribution.
-//  3. The name of the author may not be used to endorse or promote products
-//     derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include "talk/session/phone/rtcpmuxfilter.h"
-
-#include "talk/base/gunit.h"
-#include "talk/session/phone/testutils.h"
-
-TEST(RtcpMuxFilterTest, DemuxRtcpSender) {
-  cricket::RtcpMuxFilter filter;
-  const char data[] = { 0, 73, 0, 0 };
-  const int len = 4;
-
-  // Init state - refuse to demux
-  EXPECT_FALSE(filter.DemuxRtcp(data, len));
-  // After sent offer, demux should be enabled
-  filter.SetOffer(true, cricket::CS_LOCAL);
-  EXPECT_TRUE(filter.DemuxRtcp(data, len));
-  // Remote accepted, demux should be enabled
-  filter.SetAnswer(true, cricket::CS_REMOTE);
-  EXPECT_TRUE(filter.DemuxRtcp(data, len));
-}
-
-TEST(RtcpMuxFilterTest, DemuxRtcpReceiver) {
-  cricket::RtcpMuxFilter filter;
-  const char data[] = { 0, 73, 0, 0 };
-  const int len = 4;
-
-  // Init state - refuse to demux
-  EXPECT_FALSE(filter.DemuxRtcp(data, len));
-  // After received offer, demux should not be enabled
-  filter.SetOffer(true, cricket::CS_REMOTE);
-  EXPECT_FALSE(filter.DemuxRtcp(data, len));
-  // We accept, demux is now enabled.
-  filter.SetAnswer(true, cricket::CS_LOCAL);
-  EXPECT_TRUE(filter.DemuxRtcp(data, len));
-}
-
-TEST(RtcpMuxFilterTest, IsActiveSender) {
-  cricket::RtcpMuxFilter filter;
-  // Init state - not active.
-  EXPECT_FALSE(filter.IsActive());
-  // After sent offer, demux should not be active
-  filter.SetOffer(true, cricket::CS_LOCAL);
-  EXPECT_FALSE(filter.IsActive());
-  // Remote accepted, filter is now active
-  filter.SetAnswer(true, cricket::CS_REMOTE);
-  EXPECT_TRUE(filter.IsActive());
-}
-
-TEST(RtcpMuxFilterTest, IsActiveReceiver) {
-  cricket::RtcpMuxFilter filter;
-  // Init state - not active.
-  EXPECT_FALSE(filter.IsActive());
-  // After received offer, demux should not be active
-  filter.SetOffer(true, cricket::CS_REMOTE);
-  EXPECT_FALSE(filter.IsActive());
-  // We accept, filter is now active
-  filter.SetAnswer(true, cricket::CS_LOCAL);
-  EXPECT_TRUE(filter.IsActive());
-}
diff --git a/third_party/libjingle/source/talk/session/phone/rtpdump.cc b/third_party/libjingle/source/talk/session/phone/rtpdump.cc
deleted file mode 100644
index 2db2990..0000000
--- a/third_party/libjingle/source/talk/session/phone/rtpdump.cc
+++ /dev/null
@@ -1,400 +0,0 @@
-/*
- * libjingle
- * Copyright 2010 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/session/phone/rtpdump.h"
-
-#include <ctype.h>
-
-#include <string>
-
-#include "talk/base/byteorder.h"
-#include "talk/base/logging.h"
-#include "talk/base/timeutils.h"
-#include "talk/session/phone/rtputils.h"
-
-namespace cricket {
-
-static const int kRtpSsrcOffset = 8;
-
-const char RtpDumpFileHeader::kFirstLine[] = "#!rtpplay1.0 0.0.0.0/0\n";
-
-RtpDumpFileHeader::RtpDumpFileHeader(uint32 start_ms, uint32 s, uint16 p)
-    : start_sec(start_ms / 1000),
-      start_usec(start_ms % 1000 * 1000),
-      source(s),
-      port(p),
-      padding(0) {
-}
-
-void RtpDumpFileHeader::WriteToByteBuffer(talk_base::ByteBuffer* buf) {
-  buf->WriteUInt32(start_sec);
-  buf->WriteUInt32(start_usec);
-  buf->WriteUInt32(source);
-  buf->WriteUInt16(port);
-  buf->WriteUInt16(padding);
-}
-
-static const uint32 kDefaultTimeIncrease = 30;
-
-bool RtpDumpPacket::IsValidRtpPacket() const {
-  return !is_rtcp && data.size() >= kMinRtpPacketLen;
-}
-
-bool RtpDumpPacket::IsValidRtcpPacket() const {
-  return is_rtcp && data.size() >= kMinRtcpPacketLen;
-}
-
-bool RtpDumpPacket::GetRtpPayloadType(int* pt) const {
-  return IsValidRtpPacket() &&
-      cricket::GetRtpPayloadType(&data[0], data.size(), pt);
-}
-
-bool RtpDumpPacket::GetRtpSeqNum(int* seq_num) const {
-  return IsValidRtpPacket() &&
-      cricket::GetRtpSeqNum(&data[0], data.size(), seq_num);
-}
-
-bool RtpDumpPacket::GetRtpTimestamp(uint32* ts) const {
-  return IsValidRtpPacket() &&
-      cricket::GetRtpTimestamp(&data[0], data.size(), ts);
-}
-
-bool RtpDumpPacket::GetRtpSsrc(uint32* ssrc) const {
-  return IsValidRtpPacket() &&
-      cricket::GetRtpSsrc(&data[0], data.size(), ssrc);
-}
-
-bool RtpDumpPacket::GetRtpHeaderLen(size_t* len) const {
-  return IsValidRtpPacket() &&
-      cricket::GetRtpHeaderLen(&data[0], data.size(), len);
-}
-
-bool RtpDumpPacket::GetRtcpType(int* type) const {
-  return IsValidRtcpPacket() &&
-      cricket::GetRtcpType(&data[0], data.size(), type);
-}
-
-///////////////////////////////////////////////////////////////////////////
-// Implementation of RtpDumpReader.
-///////////////////////////////////////////////////////////////////////////
-void RtpDumpReader::SetSsrc(uint32 ssrc) {
-  // Convert ssrc to network endian for RTP packet.
-  ssrc_buffer_.Consume(ssrc_buffer_.Length());
-  ssrc_buffer_.WriteUInt32(ssrc);
-}
-
-talk_base::StreamResult RtpDumpReader::ReadPacket(RtpDumpPacket* packet) {
-  if (!packet) return talk_base::SR_ERROR;
-
-  talk_base::StreamResult res = talk_base::SR_SUCCESS;
-  // Read the file header if it has not been read yet.
-  if (!file_header_read_) {
-    res = ReadFileHeader();
-    if (res != talk_base::SR_SUCCESS) {
-      return res;
-    }
-    file_header_read_ = true;
-  }
-
-  // Read the RTP dump packet header.
-  char header[RtpDumpPacket::kHeaderLength];
-  res = stream_->ReadAll(header, sizeof(header), NULL, NULL);
-  if (res != talk_base::SR_SUCCESS) {
-    return res;
-  }
-  talk_base::ByteBuffer buf(header, sizeof(header));
-  uint16 dump_packet_len;
-  uint16 data_len;
-  buf.ReadUInt16(&dump_packet_len);
-  buf.ReadUInt16(&data_len);  // data.size() for RTP, 0 for RTCP.
-  packet->is_rtcp = (0 == data_len);
-  buf.ReadUInt32(&packet->elapsed_time);
-  packet->data.resize(dump_packet_len - sizeof(header));
-
-  // Read the actual RTP or RTCP packet.
-  res = stream_->ReadAll(&packet->data[0], packet->data.size(), NULL, NULL);
-  // If the packet is RTP and we have specified a ssrc, replace the RTP ssrc
-  // with the specified ssrc.
-  if (res == talk_base::SR_SUCCESS &&
-      packet->IsValidRtpPacket() &&
-      ssrc_buffer_.Length() == sizeof(uint32)) {
-    memcpy(&packet->data[kRtpSsrcOffset], ssrc_buffer_.Data(),
-           ssrc_buffer_.Length());
-  }
-
-  return res;
-}
-
-talk_base::StreamResult RtpDumpReader::ReadFileHeader() {
-  // Read the first line.
-  std::string first_line;
-  talk_base::StreamResult res = stream_->ReadLine(&first_line);
-  if (res != talk_base::SR_SUCCESS) {
-    return res;
-  }
-  if (!CheckFirstLine(first_line)) {
-    return talk_base::SR_ERROR;
-  }
-
-  // Read the 16 byte file header.
-  char header[RtpDumpFileHeader::kHeaderLength];
-  res = stream_->ReadAll(header, sizeof(header), NULL, NULL);
-  if (res == talk_base::SR_SUCCESS) {
-    talk_base::ByteBuffer buf(header, sizeof(header));
-    uint32 start_sec;
-    uint32 start_usec;
-    buf.ReadUInt32(&start_sec);
-    buf.ReadUInt32(&start_usec);
-    start_time_ms_ = start_sec * 1000 + start_usec / 1000;
-    // Increase the length by 1 since first_line does not contain the ending \n.
-    first_line_and_file_header_len_ = first_line.size() + 1 + sizeof(header);
-  }
-  return res;
-}
-
-bool RtpDumpReader::CheckFirstLine(const std::string& first_line) {
-  // The first line is like "#!rtpplay1.0 address/port"
-  bool matched = (0 == first_line.find("#!rtpplay1.0 "));
-
-  // The address could be IP or hostname. We do not check it here. Instead, we
-  // check the port at the end.
-  size_t pos = first_line.find('/');
-  matched &= (pos != std::string::npos && pos < first_line.size() - 1);
-  for (++pos; pos < first_line.size() && matched; ++pos) {
-    matched &= (0 != isdigit(first_line[pos]));
-  }
-
-  return matched;
-}
-
-///////////////////////////////////////////////////////////////////////////
-// Implementation of RtpDumpLoopReader.
-///////////////////////////////////////////////////////////////////////////
-RtpDumpLoopReader::RtpDumpLoopReader(talk_base::StreamInterface* stream)
-    : RtpDumpReader(stream),
-      loop_count_(0),
-      elapsed_time_increases_(0),
-      rtp_seq_num_increase_(0),
-      rtp_timestamp_increase_(0),
-      packet_count_(0),
-      frame_count_(0),
-      first_elapsed_time_(0),
-      first_rtp_seq_num_(0),
-      first_rtp_timestamp_(0),
-      prev_elapsed_time_(0),
-      prev_rtp_seq_num_(0),
-      prev_rtp_timestamp_(0) {
-}
-
-talk_base::StreamResult RtpDumpLoopReader::ReadPacket(RtpDumpPacket* packet) {
-  if (!packet) return talk_base::SR_ERROR;
-
-  talk_base::StreamResult res = RtpDumpReader::ReadPacket(packet);
-  if (talk_base::SR_SUCCESS == res) {
-    if (0 == loop_count_) {
-      // During the first loop, we update the statistics of the input stream.
-      UpdateStreamStatistics(*packet);
-    }
-  } else if (talk_base::SR_EOS == res) {
-    if (0 == loop_count_) {
-      // At the end of the first loop, calculate elapsed_time_increases_,
-      // rtp_seq_num_increase_, and rtp_timestamp_increase_, which will be
-      // used during the second and later loops.
-      CalculateIncreases();
-    }
-
-    // Rewind the input stream to the first dump packet and read again.
-    ++loop_count_;
-    if (RewindToFirstDumpPacket()) {
-      res = RtpDumpReader::ReadPacket(packet);
-    }
-  }
-
-  if (talk_base::SR_SUCCESS == res && loop_count_ > 0) {
-    // During the second and later loops, we update the elapsed time of the dump
-    // packet. If the dumped packet is a RTP packet, we also update its RTP
-    // sequence number and timestamp.
-    UpdateDumpPacket(packet);
-  }
-
-  return res;
-}
-
-void RtpDumpLoopReader::UpdateStreamStatistics(const RtpDumpPacket& packet) {
-  // Get the RTP sequence number and timestamp of the dump packet.
-  int rtp_seq_num = 0;
-  packet.GetRtpSeqNum(&rtp_seq_num);
-  uint32 rtp_timestamp = 0;
-  packet.GetRtpTimestamp(&rtp_timestamp);
-
-  // Set the timestamps and sequence number for the first dump packet.
-  if (0 == packet_count_++) {
-    first_elapsed_time_ = packet.elapsed_time;
-    first_rtp_seq_num_ = rtp_seq_num;
-    first_rtp_timestamp_ = rtp_timestamp;
-    // The first packet belongs to a new payload frame.
-    ++frame_count_;
-  } else if (rtp_timestamp != prev_rtp_timestamp_) {
-    // The current and previous packets belong to different payload frames.
-    ++frame_count_;
-  }
-
-  prev_elapsed_time_ = packet.elapsed_time;
-  prev_rtp_timestamp_ = rtp_timestamp;
-  prev_rtp_seq_num_ = rtp_seq_num;
-}
-
-void RtpDumpLoopReader::CalculateIncreases() {
-  // At this time, prev_elapsed_time_, prev_rtp_seq_num_, and
-  // prev_rtp_timestamp_ are values of the last dump packet in the input stream.
-  rtp_seq_num_increase_ = prev_rtp_seq_num_ - first_rtp_seq_num_ + 1;
-  // If we have only one packet or frame, we use the default timestamp
-  // increase. Otherwise, we use the difference between the first and the last
-  // packets or frames.
-  elapsed_time_increases_ = packet_count_ <= 1 ? kDefaultTimeIncrease :
-      (prev_elapsed_time_ - first_elapsed_time_) * packet_count_ /
-      (packet_count_ - 1);
-  rtp_timestamp_increase_ = frame_count_ <= 1 ? kDefaultTimeIncrease :
-      (prev_rtp_timestamp_ - first_rtp_timestamp_) * frame_count_ /
-      (frame_count_ - 1);
-}
-
-void RtpDumpLoopReader::UpdateDumpPacket(RtpDumpPacket* packet) {
-  // Increase the elapsed time of the dump packet.
-  packet->elapsed_time += loop_count_ * elapsed_time_increases_;
-
-  if (packet->IsValidRtpPacket()) {
-    // Get the old RTP sequence number and timestamp.
-    int sequence = 0;
-    packet->GetRtpSeqNum(&sequence);
-    uint32 timestamp = 0;
-    packet->GetRtpTimestamp(&timestamp);
-    // Increase the RTP sequence number and timestamp.
-    sequence += loop_count_ * rtp_seq_num_increase_;
-    timestamp += loop_count_ * rtp_timestamp_increase_;
-    // Write the updated sequence number and timestamp back to the RTP packet.
-    talk_base::ByteBuffer buffer;
-    buffer.WriteUInt16(sequence);
-    buffer.WriteUInt32(timestamp);
-    memcpy(&packet->data[2], buffer.Data(), buffer.Length());
-  }
-}
-
-///////////////////////////////////////////////////////////////////////////
-// Implementation of RtpDumpWriter.
-///////////////////////////////////////////////////////////////////////////
-
-RtpDumpWriter::RtpDumpWriter(talk_base::StreamInterface* stream)
-    : stream_(stream),
-      packet_filter_(PF_ALL),
-      file_header_written_(false),
-      start_time_ms_(talk_base::Time()) {
-}
-
-void RtpDumpWriter::set_packet_filter(int filter) {
-  packet_filter_ = filter;
-  LOG(LS_INFO) << "RtpDumpWriter set_packet_filter to " << packet_filter_;
-}
-
-uint32 RtpDumpWriter::GetElapsedTime() const {
-  return talk_base::TimeSince(start_time_ms_);
-}
-
-talk_base::StreamResult RtpDumpWriter::WriteFileHeader() {
-  talk_base::StreamResult res = stream_->WriteAll(
-      RtpDumpFileHeader::kFirstLine,
-      strlen(RtpDumpFileHeader::kFirstLine), NULL, NULL);
-  if (res != talk_base::SR_SUCCESS) {
-    return res;
-  }
-
-  talk_base::ByteBuffer buf;
-  RtpDumpFileHeader file_header(talk_base::Time(), 0, 0);
-  file_header.WriteToByteBuffer(&buf);
-  return stream_->WriteAll(buf.Data(), buf.Length(), NULL, NULL);
-}
-
-talk_base::StreamResult RtpDumpWriter::WritePacket(
-    const void* data, size_t data_len, uint32 elapsed, bool rtcp) {
-  if (!stream_ || !data || 0 == data_len) return talk_base::SR_ERROR;
-
-  talk_base::StreamResult res = talk_base::SR_SUCCESS;
-  // Write the file header if it has not been written yet.
-  if (!file_header_written_) {
-    res = WriteFileHeader();
-    if (res != talk_base::SR_SUCCESS) {
-      return res;
-    }
-    file_header_written_ = true;
-  }
-
-  // Figure out what to write.
-  size_t write_len = FilterPacket(data, data_len, rtcp);
-  if (write_len == 0) {
-    return talk_base::SR_SUCCESS;
-  }
-
-  // Write the dump packet header.
-  talk_base::ByteBuffer buf;
-  buf.WriteUInt16(static_cast<uint16>(
-                      RtpDumpPacket::kHeaderLength + write_len));
-  buf.WriteUInt16(static_cast<uint16>(rtcp ? 0 : data_len));
-  buf.WriteUInt32(elapsed);
-  res = stream_->WriteAll(buf.Data(), buf.Length(), NULL, NULL);
-  if (res != talk_base::SR_SUCCESS) {
-    return res;
-  }
-
-  // Write the header or full packet as indicated by write_len.
-  return stream_->WriteAll(data, write_len, NULL, NULL);
-}
-
-size_t RtpDumpWriter::FilterPacket(const void* data, size_t data_len,
-                                   bool rtcp) {
-  size_t filtered_len = 0;
-  if (!rtcp) {
-    if ((packet_filter_ & PF_RTPPACKET) == PF_RTPPACKET) {
-      // RTP header + payload
-      filtered_len = data_len;
-    } else if ((packet_filter_ & PF_RTPHEADER) == PF_RTPHEADER) {
-      // RTP header only
-      size_t header_len;
-      if (GetRtpHeaderLen(data, data_len, &header_len)) {
-        filtered_len = header_len;
-      }
-    }
-  } else {
-    if ((packet_filter_ & PF_RTCPPACKET) == PF_RTCPPACKET) {
-      // RTCP header + payload
-      filtered_len = data_len;
-    }
-  }
-
-  return filtered_len;
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/session/phone/rtpdump.h b/third_party/libjingle/source/talk/session/phone/rtpdump.h
deleted file mode 100644
index b120f12..0000000
--- a/third_party/libjingle/source/talk/session/phone/rtpdump.h
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * libjingle
- * Copyright 2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SESSION_PHONE_RTPDUMP_H_
-#define TALK_SESSION_PHONE_RTPDUMP_H_
-
-#include <cstring>
-#include <string>
-#include <vector>
-
-#include "talk/base/basictypes.h"
-#include "talk/base/bytebuffer.h"
-#include "talk/base/stream.h"
-
-namespace cricket {
-
-// We use the RTP dump file format compatible to the format used by rtptools
-// (http://www.cs.columbia.edu/irt/software/rtptools/) and Wireshark
-// (http://wiki.wireshark.org/rtpdump). In particular, the file starts with the
-// first line "#!rtpplay1.0 address/port\n", followed by a 16 byte file header.
-// For each packet, the file contains a 8 byte dump packet header, followed by
-// the actual RTP or RTCP packet.
-
-enum RtpDumpPacketFilter {
-  PF_NONE = 0x0,
-  PF_RTPHEADER = 0x1,
-  PF_RTPPACKET = 0x3,  // includes header
-  // PF_RTCPHEADER = 0x4,  // TODO
-  PF_RTCPPACKET = 0xC,  // includes header
-  PF_ALL = 0xF
-};
-
-struct RtpDumpFileHeader {
-  RtpDumpFileHeader(uint32 start_ms, uint32 s, uint16 p);
-  void WriteToByteBuffer(talk_base::ByteBuffer* buf);
-
-  static const char kFirstLine[];
-  static const size_t kHeaderLength = 16;
-  uint32 start_sec;   // start of recording, the seconds part.
-  uint32 start_usec;  // start of recording, the microseconds part.
-  uint32 source;      // network source (multicast address).
-  uint16 port;        // UDP port.
-  uint16 padding;     // 2 bytes padding.
-};
-
-struct RtpDumpPacket {
-  RtpDumpPacket() {}
-
-  RtpDumpPacket(const void* d, size_t s, uint32 elapsed, bool rtcp)
-      : elapsed_time(elapsed),
-        is_rtcp(rtcp) {
-    data.resize(s);
-    memcpy(&data[0], d, s);
-  }
-
-  bool IsValidRtpPacket() const;
-  bool IsValidRtcpPacket() const;
-  // Get the payload type, sequence number, timestampe, and SSRC of the RTP
-  // packet. Return true and set the output parameter if successful.
-  bool GetRtpPayloadType(int* pt) const;
-  bool GetRtpSeqNum(int* seq_num) const;
-  bool GetRtpTimestamp(uint32* ts) const;
-  bool GetRtpSsrc(uint32* ssrc) const;
-  bool GetRtpHeaderLen(size_t* len) const;
-  // Get the type of the RTCP packet. Return true and set the output parameter
-  // if successful.
-  bool GetRtcpType(int* type) const;
-
-  static const size_t kHeaderLength = 8;
-  uint32 elapsed_time;      // Milliseconds since the start of recording.
-  bool is_rtcp;             // True if the data below is a RTCP packet.
-  std::vector<uint8> data;  // The actual RTP or RTCP packet.
-};
-
-class RtpDumpReader {
- public:
-  explicit RtpDumpReader(talk_base::StreamInterface* stream)
-      : stream_(stream),
-        file_header_read_(false),
-        first_line_and_file_header_len_(0),
-        start_time_ms_(0) {
-  }
-  virtual ~RtpDumpReader() {}
-
-  // Use the specified ssrc, rather than the ssrc from dump, for RTP packets.
-  void SetSsrc(uint32 ssrc);
-  virtual talk_base::StreamResult ReadPacket(RtpDumpPacket* packet);
-
- protected:
-  talk_base::StreamResult ReadFileHeader();
-  bool RewindToFirstDumpPacket() {
-    return stream_->SetPosition(first_line_and_file_header_len_);
-  }
-
- private:
-  // Check if its matches "#!rtpplay1.0 address/port\n".
-  bool CheckFirstLine(const std::string& first_line);
-
-  talk_base::StreamInterface* stream_;
-  bool file_header_read_;
-  size_t first_line_and_file_header_len_;
-  uint32 start_time_ms_;
-  talk_base::ByteBuffer ssrc_buffer_;
-
-  DISALLOW_COPY_AND_ASSIGN(RtpDumpReader);
-};
-
-// RtpDumpLoopReader reads RTP dump packets from the input stream and rewinds
-// the stream when it ends. RtpDumpLoopReader maintains the elapsed time, the
-// RTP sequence number and the RTP timestamp properly. RtpDumpLoopReader can
-// handle both RTP dump and RTCP dump. We assume that the dump does not mix
-// RTP packets and RTCP packets.
-class RtpDumpLoopReader : public RtpDumpReader {
- public:
-  explicit RtpDumpLoopReader(talk_base::StreamInterface* stream);
-  virtual talk_base::StreamResult ReadPacket(RtpDumpPacket* packet);
-
- private:
-  // During the first loop, update the statistics, including packet count, frame
-  // count, timestamps, and sequence number, of the input stream.
-  void UpdateStreamStatistics(const RtpDumpPacket& packet);
-
-  // At the end of first loop, calculate elapsed_time_increases_,
-  // rtp_seq_num_increase_, and rtp_timestamp_increase_.
-  void CalculateIncreases();
-
-  // During the second and later loops, update the elapsed time of the dump
-  // packet. If the dumped packet is a RTP packet, update its RTP sequence
-  // number and timestamp as well.
-  void UpdateDumpPacket(RtpDumpPacket* packet);
-
-  int loop_count_;
-  // How much to increase the elapsed time, RTP sequence number, RTP timestampe
-  // for each loop. They are calcualted with the variables below during the
-  // first loop.
-  uint32 elapsed_time_increases_;
-  int rtp_seq_num_increase_;
-  uint32 rtp_timestamp_increase_;
-  // How many RTP packets and how many payload frames in the input stream. RTP
-  // packets belong to the same frame have the same RTP timestamp, different
-  // dump timestamp, and different RTP sequence number.
-  uint32 packet_count_;
-  uint32 frame_count_;
-  // The elapsed time, RTP sequence number, and RTP timestamp of the first and
-  // the previous dump packets in the input stream.
-  uint32 first_elapsed_time_;
-  int first_rtp_seq_num_;
-  uint32 first_rtp_timestamp_;
-  uint32 prev_elapsed_time_;
-  int prev_rtp_seq_num_;
-  uint32 prev_rtp_timestamp_;
-
-  DISALLOW_COPY_AND_ASSIGN(RtpDumpLoopReader);
-};
-
-class RtpDumpWriter {
- public:
-  explicit RtpDumpWriter(talk_base::StreamInterface* stream);
-
-  // Filter to control what packets we actually record.
-  void set_packet_filter(int filter);
-  // Write a RTP or RTCP packet. The parameters data points to the packet and
-  // data_len is its length.
-  talk_base::StreamResult WriteRtpPacket(const void* data, size_t data_len) {
-    return WritePacket(data, data_len, GetElapsedTime(), false);
-  }
-  talk_base::StreamResult WriteRtcpPacket(const void* data, size_t data_len) {
-    return WritePacket(data, data_len, GetElapsedTime(), true);
-  }
-  talk_base::StreamResult WritePacket(const RtpDumpPacket& packet) {
-    return WritePacket(&packet.data[0], packet.data.size(), packet.elapsed_time,
-                       packet.is_rtcp);
-  }
-  uint32 GetElapsedTime() const;
-
-  bool GetDumpSize(size_t* size) {
-    // Note that we use GetPosition(), rather than GetSize(), to avoid flush the
-    // stream per write.
-    return stream_ && size && stream_->GetPosition(size);
-  }
-
- protected:
-  talk_base::StreamResult WriteFileHeader();
-
- private:
-  talk_base::StreamResult WritePacket(const void* data, size_t data_len,
-                                      uint32 elapsed, bool rtcp);
-  size_t FilterPacket(const void* data, size_t data_len, bool rtcp);
-
-  talk_base::StreamInterface* stream_;
-  int packet_filter_;
-  bool file_header_written_;
-  uint32 start_time_ms_;  // Time when the record starts.
-  DISALLOW_COPY_AND_ASSIGN(RtpDumpWriter);
-};
-
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_RTPDUMP_H_
diff --git a/third_party/libjingle/source/talk/session/phone/rtpdump_unittest.cc b/third_party/libjingle/source/talk/session/phone/rtpdump_unittest.cc
deleted file mode 100644
index fc48858..0000000
--- a/third_party/libjingle/source/talk/session/phone/rtpdump_unittest.cc
+++ /dev/null
@@ -1,289 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string>
-
-#include "talk/base/bytebuffer.h"
-#include "talk/base/gunit.h"
-#include "talk/base/thread.h"
-#include "talk/session/phone/rtpdump.h"
-#include "talk/session/phone/rtputils.h"
-#include "talk/session/phone/testutils.h"
-
-namespace cricket {
-
-static const uint32 kTestSsrc = 1;
-
-// Test that we read the correct header fields from the RTP/RTCP packet.
-TEST(RtpDumpTest, ReadRtpDumpPacket) {
-  talk_base::ByteBuffer rtp_buf;
-  RtpTestUtility::kTestRawRtpPackets[0].WriteToByteBuffer(kTestSsrc, &rtp_buf);
-  RtpDumpPacket rtp_packet(rtp_buf.Data(), rtp_buf.Length(), 0, false);
-
-  int type;
-  int seq_num;
-  uint32 ts;
-  uint32 ssrc;
-  EXPECT_TRUE(rtp_packet.IsValidRtpPacket());
-  EXPECT_FALSE(rtp_packet.IsValidRtcpPacket());
-  EXPECT_TRUE(rtp_packet.GetRtpPayloadType(&type));
-  EXPECT_EQ(0, type);
-  EXPECT_TRUE(rtp_packet.GetRtpSeqNum(&seq_num));
-  EXPECT_EQ(0, seq_num);
-  EXPECT_TRUE(rtp_packet.GetRtpTimestamp(&ts));
-  EXPECT_EQ(0U, ts);
-  EXPECT_TRUE(rtp_packet.GetRtpSsrc(&ssrc));
-  EXPECT_EQ(kTestSsrc, ssrc);
-  EXPECT_FALSE(rtp_packet.GetRtcpType(&type));
-
-  talk_base::ByteBuffer rtcp_buf;
-  RtpTestUtility::kTestRawRtcpPackets[0].WriteToByteBuffer(&rtcp_buf);
-  RtpDumpPacket rtcp_packet(rtcp_buf.Data(), rtcp_buf.Length(), 0, true);
-
-  EXPECT_FALSE(rtcp_packet.IsValidRtpPacket());
-  EXPECT_TRUE(rtcp_packet.IsValidRtcpPacket());
-  EXPECT_TRUE(rtcp_packet.GetRtcpType(&type));
-  EXPECT_EQ(0, type);
-}
-
-// Test that we read only the RTP dump file.
-TEST(RtpDumpTest, ReadRtpDumpFile) {
-  RtpDumpPacket packet;
-  talk_base::MemoryStream stream;
-  RtpDumpWriter writer(&stream);
-  talk_base::scoped_ptr<RtpDumpReader> reader;
-
-  // Write a RTP packet to the stream, which is a valid RTP dump. Next, we will
-  // change the first line to make the RTP dump valid or invalid.
-  ASSERT_TRUE(RtpTestUtility::WriteTestPackets(1, false, kTestSsrc, &writer));
-  stream.Rewind();
-  reader.reset(new RtpDumpReader(&stream));
-  EXPECT_EQ(talk_base::SR_SUCCESS, reader->ReadPacket(&packet));
-
-  // The first line is correct.
-  stream.Rewind();
-  const char new_line[] = "#!rtpplay1.0 1.1.1.1/1\n";
-  EXPECT_EQ(talk_base::SR_SUCCESS,
-            stream.WriteAll(new_line, strlen(new_line), NULL, NULL));
-  stream.Rewind();
-  reader.reset(new RtpDumpReader(&stream));
-  EXPECT_EQ(talk_base::SR_SUCCESS, reader->ReadPacket(&packet));
-
-  // The first line is not correct: not started with #!rtpplay1.0.
-  stream.Rewind();
-  const char new_line2[] = "#!rtpplaz1.0 0.0.0.0/0\n";
-  EXPECT_EQ(talk_base::SR_SUCCESS,
-            stream.WriteAll(new_line2, strlen(new_line2), NULL, NULL));
-  stream.Rewind();
-  reader.reset(new RtpDumpReader(&stream));
-  EXPECT_EQ(talk_base::SR_ERROR, reader->ReadPacket(&packet));
-
-  // The first line is not correct: no port.
-  stream.Rewind();
-  const char new_line3[] = "#!rtpplay1.0 0.0.0.0//\n";
-  EXPECT_EQ(talk_base::SR_SUCCESS,
-            stream.WriteAll(new_line3, strlen(new_line3), NULL, NULL));
-  stream.Rewind();
-  reader.reset(new RtpDumpReader(&stream));
-  EXPECT_EQ(talk_base::SR_ERROR, reader->ReadPacket(&packet));
-}
-
-// Test that we read the same RTP packets that rtp dump writes.
-TEST(RtpDumpTest, WriteReadSameRtp) {
-  talk_base::MemoryStream stream;
-  RtpDumpWriter writer(&stream);
-  ASSERT_TRUE(RtpTestUtility::WriteTestPackets(
-      RtpTestUtility::GetTestPacketCount(), false, kTestSsrc, &writer));
-  EXPECT_TRUE(RtpTestUtility::VerifyTestPacketsFromStream(
-      RtpTestUtility::GetTestPacketCount(), &stream, kTestSsrc));
-
-  // Check stream has only RtpTestUtility::GetTestPacketCount() packets.
-  RtpDumpPacket packet;
-  RtpDumpReader reader(&stream);
-  for (size_t i = 0; i < RtpTestUtility::GetTestPacketCount(); ++i) {
-    EXPECT_EQ(talk_base::SR_SUCCESS , reader.ReadPacket(&packet));
-    uint32 ssrc;
-    EXPECT_TRUE(GetRtpSsrc(&packet.data[0], packet.data.size(), &ssrc));
-    EXPECT_EQ(kTestSsrc, ssrc);
-  }
-  // No more packets to read.
-  EXPECT_EQ(talk_base::SR_EOS, reader.ReadPacket(&packet));
-
-  // Rewind the stream and read again with a specified ssrc.
-  stream.Rewind();
-  RtpDumpReader reader_w_ssrc(&stream);
-  const uint32 send_ssrc = kTestSsrc + 1;
-  reader_w_ssrc.SetSsrc(send_ssrc);
-  for (size_t i = 0; i < RtpTestUtility::GetTestPacketCount(); ++i) {
-    EXPECT_EQ(talk_base::SR_SUCCESS , reader_w_ssrc.ReadPacket(&packet));
-    uint32 ssrc;
-    EXPECT_TRUE(GetRtpSsrc(&packet.data[0], packet.data.size(), &ssrc));
-    EXPECT_EQ(send_ssrc, ssrc);
-  }
-  // No more packets to read.
-  EXPECT_EQ(talk_base::SR_EOS, reader_w_ssrc.ReadPacket(&packet));
-}
-
-// Test that we read the same RTCP packets that rtp dump writes.
-TEST(RtpDumpTest, WriteReadSameRtcp) {
-  talk_base::MemoryStream stream;
-  RtpDumpWriter writer(&stream);
-  ASSERT_TRUE(RtpTestUtility::WriteTestPackets(
-      RtpTestUtility::GetTestPacketCount(), true, kTestSsrc, &writer));
-  EXPECT_TRUE(RtpTestUtility::VerifyTestPacketsFromStream(
-      RtpTestUtility::GetTestPacketCount(), &stream, kTestSsrc));
-
-  // Check stream has only RtpTestUtility::GetTestPacketCount() packets.
-  RtpDumpPacket packet;
-  RtpDumpReader reader(&stream);
-  reader.SetSsrc(kTestSsrc + 1);  // Does not affect RTCP packet.
-  for (size_t i = 0; i < RtpTestUtility::GetTestPacketCount(); ++i) {
-    EXPECT_EQ(talk_base::SR_SUCCESS , reader.ReadPacket(&packet));
-  }
-  // No more packets to read.
-  EXPECT_EQ(talk_base::SR_EOS, reader.ReadPacket(&packet));
-}
-
-// Test dumping only RTP packet headers.
-TEST(RtpDumpTest, WriteReadRtpHeadersOnly) {
-  talk_base::MemoryStream stream;
-  RtpDumpWriter writer(&stream);
-  writer.set_packet_filter(PF_RTPHEADER);
-
-  // Write some RTP and RTCP packets. RTP packets should only have headers;
-  // RTCP packets should be eaten.
-  ASSERT_TRUE(RtpTestUtility::WriteTestPackets(
-      RtpTestUtility::GetTestPacketCount(), false, kTestSsrc, &writer));
-  ASSERT_TRUE(RtpTestUtility::WriteTestPackets(
-      RtpTestUtility::GetTestPacketCount(), true, kTestSsrc, &writer));
-  stream.Rewind();
-
-  // Check that only RTP packet headers are present.
-  RtpDumpPacket packet;
-  RtpDumpReader reader(&stream);
-  for (size_t i = 0; i < RtpTestUtility::GetTestPacketCount(); ++i) {
-    EXPECT_EQ(talk_base::SR_SUCCESS , reader.ReadPacket(&packet));
-    EXPECT_FALSE(packet.is_rtcp);
-    size_t len = 0;
-    packet.GetRtpHeaderLen(&len);
-    EXPECT_EQ(len, packet.data.size());
-  }
-  // No more packets to read.
-  EXPECT_EQ(talk_base::SR_EOS, reader.ReadPacket(&packet));
-}
-
-// Test dumping only RTCP packets.
-TEST(RtpDumpTest, WriteReadRtcpOnly) {
-  talk_base::MemoryStream stream;
-  RtpDumpWriter writer(&stream);
-  writer.set_packet_filter(PF_RTCPPACKET);
-
-  // Write some RTP and RTCP packets. RTP packets should be eaten.
-  ASSERT_TRUE(RtpTestUtility::WriteTestPackets(
-      RtpTestUtility::GetTestPacketCount(), false, kTestSsrc, &writer));
-  ASSERT_TRUE(RtpTestUtility::WriteTestPackets(
-      RtpTestUtility::GetTestPacketCount(), true, kTestSsrc, &writer));
-  stream.Rewind();
-
-  // Check that only RTCP packets are present.
-  RtpDumpPacket packet;
-  RtpDumpReader reader(&stream);
-  for (size_t i = 0; i < RtpTestUtility::GetTestPacketCount(); ++i) {
-    EXPECT_EQ(talk_base::SR_SUCCESS , reader.ReadPacket(&packet));
-    EXPECT_TRUE(packet.is_rtcp);
-  }
-  // No more packets to read.
-  EXPECT_EQ(talk_base::SR_EOS, reader.ReadPacket(&packet));
-}
-
-// Test that RtpDumpLoopReader reads RTP packets continously and the elapsed
-// time, the sequence number, and timestamp are maintained properly.
-TEST(RtpDumpTest, LoopReadRtp) {
-  talk_base::MemoryStream stream;
-  RtpDumpWriter writer(&stream);
-  ASSERT_TRUE(RtpTestUtility::WriteTestPackets(
-      RtpTestUtility::GetTestPacketCount(), false, kTestSsrc, &writer));
-  EXPECT_TRUE(RtpTestUtility::VerifyTestPacketsFromStream(
-      3 * RtpTestUtility::GetTestPacketCount(), &stream, kTestSsrc));
-}
-
-// Test that RtpDumpLoopReader reads RTCP packets continously and the elapsed
-// time is maintained properly.
-TEST(RtpDumpTest, LoopReadRtcp) {
-  talk_base::MemoryStream stream;
-  RtpDumpWriter writer(&stream);
-  ASSERT_TRUE(RtpTestUtility::WriteTestPackets(
-      RtpTestUtility::GetTestPacketCount(), true, kTestSsrc, &writer));
-  EXPECT_TRUE(RtpTestUtility::VerifyTestPacketsFromStream(
-      3 * RtpTestUtility::GetTestPacketCount(), &stream, kTestSsrc));
-}
-
-// Test that RtpDumpLoopReader reads continously from stream with a single RTP
-// packets.
-TEST(RtpDumpTest, LoopReadSingleRtp) {
-  talk_base::MemoryStream stream;
-  RtpDumpWriter writer(&stream);
-  ASSERT_TRUE(RtpTestUtility::WriteTestPackets(1, false, kTestSsrc, &writer));
-
-  // The regular reader can read only one packet.
-  RtpDumpPacket packet;
-  stream.Rewind();
-  RtpDumpReader reader(&stream);
-  EXPECT_EQ(talk_base::SR_SUCCESS, reader.ReadPacket(&packet));
-  EXPECT_EQ(talk_base::SR_EOS, reader.ReadPacket(&packet));
-
-  // The loop reader reads three packets from the input stream.
-  stream.Rewind();
-  RtpDumpLoopReader loop_reader(&stream);
-  EXPECT_EQ(talk_base::SR_SUCCESS, loop_reader.ReadPacket(&packet));
-  EXPECT_EQ(talk_base::SR_SUCCESS, loop_reader.ReadPacket(&packet));
-  EXPECT_EQ(talk_base::SR_SUCCESS, loop_reader.ReadPacket(&packet));
-}
-
-// Test that RtpDumpLoopReader reads continously from stream with a single RTCP
-// packets.
-TEST(RtpDumpTest, LoopReadSingleRtcp) {
-  talk_base::MemoryStream stream;
-  RtpDumpWriter writer(&stream);
-  ASSERT_TRUE(RtpTestUtility::WriteTestPackets(1, true, kTestSsrc, &writer));
-
-  // The regular reader can read only one packet.
-  RtpDumpPacket packet;
-  stream.Rewind();
-  RtpDumpReader reader(&stream);
-  EXPECT_EQ(talk_base::SR_SUCCESS, reader.ReadPacket(&packet));
-  EXPECT_EQ(talk_base::SR_EOS, reader.ReadPacket(&packet));
-
-  // The loop reader reads three packets from the input stream.
-  stream.Rewind();
-  RtpDumpLoopReader loop_reader(&stream);
-  EXPECT_EQ(talk_base::SR_SUCCESS, loop_reader.ReadPacket(&packet));
-  EXPECT_EQ(talk_base::SR_SUCCESS, loop_reader.ReadPacket(&packet));
-  EXPECT_EQ(talk_base::SR_SUCCESS, loop_reader.ReadPacket(&packet));
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/session/phone/rtputils.cc b/third_party/libjingle/source/talk/session/phone/rtputils.cc
deleted file mode 100644
index 1599b5d..0000000
--- a/third_party/libjingle/source/talk/session/phone/rtputils.cc
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * libjingle
- * Copyright 2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/session/phone/rtputils.h"
-
-namespace cricket {
-
-bool GetRtpPayloadType(const void* data, size_t len, int* value) {
-  if (!data || len < kMinRtpPacketLen || !value) return false;
-  *value = *(static_cast<const uint8*>(data) + 1) & 0x7F;
-  return true;
-}
-
-bool GetRtpSeqNum(const void* data, size_t len, int* value) {
-  if (!data || len < kMinRtpPacketLen || !value) return false;
-  *value = static_cast<int>(
-      talk_base::GetBE16(static_cast<const uint8*>(data) + 2));
-  return true;
-}
-
-bool GetRtpTimestamp(const void* data, size_t len, uint32* value) {
-  if (!data || len < kMinRtpPacketLen || !value) return false;
-  *value = talk_base::GetBE32(static_cast<const uint8*>(data) + 4);
-  return true;
-}
-
-bool GetRtpSsrc(const void* data, size_t len, uint32* value) {
-  if (!data || len < kMinRtpPacketLen || !value) return false;
-  *value = talk_base::GetBE32(static_cast<const uint8*>(data) + 8);
-  return true;
-}
-
-bool GetRtpHeaderLen(const void* data, size_t len, size_t* value) {
-  if (!data || len < kMinRtpPacketLen || !value) return false;
-  const uint8* header = static_cast<const uint8*>(data);
-  // Get base header size + length of CSRCs (not counting extension yet).
-  size_t header_size = kMinRtpPacketLen + (header[0] & 0xF) * sizeof(uint32);
-  if (len < header_size) return false;
-  // If there's an extension, read and add in the extension size.
-  if (header[0] & 0x10) {
-    if (len < header_size + sizeof(uint32)) return false;
-    header_size += ((talk_base::GetBE16(header + header_size + 2) + 1) *
-                    sizeof(uint32));
-    if (len < header_size) return false;
-  }
-  *value = header_size;
-  return true;
-}
-
-bool GetRtcpType(const void* data, size_t len, int* value) {
-  if (!data || len < kMinRtcpPacketLen || !value) return false;
-  *value = static_cast<int>(*(static_cast<const uint8*>(data) + 1));
-  return true;
-}
-
-// This should be called only for SR or RR RTCP packets.
-bool GetRtcpSsrc(const void* data, size_t len, uint32* value) {
-  // Packet should be at least of 8 bytes, to get SSRC from a RTCP packet.
-  if (!data || len < kMinRtcpPacketLen + 4 || !value) return false;
-  int pl_type;
-  if (!GetRtcpType(data, len, &pl_type)) return false;
-  if (pl_type == kRtcpTypeSR || pl_type == kRtcpTypeRR) {
-    *value = talk_base::GetBE32(static_cast<const uint8*>(data) + 4);
-    return true;
-  }
-  return false;
-}
-
-}  // namespace cricket
-
diff --git a/third_party/libjingle/source/talk/session/phone/rtputils.h b/third_party/libjingle/source/talk/session/phone/rtputils.h
deleted file mode 100644
index 3c4f507..0000000
--- a/third_party/libjingle/source/talk/session/phone/rtputils.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * libjingle
- * Copyright 2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SESSION_PHONE_RTPUTILS_H_
-#define TALK_SESSION_PHONE_RTPUTILS_H_
-
-#include "talk/base/byteorder.h"
-
-namespace cricket {
-
-const size_t kMinRtpPacketLen = 12;
-const size_t kMaxRtpPacketLen = 2048;
-const size_t kMinRtcpPacketLen = 4;
-const int kRtcpTypeSR = 200;  // PT of SR
-const int kRtcpTypeRR = 201;  // PT of RR
-
-bool GetRtpPayloadType(const void* data, size_t len, int* value);
-bool GetRtpSeqNum(const void* data, size_t len, int* value);
-bool GetRtpTimestamp(const void* data, size_t len, uint32* value);
-bool GetRtpSsrc(const void* data, size_t len, uint32* value);
-bool GetRtpHeaderLen(const void* data, size_t len, size_t* value);
-bool GetRtcpType(const void* data, size_t len, int* value);
-bool GetRtcpSsrc(const void* data, size_t len, uint32* value);
-
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_RTPUTILS_H_
diff --git a/third_party/libjingle/source/talk/session/phone/rtputils_unittest.cc b/third_party/libjingle/source/talk/session/phone/rtputils_unittest.cc
deleted file mode 100644
index 23a715e..0000000
--- a/third_party/libjingle/source/talk/session/phone/rtputils_unittest.cc
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/gunit.h"
-#include "talk/session/phone/fakertp.h"
-#include "talk/session/phone/rtputils.h"
-
-namespace cricket {
-
-static const unsigned char kRtpPacketWithMarker[] = {
-    0x80, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
-};
-// 3 CSRCs (0x01020304, 0x12345678, 0xAABBCCDD)
-// Extension (0xBEDE, 0x1122334455667788)
-static const unsigned char kRtpPacketWithMarkerAndCsrcAndExtension[] = {
-    0x93, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-    0x01, 0x02, 0x03, 0x04, 0x12, 0x34, 0x56, 0x78, 0xAA, 0xBB, 0xCC, 0xDD,
-    0xBE, 0xDE, 0x00, 0x02, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88
-};
-static const unsigned char kInvalidPacket[] = { 0x80, 0x00 };
-static const unsigned char kInvalidPacketWithCsrc[] = {
-    0x83, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-    0x01, 0x02, 0x03, 0x04, 0x12, 0x34, 0x56, 0x78, 0xAA, 0xBB, 0xCC
-};
-static const unsigned char kInvalidPacketWithCsrcAndExtension1[] = {
-    0x93, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-    0x01, 0x02, 0x03, 0x04, 0x12, 0x34, 0x56, 0x78, 0xAA, 0xBB, 0xCC, 0xDD,
-    0xBE, 0xDE, 0x00
-};
-static const unsigned char kInvalidPacketWithCsrcAndExtension2[] = {
-    0x93, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-    0x01, 0x02, 0x03, 0x04, 0x12, 0x34, 0x56, 0x78, 0xAA, 0xBB, 0xCC, 0xDD,
-    0xBE, 0xDE, 0x00, 0x02, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77
-};
-
-TEST(RtpUtilsTest, GetRtp) {
-  int pt;
-  EXPECT_TRUE(GetRtpPayloadType(kPcmuFrame, sizeof(kPcmuFrame), &pt));
-  EXPECT_EQ(0, pt);
-  EXPECT_TRUE(GetRtpPayloadType(kRtpPacketWithMarker,
-                                sizeof(kRtpPacketWithMarker), &pt));
-  EXPECT_EQ(0, pt);
-
-  int seq_num;
-  EXPECT_TRUE(GetRtpSeqNum(kPcmuFrame, sizeof(kPcmuFrame), &seq_num));
-  EXPECT_EQ(1, seq_num);
-
-  uint32 ts;
-  EXPECT_TRUE(GetRtpTimestamp(kPcmuFrame, sizeof(kPcmuFrame), &ts));
-  EXPECT_EQ(0u, ts);
-
-  uint32 ssrc;
-  EXPECT_TRUE(GetRtpSsrc(kPcmuFrame, sizeof(kPcmuFrame), &ssrc));
-  EXPECT_EQ(1u, ssrc);
-
-  EXPECT_FALSE(GetRtpPayloadType(kInvalidPacket, sizeof(kInvalidPacket), &pt));
-  EXPECT_FALSE(GetRtpSeqNum(kInvalidPacket, sizeof(kInvalidPacket), &seq_num));
-  EXPECT_FALSE(GetRtpTimestamp(kInvalidPacket, sizeof(kInvalidPacket), &ts));
-  EXPECT_FALSE(GetRtpSsrc(kInvalidPacket, sizeof(kInvalidPacket), &ssrc));
-}
-
-TEST(RtpUtilsTest, GetRtpHeaderLen) {
-  size_t len;
-  EXPECT_TRUE(GetRtpHeaderLen(kPcmuFrame, sizeof(kPcmuFrame), &len));
-  EXPECT_EQ(12U, len);
-
-  EXPECT_TRUE(GetRtpHeaderLen(kRtpPacketWithMarkerAndCsrcAndExtension,
-                              sizeof(kRtpPacketWithMarkerAndCsrcAndExtension),
-                              &len));
-  EXPECT_EQ(sizeof(kRtpPacketWithMarkerAndCsrcAndExtension), len);
-
-  EXPECT_FALSE(GetRtpHeaderLen(kInvalidPacket, sizeof(kInvalidPacket), &len));
-  EXPECT_FALSE(GetRtpHeaderLen(kInvalidPacketWithCsrc,
-                               sizeof(kInvalidPacketWithCsrc), &len));
-  EXPECT_FALSE(GetRtpHeaderLen(kInvalidPacketWithCsrcAndExtension1,
-                               sizeof(kInvalidPacketWithCsrcAndExtension1),
-                               &len));
-  EXPECT_FALSE(GetRtpHeaderLen(kInvalidPacketWithCsrcAndExtension2,
-                               sizeof(kInvalidPacketWithCsrcAndExtension2),
-                               &len));
-}
-
-TEST(RtpUtilsTest, GetRtcp) {
-  int pt;
-  EXPECT_TRUE(GetRtcpType(kRtcpReport, sizeof(kRtcpReport), &pt));
-  EXPECT_EQ(0xc9, pt);
-
-  EXPECT_FALSE(GetRtcpType(kInvalidPacket, sizeof(kInvalidPacket), &pt));
-}
-
-}  // namespace cricket
-
diff --git a/third_party/libjingle/source/talk/session/phone/soundclip.cc b/third_party/libjingle/source/talk/session/phone/soundclip.cc
deleted file mode 100644
index f1069e0..0000000
--- a/third_party/libjingle/source/talk/session/phone/soundclip.cc
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2009, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/session/phone/soundclip.h"
-
-namespace cricket {
-
-enum {
-  MSG_PLAYSOUND = 1,
-};
-
-struct PlaySoundMessageData : talk_base::MessageData {
-  PlaySoundMessageData(const void *c,
-                       int l,
-                       SoundclipMedia::SoundclipFlags f) 
-      : clip(c),
-        len(l),
-        flags(f),
-        result(false) {
-  }
-
-  const void *clip;
-  int len;
-  SoundclipMedia::SoundclipFlags flags;
-  bool result;
-};
-
-Soundclip::Soundclip(talk_base::Thread *thread, SoundclipMedia *soundclip_media)
-    : worker_thread_(thread),
-      soundclip_media_(soundclip_media) {
-}
-
-bool Soundclip::PlaySound(const void *clip,
-                          int len,
-                          SoundclipMedia::SoundclipFlags flags) {
-  PlaySoundMessageData data(clip, len, flags);
-  worker_thread_->Send(this, MSG_PLAYSOUND, &data);
-  return data.result;
-}
-
-bool Soundclip::PlaySound_w(const void *clip,
-                            int len,
-                            SoundclipMedia::SoundclipFlags flags) {
-  return soundclip_media_->PlaySound(static_cast<const char *>(clip),
-                                     len,
-                                     flags);
-}
-
-void Soundclip::OnMessage(talk_base::Message *message) {
-  ASSERT(message->message_id == MSG_PLAYSOUND);
-  PlaySoundMessageData *data =
-      static_cast<PlaySoundMessageData *>(message->pdata);
-  data->result = PlaySound_w(data->clip,
-                             data->len,
-                             data->flags);
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/session/phone/soundclip.h b/third_party/libjingle/source/talk/session/phone/soundclip.h
deleted file mode 100644
index 4038477..0000000
--- a/third_party/libjingle/source/talk/session/phone/soundclip.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2009, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SESSION_PHONE_SOUNDCLIP_H_
-#define TALK_SESSION_PHONE_SOUNDCLIP_H_
-
-#include "talk/base/scoped_ptr.h"
-#include "talk/session/phone/mediaengine.h"
-
-namespace talk_base {
-
-class Thread;
-
-}
-
-namespace cricket {
-
-// Soundclip wraps SoundclipMedia to support marshalling calls to the proper
-// thread.
-class Soundclip : private talk_base::MessageHandler {
- public:
-  Soundclip(talk_base::Thread* thread, SoundclipMedia* soundclip_media);
-
-  // Plays a sound out to the speakers with the given audio stream. The stream
-  // must be 16-bit little-endian 16 kHz PCM. If a stream is already playing
-  // on this Soundclip, it is stopped. If clip is NULL, nothing is played.
-  // Returns whether it was successful.
-  bool PlaySound(const void* clip,
-                 int len,
-                 SoundclipMedia::SoundclipFlags flags);
-
- private:
-  bool PlaySound_w(const void* clip,
-                   int len,
-                   SoundclipMedia::SoundclipFlags flags);
-
-  // From MessageHandler
-  virtual void OnMessage(talk_base::Message* message);
-
-  talk_base::Thread* worker_thread_;
-  talk_base::scoped_ptr<SoundclipMedia> soundclip_media_;
-};
-
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_SOUNDCLIP_H_
diff --git a/third_party/libjingle/source/talk/session/phone/srtpfilter.cc b/third_party/libjingle/source/talk/session/phone/srtpfilter.cc
deleted file mode 100644
index a3e15cb..0000000
--- a/third_party/libjingle/source/talk/session/phone/srtpfilter.cc
+++ /dev/null
@@ -1,647 +0,0 @@
-/*
- * libjingle
- * Copyright 2009, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#undef HAVE_CONFIG_H
-
-#include "talk/session/phone/srtpfilter.h"
-
-#include <algorithm>
-#include <cstring>
-
-#include "talk/base/base64.h"
-#include "talk/base/logging.h"
-#include "talk/base/timeutils.h"
-#include "talk/session/phone/rtputils.h"
-
-// Enable this line to turn on SRTP debugging
-// #define SRTP_DEBUG
-
-#ifdef HAVE_SRTP
-#ifdef SRTP_RELATIVE_PATH
-#include "srtp.h"  // NOLINT
-#else
-#include "third_party/libsrtp/include/srtp.h"
-#endif  // SRTP_RELATIVE_PATH
-#ifdef _DEBUG
-extern "C" debug_module_t mod_srtp;
-extern "C" debug_module_t mod_auth;
-extern "C" debug_module_t mod_cipher;
-extern "C" debug_module_t mod_stat;
-extern "C" debug_module_t mod_alloc;
-extern "C" debug_module_t mod_aes_icm;
-extern "C" debug_module_t mod_aes_hmac;
-#endif
-#else
-// SrtpFilter needs that constant.
-#define SRTP_MASTER_KEY_LEN 30
-#endif  // HAVE_SRTP
-
-namespace cricket {
-
-const char CS_AES_CM_128_HMAC_SHA1_80[] = "AES_CM_128_HMAC_SHA1_80";
-const char CS_AES_CM_128_HMAC_SHA1_32[] = "AES_CM_128_HMAC_SHA1_32";
-const int SRTP_MASTER_KEY_BASE64_LEN = SRTP_MASTER_KEY_LEN * 4 / 3;
-
-#ifndef HAVE_SRTP
-
-// This helper function is used on systems that don't (yet) have SRTP,
-// to log that the functions that require it won't do anything.
-namespace {
-bool SrtpNotAvailable(const char *func) {
-  LOG(LS_ERROR) << func << ": SRTP is not available on your system.";
-  return false;
-}
-}  // anonymous namespace
-
-#endif  // !HAVE_SRTP
-
-void EnableSrtpDebugging() {
-#ifdef HAVE_SRTP
-#ifdef _DEBUG
-  debug_on(mod_srtp);
-  debug_on(mod_auth);
-  debug_on(mod_cipher);
-  debug_on(mod_stat);
-  debug_on(mod_alloc);
-  debug_on(mod_aes_icm);
-  // debug_on(mod_aes_cbc);
-  // debug_on(mod_hmac);
-#endif
-#endif  // HAVE_SRTP
-}
-
-SrtpFilter::SrtpFilter()
-    : state_(ST_INIT),
-      send_session_(new SrtpSession()),
-      recv_session_(new SrtpSession()) {
-  SignalSrtpError.repeat(send_session_->SignalSrtpError);
-  SignalSrtpError.repeat(recv_session_->SignalSrtpError);
-}
-
-SrtpFilter::~SrtpFilter() {
-}
-
-bool SrtpFilter::IsActive() const {
-  return (state_ == ST_ACTIVE);
-}
-
-bool SrtpFilter::SetOffer(const std::vector<CryptoParams>& offer_params,
-                          ContentSource source) {
-  bool ret = false;
-  if (state_ == ST_INIT) {
-    ret = StoreParams(offer_params, source);
-  } else {
-    LOG(LS_ERROR) << "Invalid state for SRTP offer";
-  }
-  return ret;
-}
-
-bool SrtpFilter::SetAnswer(const std::vector<CryptoParams>& answer_params,
-                           ContentSource source) {
-  bool ret = false;
-  if ((state_ == ST_SENTOFFER && source == CS_REMOTE) ||
-      (state_ == ST_RECEIVEDOFFER && source == CS_LOCAL)) {
-    // If the answer requests crypto, finalize the parameters and apply them.
-    // Otherwise, complete the negotiation of a unencrypted session.
-    if (!answer_params.empty()) {
-      CryptoParams selected_params;
-      ret = NegotiateParams(answer_params, &selected_params);
-      if (ret) {
-        if (state_ == ST_SENTOFFER) {
-          ret = ApplyParams(selected_params, answer_params[0]);
-        } else {  // ST_RECEIVEDOFFER
-          ret = ApplyParams(answer_params[0], selected_params);
-        }
-      }
-    } else {
-      ret = ResetParams();
-    }
-  } else {
-    LOG(LS_ERROR) << "Invalid state for SRTP answer";
-  }
-  return ret;
-}
-
-bool SrtpFilter::ProtectRtp(void* p, int in_len, int max_len, int* out_len) {
-  if (!IsActive()) {
-    LOG(LS_WARNING) << "Failed to ProtectRtp: SRTP not active";
-    return false;
-  }
-  return send_session_->ProtectRtp(p, in_len, max_len, out_len);
-}
-
-bool SrtpFilter::ProtectRtcp(void* p, int in_len, int max_len, int* out_len) {
-  if (!IsActive()) {
-    LOG(LS_WARNING) << "Failed to ProtectRtcp: SRTP not active";
-    return false;
-  }
-  return send_session_->ProtectRtcp(p, in_len, max_len, out_len);
-}
-
-bool SrtpFilter::UnprotectRtp(void* p, int in_len, int* out_len) {
-  if (!IsActive()) {
-    LOG(LS_WARNING) << "Failed to UnprotectRtp: SRTP not active";
-    return false;
-  }
-  return recv_session_->UnprotectRtp(p, in_len, out_len);
-}
-
-bool SrtpFilter::UnprotectRtcp(void* p, int in_len, int* out_len) {
-  if (!IsActive()) {
-    LOG(LS_WARNING) << "Failed to UnprotectRtcp: SRTP not active";
-    return false;
-  }
-  return recv_session_->UnprotectRtcp(p, in_len, out_len);
-}
-
-void SrtpFilter::set_signal_silent_time(uint32 signal_silent_time_in_ms) {
-  send_session_->set_signal_silent_time(signal_silent_time_in_ms);
-  recv_session_->set_signal_silent_time(signal_silent_time_in_ms);
-}
-
-bool SrtpFilter::StoreParams(const std::vector<CryptoParams>& params,
-                             ContentSource source) {
-  offer_params_ = params;
-  state_ = (source == CS_LOCAL) ? ST_SENTOFFER : ST_RECEIVEDOFFER;
-  return true;
-}
-
-bool SrtpFilter::NegotiateParams(const std::vector<CryptoParams>& answer_params,
-                                 CryptoParams* selected_params) {
-  // We're processing an accept. We should have exactly one set of params,
-  // unless the offer didn't mention crypto, in which case we shouldn't be here.
-  bool ret = (answer_params.size() == 1U && !offer_params_.empty());
-  if (ret) {
-    // We should find a match between the answer params and the offered params.
-    std::vector<CryptoParams>::const_iterator it;
-    for (it = offer_params_.begin(); it != offer_params_.end(); ++it) {
-      if (answer_params[0].Matches(*it)) {
-        break;
-      }
-    }
-
-    if (it != offer_params_.end()) {
-      *selected_params = *it;
-    } else {
-      ret = false;
-    }
-  }
-
-  if (!ret) {
-    LOG(LS_WARNING) << "Invalid parameters in SRTP answer";
-  }
-  return ret;
-}
-
-bool SrtpFilter::ApplyParams(const CryptoParams& send_params,
-                             const CryptoParams& recv_params) {
-  // TODO: Zero these buffers after use.
-  bool ret;
-  uint8 send_key[SRTP_MASTER_KEY_LEN], recv_key[SRTP_MASTER_KEY_LEN];
-  ret = (ParseKeyParams(send_params.key_params, send_key, sizeof(send_key)) &&
-         ParseKeyParams(recv_params.key_params, recv_key, sizeof(recv_key)));
-  if (ret) {
-    ret = (send_session_->SetSend(send_params.cipher_suite,
-                                  send_key, sizeof(send_key)) &&
-           recv_session_->SetRecv(recv_params.cipher_suite,
-                                  recv_key, sizeof(recv_key)));
-  }
-  if (ret) {
-    offer_params_.clear();
-    state_ = ST_ACTIVE;
-    LOG(LS_INFO) << "SRTP activated with negotiated parameters:"
-                 << " send cipher_suite " << send_params.cipher_suite
-                 << " recv cipher_suite " << recv_params.cipher_suite;
-  } else {
-    LOG(LS_WARNING) << "Failed to apply negotiated SRTP parameters";
-  }
-  return ret;
-}
-
-bool SrtpFilter::ResetParams() {
-  offer_params_.clear();
-  state_ = ST_INIT;
-  LOG(LS_INFO) << "SRTP reset to init state";
-  return true;
-}
-
-bool SrtpFilter::ParseKeyParams(const std::string& key_params,
-                                uint8* key, int len) {
-  // example key_params: "inline:YUJDZGVmZ2hpSktMbW9QUXJzVHVWd3l6MTIzNDU2"
-
-  // Fail if key-method is wrong.
-  if (key_params.find("inline:") != 0) {
-    return false;
-  }
-
-  // Fail if base64 decode fails, or the key is the wrong size.
-  std::string key_b64(key_params.substr(7)), key_str;
-  if (!talk_base::Base64::Decode(key_b64, talk_base::Base64::DO_STRICT,
-                                 &key_str, NULL) ||
-      static_cast<int>(key_str.size()) != len) {
-    return false;
-  }
-
-  memcpy(key, key_str.c_str(), len);
-  return true;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// SrtpSession
-
-#ifdef HAVE_SRTP
-
-bool SrtpSession::inited_ = false;
-std::list<SrtpSession*> SrtpSession::sessions_;
-
-SrtpSession::SrtpSession()
-    : session_(NULL),
-      rtp_auth_tag_len_(0),
-      rtcp_auth_tag_len_(0),
-      srtp_stat_(new SrtpStat()),
-      last_send_seq_num_(-1) {
-  sessions_.push_back(this);
-  SignalSrtpError.repeat(srtp_stat_->SignalSrtpError);
-}
-
-SrtpSession::~SrtpSession() {
-  sessions_.erase(std::find(sessions_.begin(), sessions_.end(), this));
-  if (session_) {
-    srtp_dealloc(session_);
-  }
-}
-
-bool SrtpSession::SetSend(const std::string& cs, const uint8* key, int len) {
-  return SetKey(ssrc_any_outbound, cs, key, len);
-}
-
-bool SrtpSession::SetRecv(const std::string& cs, const uint8* key, int len) {
-  return SetKey(ssrc_any_inbound, cs, key, len);
-}
-
-bool SrtpSession::ProtectRtp(void* p, int in_len, int max_len, int* out_len) {
-  if (!session_) {
-    LOG(LS_WARNING) << "Failed to protect SRTP packet: no SRTP Session";
-    return false;
-  }
-
-  int need_len = in_len + rtp_auth_tag_len_;  // NOLINT
-  if (max_len < need_len) {
-    LOG(LS_WARNING) << "Failed to protect SRTP packet: The buffer length "
-                    << max_len << " is less than the needed " << need_len;
-    return false;
-  }
-
-  *out_len = in_len;
-  int err = srtp_protect(session_, p, out_len);
-  uint32 ssrc;
-  if (GetRtpSsrc(p, in_len, &ssrc)) {
-    srtp_stat_->AddProtectRtpResult(ssrc, err);
-  }
-  int seq_num;
-  GetRtpSeqNum(p, in_len, &seq_num);
-  if (err != err_status_ok) {
-    LOG(LS_WARNING) << "Failed to protect SRTP packet, seqnum="
-                    << seq_num << ", err=" << err << ", last seqnum="
-                    << last_send_seq_num_;
-    return false;
-  }
-  last_send_seq_num_ = seq_num;
-  return true;
-}
-
-bool SrtpSession::ProtectRtcp(void* p, int in_len, int max_len, int* out_len) {
-  if (!session_) {
-    LOG(LS_WARNING) << "Failed to protect SRTCP packet: no SRTP Session";
-    return false;
-  }
-
-  int need_len = in_len + sizeof(uint32) + rtcp_auth_tag_len_;  // NOLINT
-  if (max_len < need_len) {
-    LOG(LS_WARNING) << "Failed to protect SRTCP packet: The buffer length "
-                    << max_len << " is less than the needed " << need_len;
-    return false;
-  }
-
-  *out_len = in_len;
-  int err = srtp_protect_rtcp(session_, p, out_len);
-  srtp_stat_->AddProtectRtcpResult(err);
-  if (err != err_status_ok) {
-    LOG(LS_WARNING) << "Failed to protect SRTCP packet, err=" << err;
-    return false;
-  }
-  return true;
-}
-
-bool SrtpSession::UnprotectRtp(void* p, int in_len, int* out_len) {
-  if (!session_) {
-    LOG(LS_WARNING) << "Failed to unprotect SRTP packet: no SRTP Session";
-    return false;
-  }
-
-  *out_len = in_len;
-  int err = srtp_unprotect(session_, p, out_len);
-  uint32 ssrc;
-  if (GetRtpSsrc(p, in_len, &ssrc)) {
-    srtp_stat_->AddUnprotectRtpResult(ssrc, err);
-  }
-  if (err != err_status_ok) {
-    LOG(LS_WARNING) << "Failed to unprotect SRTP packet, err=" << err;
-    return false;
-  }
-  return true;
-}
-
-bool SrtpSession::UnprotectRtcp(void* p, int in_len, int* out_len) {
-  if (!session_) {
-    LOG(LS_WARNING) << "Failed to unprotect SRTCP packet: no SRTP Session";
-    return false;
-  }
-
-  *out_len = in_len;
-  int err = srtp_unprotect_rtcp(session_, p, out_len);
-  srtp_stat_->AddUnprotectRtcpResult(err);
-  if (err != err_status_ok) {
-    LOG(LS_WARNING) << "Failed to unprotect SRTCP packet, err=" << err;
-    return false;
-  }
-  return true;
-}
-
-void SrtpSession::set_signal_silent_time(uint32 signal_silent_time_in_ms) {
-  srtp_stat_->set_signal_silent_time(signal_silent_time_in_ms);
-}
-
-bool SrtpSession::SetKey(int type, const std::string& cs,
-                         const uint8* key, int len) {
-  if (session_) {
-    LOG(LS_ERROR) << "Failed to create SRTP session: "
-                  << "SRTP session already created";
-    return false;
-  }
-
-  if (!Init()) {
-    return false;
-  }
-
-  srtp_policy_t policy;
-  memset(&policy, 0, sizeof(policy));
-
-  if (cs == CS_AES_CM_128_HMAC_SHA1_80) {
-    crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtp);
-    crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp);
-  } else if (cs == CS_AES_CM_128_HMAC_SHA1_32) {
-    crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy.rtp);   // rtp is 32,
-    crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp);  // rtcp still 80
-  } else {
-    LOG(LS_WARNING) << "Failed to create SRTP session: unsupported"
-                    << " cipher_suite " << cs.c_str();
-    return false;
-  }
-
-  if (!key || len != SRTP_MASTER_KEY_LEN) {
-    LOG(LS_WARNING) << "Failed to create SRTP session: invalid key";
-    return false;
-  }
-
-  policy.ssrc.type = static_cast<ssrc_type_t>(type);
-  policy.ssrc.value = 0;
-  policy.key = const_cast<uint8*>(key);
-  // TODO parse window size from WSH session-param
-  policy.window_size = 1024;
-  policy.allow_repeat_tx = 1;
-  policy.next = NULL;
-
-  int err = srtp_create(&session_, &policy);
-  if (err != err_status_ok) {
-    LOG(LS_ERROR) << "Failed to create SRTP session, err=" << err;
-    return false;
-  }
-
-  rtp_auth_tag_len_ = policy.rtp.auth_tag_len;
-  rtcp_auth_tag_len_ = policy.rtcp.auth_tag_len;
-  return true;
-}
-
-bool SrtpSession::Init() {
-  if (!inited_) {
-    int err;
-    err = srtp_init();
-    if (err != err_status_ok) {
-      LOG(LS_ERROR) << "Failed to init SRTP, err=" << err;
-      return false;
-    }
-
-    err = srtp_install_event_handler(&SrtpSession::HandleEventThunk);
-    if (err != err_status_ok) {
-      LOG(LS_ERROR) << "Failed to install SRTP event handler, err=" << err;
-      return false;
-    }
-
-    inited_ = true;
-  }
-
-  return true;
-}
-
-void SrtpSession::HandleEvent(const srtp_event_data_t* ev) {
-  switch (ev->event) {
-    case event_ssrc_collision:
-      LOG(LS_INFO) << "SRTP event: SSRC collision";
-      break;
-    case event_key_soft_limit:
-      LOG(LS_INFO) << "SRTP event: reached soft key usage limit";
-      break;
-    case event_key_hard_limit:
-      LOG(LS_INFO) << "SRTP event: reached hard key usage limit";
-      break;
-    case event_packet_index_limit:
-      LOG(LS_INFO) << "SRTP event: reached hard packet limit (2^48 packets)";
-      break;
-    default:
-      LOG(LS_INFO) << "SRTP event: unknown " << ev->event;
-      break;
-  }
-}
-
-void SrtpSession::HandleEventThunk(srtp_event_data_t* ev) {
-  for (std::list<SrtpSession*>::iterator it = sessions_.begin();
-       it != sessions_.end(); ++it) {
-    if ((*it)->session_ == ev->session) {
-      (*it)->HandleEvent(ev);
-      break;
-    }
-  }
-}
-
-#else   // !HAVE_SRTP
-
-// On some systems, SRTP is not (yet) available.
-
-SrtpSession::SrtpSession() {
-  LOG(WARNING) << "SRTP implementation is missing.";
-}
-
-SrtpSession::~SrtpSession() {
-}
-
-bool SrtpSession::SetSend(const std::string& cs, const uint8* key, int len) {
-  return SrtpNotAvailable(__FUNCTION__);
-}
-
-bool SrtpSession::SetRecv(const std::string& cs, const uint8* key, int len) {
-  return SrtpNotAvailable(__FUNCTION__);
-}
-
-bool SrtpSession::ProtectRtp(void* data, int in_len, int max_len,
-                             int* out_len) {
-  return SrtpNotAvailable(__FUNCTION__);
-}
-
-bool SrtpSession::ProtectRtcp(void* data, int in_len, int max_len,
-                              int* out_len) {
-  return SrtpNotAvailable(__FUNCTION__);
-}
-
-bool SrtpSession::UnprotectRtp(void* data, int in_len, int* out_len) {
-  return SrtpNotAvailable(__FUNCTION__);
-}
-
-bool SrtpSession::UnprotectRtcp(void* data, int in_len, int* out_len) {
-  return SrtpNotAvailable(__FUNCTION__);
-}
-
-void SrtpSession::set_signal_silent_time(uint32 signal_silent_time) {
-  // Do nothing.
-}
-
-#endif  // HAVE_SRTP
-
-///////////////////////////////////////////////////////////////////////////////
-// SrtpStat
-
-#ifdef HAVE_SRTP
-
-SrtpStat::SrtpStat()
-    : signal_silent_time_(1000) {
-}
-
-void SrtpStat::AddProtectRtpResult(uint32 ssrc, int result) {
-  FailureKey key;
-  key.ssrc = ssrc;
-  key.mode = SrtpFilter::PROTECT;
-  switch (result) {
-    case err_status_ok:
-      key.error = SrtpFilter::ERROR_NONE;
-      break;
-    case err_status_auth_fail:
-      key.error = SrtpFilter::ERROR_AUTH;
-      break;
-    default:
-      key.error = SrtpFilter::ERROR_FAIL;
-  }
-  HandleSrtpResult(key);
-}
-
-void SrtpStat::AddUnprotectRtpResult(uint32 ssrc, int result) {
-  FailureKey key;
-  key.ssrc = ssrc;
-  key.mode = SrtpFilter::UNPROTECT;
-  switch (result) {
-    case err_status_ok:
-      key.error = SrtpFilter::ERROR_NONE;
-      break;
-    case err_status_auth_fail:
-      key.error = SrtpFilter::ERROR_AUTH;
-      break;
-    case err_status_replay_fail:
-    case err_status_replay_old:
-      key.error = SrtpFilter::ERROR_REPLAY;
-      break;
-    default:
-      key.error = SrtpFilter::ERROR_FAIL;
-  }
-  HandleSrtpResult(key);
-}
-
-void SrtpStat::AddProtectRtcpResult(int result) {
-  AddProtectRtpResult(0U, result);
-}
-
-void SrtpStat::AddUnprotectRtcpResult(int result) {
-  AddUnprotectRtpResult(0U, result);
-}
-
-void SrtpStat::HandleSrtpResult(const SrtpStat::FailureKey& key) {
-  // Handle some cases where error should be signalled right away. For other
-  // errors, trigger error for the first time seeing it.  After that, silent
-  // the same error for a certain amount of time (default 1 sec).
-  if (key.error != SrtpFilter::ERROR_NONE) {
-    // For errors, signal first time and wait for 1 sec.
-    FailureStat* stat = &(failures_[key]);
-    uint32 current_time = talk_base::Time();
-    if (stat->last_signal_time == 0 ||
-        talk_base::TimeDiff(current_time, stat->last_signal_time) >
-        static_cast<int>(signal_silent_time_)) {
-      SignalSrtpError(key.ssrc, key.mode, key.error);
-      stat->last_signal_time = current_time;
-    }
-  }
-}
-
-#else   // !HAVE_SRTP
-
-// On some systems, SRTP is not (yet) available.
-
-SrtpStat::SrtpStat()
-    : signal_silent_time_(1000) {
-  LOG(WARNING) << "SRTP implementation is missing.";
-}
-
-void SrtpStat::AddProtectRtpResult(uint32 ssrc, int result) {
-  SrtpNotAvailable(__FUNCTION__);
-}
-
-void SrtpStat::AddUnprotectRtpResult(uint32 ssrc, int result) {
-  SrtpNotAvailable(__FUNCTION__);
-}
-
-void SrtpStat::AddProtectRtcpResult(int result) {
-  SrtpNotAvailable(__FUNCTION__);
-}
-
-void SrtpStat::AddUnprotectRtcpResult(int result) {
-  SrtpNotAvailable(__FUNCTION__);
-}
-
-void SrtpStat::HandleSrtpResult(const SrtpStat::FailureKey& key) {
-  SrtpNotAvailable(__FUNCTION__);
-}
-
-#endif  // HAVE_SRTP
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/session/phone/srtpfilter.h b/third_party/libjingle/source/talk/session/phone/srtpfilter.h
deleted file mode 100644
index 409a3a9..0000000
--- a/third_party/libjingle/source/talk/session/phone/srtpfilter.h
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * libjingle
- * Copyright 2009, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SESSION_PHONE_SRTPFILTER_H_
-#define TALK_SESSION_PHONE_SRTPFILTER_H_
-
-#include <list>
-#include <map>
-#include <string>
-#include <vector>
-
-#include "talk/base/basictypes.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/base/sigslotrepeater.h"
-#include "talk/session/phone/cryptoparams.h"
-#include "talk/p2p/base/sessiondescription.h"
-
-// Forward declaration to avoid pulling in libsrtp headers here
-struct srtp_event_data_t;
-struct srtp_ctx_t;
-typedef srtp_ctx_t* srtp_t;
-struct srtp_policy_t;
-
-namespace cricket {
-
-// Cipher suite to use for SRTP. Typically a 80-bit HMAC will be used, except
-// in applications (voice) where the additional bandwidth may be significant.
-// A 80-bit HMAC is always used for SRTCP.
-// 128-bit AES with 80-bit SHA-1 HMAC.
-extern const char CS_AES_CM_128_HMAC_SHA1_80[];
-// 128-bit AES with 32-bit SHA-1 HMAC.
-extern const char CS_AES_CM_128_HMAC_SHA1_32[];
-// Key is 128 bits and salt is 112 bits == 30 bytes. B64 bloat => 40 bytes.
-extern const int SRTP_MASTER_KEY_BASE64_LEN;
-
-class SrtpSession;
-class SrtpStat;
-
-void EnableSrtpDebugging();
-
-// Class to transform SRTP to/from RTP.
-// Initialize by calling SetSend with the local security params, then call
-// SetRecv once the remote security params are received. At that point
-// Protect/UnprotectRt(c)p can be called to encrypt/decrypt data.
-// TODO: Figure out concurrency policy for SrtpFilter.
-class SrtpFilter {
- public:
-  enum Mode {
-    PROTECT,
-    UNPROTECT
-  };
-  enum Error {
-    ERROR_NONE,
-    ERROR_FAIL,
-    ERROR_AUTH,
-    ERROR_REPLAY,
-  };
-
-  SrtpFilter();
-  ~SrtpFilter();
-
-  // Whether the filter is active (i.e. crypto has been properly negotiated).
-  bool IsActive() const;
-
-  // Indicates which crypto algorithms and keys were contained in the offer.
-  // offer_params should contain a list of available parameters to use, or none,
-  // if crypto is not desired. This must be called before SetAnswer.
-  bool SetOffer(const std::vector<CryptoParams>& offer_params,
-                ContentSource source);
-  // Indicates which crypto algorithms and keys were contained in the answer.
-  // answer_params should contain the negotiated parameters, which may be none,
-  // if crypto was not desired or could not be negotiated (and not required).
-  // This must be called after SetOffer. If crypto negotiation completes
-  // successfully, this will advance the filter to the active state.
-  bool SetAnswer(const std::vector<CryptoParams>& answer_params,
-                 ContentSource source);
-
-  // Encrypts/signs an individual RTP/RTCP packet, in-place.
-  // If an HMAC is used, this will increase the packet size.
-  bool ProtectRtp(void* data, int in_len, int max_len, int* out_len);
-  bool ProtectRtcp(void* data, int in_len, int max_len, int* out_len);
-  // Decrypts/verifies an invidiual RTP/RTCP packet.
-  // If an HMAC is used, this will decrease the packet size.
-  bool UnprotectRtp(void* data, int in_len, int* out_len);
-  bool UnprotectRtcp(void* data, int in_len, int* out_len);
-
-  // Update the silent threshold (in ms) for signaling errors.
-  void set_signal_silent_time(uint32 signal_silent_time_in_ms);
-
-  sigslot::repeater3<uint32, Mode, Error> SignalSrtpError;
-
- protected:
-  bool StoreParams(const std::vector<CryptoParams>& offer_params,
-                   ContentSource source);
-  bool NegotiateParams(const std::vector<CryptoParams>& answer_params,
-                       CryptoParams* selected_params);
-  bool ApplyParams(const CryptoParams& send_params,
-                   const CryptoParams& recv_params);
-  bool ResetParams();
-  static bool ParseKeyParams(const std::string& params, uint8* key, int len);
-
- private:
-  enum State { ST_INIT, ST_SENTOFFER, ST_RECEIVEDOFFER, ST_ACTIVE };
-  State state_;
-  std::vector<CryptoParams> offer_params_;
-  talk_base::scoped_ptr<SrtpSession> send_session_;
-  talk_base::scoped_ptr<SrtpSession> recv_session_;
-};
-
-// Class that wraps a libSRTP session.
-class SrtpSession {
- public:
-  SrtpSession();
-  ~SrtpSession();
-
-  // Configures the session for sending data using the specified
-  // cipher-suite and key. Receiving must be done by a separate session.
-  bool SetSend(const std::string& cs, const uint8* key, int len);
-  // Configures the session for receiving data using the specified
-  // cipher-suite and key. Sending must be done by a separate session.
-  bool SetRecv(const std::string& cs, const uint8* key, int len);
-
-  // Encrypts/signs an individual RTP/RTCP packet, in-place.
-  // If an HMAC is used, this will increase the packet size.
-  bool ProtectRtp(void* data, int in_len, int max_len, int* out_len);
-  bool ProtectRtcp(void* data, int in_len, int max_len, int* out_len);
-  // Decrypts/verifies an invidiual RTP/RTCP packet.
-  // If an HMAC is used, this will decrease the packet size.
-  bool UnprotectRtp(void* data, int in_len, int* out_len);
-  bool UnprotectRtcp(void* data, int in_len, int* out_len);
-
-  // Update the silent threshold (in ms) for signaling errors.
-  void set_signal_silent_time(uint32 signal_silent_time_in_ms);
-
-  sigslot::repeater3<uint32, SrtpFilter::Mode, SrtpFilter::Error>
-      SignalSrtpError;
-
- private:
-  bool SetKey(int type, const std::string& cs, const uint8* key, int len);
-  static bool Init();
-  void HandleEvent(const srtp_event_data_t* ev);
-  static void HandleEventThunk(srtp_event_data_t* ev);
-
-  srtp_t session_;
-  int rtp_auth_tag_len_;
-  int rtcp_auth_tag_len_;
-  talk_base::scoped_ptr<SrtpStat> srtp_stat_;
-  static bool inited_;
-  static std::list<SrtpSession*> sessions_;
-  int last_send_seq_num_;
-  DISALLOW_COPY_AND_ASSIGN(SrtpSession);
-};
-
-// Class that collects failures of SRTP.
-class SrtpStat {
- public:
-  SrtpStat();
-
-  // Report RTP protection results to the handler.
-  void AddProtectRtpResult(uint32 ssrc, int result);
-  // Report RTP unprotection results to the handler.
-  void AddUnprotectRtpResult(uint32 ssrc, int result);
-  // Report RTCP protection results to the handler.
-  void AddProtectRtcpResult(int result);
-  // Report RTCP unprotection results to the handler.
-  void AddUnprotectRtcpResult(int result);
-
-  // Get silent time (in ms) for SRTP statistics handler.
-  uint32 signal_silent_time() const { return signal_silent_time_; }
-  // Set silent time (in ms) for SRTP statistics handler.
-  void set_signal_silent_time(uint32 signal_silent_time) {
-    signal_silent_time_ = signal_silent_time;
-  }
-
-  // Sigslot for reporting errors.
-  sigslot::signal3<uint32, SrtpFilter::Mode, SrtpFilter::Error>
-      SignalSrtpError;
-
- private:
-  // For each different ssrc and error, we collect statistics separately.
-  struct FailureKey {
-    FailureKey()
-        : ssrc(0),
-          mode(SrtpFilter::PROTECT),
-          error(SrtpFilter::ERROR_NONE) {
-    }
-    FailureKey(uint32 in_ssrc, SrtpFilter::Mode in_mode,
-               SrtpFilter::Error in_error)
-        : ssrc(in_ssrc),
-          mode(in_mode),
-          error(in_error) {
-    }
-    bool operator <(const FailureKey& key) const {
-      return ssrc < key.ssrc || mode < key.mode || error < key.error;
-    }
-    uint32 ssrc;
-    SrtpFilter::Mode mode;
-    SrtpFilter::Error error;
-  };
-  // For tracing conditions for signaling, currently we only use
-  // last_signal_time.  Wrap this as a struct so that later on, if we need any
-  // other improvements, it will be easier.
-  struct FailureStat {
-    FailureStat()
-        : last_signal_time(0) {
-    }
-    FailureStat(uint32 in_last_signal_time)
-        : last_signal_time(in_last_signal_time) {
-    }
-    void Reset() {
-      last_signal_time = 0;
-    }
-    uint32 last_signal_time;
-  };
-
-  // Inspect SRTP result and signal error if needed.
-  void HandleSrtpResult(const FailureKey& key);
-
-  std::map<FailureKey, FailureStat> failures_;
-  // Threshold in ms to silent the signaling errors.
-  uint32 signal_silent_time_;
-
-  DISALLOW_COPY_AND_ASSIGN(SrtpStat);
-};
-
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_SRTPFILTER_H_
diff --git a/third_party/libjingle/source/talk/session/phone/srtpfilter_unittest.cc b/third_party/libjingle/source/talk/session/phone/srtpfilter_unittest.cc
deleted file mode 100644
index 25eec18..0000000
--- a/third_party/libjingle/source/talk/session/phone/srtpfilter_unittest.cc
+++ /dev/null
@@ -1,636 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2009, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/byteorder.h"
-#include "talk/base/gunit.h"
-#include "talk/base/thread.h"
-#include "talk/p2p/base/sessiondescription.h"
-#include "talk/session/phone/cryptoparams.h"
-#include "talk/session/phone/fakertp.h"
-#include "talk/session/phone/srtpfilter.h"
-#ifdef SRTP_RELATIVE_PATH
-#include "crypto/include/err.h"
-#else
-#include "third_party/libsrtp/crypto/include/err.h"
-#endif
-
-using cricket::CS_AES_CM_128_HMAC_SHA1_80;
-using cricket::CS_AES_CM_128_HMAC_SHA1_32;
-using cricket::CryptoParams;
-using cricket::CS_LOCAL;
-using cricket::CS_REMOTE;
-
-static const uint8 kTestKey1[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234";
-static const uint8 kTestKey2[] = "4321ZYXWVUTSRQPONMLKJIHGFEDCBA";
-static const int kTestKeyLen = 30;
-static const std::string kTestKeyParams1 =
-    "inline:WVNfX19zZW1jdGwgKCkgewkyMjA7fQp9CnVubGVz";
-static const std::string kTestKeyParams2 =
-    "inline:PS1uQCVeeCFCanVmcjkpPywjNWhcYD0mXXtxaVBR";
-static const cricket::CryptoParams kTestCryptoParams1(
-    1, "AES_CM_128_HMAC_SHA1_80", kTestKeyParams1, "");
-static const cricket::CryptoParams kTestCryptoParams2(
-    1, "AES_CM_128_HMAC_SHA1_80", kTestKeyParams2, "");
-
-static int rtp_auth_tag_len(const std::string& cs) {
-  return (cs == CS_AES_CM_128_HMAC_SHA1_32) ? 4 : 10;
-}
-static int rtcp_auth_tag_len(const std::string& cs) {
-  return 10;
-}
-
-class SrtpFilterTest : public testing::Test {
- protected:
-  static std::vector<CryptoParams> MakeVector(const CryptoParams& params) {
-    std::vector<CryptoParams> vec;
-    vec.push_back(params);
-    return vec;
-  }
-  void TestSetParams(const std::vector<CryptoParams>& params1,
-                     const std::vector<CryptoParams>& params2) {
-    EXPECT_TRUE(f1_.SetOffer(params1, CS_LOCAL));
-    EXPECT_TRUE(f2_.SetOffer(params1, CS_REMOTE));
-    EXPECT_TRUE(f2_.SetAnswer(params2, CS_LOCAL));
-    EXPECT_TRUE(f1_.SetAnswer(params2, CS_REMOTE));
-    EXPECT_TRUE(f1_.IsActive());
-  }
-  void TestProtectUnprotect(const std::string& cs1, const std::string& cs2) {
-    char rtp_packet[sizeof(kPcmuFrame) + 10];
-    char rtcp_packet[sizeof(kRtcpReport) + 4 + 10];
-    int rtp_len = sizeof(kPcmuFrame), rtcp_len = sizeof(kRtcpReport), out_len;
-    memcpy(rtp_packet, kPcmuFrame, rtp_len);
-    memcpy(rtcp_packet, kRtcpReport, rtcp_len);
-
-    EXPECT_TRUE(f1_.ProtectRtp(rtp_packet, rtp_len,
-                               sizeof(rtp_packet), &out_len));
-    EXPECT_EQ(out_len, rtp_len + rtp_auth_tag_len(cs1));
-    EXPECT_NE(0, memcmp(rtp_packet, kPcmuFrame, rtp_len));
-    EXPECT_TRUE(f2_.UnprotectRtp(rtp_packet, out_len, &out_len));
-    EXPECT_EQ(rtp_len, out_len);
-    EXPECT_EQ(0, memcmp(rtp_packet, kPcmuFrame, rtp_len));
-
-    EXPECT_TRUE(f2_.ProtectRtp(rtp_packet, rtp_len,
-                               sizeof(rtp_packet), &out_len));
-    EXPECT_EQ(out_len, rtp_len + rtp_auth_tag_len(cs2));
-    EXPECT_NE(0, memcmp(rtp_packet, kPcmuFrame, rtp_len));
-    EXPECT_TRUE(f1_.UnprotectRtp(rtp_packet, out_len, &out_len));
-    EXPECT_EQ(rtp_len, out_len);
-    EXPECT_EQ(0, memcmp(rtp_packet, kPcmuFrame, rtp_len));
-
-    EXPECT_TRUE(f1_.ProtectRtcp(rtcp_packet, rtcp_len,
-                                sizeof(rtcp_packet), &out_len));
-    EXPECT_EQ(out_len, rtcp_len + 4 + rtcp_auth_tag_len(cs1));  // NOLINT
-    EXPECT_NE(0, memcmp(rtcp_packet, kRtcpReport, rtcp_len));
-    EXPECT_TRUE(f2_.UnprotectRtcp(rtcp_packet, out_len, &out_len));
-    EXPECT_EQ(rtcp_len, out_len);
-    EXPECT_EQ(0, memcmp(rtcp_packet, kRtcpReport, rtcp_len));
-
-    EXPECT_TRUE(f2_.ProtectRtcp(rtcp_packet, rtcp_len,
-                                sizeof(rtcp_packet), &out_len));
-    EXPECT_EQ(out_len, rtcp_len + 4 + rtcp_auth_tag_len(cs2));  // NOLINT
-    EXPECT_NE(0, memcmp(rtcp_packet, kRtcpReport, rtcp_len));
-    EXPECT_TRUE(f1_.UnprotectRtcp(rtcp_packet, out_len, &out_len));
-    EXPECT_EQ(rtcp_len, out_len);
-    EXPECT_EQ(0, memcmp(rtcp_packet, kRtcpReport, rtcp_len));
-  }
-  cricket::SrtpFilter f1_;
-  cricket::SrtpFilter f2_;
-};
-
-// Test that we can set up the session and keys properly.
-TEST_F(SrtpFilterTest, TestGoodSetupOneCipherSuite) {
-  EXPECT_TRUE(f1_.SetOffer(MakeVector(kTestCryptoParams1), CS_LOCAL));
-  EXPECT_TRUE(f1_.SetAnswer(MakeVector(kTestCryptoParams2), CS_REMOTE));
-  EXPECT_TRUE(f1_.IsActive());
-}
-
-// Test that we can set up things with multiple params.
-TEST_F(SrtpFilterTest, TestGoodSetupMultipleCipherSuites) {
-  std::vector<CryptoParams> offer(MakeVector(kTestCryptoParams1));
-  std::vector<CryptoParams> answer(MakeVector(kTestCryptoParams2));
-  offer.push_back(kTestCryptoParams1);
-  offer[1].tag = 2;
-  offer[1].cipher_suite = CS_AES_CM_128_HMAC_SHA1_32;
-  answer[0].tag = 2;
-  answer[0].cipher_suite = CS_AES_CM_128_HMAC_SHA1_32;
-  EXPECT_TRUE(f1_.SetOffer(offer, CS_LOCAL));
-  EXPECT_TRUE(f1_.SetAnswer(answer, CS_REMOTE));
-  EXPECT_TRUE(f1_.IsActive());
-}
-
-// Test that we handle the cases where crypto is not desired.
-TEST_F(SrtpFilterTest, TestGoodSetupNoCipherSuites) {
-  std::vector<CryptoParams> offer, answer;
-  EXPECT_TRUE(f1_.SetOffer(offer, CS_LOCAL));
-  EXPECT_TRUE(f1_.SetAnswer(answer, CS_REMOTE));
-  EXPECT_FALSE(f1_.IsActive());
-}
-
-// Test that we handle the cases where crypto is not desired by the remote side.
-TEST_F(SrtpFilterTest, TestGoodSetupNoAnswerCipherSuites) {
-  std::vector<CryptoParams> answer;
-  EXPECT_TRUE(f1_.SetOffer(MakeVector(kTestCryptoParams1), CS_LOCAL));
-  EXPECT_TRUE(f1_.SetAnswer(answer, CS_REMOTE));
-  EXPECT_FALSE(f1_.IsActive());
-}
-
-// Test that we fail if we call the functions the wrong way.
-TEST_F(SrtpFilterTest, TestBadSetup) {
-  std::vector<CryptoParams> offer(MakeVector(kTestCryptoParams1));
-  std::vector<CryptoParams> answer(MakeVector(kTestCryptoParams2));
-  EXPECT_FALSE(f1_.SetAnswer(answer, CS_LOCAL));
-  EXPECT_FALSE(f1_.SetAnswer(answer, CS_REMOTE));
-  EXPECT_TRUE(f1_.SetOffer(offer, CS_LOCAL));
-  EXPECT_FALSE(f1_.SetOffer(answer, CS_REMOTE));
-  EXPECT_FALSE(f1_.SetAnswer(answer, CS_LOCAL));
-  EXPECT_FALSE(f1_.IsActive());
-}
-
-// Test that we fail if we have params in the answer when none were offered.
-TEST_F(SrtpFilterTest, TestNoAnswerCipherSuites) {
-  std::vector<CryptoParams> offer;
-  EXPECT_TRUE(f1_.SetOffer(offer, CS_LOCAL));
-  EXPECT_FALSE(f1_.SetAnswer(MakeVector(kTestCryptoParams2), CS_REMOTE));
-  EXPECT_FALSE(f1_.IsActive());
-}
-
-// Test that we fail if we have too many params in our answer.
-TEST_F(SrtpFilterTest, TestMultipleAnswerCipherSuites) {
-  std::vector<CryptoParams> answer(MakeVector(kTestCryptoParams2));
-  answer.push_back(kTestCryptoParams2);
-  answer[1].tag = 2;
-  answer[1].cipher_suite = CS_AES_CM_128_HMAC_SHA1_32;
-  EXPECT_TRUE(f1_.SetOffer(MakeVector(kTestCryptoParams1), CS_LOCAL));
-  EXPECT_FALSE(f1_.SetAnswer(answer, CS_REMOTE));
-  EXPECT_FALSE(f1_.IsActive());
-}
-
-// Test that we fail if we don't support the cipher-suite.
-TEST_F(SrtpFilterTest, TestInvalidCipherSuite) {
-  std::vector<CryptoParams> offer(MakeVector(kTestCryptoParams1));
-  std::vector<CryptoParams> answer(MakeVector(kTestCryptoParams2));
-  offer[0].cipher_suite = answer[0].cipher_suite = "FOO";
-  EXPECT_TRUE(f1_.SetOffer(offer, CS_LOCAL));
-  EXPECT_FALSE(f1_.SetAnswer(answer, CS_REMOTE));
-  EXPECT_FALSE(f1_.IsActive());
-}
-
-// Test that we fail if we can't agree on a tag.
-TEST_F(SrtpFilterTest, TestNoMatchingTag) {
-  std::vector<CryptoParams> offer(MakeVector(kTestCryptoParams1));
-  std::vector<CryptoParams> answer(MakeVector(kTestCryptoParams2));
-  answer[0].tag = 99;
-  EXPECT_TRUE(f1_.SetOffer(offer, CS_LOCAL));
-  EXPECT_FALSE(f1_.SetAnswer(answer, CS_REMOTE));
-  EXPECT_FALSE(f1_.IsActive());
-}
-
-// Test that we fail if we can't agree on a cipher-suite.
-TEST_F(SrtpFilterTest, TestNoMatchingCipherSuite) {
-  std::vector<CryptoParams> offer(MakeVector(kTestCryptoParams1));
-  std::vector<CryptoParams> answer(MakeVector(kTestCryptoParams2));
-  answer[0].tag = 2;
-  answer[0].cipher_suite = "FOO";
-  EXPECT_TRUE(f1_.SetOffer(offer, CS_LOCAL));
-  EXPECT_FALSE(f1_.SetAnswer(answer, CS_REMOTE));
-  EXPECT_FALSE(f1_.IsActive());
-}
-
-// Test that we fail keys with bad base64 content.
-TEST_F(SrtpFilterTest, TestInvalidKeyData) {
-  std::vector<CryptoParams> offer(MakeVector(kTestCryptoParams1));
-  std::vector<CryptoParams> answer(MakeVector(kTestCryptoParams2));
-  answer[0].key_params = "inline:!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!";
-  EXPECT_TRUE(f1_.SetOffer(offer, CS_LOCAL));
-  EXPECT_FALSE(f1_.SetAnswer(answer, CS_REMOTE));
-  EXPECT_FALSE(f1_.IsActive());
-}
-
-// Test that we fail keys with the wrong key-method.
-TEST_F(SrtpFilterTest, TestWrongKeyMethod) {
-  std::vector<CryptoParams> offer(MakeVector(kTestCryptoParams1));
-  std::vector<CryptoParams> answer(MakeVector(kTestCryptoParams2));
-  answer[0].key_params = "outline:PS1uQCVeeCFCanVmcjkpPywjNWhcYD0mXXtxaVBR";
-  EXPECT_TRUE(f1_.SetOffer(offer, CS_LOCAL));
-  EXPECT_FALSE(f1_.SetAnswer(answer, CS_REMOTE));
-  EXPECT_FALSE(f1_.IsActive());
-}
-
-// Test that we fail keys of the wrong length.
-TEST_F(SrtpFilterTest, TestKeyTooShort) {
-  std::vector<CryptoParams> offer(MakeVector(kTestCryptoParams1));
-  std::vector<CryptoParams> answer(MakeVector(kTestCryptoParams2));
-  answer[0].key_params = "inline:PS1uQCVeeCFCanVmcjkpPywjNWhcYD0mXXtx";
-  EXPECT_TRUE(f1_.SetOffer(offer, CS_LOCAL));
-  EXPECT_FALSE(f1_.SetAnswer(answer, CS_REMOTE));
-  EXPECT_FALSE(f1_.IsActive());
-}
-
-// Test that we fail keys of the wrong length.
-TEST_F(SrtpFilterTest, TestKeyTooLong) {
-  std::vector<CryptoParams> offer(MakeVector(kTestCryptoParams1));
-  std::vector<CryptoParams> answer(MakeVector(kTestCryptoParams2));
-  answer[0].key_params = "inline:PS1uQCVeeCFCanVmcjkpPywjNWhcYD0mXXtxaVBRABCD";
-  EXPECT_TRUE(f1_.SetOffer(offer, CS_LOCAL));
-  EXPECT_FALSE(f1_.SetAnswer(answer, CS_REMOTE));
-  EXPECT_FALSE(f1_.IsActive());
-}
-
-// Test that we fail keys with lifetime or MKI set (since we don't support)
-TEST_F(SrtpFilterTest, TestUnsupportedOptions) {
-  std::vector<CryptoParams> offer(MakeVector(kTestCryptoParams1));
-  std::vector<CryptoParams> answer(MakeVector(kTestCryptoParams2));
-  answer[0].key_params =
-      "inline:PS1uQCVeeCFCanVmcjkpPywjNWhcYD0mXXtxaVBR|2^20|1:4";
-  EXPECT_TRUE(f1_.SetOffer(offer, CS_LOCAL));
-  EXPECT_FALSE(f1_.SetAnswer(answer, CS_REMOTE));
-  EXPECT_FALSE(f1_.IsActive());
-}
-
-// Test that we can encrypt/decrypt after negotiating AES_CM_128_HMAC_SHA1_80.
-TEST_F(SrtpFilterTest, TestProtect_AES_CM_128_HMAC_SHA1_80) {
-  std::vector<CryptoParams> offer(MakeVector(kTestCryptoParams1));
-  std::vector<CryptoParams> answer(MakeVector(kTestCryptoParams2));
-  offer.push_back(kTestCryptoParams1);
-  offer[1].tag = 2;
-  offer[1].cipher_suite = CS_AES_CM_128_HMAC_SHA1_32;
-  TestSetParams(offer, answer);
-  TestProtectUnprotect(CS_AES_CM_128_HMAC_SHA1_80, CS_AES_CM_128_HMAC_SHA1_80);
-}
-
-// Test that we can encrypt/decrypt after negotiating AES_CM_128_HMAC_SHA1_32.
-TEST_F(SrtpFilterTest, TestProtect_AES_CM_128_HMAC_SHA1_32) {
-  std::vector<CryptoParams> offer(MakeVector(kTestCryptoParams1));
-  std::vector<CryptoParams> answer(MakeVector(kTestCryptoParams2));
-  offer.push_back(kTestCryptoParams1);
-  offer[1].tag = 2;
-  offer[1].cipher_suite = CS_AES_CM_128_HMAC_SHA1_32;
-  answer[0].tag = 2;
-  answer[0].cipher_suite = CS_AES_CM_128_HMAC_SHA1_32;
-  TestSetParams(offer, answer);
-  TestProtectUnprotect(CS_AES_CM_128_HMAC_SHA1_32, CS_AES_CM_128_HMAC_SHA1_32);
-}
-
-class SrtpSessionTest : public testing::Test {
- protected:
-  virtual void SetUp() {
-    rtp_len_ = sizeof(kPcmuFrame);
-    rtcp_len_ = sizeof(kRtcpReport);
-    memcpy(rtp_packet_, kPcmuFrame, rtp_len_);
-    memcpy(rtcp_packet_, kRtcpReport, rtcp_len_);
-  }
-  void TestProtectRtp(const std::string& cs) {
-    int out_len = 0;
-    EXPECT_TRUE(s1_.ProtectRtp(rtp_packet_, rtp_len_,
-                               sizeof(rtp_packet_), &out_len));
-    EXPECT_EQ(out_len, rtp_len_ + rtp_auth_tag_len(cs));
-    EXPECT_NE(0, memcmp(rtp_packet_, kPcmuFrame, rtp_len_));
-    rtp_len_ = out_len;
-  }
-  void TestProtectRtcp(const std::string& cs) {
-    int out_len = 0;
-    EXPECT_TRUE(s1_.ProtectRtcp(rtcp_packet_, rtcp_len_,
-                                sizeof(rtcp_packet_), &out_len));
-    EXPECT_EQ(out_len, rtcp_len_ + 4 + rtcp_auth_tag_len(cs));  // NOLINT
-    EXPECT_NE(0, memcmp(rtcp_packet_, kRtcpReport, rtcp_len_));
-    rtcp_len_ = out_len;
-  }
-  void TestUnprotectRtp(const std::string& cs) {
-    int out_len = 0, expected_len = sizeof(kPcmuFrame);
-    EXPECT_TRUE(s2_.UnprotectRtp(rtp_packet_, rtp_len_, &out_len));
-    EXPECT_EQ(expected_len, out_len);
-    EXPECT_EQ(0, memcmp(rtp_packet_, kPcmuFrame, out_len));
-  }
-  void TestUnprotectRtcp(const std::string& cs) {
-    int out_len = 0, expected_len = sizeof(kRtcpReport);
-    EXPECT_TRUE(s2_.UnprotectRtcp(rtcp_packet_, rtcp_len_, &out_len));
-    EXPECT_EQ(expected_len, out_len);
-    EXPECT_EQ(0, memcmp(rtcp_packet_, kRtcpReport, out_len));
-  }
-  cricket::SrtpSession s1_;
-  cricket::SrtpSession s2_;
-  char rtp_packet_[sizeof(kPcmuFrame) + 10];
-  char rtcp_packet_[sizeof(kRtcpReport) + 4 + 10];
-  int rtp_len_;
-  int rtcp_len_;
-};
-
-// Test that we can set up the session and keys properly.
-TEST_F(SrtpSessionTest, TestGoodSetup) {
-  EXPECT_TRUE(s1_.SetSend(CS_AES_CM_128_HMAC_SHA1_80, kTestKey1, kTestKeyLen));
-  EXPECT_TRUE(s2_.SetRecv(CS_AES_CM_128_HMAC_SHA1_80, kTestKey1, kTestKeyLen));
-}
-
-// Test that we can't change the keys once set.
-TEST_F(SrtpSessionTest, TestBadSetup) {
-  EXPECT_TRUE(s1_.SetSend(CS_AES_CM_128_HMAC_SHA1_80, kTestKey1, kTestKeyLen));
-  EXPECT_TRUE(s2_.SetRecv(CS_AES_CM_128_HMAC_SHA1_80, kTestKey1, kTestKeyLen));
-  EXPECT_FALSE(s1_.SetSend(CS_AES_CM_128_HMAC_SHA1_80, kTestKey2, kTestKeyLen));
-  EXPECT_FALSE(s2_.SetRecv(CS_AES_CM_128_HMAC_SHA1_80, kTestKey2, kTestKeyLen));
-}
-
-// Test that we fail keys of the wrong length.
-TEST_F(SrtpSessionTest, TestKeysTooShort) {
-  EXPECT_FALSE(s1_.SetSend(CS_AES_CM_128_HMAC_SHA1_80, kTestKey1, 1));
-  EXPECT_FALSE(s2_.SetRecv(CS_AES_CM_128_HMAC_SHA1_80, kTestKey1, 1));
-}
-
-// Test that we can encrypt and decrypt RTP/RTCP using AES_CM_128_HMAC_SHA1_80.
-TEST_F(SrtpSessionTest, TestProtect_AES_CM_128_HMAC_SHA1_80) {
-  EXPECT_TRUE(s1_.SetSend(CS_AES_CM_128_HMAC_SHA1_80, kTestKey1, kTestKeyLen));
-  EXPECT_TRUE(s2_.SetRecv(CS_AES_CM_128_HMAC_SHA1_80, kTestKey1, kTestKeyLen));
-  TestProtectRtp(CS_AES_CM_128_HMAC_SHA1_80);
-  TestProtectRtcp(CS_AES_CM_128_HMAC_SHA1_80);
-  TestUnprotectRtp(CS_AES_CM_128_HMAC_SHA1_80);
-  TestUnprotectRtcp(CS_AES_CM_128_HMAC_SHA1_80);
-}
-
-// Test that we can encrypt and decrypt RTP/RTCP using AES_CM_128_HMAC_SHA1_32.
-TEST_F(SrtpSessionTest, TestProtect_AES_CM_128_HMAC_SHA1_32) {
-  EXPECT_TRUE(s1_.SetSend(CS_AES_CM_128_HMAC_SHA1_32, kTestKey1, kTestKeyLen));
-  EXPECT_TRUE(s2_.SetRecv(CS_AES_CM_128_HMAC_SHA1_32, kTestKey1, kTestKeyLen));
-  TestProtectRtp(CS_AES_CM_128_HMAC_SHA1_32);
-  TestProtectRtcp(CS_AES_CM_128_HMAC_SHA1_32);
-  TestUnprotectRtp(CS_AES_CM_128_HMAC_SHA1_32);
-  TestUnprotectRtcp(CS_AES_CM_128_HMAC_SHA1_32);
-}
-
-// Test that we fail to unprotect if someone tampers with the RTP/RTCP paylaods.
-TEST_F(SrtpSessionTest, TestTamperReject) {
-  int out_len;
-  EXPECT_TRUE(s1_.SetSend(CS_AES_CM_128_HMAC_SHA1_80, kTestKey1, kTestKeyLen));
-  EXPECT_TRUE(s2_.SetRecv(CS_AES_CM_128_HMAC_SHA1_80, kTestKey1, kTestKeyLen));
-  TestProtectRtp(CS_AES_CM_128_HMAC_SHA1_80);
-  TestProtectRtcp(CS_AES_CM_128_HMAC_SHA1_80);
-  rtp_packet_[0] = 0x12;
-  rtcp_packet_[1] = 0x34;
-  EXPECT_FALSE(s2_.UnprotectRtp(rtp_packet_, rtp_len_, &out_len));
-  EXPECT_FALSE(s2_.UnprotectRtcp(rtcp_packet_, rtcp_len_, &out_len));
-}
-
-// Test that we fail to unprotect if the payloads are not authenticated.
-TEST_F(SrtpSessionTest, TestUnencryptReject) {
-  int out_len;
-  EXPECT_TRUE(s1_.SetSend(CS_AES_CM_128_HMAC_SHA1_80, kTestKey1, kTestKeyLen));
-  EXPECT_TRUE(s2_.SetRecv(CS_AES_CM_128_HMAC_SHA1_80, kTestKey1, kTestKeyLen));
-  EXPECT_FALSE(s2_.UnprotectRtp(rtp_packet_, rtp_len_, &out_len));
-  EXPECT_FALSE(s2_.UnprotectRtcp(rtcp_packet_, rtcp_len_, &out_len));
-}
-
-// Test that we fail when using buffers that are too small.
-TEST_F(SrtpSessionTest, TestBuffersTooSmall) {
-  int out_len;
-  EXPECT_TRUE(s1_.SetSend(CS_AES_CM_128_HMAC_SHA1_80, kTestKey1, kTestKeyLen));
-  EXPECT_FALSE(s1_.ProtectRtp(rtp_packet_, rtp_len_,
-                              sizeof(rtp_packet_) - 10, &out_len));
-  EXPECT_FALSE(s1_.ProtectRtcp(rtcp_packet_, rtcp_len_,
-                               sizeof(rtcp_packet_) - 14, &out_len));
-}
-
-TEST_F(SrtpSessionTest, TestReplay) {
-  static const uint16 kMaxSeqnum = static_cast<uint16>(-1);
-  static const uint16 seqnum_big = 62275;
-  static const uint16 seqnum_small = 10;
-  static const uint16 replay_window = 1024;
-  int out_len;
-
-  EXPECT_TRUE(s1_.SetSend(CS_AES_CM_128_HMAC_SHA1_80, kTestKey1, kTestKeyLen));
-  EXPECT_TRUE(s2_.SetRecv(CS_AES_CM_128_HMAC_SHA1_80, kTestKey1, kTestKeyLen));
-
-  // Initial sequence number.
-  talk_base::SetBE16(reinterpret_cast<uint8*>(rtp_packet_) + 2, seqnum_big);
-  EXPECT_TRUE(s1_.ProtectRtp(rtp_packet_, rtp_len_, sizeof(rtp_packet_),
-                             &out_len));
-
-  // Replay within the 1024 window should succeed.
-  talk_base::SetBE16(reinterpret_cast<uint8*>(rtp_packet_) + 2,
-                     seqnum_big - replay_window + 1);
-  EXPECT_TRUE(s1_.ProtectRtp(rtp_packet_, rtp_len_, sizeof(rtp_packet_),
-                             &out_len));
-
-  // Replay out side of the 1024 window should fail.
-  talk_base::SetBE16(reinterpret_cast<uint8*>(rtp_packet_) + 2,
-                     seqnum_big - replay_window - 1);
-  EXPECT_FALSE(s1_.ProtectRtp(rtp_packet_, rtp_len_, sizeof(rtp_packet_),
-                              &out_len));
-
-  // Increment sequence number to a small number.
-  talk_base::SetBE16(reinterpret_cast<uint8*>(rtp_packet_) + 2, seqnum_small);
-  EXPECT_TRUE(s1_.ProtectRtp(rtp_packet_, rtp_len_, sizeof(rtp_packet_),
-                             &out_len));
-
-  // Replay around 0 but out side of the 1024 window should fail.
-  talk_base::SetBE16(reinterpret_cast<uint8*>(rtp_packet_) + 2,
-                     kMaxSeqnum + seqnum_small - replay_window - 1);
-  EXPECT_FALSE(s1_.ProtectRtp(rtp_packet_, rtp_len_, sizeof(rtp_packet_),
-                              &out_len));
-
-  // Replay around 0 but within the 1024 window should succeed.
-  for (uint16 seqnum = 65000; seqnum < 65003; ++seqnum) {
-    talk_base::SetBE16(reinterpret_cast<uint8*>(rtp_packet_) + 2, seqnum);
-    EXPECT_TRUE(s1_.ProtectRtp(rtp_packet_, rtp_len_, sizeof(rtp_packet_),
-                               &out_len));
-  }
-
-  // Go back to normal sequence nubmer.
-  // NOTE: without the fix in libsrtp, this would fail. This is because
-  // without the fix, the loop above would keep incrementing local sequence
-  // number in libsrtp, eventually the new sequence number would go out side
-  // of the window.
-  talk_base::SetBE16(reinterpret_cast<uint8*>(rtp_packet_) + 2,
-                     seqnum_small + 1);
-  EXPECT_TRUE(s1_.ProtectRtp(rtp_packet_, rtp_len_, sizeof(rtp_packet_),
-                             &out_len));
-}
-
-class SrtpStatTest
-    : public testing::Test,
-      public sigslot::has_slots<> {
- public:
-  SrtpStatTest()
-      : ssrc_(0U),
-        mode_(-1),
-        error_(cricket::SrtpFilter::ERROR_NONE) {
-    srtp_stat_.SignalSrtpError.connect(this, &SrtpStatTest::OnSrtpError);
-    srtp_stat_.set_signal_silent_time(200);
-  }
-
- protected:
-  void OnSrtpError(uint32 ssrc, cricket::SrtpFilter::Mode mode,
-                   cricket::SrtpFilter::Error error) {
-    ssrc_ = ssrc;
-    mode_ = mode;
-    error_ = error;
-  }
-  void Reset() {
-    ssrc_ = 0U;
-    mode_ = -1;
-    error_ = cricket::SrtpFilter::ERROR_NONE;
-  }
-
-  cricket::SrtpStat srtp_stat_;
-  uint32 ssrc_;
-  int mode_;
-  cricket::SrtpFilter::Error error_;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(SrtpStatTest);
-};
-
-TEST_F(SrtpStatTest, TestProtectRtpError) {
-  Reset();
-  srtp_stat_.AddProtectRtpResult(1, err_status_ok);
-  EXPECT_EQ(0U, ssrc_);
-  EXPECT_EQ(-1, mode_);
-  EXPECT_EQ(cricket::SrtpFilter::ERROR_NONE, error_);
-  Reset();
-  srtp_stat_.AddProtectRtpResult(1, err_status_auth_fail);
-  EXPECT_EQ(1U, ssrc_);
-  EXPECT_EQ(cricket::SrtpFilter::PROTECT, mode_);
-  EXPECT_EQ(cricket::SrtpFilter::ERROR_AUTH, error_);
-  Reset();
-  srtp_stat_.AddProtectRtpResult(1, err_status_fail);
-  EXPECT_EQ(1U, ssrc_);
-  EXPECT_EQ(cricket::SrtpFilter::PROTECT, mode_);
-  EXPECT_EQ(cricket::SrtpFilter::ERROR_FAIL, error_);
-  // Within 200ms, the error will not be triggered.
-  Reset();
-  srtp_stat_.AddProtectRtpResult(1, err_status_fail);
-  EXPECT_EQ(0U, ssrc_);
-  EXPECT_EQ(-1, mode_);
-  EXPECT_EQ(cricket::SrtpFilter::ERROR_NONE, error_);
-  // Now the error will be triggered again.
-  Reset();
-  talk_base::Thread::Current()->SleepMs(210);
-  srtp_stat_.AddProtectRtpResult(1, err_status_fail);
-  EXPECT_EQ(1U, ssrc_);
-  EXPECT_EQ(cricket::SrtpFilter::PROTECT, mode_);
-  EXPECT_EQ(cricket::SrtpFilter::ERROR_FAIL, error_);
-}
-
-TEST_F(SrtpStatTest, TestUnprotectRtpError) {
-  Reset();
-  srtp_stat_.AddUnprotectRtpResult(1, err_status_ok);
-  EXPECT_EQ(0U, ssrc_);
-  EXPECT_EQ(-1, mode_);
-  EXPECT_EQ(cricket::SrtpFilter::ERROR_NONE, error_);
-  Reset();
-  srtp_stat_.AddUnprotectRtpResult(1, err_status_auth_fail);
-  EXPECT_EQ(1U, ssrc_);
-  EXPECT_EQ(cricket::SrtpFilter::UNPROTECT, mode_);
-  EXPECT_EQ(cricket::SrtpFilter::ERROR_AUTH, error_);
-  Reset();
-  srtp_stat_.AddUnprotectRtpResult(1, err_status_replay_fail);
-  EXPECT_EQ(1U, ssrc_);
-  EXPECT_EQ(cricket::SrtpFilter::UNPROTECT, mode_);
-  EXPECT_EQ(cricket::SrtpFilter::ERROR_REPLAY, error_);
-  Reset();
-  talk_base::Thread::Current()->SleepMs(210);
-  srtp_stat_.AddUnprotectRtpResult(1, err_status_replay_old);
-  EXPECT_EQ(1U, ssrc_);
-  EXPECT_EQ(cricket::SrtpFilter::UNPROTECT, mode_);
-  EXPECT_EQ(cricket::SrtpFilter::ERROR_REPLAY, error_);
-  Reset();
-  srtp_stat_.AddUnprotectRtpResult(1, err_status_fail);
-  EXPECT_EQ(1U, ssrc_);
-  EXPECT_EQ(cricket::SrtpFilter::UNPROTECT, mode_);
-  EXPECT_EQ(cricket::SrtpFilter::ERROR_FAIL, error_);
-  // Within 200ms, the error will not be triggered.
-  Reset();
-  srtp_stat_.AddUnprotectRtpResult(1, err_status_fail);
-  EXPECT_EQ(0U, ssrc_);
-  EXPECT_EQ(-1, mode_);
-  EXPECT_EQ(cricket::SrtpFilter::ERROR_NONE, error_);
-  // Now the error will be triggered again.
-  Reset();
-  talk_base::Thread::Current()->SleepMs(210);
-  srtp_stat_.AddUnprotectRtpResult(1, err_status_fail);
-  EXPECT_EQ(1U, ssrc_);
-  EXPECT_EQ(cricket::SrtpFilter::UNPROTECT, mode_);
-  EXPECT_EQ(cricket::SrtpFilter::ERROR_FAIL, error_);
-}
-
-TEST_F(SrtpStatTest, TestProtectRtcpError) {
-  Reset();
-  srtp_stat_.AddProtectRtcpResult(err_status_ok);
-  EXPECT_EQ(-1, mode_);
-  EXPECT_EQ(cricket::SrtpFilter::ERROR_NONE, error_);
-  Reset();
-  srtp_stat_.AddProtectRtcpResult(err_status_auth_fail);
-  EXPECT_EQ(cricket::SrtpFilter::PROTECT, mode_);
-  EXPECT_EQ(cricket::SrtpFilter::ERROR_AUTH, error_);
-  Reset();
-  srtp_stat_.AddProtectRtcpResult(err_status_fail);
-  EXPECT_EQ(cricket::SrtpFilter::PROTECT, mode_);
-  EXPECT_EQ(cricket::SrtpFilter::ERROR_FAIL, error_);
-  // Within 200ms, the error will not be triggered.
-  Reset();
-  srtp_stat_.AddProtectRtcpResult(err_status_fail);
-  EXPECT_EQ(-1, mode_);
-  EXPECT_EQ(cricket::SrtpFilter::ERROR_NONE, error_);
-  // Now the error will be triggered again.
-  Reset();
-  talk_base::Thread::Current()->SleepMs(210);
-  srtp_stat_.AddProtectRtcpResult(err_status_fail);
-  EXPECT_EQ(cricket::SrtpFilter::PROTECT, mode_);
-  EXPECT_EQ(cricket::SrtpFilter::ERROR_FAIL, error_);
-}
-
-TEST_F(SrtpStatTest, TestUnprotectRtcpError) {
-  Reset();
-  srtp_stat_.AddUnprotectRtcpResult(err_status_ok);
-  EXPECT_EQ(-1, mode_);
-  EXPECT_EQ(cricket::SrtpFilter::ERROR_NONE, error_);
-  Reset();
-  srtp_stat_.AddUnprotectRtcpResult(err_status_auth_fail);
-  EXPECT_EQ(cricket::SrtpFilter::UNPROTECT, mode_);
-  EXPECT_EQ(cricket::SrtpFilter::ERROR_AUTH, error_);
-  Reset();
-  srtp_stat_.AddUnprotectRtcpResult(err_status_replay_fail);
-  EXPECT_EQ(cricket::SrtpFilter::UNPROTECT, mode_);
-  EXPECT_EQ(cricket::SrtpFilter::ERROR_REPLAY, error_);
-  Reset();
-  talk_base::Thread::Current()->SleepMs(210);
-  srtp_stat_.AddUnprotectRtcpResult(err_status_replay_fail);
-  EXPECT_EQ(cricket::SrtpFilter::UNPROTECT, mode_);
-  EXPECT_EQ(cricket::SrtpFilter::ERROR_REPLAY, error_);
-  Reset();
-  srtp_stat_.AddUnprotectRtcpResult(err_status_fail);
-  EXPECT_EQ(cricket::SrtpFilter::UNPROTECT, mode_);
-  EXPECT_EQ(cricket::SrtpFilter::ERROR_FAIL, error_);
-  // Within 200ms, the error will not be triggered.
-  Reset();
-  srtp_stat_.AddUnprotectRtcpResult(err_status_fail);
-  EXPECT_EQ(-1, mode_);
-  EXPECT_EQ(cricket::SrtpFilter::ERROR_NONE, error_);
-  // Now the error will be triggered again.
-  Reset();
-  talk_base::Thread::Current()->SleepMs(210);
-  srtp_stat_.AddUnprotectRtcpResult(err_status_fail);
-  EXPECT_EQ(cricket::SrtpFilter::UNPROTECT, mode_);
-  EXPECT_EQ(cricket::SrtpFilter::ERROR_FAIL, error_);
-}
diff --git a/third_party/libjingle/source/talk/session/phone/ssrcmuxfilter.cc b/third_party/libjingle/source/talk/session/phone/ssrcmuxfilter.cc
deleted file mode 100644
index 2f3e1f2..0000000
--- a/third_party/libjingle/source/talk/session/phone/ssrcmuxfilter.cc
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/session/phone/ssrcmuxfilter.h"
-
-#include <algorithm>
-
-#include "talk/base/byteorder.h"
-#include "talk/base/logging.h"
-#include "talk/session/phone/rtputils.h"
-
-namespace cricket {
-
-static const uint32 kSsrc01 = 0x01;
-
-SsrcMuxFilter::SsrcMuxFilter()
-    : state_(ST_INIT),
-      enabled_(false) {
-}
-
-SsrcMuxFilter::~SsrcMuxFilter() {
-}
-
-bool SsrcMuxFilter::SetOffer(bool offer_enable, ContentSource src) {
-  bool ret = false;
-  if (state_ == ST_INIT) {
-    enabled_ = offer_enable;
-    state_ = (src == CS_LOCAL) ? ST_SENTOFFER : ST_RECEIVEDOFFER;
-    ret = true;
-  } else {
-    LOG(LS_ERROR) << "Invalid state for SSRC mux offer";
-  }
-  return ret;
-}
-
-bool SsrcMuxFilter::SetAnswer(bool answer_enable, ContentSource src) {
-  bool ret = false;
-  if ((state_ == ST_SENTOFFER && src == CS_REMOTE) ||
-      (state_ == ST_RECEIVEDOFFER && src == CS_LOCAL)) {
-    if (enabled_ && answer_enable) {
-      state_ = ST_ACTIVE;
-      ret = true;
-    } else if (!answer_enable || !enabled_) {
-      // If offer is not enabled, SSRC mux shouldn't be enabled.
-      state_ = ST_INIT;
-      ret = true;
-    } else {
-      LOG(LS_WARNING) << "Invalid parameters for SSRC mux answer";
-    }
-  } else {
-    LOG(LS_ERROR) << "Invalid state for SSRC mux answer";
-  }
-  return ret;
-}
-
-bool SsrcMuxFilter::IsActive() const {
-  return (state_ == ST_ACTIVE);
-}
-
-bool SsrcMuxFilter::DemuxPacket(const char* data, size_t len, bool rtcp) {
-  uint32 ssrc = 0;
-  if (!rtcp) {
-    GetRtpSsrc(data, len, &ssrc);
-  } else {
-    int pl_type = 0;
-    if (!GetRtcpType(data, len, &pl_type)) return false;
-    if (pl_type == kRtcpTypeSR || pl_type == kRtcpTypeRR) {
-      // Getting SSRC from the report packets.
-      if (!GetRtcpSsrc(data, len, &ssrc)) return false;
-      if (ssrc == kSsrc01) {
-        // SSRC 1 has a special meaning and indicates generic feedback on
-        // some systems and should never be dropped.  If it is forwarded
-        // incorrectly it will be ignored by lower layers anyway.
-        return true;
-      }
-    } else {
-      // All other RTCP packets are handled by the all channels.
-      // TODO: Add SSRC parsing to all RTCP messages.
-      LOG(LS_INFO) << "Non RTCP report packet received for demux.";
-      return true;
-    }
-  }
-  return FindStream(ssrc);
-}
-
-bool SsrcMuxFilter::AddStream(uint32 ssrc) {
-  if (FindStream(ssrc)) {
-    LOG(LS_WARNING) << "SSRC is already added to filter";
-    return false;
-  }
-  mux_ssrcs_.insert(ssrc);
-  return true;
-}
-
-bool SsrcMuxFilter::RemoveStream(uint32 ssrc) {
-  if (!FindStream(ssrc)) {
-    LOG(LS_WARNING) << "SSRC is not added added to filter";
-    return false;
-  }
-  bool ret = false;
-  std::set<uint32>::iterator iter =
-      std::find(mux_ssrcs_.begin(), mux_ssrcs_.end(), ssrc);
-  if (iter != mux_ssrcs_.end()) {
-    mux_ssrcs_.erase(iter);
-    ret = true;
-  }
-  return ret;
-}
-
-bool SsrcMuxFilter::FindStream(uint32 ssrc) const {
-  std::set<uint32>::const_iterator citer =
-      std::find(mux_ssrcs_.begin(), mux_ssrcs_.end(), ssrc);
-  return citer != mux_ssrcs_.end();
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/session/phone/ssrcmuxfilter.h b/third_party/libjingle/source/talk/session/phone/ssrcmuxfilter.h
deleted file mode 100644
index 18db79a..0000000
--- a/third_party/libjingle/source/talk/session/phone/ssrcmuxfilter.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SESSION_PHONE_SSRCMUXFILTER_H_
-#define TALK_SESSION_PHONE_SSRCMUXFILTER_H_
-
-#include <set>
-
-#include "talk/base/basictypes.h"
-#include "talk/p2p/base/sessiondescription.h"
-
-namespace cricket {
-
-// This class maintains list of recv SSRC's destined for cricket::BaseChannel.
-// In case of single RTP session and single transport channel, all session
-// ( or media) channels share a common transport channel. Hence they all get
-// SignalReadPacket when packet received on transport channel. This requires
-// cricket::BaseChannel to know all the valid sources, else media channel
-// will decode invalid packets.
-class SsrcMuxFilter {
- public:
-  SsrcMuxFilter();
-  ~SsrcMuxFilter();
-
-  // Whether the rtp mux is active for a sdp session through proper
-  // negotiation.
-  bool IsActive() const;
-  // Set based on what offer indicates use of RTP mux.
-  bool SetOffer(bool offer_enable, ContentSource src);
-  // Set based on what answer indiacates use of RTP mux.
-  bool SetAnswer(bool answer_enable, ContentSource src);
-  // Determines packet belongs to valid cricket::BaseChannel.
-  bool DemuxPacket(const char* data, size_t len, bool rtcp);
-  // Adding a valid source to the filter.
-  bool AddStream(uint32 ssrc);
-  // Removes source from the filter.
-  bool RemoveStream(uint32 ssrc);
-  // Utility method added for unitest.
-  bool FindStream(uint32 ssrc) const;
-
- private:
-  enum State {
-    ST_INIT = 0,
-    ST_SENTOFFER,
-    ST_RECEIVEDOFFER,
-    ST_ACTIVE
-  };
-
-  State state_;
-  bool enabled_;
-  std::set<uint32> mux_ssrcs_;
-};
-
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_SSRCMUXFILTER_H_
diff --git a/third_party/libjingle/source/talk/session/phone/ssrcmuxfilter_unittest.cc b/third_party/libjingle/source/talk/session/phone/ssrcmuxfilter_unittest.cc
deleted file mode 100644
index 6487fac..0000000
--- a/third_party/libjingle/source/talk/session/phone/ssrcmuxfilter_unittest.cc
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-#include "talk/base/gunit.h"
-#include "talk/session/phone/ssrcmuxfilter.h"
-
-static const int kSsrc1 = 0x1111;
-static const int kSsrc2 = 0x2222;
-
-// SSRC = 0x1111
-static const unsigned char kRtpPacketSsrc1[] = {
-    0x80, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11,
-};
-
-// SSRC = 0x2222
-static const unsigned char kRtpPacketSsrc2[] = {
-    0x80, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22,
-};
-
-// SSRC = 0
-static const unsigned char kRtpPacketInvalidSsrc[] = {
-    0x80, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-};
-
-// invalid size
-static const unsigned char kRtpPacketTooSmall[] = {
-    0x80, 0x80, 0x00, 0x00,
-};
-
-// PT = 200 = SR, len = 28, SSRC of sender = 0x0001
-// NTP TS = 0, RTP TS = 0, packet count = 0
-static const unsigned char kRtcpPacketSrSsrc01[] = {
-    0x80, 0xC8, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x01,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00,
-};
-
-// PT = 200 = SR, len = 28, SSRC of sender = 0x2222
-// NTP TS = 0, RTP TS = 0, packet count = 0
-static const unsigned char kRtcpPacketSrSsrc2[] = {
-    0x80, 0xC8, 0x00, 0x1B, 0x00, 0x00, 0x22, 0x22,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00,
-};
-
-// First packet - SR = PT = 200, len = 0, SSRC of sender = 0x1111
-// NTP TS = 0, RTP TS = 0, packet count = 0
-// second packet - SDES = PT =  202, count = 0, SSRC = 0x1111, cname len = 0
-static const unsigned char kRtcpPacketCompoundSrSdesSsrc1[] = {
-    0x80, 0xC8, 0x00, 0x01, 0x00, 0x00, 0x11, 0x11,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00,
-    0x81, 0xCA, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x01, 0x00,
-};
-
-// SDES = PT =  202, count = 0, SSRC = 0x2222, cname len = 0
-static const unsigned char kRtcpPacketSdesSsrc2[] = {
-    0x81, 0xCA, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x01, 0x00,
-};
-
-// Packet has only mandatory fixed RTCP header
-static const unsigned char kRtcpPacketFixedHeaderOnly[] = {
-    0x80, 0xC8, 0x00, 0x00,
-};
-
-// Small packet for SSRC demux.
-static const unsigned char kRtcpPacketTooSmall[] = {
-    0x80, 0xC8, 0x00, 0x00, 0x00, 0x00,
-};
-
-TEST(SsrcMuxFilterTest, TestOfferSetup) {
-  cricket::SsrcMuxFilter ssrc_filter;
-  EXPECT_TRUE(ssrc_filter.SetOffer(true, cricket::CS_LOCAL));
-  EXPECT_TRUE(ssrc_filter.SetAnswer(true, cricket::CS_REMOTE));
-  EXPECT_TRUE(ssrc_filter.IsActive());
-}
-
-TEST(SsrcMuxFilterTest, TestAnswerSetup) {
-  cricket::SsrcMuxFilter ssrc_filter;
-  EXPECT_TRUE(ssrc_filter.SetOffer(true, cricket::CS_REMOTE));
-  EXPECT_TRUE(ssrc_filter.SetAnswer(true, cricket::CS_LOCAL));
-  EXPECT_TRUE(ssrc_filter.IsActive());
-}
-
-TEST(SsrcMuxFilterTest, TestIncorrectOrder) {
-  cricket::SsrcMuxFilter ssrc_filter;
-  EXPECT_TRUE(ssrc_filter.SetOffer(true, cricket::CS_REMOTE));
-  EXPECT_FALSE(ssrc_filter.SetAnswer(true, cricket::CS_REMOTE));
-  EXPECT_FALSE(ssrc_filter.IsActive());
-}
-
-TEST(SsrcMuxFilterTest, AddRemoveStreamTest) {
-  cricket::SsrcMuxFilter ssrc_filter;
-  EXPECT_TRUE(ssrc_filter.AddStream(kSsrc1));
-  EXPECT_TRUE(ssrc_filter.AddStream(kSsrc2));
-  EXPECT_TRUE(ssrc_filter.FindStream(kSsrc1));
-  EXPECT_TRUE(ssrc_filter.FindStream(kSsrc2));
-  EXPECT_TRUE(ssrc_filter.RemoveStream(kSsrc1));
-  EXPECT_FALSE(ssrc_filter.FindStream(kSsrc1));
-}
-
-TEST(SsrcMuxFilterTest, RtpPacketTest) {
-  cricket::SsrcMuxFilter ssrc_filter;
-  EXPECT_TRUE(ssrc_filter.AddStream(kSsrc1));
-  EXPECT_TRUE(ssrc_filter.DemuxPacket(
-      reinterpret_cast<const char*>(kRtpPacketSsrc1),
-      sizeof(kRtpPacketSsrc1), false));
-  EXPECT_TRUE(ssrc_filter.AddStream(kSsrc2));
-  EXPECT_TRUE(ssrc_filter.DemuxPacket(
-      reinterpret_cast<const char*>(kRtpPacketSsrc2),
-      sizeof(kRtpPacketSsrc2), false));
-  EXPECT_TRUE(ssrc_filter.RemoveStream(kSsrc2));
-  EXPECT_FALSE(ssrc_filter.DemuxPacket(
-      reinterpret_cast<const char*>(kRtpPacketSsrc2),
-      sizeof(kRtpPacketSsrc2), false));
-  EXPECT_FALSE(ssrc_filter.DemuxPacket(
-      reinterpret_cast<const char*>(kRtpPacketInvalidSsrc),
-      sizeof(kRtpPacketInvalidSsrc), false));
-  EXPECT_FALSE(ssrc_filter.DemuxPacket(
-      reinterpret_cast<const char*>(kRtpPacketTooSmall),
-      sizeof(kRtpPacketTooSmall), false));
-}
-
-TEST(SsrcMuxFilterTest, RtcpPacketTest) {
-  cricket::SsrcMuxFilter ssrc_filter;
-  EXPECT_TRUE(ssrc_filter.AddStream(kSsrc1));
-  EXPECT_TRUE(ssrc_filter.DemuxPacket(
-      reinterpret_cast<const char*>(kRtcpPacketCompoundSrSdesSsrc1),
-      sizeof(kRtcpPacketCompoundSrSdesSsrc1), true));
-  EXPECT_TRUE(ssrc_filter.AddStream(kSsrc2));
-  EXPECT_TRUE(ssrc_filter.DemuxPacket(
-      reinterpret_cast<const char*>(kRtcpPacketSrSsrc2),
-      sizeof(kRtcpPacketSrSsrc2), true));
-  EXPECT_TRUE(ssrc_filter.DemuxPacket(
-      reinterpret_cast<const char*>(kRtcpPacketSdesSsrc2),
-      sizeof(kRtcpPacketSdesSsrc2), true));
-  EXPECT_TRUE(ssrc_filter.RemoveStream(kSsrc2));
-  // RTCP Packets other than SR and RR are demuxed regardless of SSRC.
-  EXPECT_TRUE(ssrc_filter.DemuxPacket(
-      reinterpret_cast<const char*>(kRtcpPacketSdesSsrc2),
-      sizeof(kRtcpPacketSdesSsrc2), true));
-  // RTCP Packets with 'special' SSRC 0x01 are demuxed also
-  EXPECT_TRUE(ssrc_filter.DemuxPacket(
-      reinterpret_cast<const char*>(kRtcpPacketSrSsrc01),
-      sizeof(kRtcpPacketSrSsrc01), true));
-  EXPECT_FALSE(ssrc_filter.DemuxPacket(
-      reinterpret_cast<const char*>(kRtcpPacketSrSsrc2),
-      sizeof(kRtcpPacketSrSsrc2), true));
-  EXPECT_FALSE(ssrc_filter.DemuxPacket(
-      reinterpret_cast<const char*>(kRtcpPacketFixedHeaderOnly),
-      sizeof(kRtcpPacketFixedHeaderOnly), true));
-  EXPECT_FALSE(ssrc_filter.DemuxPacket(
-      reinterpret_cast<const char*>(kRtcpPacketTooSmall),
-      sizeof(kRtcpPacketTooSmall), true));
-}
-
diff --git a/third_party/libjingle/source/talk/session/phone/streamparams.h b/third_party/libjingle/source/talk/session/phone/streamparams.h
deleted file mode 100644
index ec4b380..0000000
--- a/third_party/libjingle/source/talk/session/phone/streamparams.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * libjingle
- * Copyright 2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// This file contains structures for describing SSRCs from a media source such
-// as a MediaStreamTrack when it is sent across an RTP session. Multiple media
-// sources may be sent across the same RTP session, each of them will be
-// described by one StreamParams object
-// SsrcGroup is used to describe the relationship between the SSRCs that
-// are used for this media source.
-// E.x: Consider a source that is sent as 3 simulcast streams
-// Let the simulcast elements have SSRC 10, 20, 30.
-// Let each simulcast element use FEC and let the protection packets have
-// SSRC 11,21,31.
-// To describe this 4 SsrcGroups are needed,
-// StreamParams would then contain ssrc = {10,11,20,21,30,31} and
-// ssrc_groups = {{SIM,{10,20,30}, {FEC,{10,11}, {FEC, {20,21}, {FEC {30,31}}}
-// Please see RFC 5576.
-
-#ifndef TALK_SESSION_PHONE_STREAMPARAMS_H_
-#define TALK_SESSION_PHONE_STREAMPARAMS_H_
-
-#include <string>
-#include <vector>
-
-namespace cricket {
-
-struct SsrcGroup {
-  SsrcGroup(const std::string& usage, const std::vector<uint32>& ssrcs)
-      : semantics(usage), ssrcs(ssrcs) {
-  }
-
-  bool operator==(const SsrcGroup& other) const {
-    return (semantics == other.semantics && ssrcs == other.ssrcs);
-  }
-  bool operator!=(const SsrcGroup &other) const {
-    return !(*this == other);
-  }
-
-  std::string semantics;  // e.g FIX, FEC, SIM.
-  std::vector<uint32> ssrcs;  // SSRCs of this type.
-};
-
-struct StreamParams {
-  static StreamParams CreateLegacy(uint32 ssrc) {
-    StreamParams stream;
-    stream.ssrcs.push_back(ssrc);
-    return stream;
-  }
-  bool operator==(const StreamParams& other) const {
-    return (nick == other.nick &&
-            name == other.name &&
-            ssrcs == other.ssrcs &&
-            ssrc_groups == other.ssrc_groups &&
-            type == other.type &&
-            display == other.display &&
-            cname == other.cname &&
-            sync_label == sync_label);
-  }
-  bool operator!=(const StreamParams &other) const {
-    return !(*this == other);
-  }
-
-  uint32 first_ssrc() const {
-    if (ssrcs.empty()) {
-      return 0;
-    }
-
-    return ssrcs[0];
-  }
-  bool has_ssrcs() const {
-    return !ssrcs.empty();
-  }
-
-  // Resource of the MUC jid of the participant of with this stream.
-  // For 1:1 calls, should be left empty (which means remote streams
-  // and local streams should not be mixed together).
-  std::string nick;
-  // Unique name of this source (unique per-nick, not for all nicks)
-  std::string name;
-  std::vector<uint32> ssrcs;  // All SSRCs for this source
-  std::vector<SsrcGroup> ssrc_groups;  // e.g. FID, FEC, SIM
-  // Examples: "camera", "screencast"
-  std::string type;
-  // Friendly name describing stream
-  std::string display;
-  std::string cname;  // RTCP CNAME
-  std::string sync_label;  // Friendly name of cname.
-};
-
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_STREAMPARAMS_H_
diff --git a/third_party/libjingle/source/talk/session/phone/testdata/captured-320x240-2s-48.frames b/third_party/libjingle/source/talk/session/phone/testdata/captured-320x240-2s-48.frames
deleted file mode 100644
index 292a170..0000000
--- a/third_party/libjingle/source/talk/session/phone/testdata/captured-320x240-2s-48.frames
+++ /dev/null
Binary files differ
diff --git a/third_party/libjingle/source/talk/session/phone/testdata/h264-svc-99-640x360.rtpdump b/third_party/libjingle/source/talk/session/phone/testdata/h264-svc-99-640x360.rtpdump
deleted file mode 100644
index ffa521d..0000000
--- a/third_party/libjingle/source/talk/session/phone/testdata/h264-svc-99-640x360.rtpdump
+++ /dev/null
Binary files differ
diff --git a/third_party/libjingle/source/talk/session/phone/testdata/video.rtpdump b/third_party/libjingle/source/talk/session/phone/testdata/video.rtpdump
deleted file mode 100644
index 7be863e..0000000
--- a/third_party/libjingle/source/talk/session/phone/testdata/video.rtpdump
+++ /dev/null
Binary files differ
diff --git a/third_party/libjingle/source/talk/session/phone/testdata/voice.rtpdump b/third_party/libjingle/source/talk/session/phone/testdata/voice.rtpdump
deleted file mode 100644
index 8f0ec15..0000000
--- a/third_party/libjingle/source/talk/session/phone/testdata/voice.rtpdump
+++ /dev/null
Binary files differ
diff --git a/third_party/libjingle/source/talk/session/phone/testutils.cc b/third_party/libjingle/source/talk/session/phone/testutils.cc
deleted file mode 100644
index 679506a..0000000
--- a/third_party/libjingle/source/talk/session/phone/testutils.cc
+++ /dev/null
@@ -1,364 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/session/phone/testutils.h"
-
-#include <math.h>
-
-#include "talk/base/bytebuffer.h"
-#include "talk/base/fileutils.h"
-#include "talk/base/gunit.h"
-#include "talk/base/pathutils.h"
-#include "talk/base/stream.h"
-#include "talk/base/stringutils.h"
-#include "talk/session/phone/rtpdump.h"
-#include "talk/session/phone/videocapturer.h"
-#include "talk/session/phone/videoframe.h"
-
-namespace cricket {
-
-/////////////////////////////////////////////////////////////////////////
-// Implementation of RawRtpPacket
-/////////////////////////////////////////////////////////////////////////
-void RawRtpPacket::WriteToByteBuffer(
-    uint32 in_ssrc, talk_base::ByteBuffer *buf) const {
-  if (!buf) return;
-
-  buf->WriteUInt8(ver_to_cc);
-  buf->WriteUInt8(m_to_pt);
-  buf->WriteUInt16(sequence_number);
-  buf->WriteUInt32(timestamp);
-  buf->WriteUInt32(in_ssrc);
-  buf->WriteBytes(payload, sizeof(payload));
-}
-
-bool RawRtpPacket::ReadFromByteBuffer(talk_base::ByteBuffer* buf) {
-  if (!buf) return false;
-
-  bool ret = true;
-  ret &= buf->ReadUInt8(&ver_to_cc);
-  ret &= buf->ReadUInt8(&m_to_pt);
-  ret &= buf->ReadUInt16(&sequence_number);
-  ret &= buf->ReadUInt32(&timestamp);
-  ret &= buf->ReadUInt32(&ssrc);
-  ret &= buf->ReadBytes(payload, sizeof(payload));
-  return ret;
-}
-
-bool RawRtpPacket::SameExceptSeqNumTimestampSsrc(
-    const RawRtpPacket& packet, uint16 seq, uint32 ts, uint32 ssc) const {
-  return sequence_number == seq &&
-      timestamp == ts &&
-      ver_to_cc == packet.ver_to_cc &&
-      m_to_pt == packet.m_to_pt &&
-      ssrc == ssc &&
-      0 == memcmp(payload, packet.payload, sizeof(payload));
-}
-
-/////////////////////////////////////////////////////////////////////////
-// Implementation of RawRtcpPacket
-/////////////////////////////////////////////////////////////////////////
-void RawRtcpPacket::WriteToByteBuffer(talk_base::ByteBuffer *buf) const {
-  if (!buf) return;
-
-  buf->WriteUInt8(ver_to_count);
-  buf->WriteUInt8(type);
-  buf->WriteUInt16(length);
-  buf->WriteBytes(payload, sizeof(payload));
-}
-
-bool RawRtcpPacket::ReadFromByteBuffer(talk_base::ByteBuffer* buf) {
-  if (!buf) return false;
-
-  bool ret = true;
-  ret &= buf->ReadUInt8(&ver_to_count);
-  ret &= buf->ReadUInt8(&type);
-  ret &= buf->ReadUInt16(&length);
-  ret &= buf->ReadBytes(payload, sizeof(payload));
-  return ret;
-}
-
-bool RawRtcpPacket::EqualsTo(const RawRtcpPacket& packet) const {
-  return ver_to_count == packet.ver_to_count &&
-      type == packet.type &&
-      length == packet.length &&
-      0 == memcmp(payload, packet.payload, sizeof(payload));
-}
-
-/////////////////////////////////////////////////////////////////////////
-// Implementation of class RtpTestUtility
-/////////////////////////////////////////////////////////////////////////
-const RawRtpPacket RtpTestUtility::kTestRawRtpPackets[] = {
-    {0x80, 0, 0, 0,  RtpTestUtility::kDefaultSsrc, "RTP frame 0"},
-    {0x80, 0, 1, 30, RtpTestUtility::kDefaultSsrc, "RTP frame 1"},
-    {0x80, 0, 2, 30, RtpTestUtility::kDefaultSsrc, "RTP frame 1"},
-    {0x80, 0, 3, 60, RtpTestUtility::kDefaultSsrc, "RTP frame 2"}
-};
-const RawRtcpPacket RtpTestUtility::kTestRawRtcpPackets[] = {
-    // The Version is 2, the Length is 2, and the payload has 8 bytes.
-    {0x80, 0, 2, "RTCP0000"},
-    {0x80, 0, 2, "RTCP0001"},
-    {0x80, 0, 2, "RTCP0002"},
-    {0x80, 0, 2, "RTCP0003"},
-};
-
-size_t RtpTestUtility::GetTestPacketCount() {
-  return talk_base::_min(
-      ARRAY_SIZE(kTestRawRtpPackets),
-      ARRAY_SIZE(kTestRawRtcpPackets));
-}
-
-bool RtpTestUtility::WriteTestPackets(
-    size_t count, bool rtcp, uint32 rtp_ssrc, RtpDumpWriter* writer) {
-  if (!writer || count > GetTestPacketCount()) return false;
-
-  bool result = true;
-  uint32 elapsed_time_ms = 0;
-  for (size_t i = 0; i < count && result; ++i) {
-    talk_base::ByteBuffer buf;
-    if (rtcp) {
-      kTestRawRtcpPackets[i].WriteToByteBuffer(&buf);
-    } else {
-      kTestRawRtpPackets[i].WriteToByteBuffer(rtp_ssrc, &buf);
-    }
-
-    RtpDumpPacket dump_packet(buf.Data(), buf.Length(), elapsed_time_ms, rtcp);
-    elapsed_time_ms += kElapsedTimeInterval;
-    result &= (talk_base::SR_SUCCESS == writer->WritePacket(dump_packet));
-  }
-  return result;
-}
-
-bool RtpTestUtility::VerifyTestPacketsFromStream(
-    size_t count, talk_base::StreamInterface* stream, uint32 ssrc) {
-  if (!stream) return false;
-
-  uint32 prev_elapsed_time = 0;
-  bool result = true;
-  stream->Rewind();
-  RtpDumpLoopReader reader(stream);
-  for (size_t i = 0; i < count && result; ++i) {
-    // Which loop and which index in the loop are we reading now.
-    size_t loop = i / GetTestPacketCount();
-    size_t index = i % GetTestPacketCount();
-
-    RtpDumpPacket packet;
-    result &= (talk_base::SR_SUCCESS == reader.ReadPacket(&packet));
-    // Check the elapsed time of the dump packet.
-    result &= (packet.elapsed_time >= prev_elapsed_time);
-    prev_elapsed_time = packet.elapsed_time;
-
-    // Check the RTP or RTCP packet.
-    talk_base::ByteBuffer buf(reinterpret_cast<const char*>(&packet.data[0]),
-                              packet.data.size());
-    if (packet.is_rtcp) {
-      // RTCP packet.
-      RawRtcpPacket rtcp_packet;
-      result &= rtcp_packet.ReadFromByteBuffer(&buf);
-      result &= rtcp_packet.EqualsTo(kTestRawRtcpPackets[index]);
-    } else {
-      // RTP packet.
-      RawRtpPacket rtp_packet;
-      result &= rtp_packet.ReadFromByteBuffer(&buf);
-      result &= rtp_packet.SameExceptSeqNumTimestampSsrc(
-          kTestRawRtpPackets[index],
-          kTestRawRtpPackets[index].sequence_number +
-              loop * GetTestPacketCount(),
-          kTestRawRtpPackets[index].timestamp + loop * kRtpTimestampIncrease,
-          ssrc);
-    }
-  }
-
-  stream->Rewind();
-  return result;
-}
-
-bool RtpTestUtility::VerifyPacket(const RtpDumpPacket* dump,
-                                  const RawRtpPacket* raw,
-                                  bool header_only) {
-  if (!dump || !raw) return false;
-
-  talk_base::ByteBuffer buf;
-  raw->WriteToByteBuffer(RtpTestUtility::kDefaultSsrc, &buf);
-
-  if (header_only) {
-    size_t header_len = 0;
-    dump->GetRtpHeaderLen(&header_len);
-    return header_len == dump->data.size() &&
-        buf.Length() > dump->data.size() &&
-        0 == memcmp(buf.Data(), &dump->data[0], dump->data.size());
-  } else {
-    return buf.Length() == dump->data.size() &&
-        0 == memcmp(buf.Data(), &dump->data[0], dump->data.size());
-  }
-}
-
-// Implementation of VideoCaptureListener.
-VideoCapturerListener::VideoCapturerListener(VideoCapturer* capturer)
-    : start_result_(CR_PENDING),
-      frame_count_(0),
-      frame_fourcc_(0),
-      frame_width_(0),
-      frame_height_(0),
-      frame_size_(0),
-      resolution_changed_(false) {
-  capturer->SignalStartResult.connect(this,
-      &VideoCapturerListener::OnStartResult);
-  capturer->SignalFrameCaptured.connect(this,
-      &VideoCapturerListener::OnFrameCaptured);
-  capturer->SignalCaptureEvent.connect(this,
-      &VideoCapturerListener::OnCaptureEvent);
-}
-
-void VideoCapturerListener::OnStartResult(VideoCapturer* capturer,
-                                          CaptureResult result) {
-  start_result_ = result;
-}
-
-void VideoCapturerListener::OnFrameCaptured(VideoCapturer* capturer,
-                                            const CapturedFrame* frame) {
-  ++frame_count_;
-  if (1 == frame_count_) {
-    frame_fourcc_ = frame->fourcc;
-    frame_width_ = frame->width;
-    frame_height_ = frame->height;
-    frame_size_ = frame->data_size;
-  } else if (frame_width_ != frame->width || frame_height_ != frame->height) {
-    resolution_changed_ = true;
-  }
-}
-
-void VideoCapturerListener::OnCaptureEvent(VideoCapturer* capturer,
-                                           CaptureEvent ev) {
-}
-
-
-// Returns the absolute path to a file in the testdata/ directory.
-std::string GetTestFilePath(const std::string& filename) {
-  // Locate test data directory.
-  talk_base::Pathname path = GetTalkDirectory();
-  EXPECT_FALSE(path.empty());  // must be run from inside "talk"
-  path.AppendFolder("session");
-  path.AppendFolder("phone");
-  path.AppendFolder("testdata");
-  path.SetFilename(filename);
-  return path.pathname();
-}
-
-// PSNR formula: psnr = 10 * log10 (Peak Signal^2 / mse)
-// sse is set to a small number for identical frames or sse == 0
-double ComputePSNR(double sse, double size) {
-  if (sse <= 0.)
-    sse = 65025.0 * size / pow(10., 128./10.);  // produces max PSNR of 128
-  return 10.0 * log10(65025.0 * size / sse);
-}
-
-double ComputeSumSquareError(const uint8 *org, const uint8 *rec,
-                             int size) {
-  double sse = 0.;
-  for (int j = 0; j < size; ++j) {
-    const int diff = static_cast<int>(org[j]) - static_cast<int>(rec[j]);
-    sse += static_cast<double>(diff * diff);
-  }
-  return sse;
-}
-
-// Loads the image with the specified prefix and size into |out|.
-bool LoadPlanarYuvTestImage(const std::string& prefix,
-                            int width, int height, uint8* out) {
-  std::stringstream ss;
-  ss << prefix << "." << width << "x" << height << "_P420.yuv";
-
-  talk_base::scoped_ptr<talk_base::FileStream> stream(
-      talk_base::Filesystem::OpenFile(talk_base::Pathname(
-          GetTestFilePath(ss.str())), "rb"));
-  if (!stream.get()) {
-    return false;
-  }
-
-  talk_base::StreamResult res =
-      stream->ReadAll(out, I420_SIZE(width, height), NULL, NULL);
-  return (res == talk_base::SR_SUCCESS);
-}
-
-// Dumps the YUV image out to a file, for visual inspection.
-// PYUV tool can be used to view dump files.
-void DumpPlanarYuvTestImage(const std::string& prefix, const uint8* img,
-                            int w, int h) {
-  talk_base::FileStream fs;
-  char filename[256];
-  talk_base::sprintfn(filename, sizeof(filename), "%s.%dx%d_P420.yuv",
-                      prefix.c_str(), w, h);
-  fs.Open(filename, "wb", NULL);
-  fs.Write(img, I420_SIZE(w, h), NULL, NULL);
-}
-
-// Dumps the ARGB image out to a file, for visual inspection.
-// ffplay tool can be used to view dump files.
-void DumpPlanarArgbTestImage(const std::string& prefix, const uint8* img,
-                             int w, int h) {
-  talk_base::FileStream fs;
-  char filename[256];
-  talk_base::sprintfn(filename, sizeof(filename), "%s.%dx%d_ARGB.raw",
-                      prefix.c_str(), w, h);
-  fs.Open(filename, "wb", NULL);
-  fs.Write(img, ARGB_SIZE(w, h), NULL, NULL);
-}
-
-bool VideoFrameEqual(const VideoFrame* frame0, const VideoFrame* frame1) {
-  const uint8* y0 = frame0->GetYPlane();
-  const uint8* u0 = frame0->GetUPlane();
-  const uint8* v0 = frame0->GetVPlane();
-  const uint8* y1 = frame1->GetYPlane();
-  const uint8* u1 = frame1->GetUPlane();
-  const uint8* v1 = frame1->GetVPlane();
-
-  for (size_t i = 0; i < frame0->GetHeight(); ++i) {
-    if (0 != memcmp(y0, y1, frame0->GetWidth())) {
-      return false;
-    }
-    y0 += frame0->GetYPitch();
-    y1 += frame1->GetYPitch();
-  }
-
-  for (size_t i = 0; i < frame0->GetChromaHeight(); ++i) {
-    if (0 != memcmp(u0, u1, frame0->GetChromaWidth())) {
-      return false;
-    }
-    if (0 != memcmp(v0, v1, frame0->GetChromaWidth())) {
-      return false;
-    }
-    u0 += frame0->GetUPitch();
-    v0 += frame0->GetVPitch();
-    u1 += frame1->GetUPitch();
-    v1 += frame1->GetVPitch();
-  }
-
-  return true;
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/session/phone/testutils.h b/third_party/libjingle/source/talk/session/phone/testutils.h
deleted file mode 100644
index b4ce454..0000000
--- a/third_party/libjingle/source/talk/session/phone/testutils.h
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SESSION_PHONE_TESTUTILS_H_
-#define TALK_SESSION_PHONE_TESTUTILS_H_
-
-#include <string>
-#include <vector>
-
-#include "talk/base/basictypes.h"
-#include "talk/base/sigslot.h"
-#include "talk/base/window.h"
-#include "talk/session/phone/mediachannel.h"
-#include "talk/session/phone/videocommon.h"
-#include "talk/session/phone/videocapturer.h"
-
-namespace talk_base {
-class ByteBuffer;
-class StreamInterface;
-}
-
-namespace cricket {
-
-// Returns size of 420 image with rounding on chroma for odd sizes.
-#define I420_SIZE(w, h) (w * h + (((w + 1) / 2) * ((h + 1) / 2)) * 2)
-// Returns size of ARGB image.
-#define ARGB_SIZE(w, h) (w * h * 4)
-
-template <class T> inline std::vector<T> MakeVector(const T a[], size_t s) {
-  return std::vector<T>(a, a + s);
-}
-#define MAKE_VECTOR(a) cricket::MakeVector(a, ARRAY_SIZE(a))
-
-struct RtpDumpPacket;
-class RtpDumpWriter;
-class VideoFrame;
-
-struct RawRtpPacket {
-  void WriteToByteBuffer(uint32 in_ssrc, talk_base::ByteBuffer* buf) const;
-  bool ReadFromByteBuffer(talk_base::ByteBuffer* buf);
-  // Check if this packet is the same as the specified packet except the
-  // sequence number and timestamp, which should be the same as the specified
-  // parameters.
-  bool SameExceptSeqNumTimestampSsrc(
-      const RawRtpPacket& packet, uint16 seq, uint32 ts, uint32 ssc) const;
-  int size() const { return 28; }
-
-  uint8 ver_to_cc;
-  uint8 m_to_pt;
-  uint16 sequence_number;
-  uint32 timestamp;
-  uint32 ssrc;
-  char payload[16];
-};
-
-struct RawRtcpPacket {
-  void WriteToByteBuffer(talk_base::ByteBuffer* buf) const;
-  bool ReadFromByteBuffer(talk_base::ByteBuffer* buf);
-  bool EqualsTo(const RawRtcpPacket& packet) const;
-
-  uint8 ver_to_count;
-  uint8 type;
-  uint16 length;
-  char payload[16];
-};
-
-class RtpTestUtility {
- public:
-  static size_t GetTestPacketCount();
-
-  // Write the first count number of kTestRawRtcpPackets or kTestRawRtpPackets,
-  // depending on the flag rtcp. If it is RTP, use the specified SSRC. Return
-  // true if successful.
-  static bool WriteTestPackets(
-      size_t count, bool rtcp, uint32 rtp_ssrc, RtpDumpWriter* writer);
-
-  // Loop read the first count number of packets from the specified stream.
-  // Verify the elapsed time of the dump packets increase monotonically. If the
-  // stream is a RTP stream, verify the RTP sequence number, timestamp, and
-  // payload. If the stream is a RTCP stream, verify the RTCP header and
-  // payload.
-  static bool VerifyTestPacketsFromStream(
-      size_t count, talk_base::StreamInterface* stream, uint32 ssrc);
-
-  // Verify the dump packet is the same as the raw RTP packet.
-  static bool VerifyPacket(const RtpDumpPacket* dump,
-                           const RawRtpPacket* raw,
-                           bool header_only);
-
-  static const uint32 kDefaultSsrc = 1;
-  static const uint32 kRtpTimestampIncrease = 90;
-  static const uint32 kDefaultTimeIncrease = 30;
-  static const uint32 kElapsedTimeInterval = 10;
-  static const RawRtpPacket kTestRawRtpPackets[];
-  static const RawRtcpPacket kTestRawRtcpPackets[];
-
- private:
-  RtpTestUtility() {}
-};
-
-// Test helper for testing VideoCapturer implementations.
-class VideoCapturerListener : public sigslot::has_slots<> {
- public:
-  explicit VideoCapturerListener(VideoCapturer* cap);
-
-  CaptureResult start_result() const { return start_result_; }
-  int frame_count() const { return frame_count_; }
-  uint32 frame_fourcc() const { return frame_fourcc_; }
-  int frame_width() const { return frame_width_; }
-  int frame_height() const { return frame_height_; }
-  uint32 frame_size() const { return frame_size_; }
-  bool resolution_changed() const { return resolution_changed_; }
-
-  void OnStartResult(VideoCapturer* capturer, CaptureResult result);
-  void OnFrameCaptured(VideoCapturer* capturer, const CapturedFrame* frame);
-  void OnCaptureEvent(VideoCapturer* capturer, CaptureEvent ev);
-
- private:
-  CaptureResult start_result_;
-  int frame_count_;
-  uint32 frame_fourcc_;
-  int frame_width_;
-  int frame_height_;
-  uint32 frame_size_;
-  bool resolution_changed_;
-};
-
-class ScreencastEventCatcher : public sigslot::has_slots<> {
- public:
-  ScreencastEventCatcher() : ssrc_(0), ev_(talk_base::WE_RESIZE) { }
-  uint32 ssrc() const { return ssrc_; }
-  talk_base::WindowEvent event() const { return ev_; }
-  void OnEvent(uint32 ssrc, talk_base::WindowEvent ev) {
-    ssrc_ = ssrc;
-    ev_ = ev;
-  }
- private:
-  uint32 ssrc_;
-  talk_base::WindowEvent ev_;
-};
-
-class VideoMediaErrorCatcher : public sigslot::has_slots<> {
- public:
-  VideoMediaErrorCatcher() : ssrc_(0), error_(VideoMediaChannel::ERROR_NONE) { }
-  uint32 ssrc() const { return ssrc_; }
-  VideoMediaChannel::Error error() const { return error_; }
-  void OnError(uint32 ssrc, VideoMediaChannel::Error error) {
-    ssrc_ = ssrc;
-    error_ = error;
-  }
- private:
-  uint32 ssrc_;
-  VideoMediaChannel::Error error_;
-};
-
-// Returns the absolute path to a file in the testdata/ directory.
-std::string GetTestFilePath(const std::string& filename);
-
-// PSNR formula: psnr = 10 * log10 (Peak Signal^2 / mse)
-// sse is set to a small number for identical frames or sse == 0
-double ComputePSNR(double sse, double size);
-
-double ComputeSumSquareError(const uint8 *org, const uint8 *rec,
-                             int size);
-
-// Loads the image with the specified prefix and size into |out|.
-bool LoadPlanarYuvTestImage(const std::string& prefix,
-                            int width, int height, uint8* out);
-
-// Dumps the YUV image out to a file, for visual inspection.
-// PYUV tool can be used to view dump files.
-void DumpPlanarYuvTestImage(const std::string& prefix, const uint8* img,
-                            int w, int h);
-
-// Dumps the ARGB image out to a file, for visual inspection.
-// ffplay tool can be used to view dump files.
-void DumpPlanarArgbTestImage(const std::string& prefix, const uint8* img,
-                             int w, int h);
-
-// Compare two I420 frames.
-bool VideoFrameEqual(const VideoFrame* frame0, const VideoFrame* frame1);
-
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_TESTUTILS_H_
diff --git a/third_party/libjingle/source/talk/session/phone/v4llookup.cc b/third_party/libjingle/source/talk/session/phone/v4llookup.cc
deleted file mode 100644
index f68d219..0000000
--- a/third_party/libjingle/source/talk/session/phone/v4llookup.cc
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright 2009, Google Inc.
- * Author: lexnikitin@google.com (Alexey Nikitin)
- *
- * V4LLookup provides basic functionality to work with V2L2 devices in Linux
- * The functionality is implemented as a class with virtual methods for
- * the purpose of unit testing.
- */
-#include "talk/session/phone/v4llookup.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <linux/types.h>
-#include <linux/videodev2.h>
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <cstring>
-
-#include "talk/base/logging.h"
-
-namespace cricket {
-
-V4LLookup *V4LLookup::v4l_lookup_ = NULL;
-
-bool V4LLookup::CheckIsV4L2Device(const std::string& device_path) {
-  // check device major/minor numbers are in the range for video devices.
-  struct stat s;
-
-  if (lstat(device_path.c_str(), &s) != 0 || !S_ISCHR(s.st_mode)) return false;
-
-  int video_fd = -1;
-  bool is_v4l2 = false;
-
-  // check major/minur device numbers are in range for video device
-  if (major(s.st_rdev) == 81) {
-    dev_t num = minor(s.st_rdev);
-    if (num <= 63 && num >= 0) {
-      video_fd = ::open(device_path.c_str(), O_RDONLY | O_NONBLOCK);
-      if ((video_fd >= 0) || (errno == EBUSY)) {
-        ::v4l2_capability video_caps;
-        memset(&video_caps, 0, sizeof(video_caps));
-
-        if ((errno == EBUSY) ||
-            (::ioctl(video_fd, VIDIOC_QUERYCAP, &video_caps) >= 0 &&
-            (video_caps.capabilities & V4L2_CAP_VIDEO_CAPTURE))) {
-          LOG(LS_INFO) << "Found V4L2 capture device " << device_path;
-
-          is_v4l2 = true;
-        } else {
-          LOG(LS_ERROR) << "VIDIOC_QUERYCAP failed for " << device_path;
-        }
-      } else {
-        LOG(LS_ERROR) << "Failed to open " << device_path;
-      }
-    }
-  }
-
-  if (video_fd >= 0)
-    ::close(video_fd);
-
-  return is_v4l2;
-}
-
-};  // namespace cricket
diff --git a/third_party/libjingle/source/talk/session/phone/v4llookup.h b/third_party/libjingle/source/talk/session/phone/v4llookup.h
deleted file mode 100644
index 966d6c5..0000000
--- a/third_party/libjingle/source/talk/session/phone/v4llookup.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright 2009, Google Inc.
- * Author: lexnikitin@google.com (Alexey Nikitin)
- *
- * V4LLookup provides basic functionality to work with V2L2 devices in Linux
- * The functionality is implemented as a class with virtual methods for
- * the purpose of unit testing.
- */
-#ifndef TALK_SESSION_PHONE_V4LLOOKUP_H_
-#define TALK_SESSION_PHONE_V4LLOOKUP_H_
-
-#include <string>
-
-#ifdef LINUX
-namespace cricket {
-class V4LLookup {
- public:
-  virtual ~V4LLookup() {}
-
-  static bool IsV4L2Device(const std::string& device_path) {
-    return GetV4LLookup()->CheckIsV4L2Device(device_path);
-  }
-
-  static void SetV4LLookup(V4LLookup* v4l_lookup) {
-    v4l_lookup_ = v4l_lookup;
-  }
-
-  static V4LLookup* GetV4LLookup() {
-    if (!v4l_lookup_) {
-      v4l_lookup_ = new V4LLookup();
-    }
-    return v4l_lookup_;
-  }
-
- protected:
-  static V4LLookup* v4l_lookup_;
-  // Making virtual so it is easier to mock
-  virtual bool CheckIsV4L2Device(const std::string& device_path);
-};
-
-}  // namespace cricket
-
-#endif  // LINUX
-#endif  // TALK_SESSION_PHONE_V4LLOOKUP_H_
diff --git a/third_party/libjingle/source/talk/session/phone/videocapturer.cc b/third_party/libjingle/source/talk/session/phone/videocapturer.cc
deleted file mode 100644
index ac544eb..0000000
--- a/third_party/libjingle/source/talk/session/phone/videocapturer.cc
+++ /dev/null
@@ -1,234 +0,0 @@
-// libjingle
-// Copyright 2010 Google Inc.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-//  1. Redistributions of source code must retain the above copyright notice,
-//     this list of conditions and the following disclaimer.
-//  2. Redistributions in binary form must reproduce the above copyright notice,
-//     this list of conditions and the following disclaimer in the documentation
-//     and/or other materials provided with the distribution.
-//  3. The name of the author may not be used to endorse or promote products
-//     derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Implementartion file of class VideoCapturer.
-
-#include "talk/session/phone/videocapturer.h"
-
-#include <algorithm>
-
-#include "talk/base/logging.h"
-
-namespace cricket {
-
-static const int64 kMaxDistance = ~(static_cast<int64>(1) << 63);
-static const int64  kMinDesirableFps = static_cast<int64>(15);
-
-/////////////////////////////////////////////////////////////////////
-// Implementation of struct CapturedFrame
-/////////////////////////////////////////////////////////////////////
-CapturedFrame::CapturedFrame()
-    : width(0),
-      height(0),
-      fourcc(0),
-      pixel_width(0),
-      pixel_height(0),
-      elapsed_time(0),
-      time_stamp(0),
-      data_size(0),
-      rotation(0),
-      data(NULL) {
-}
-
-// TODO: Remove this function once lmimediaengine stops using it.
-bool CapturedFrame::GetDataSize(uint32* size) const {
-  if (!size || data_size == CapturedFrame::kUnknownDataSize) {
-    return false;
-  }
-  *size = data_size;
-  return true;
-}
-
-/////////////////////////////////////////////////////////////////////
-// Implementation of class VideoCapturer
-/////////////////////////////////////////////////////////////////////
-void VideoCapturer::SetSupportedFormats(
-    const std::vector<VideoFormat>& formats) {
-  if (!supported_formats_.get()) {
-    supported_formats_.reset(new std::vector<VideoFormat>);
-  }
-  *(supported_formats_.get()) = formats;
-}
-
-bool VideoCapturer::GetBestCaptureFormat(const VideoFormat& desired,
-                                         VideoFormat* best_format) {
-  if (!supported_formats_.get()) {
-    return false;
-  }
-
-  VideoFormat format = desired;
-  // If the application requests 16x9 and the camera does not support 16x9 HD
-  // or the application requests 16x10, change the request to 4x3. Otherwise,
-  // keep the request.
-  if (format.width * 9 == format.height * 16 &&
-      !Includes16x9HD(*supported_formats_.get())) {
-    format.height = format.width * 3 / 4;
-  } else if (format.width * 10 == format.height * 16) {
-    format.height = format.width * 3 / 4;
-  }
-  LOG(LS_INFO) << " Capture Desired " << desired.ToString()
-               << " Capture Requested " << format.ToString();
-  int64 best_distance = kMaxDistance;
-  std::vector<VideoFormat>::const_iterator best = supported_formats_->end();
-  std::vector<VideoFormat>::const_iterator i;
-  for (i = supported_formats_->begin(); i != supported_formats_->end(); ++i) {
-    int64 distance = GetFormatDistance(format, *i);
-    // TODO: Reduce to LS_VERBOSE if/when camera capture is
-    // relatively bug free.
-    LOG(LS_INFO) << " Supported " << i->ToString()
-                 << " distance " << distance;
-    if (distance < best_distance) {
-      best_distance = distance;
-      best = i;
-    }
-  }
-  if (supported_formats_->end() == best) {
-    return false;
-  }
-
-  if (best_format) {
-    best_format->width = best->width;
-    best_format->height = best->height;
-    best_format->fourcc = best->fourcc;
-    best_format->interval = talk_base::_max(format.interval, best->interval);
-    LOG(LS_INFO) << " Best " << best_format->ToString()
-                 << " distance " << best_distance;
-  }
-  return true;
-}
-
-// Get the distance between the supported and desired formats.
-// Prioritization is done according to this algorithm:
-// 1) Width closeness. If not same, we prefer wider.
-// 2) Height closeness. If not same, we prefer higher.
-// 3) Framerate closeness. If not same, we prefer faster.
-// 4) Compression. If desired format has a specific fourcc, we need exact match;
-//                otherwise, we use preference.
-int64 VideoCapturer::GetFormatDistance(const VideoFormat& desired,
-                                       const VideoFormat& supported) {
-  int64 distance = kMaxDistance;
-
-  // Check fourcc.
-  uint32 supported_fourcc = CanonicalFourCC(supported.fourcc);
-  int64 delta_fourcc = kMaxDistance;
-  if (FOURCC_ANY == desired.fourcc) {
-    // Any fourcc is OK for the desired. Use preference to find best fourcc.
-    std::vector<uint32> preferred_fourccs;
-    if (!GetPreferredFourccs(&preferred_fourccs)) {
-      return distance;
-    }
-
-    for (size_t i = 0; i < preferred_fourccs.size(); ++i) {
-      if (supported_fourcc == CanonicalFourCC(preferred_fourccs[i])) {
-        delta_fourcc = i;
-        break;
-      }
-    }
-  } else if (supported_fourcc == CanonicalFourCC(desired.fourcc)) {
-    delta_fourcc = 0;  // Need exact match.
-  }
-
-  if (kMaxDistance == delta_fourcc) {
-    // Failed to match fourcc.
-    return distance;
-  }
-
-  // Check resolution and fps.
-  int desired_width = desired.width;
-  int desired_height = desired.height;
-#ifdef OSX
-  // QVGA on OSX is not well supported.  For 16x10, if 320x240 is used, it has
-  // 15x11 pixel aspect ratio on logitech B910/C260 and others.  ComputeCrop
-  // in mediaengine does not crop, so we keep 320x240, which magiccam on Mac
-  // can not display.  Some other viewers can display 320x240, but do not
-  // support pixel aspect ratio and appear distorted.
-  // This code below bumps the preferred resolution to VGA, maintaining aspect
-  // ratio. ie 320x200 -> 640x400.  VGA on logitech and most cameras is 1x1
-  // pixel aspect ratio.  The camera will capture 640x480, ComputeCrop will
-  // crop to 640x400, and the adapter will scale down to QVGA due to JUP view
-  // request.
-  static const int kMinWidth = 640;
-  if (desired_width > 0 && desired_width < kMinWidth) {
-    int new_desired_height = desired_height * kMinWidth / desired_width;
-    LOG(LS_VERBOSE) << " Changed desired from "
-                    << desired_width << "x" << desired_height
-                    << " To "
-                    << kMinWidth << "x" << new_desired_height;
-    desired_width = kMinWidth;
-    desired_height = new_desired_height;
-  }
-#endif
-  int64 delta_w = supported.width - desired_width;
-  int64 supported_fps = VideoFormat::IntervalToFps(supported.interval);
-  int64 delta_fps = supported_fps -
-      VideoFormat::IntervalToFps(desired.interval);
-  // Check height of supported height compared to height we would like it to be.
-  int64 aspect_h = desired_width ?
-      supported.width * desired_height / desired_width : desired_height;
-  int64 delta_h = supported.height - aspect_h;
-
-  distance = 0;
-  // Set high penalty if the supported format is lower than the desired format.
-  // 3x means we would prefer down to down to 3/4, than up to double.
-  // But we'd prefer up to double than down to 1/2.  This is conservative,
-  // strongly avoiding going down in resolution, similar to
-  // the old method, but not completely ruling it out in extreme situations.
-  // It also ignores framerate, which is often very low at high resolutions.
-  // TODO: Improve logic to use weighted factors.
-  static const int kDownPenalty = -3;
-  if (delta_w < 0) {
-    delta_w = delta_w * kDownPenalty;
-  }
-  if (delta_h < 0) {
-    delta_h = delta_h * kDownPenalty;
-  }
-  if (delta_fps < 0) {
-    // For same resolution, prefer higher framerate but accept lower.
-    // Otherwise prefer higher resolution.
-    distance |= static_cast<int64>(1) << 15;
-    delta_fps = -delta_fps;
-    if (supported_fps <  kMinDesirableFps) {
-      distance |= kMaxDistance;
-    }
-  }
-
-  // 12 bits for width and height and 8 bits for fps and fourcc.
-  distance |= (delta_w << 28) | (delta_h << 16) |
-      (delta_fps << 8) | delta_fourcc;
-
-  return distance;
-}
-
-bool VideoCapturer::Includes16x9HD(const std::vector<VideoFormat>& formats) {
-  std::vector<VideoFormat>::const_iterator i;
-  for (i = formats.begin(); i != formats.end(); ++i) {
-    if ((i->height >= 720) && (i->width * 9 == i->height * 16)) {
-      return true;
-    }
-  }
-  return false;
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/session/phone/videocapturer.h b/third_party/libjingle/source/talk/session/phone/videocapturer.h
deleted file mode 100644
index 93e5152..0000000
--- a/third_party/libjingle/source/talk/session/phone/videocapturer.h
+++ /dev/null
@@ -1,210 +0,0 @@
-// libjingle
-// Copyright 2010 Google Inc.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-//  1. Redistributions of source code must retain the above copyright notice,
-//     this list of conditions and the following disclaimer.
-//  2. Redistributions in binary form must reproduce the above copyright notice,
-//     this list of conditions and the following disclaimer in the documentation
-//     and/or other materials provided with the distribution.
-//  3. The name of the author may not be used to endorse or promote products
-//     derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Declaration of abstract class VideoCapturer
-
-#ifndef TALK_SESSION_PHONE_VIDEOCAPTURER_H_
-#define TALK_SESSION_PHONE_VIDEOCAPTURER_H_
-
-#include <string>
-#include <vector>
-
-#include "talk/base/basictypes.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/base/sigslot.h"
-#include "talk/session/phone/devicemanager.h"
-#include "talk/session/phone/videocommon.h"
-
-namespace cricket {
-
-// General capturer events.
-enum CaptureEvent {
-  // CE_FAILED = -1
-  // CE_STARTED = 0
-  CE_STOPPED = 1,
-  CE_PAUSED = 2,
-  CE_RESUMED = 3
-};
-
-struct CapturedFrame {
-  static const uint32 kFrameHeaderSize = 40;  // Size from width to data_size.
-  static const uint32 kUnknownDataSize = 0xFFFFFFFF;
-
-  CapturedFrame();
-
-  // Get the number of bytes of the frame data. If data_size is known, return
-  // it directly. Otherwise, calculate the size based on width, height, and
-  // fourcc. Return true if succeeded.
-  bool GetDataSize(uint32* size) const;
-
-  // The width and height of the captured frame could be different from those
-  // of VideoFormat. Once the first frame is captured, the width, height,
-  // fourcc, pixel_width, and pixel_height should keep the same over frames.
-  int    width;         // in number of pixels
-  int    height;        // in number of pixels
-  uint32 fourcc;        // compression
-  uint32 pixel_width;   // width of a pixel, default is 1
-  uint32 pixel_height;  // height of a pixel, default is 1
-  int64  elapsed_time;  // elapsed time since the creation of the frame
-                        // source (that is, the camera), in nanoseconds.
-  int64  time_stamp;    // timestamp of when the frame was captured, in
-                        // nanoseconds.
-  uint32 data_size;     // number of bytes of the frame data
-  int    rotation;      // rotation in degrees of the frame (0, 90, 180, 270)
-  void*  data;          // pointer to the frame data. This object allocates the
-                        // memory or points to an existing memory.
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(CapturedFrame);
-};
-
-// VideoCapturer is an abstract class that defines the interfaces for video
-// capturing. The subclasses implement the video capturer for various platforms.
-//
-// The captured frames may need to be adapted (for example, cropping). Such an
-// adaptor is out of the scope of VideoCapturer. If the adaptor is needed, it
-// acts as the downstream of VideoCapturer, adapts the captured frames, and
-// delivers the adapted frames to other components such as the encoder.
-//
-// Programming model:
-//   Create and initialize an object of a subclass of VideoCapturer
-//   SignalStartResult.connect()
-//   SignalFrameCaptured.connect()
-//   Find the capture format for Start() by either calling GetSupportedFormats()
-//   and selecting one of the supported or calling GetBestCaptureFormat().
-//   Start()
-//   GetCaptureFormat() optionally
-//   Stop()
-//
-// Assumption:
-//   The Start() and Stop() methods are called by a single thread (that is, the
-//   media engine thread). Hence, there is no need to make them thread safe.
-//
-class VideoCapturer {
- public:
-  VideoCapturer() {}
-  virtual ~VideoCapturer() {}
-
-  // Gets the id of the underlying device, which is available after the capturer
-  // is initialized. Can be used to determine if two capturers reference the
-  // same device.
-  const std::string& GetId() const { return id_; }
-
-  // Get the capture formats supported by the video capturer. The supported
-  // formats are available after the device is opened successfully.
-  // Return NULL if the supported formats are not available.
-  const std::vector<VideoFormat>* GetSupportedFormats() const {
-    return supported_formats_.get();
-  }
-
-  // Get the best capture format for the desired format. The best format is the
-  // same as one of the supported formats except that the frame interval may be
-  // different. If the application asks for 16x9 and the camera does not support
-  // 16x9 HD or the application asks for 16x10, we find the closest 4x3 and then
-  // crop; Otherwise, we find what the application asks for. Note that we assume
-  // that for HD, the desired format is always 16x9. The subclasses can override
-  // the default implementation.
-  // Parameters
-  //   desired: the input desired format. If desired.fourcc is not kAnyFourcc,
-  //            the best capture format has the exactly same fourcc. Otherwise,
-  //            the best capture format uses a fourcc in GetPreferredFourccs().
-  //   best_format: the output of the best capture format.
-  // Return false if there is no such a best format, that is, the desired format
-  // is not supported.
-  virtual bool GetBestCaptureFormat(const VideoFormat& desired,
-                                    VideoFormat* best_format);
-
-  // Start the video capturer with the specified capture format.
-  // Parameter
-  //   capture_format: The caller got this parameter by either calling
-  //                   GetSupportedFormats() and selecting one of the supported
-  //                   or calling GetBestCaptureFormat().
-  // Return
-  //   CR_SUCCESS:   if the capturer starts successfully.
-  //   CR_PENDING:   if the capturer is pending to start. SignalStartResult
-  //                 below will signal the result after the pending.
-  //   CR_NO_DEVICE: if the capturer has no device and fails to start.
-  //   CR_FAILURE:   otherwise.
-  virtual CaptureResult Start(const VideoFormat& capture_format) = 0;
-
-  // Get the current capture format, which is set by the Start() call.
-  // Note that the width and height of the captured frames may differ from the
-  // capture format. For example, the capture format is HD but the captured
-  // frames may be smaller than HD.
-  const VideoFormat* GetCaptureFormat() const {
-    return capture_format_.get();
-  }
-
-  // Stop the video capturer.
-  virtual void Stop() = 0;
-  // Check if the video capturer is running.
-  virtual bool IsRunning() = 0;
-
-  // Signal the result of Start() if it returned CR_PENDING.
-  sigslot::signal2<VideoCapturer*, CaptureResult> SignalStartResult;
-  // Signal the captured frame to downstream.
-  sigslot::signal2<VideoCapturer*, const CapturedFrame*> SignalFrameCaptured;
-  // Signals a change in capturer state.
-  sigslot::signal2<VideoCapturer*, CaptureEvent> SignalCaptureEvent;
-
- protected:
-  // subclasses override this virtual method to provide a vector of fourccs, in
-  // order of preference, that are expected by the media engine.
-  virtual bool GetPreferredFourccs(std::vector<uint32>* fourccs) = 0;
-
-  // mutators to set private attributes
-  void SetId(const std::string& id) {
-    id_ = id;
-  }
-
-  void SetCaptureFormat(const VideoFormat* format) {
-    capture_format_.reset(format ? new VideoFormat(*format) : NULL);
-  }
-
-  void SetSupportedFormats(const std::vector<VideoFormat>& formats);
-
- private:
-  // Check if the specified formats include a format with height no less than
-  // 720 and aspect ratio 16x9. In such a case, if we open the camera in 4x3 and
-  // crop to 16x9, the camera or driver may crop from 16x9 to 4x3 and then our
-  // code crop again from 4x3 to 16x9, which is not good.
-  static bool Includes16x9HD(const std::vector<VideoFormat>& formats);
-
-  // Get the distance between the desired format and the supported format.
-  // Return the max distance if they mismatch. See the implementation for
-  // details.
-  int64 GetFormatDistance(const VideoFormat& desired,
-                          const VideoFormat& supported);
-
-  std::string id_;
-  talk_base::scoped_ptr<VideoFormat> capture_format_;
-  talk_base::scoped_ptr<std::vector<VideoFormat> > supported_formats_;
-
-  DISALLOW_COPY_AND_ASSIGN(VideoCapturer);
-};
-
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_VIDEOCAPTURER_H_
diff --git a/third_party/libjingle/source/talk/session/phone/videocapturer_unittest.cc b/third_party/libjingle/source/talk/session/phone/videocapturer_unittest.cc
deleted file mode 100644
index 1b73b15..0000000
--- a/third_party/libjingle/source/talk/session/phone/videocapturer_unittest.cc
+++ /dev/null
@@ -1,416 +0,0 @@
-// Copyright 2008 Google Inc. All Rights Reserved
-
-#include <stdio.h>
-#include <vector>
-
-#include "talk/base/gunit.h"
-#include "talk/base/logging.h"
-#include "talk/base/thread.h"
-#include "talk/session/phone/videocapturer.h"
-#include "talk/session/phone/testutils.h"
-
-namespace {
-
-class FakeVideoCapturer : public cricket::VideoCapturer {
- public:
-  FakeVideoCapturer() {
-    // Default supported formats. Use ResetSupportedFormats to over write.
-    std::vector<cricket::VideoFormat> formats;
-    formats.push_back(cricket::VideoFormat(640, 480,
-        cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
-    formats.push_back(cricket::VideoFormat(320, 240,
-        cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
-    ResetSupportedFormats(formats);
-  }
-  ~FakeVideoCapturer() {}
-
-  void ResetSupportedFormats(const std::vector<cricket::VideoFormat>& formats) {
-    SetSupportedFormats(formats);
-  }
-  virtual cricket::CaptureResult Start(const cricket::VideoFormat& format) {
-    return cricket::CR_SUCCESS;
-  }
-  virtual void Stop() {}
-  virtual bool IsRunning() { return true; }
-  bool GetPreferredFourccs(std::vector<uint32>* fourccs) {
-    fourccs->push_back(cricket::FOURCC_I420);
-    fourccs->push_back(cricket::FOURCC_MJPG);
-    return true;
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(FakeVideoCapturer);
-};
-
-TEST(VideoCapturerTest, TestFourccMatch) {
-  FakeVideoCapturer capturer;
-  cricket::VideoFormat desired(640, 480,
-                               cricket::VideoFormat::FpsToInterval(30),
-                               cricket::FOURCC_ANY);
-  cricket::VideoFormat best;
-  EXPECT_TRUE(capturer.GetBestCaptureFormat(desired, &best));
-  EXPECT_EQ(640, best.width);
-  EXPECT_EQ(480, best.height);
-  EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval);
-
-  desired.fourcc = cricket::FOURCC_MJPG;
-  EXPECT_FALSE(capturer.GetBestCaptureFormat(desired, &best));
-
-  desired.fourcc = cricket::FOURCC_I420;
-  EXPECT_TRUE(capturer.GetBestCaptureFormat(desired, &best));
-}
-
-TEST(VideoCapturerTest, TestResolutionMatch) {
-  FakeVideoCapturer capturer;
-  cricket::VideoFormat desired(960, 720,
-                               cricket::VideoFormat::FpsToInterval(30),
-                               cricket::FOURCC_ANY);
-  cricket::VideoFormat best;
-  // Ask for 960x720. Get VGA which is the highest.
-  EXPECT_TRUE(capturer.GetBestCaptureFormat(desired, &best));
-  EXPECT_EQ(640, best.width);
-  EXPECT_EQ(480, best.height);
-  EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval);
-
-  desired.width = 360;
-  desired.height = 250;
-  // Ask for a little higher than QVGA. Get QVGA.  On OSX gets VGA
-  EXPECT_TRUE(capturer.GetBestCaptureFormat(desired, &best));
-#ifdef OSX
-  EXPECT_EQ(640, best.width);
-  EXPECT_EQ(480, best.height);
-#else
-  EXPECT_EQ(320, best.width);
-  EXPECT_EQ(240, best.height);
-#endif
-  EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval);
-
-  desired.width = 480;
-  desired.height = 270;
-  // Ask for HVGA. Get VGA.
-  EXPECT_TRUE(capturer.GetBestCaptureFormat(desired, &best));
-  EXPECT_EQ(640, best.width);
-  EXPECT_EQ(480, best.height);
-  EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval);
-
-  desired.width = 320;
-  desired.height = 240;
-  // Ask for QVGA. Get QVGA.  On OSX get VGA
-  EXPECT_TRUE(capturer.GetBestCaptureFormat(desired, &best));
-#ifdef OSX
-  EXPECT_EQ(640, best.width);
-  EXPECT_EQ(480, best.height);
-#else
-  EXPECT_EQ(320, best.width);
-  EXPECT_EQ(240, best.height);
-#endif
-  EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval);
-
-  desired.width = 160;
-  desired.height = 120;
-  // Ask for lower than QVGA. Get QVGA, which is the lowest.  OSX gets VGA
-  EXPECT_TRUE(capturer.GetBestCaptureFormat(desired, &best));
-#ifdef OSX
-  EXPECT_EQ(640, best.width);
-  EXPECT_EQ(480, best.height);
-#else
-  EXPECT_EQ(320, best.width);
-  EXPECT_EQ(240, best.height);
-#endif
-  EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval);
-}
-
-TEST(VideoCapturerTest, TestHDResolutionMatch) {
-  FakeVideoCapturer capturer;
-
-  // Add some HD formats
-  std::vector<cricket::VideoFormat> formats;
-  formats.push_back(cricket::VideoFormat(320, 240,
-      cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
-  formats.push_back(cricket::VideoFormat(640, 480,
-      cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
-  formats.push_back(cricket::VideoFormat(960, 544,
-      cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
-  formats.push_back(cricket::VideoFormat(2592, 1944,
-      cricket::VideoFormat::FpsToInterval(15), cricket::FOURCC_I420));
-  capturer.ResetSupportedFormats(formats);
-
-  cricket::VideoFormat desired(960, 720,
-                               cricket::VideoFormat::FpsToInterval(30),
-                               cricket::FOURCC_ANY);
-  cricket::VideoFormat best;
-  // Ask for 960x720. Get qHD
-  EXPECT_TRUE(capturer.GetBestCaptureFormat(desired, &best));
-  EXPECT_EQ(960, best.width);
-  EXPECT_EQ(544, best.height);
-  EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval);
-
-  desired.width = 360;
-  desired.height = 250;
-  // Ask for a litter higher than QVGA. Get QVGA.  OSX gets VGA
-  EXPECT_TRUE(capturer.GetBestCaptureFormat(desired, &best));
-#ifdef OSX
-  EXPECT_EQ(640, best.width);
-  EXPECT_EQ(480, best.height);
-#else
-  EXPECT_EQ(320, best.width);
-  EXPECT_EQ(240, best.height);
-#endif
-  EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval);
-
-  desired.width = 480;
-  desired.height = 270;
-  // Ask for HVGA. Get VGA.
-  EXPECT_TRUE(capturer.GetBestCaptureFormat(desired, &best));
-  EXPECT_EQ(640, best.width);
-  EXPECT_EQ(480, best.height);
-  EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval);
-
-  desired.width = 320;
-  desired.height = 240;
-  // Ask for QVGA. Get QVGA.  OSX gets VGA
-  EXPECT_TRUE(capturer.GetBestCaptureFormat(desired, &best));
-#ifdef OSX
-  EXPECT_EQ(640, best.width);
-  EXPECT_EQ(480, best.height);
-#else
-  EXPECT_EQ(320, best.width);
-  EXPECT_EQ(240, best.height);
-#endif
-  EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval);
-
-  desired.width = 160;
-  desired.height = 120;
-  // Ask for lower than QVGA. Get QVGA, which is the lowest.
-  EXPECT_TRUE(capturer.GetBestCaptureFormat(desired, &best));
-#ifdef OSX
-  EXPECT_EQ(640, best.width);
-  EXPECT_EQ(480, best.height);
-#else
-  EXPECT_EQ(320, best.width);
-  EXPECT_EQ(240, best.height);
-#endif
-  EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval);
-
-  desired.width = 1280;
-  desired.height = 720;
-  // Ask for HD. Get qHD.
-  EXPECT_TRUE(capturer.GetBestCaptureFormat(desired, &best));
-  EXPECT_EQ(960, best.width);
-  EXPECT_EQ(544, best.height);
-  EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval);
-
-  desired.width = 1920;
-  desired.height = 1080;
-  // Ask for 1080p. Get 2592x1944x15.
-  EXPECT_TRUE(capturer.GetBestCaptureFormat(desired, &best));
-  EXPECT_EQ(2592, best.width);
-  EXPECT_EQ(1944, best.height);
-  EXPECT_EQ(cricket::VideoFormat::FpsToInterval(15), best.interval);
-}
-
-// Some cameras support 320x240 and 320x640. Verify we choose 320x240.
-// On OSX we choose VGA
-TEST(VideoCapturerTest, TestStrangeFormats) {
-  FakeVideoCapturer capturer;
-  std::vector<cricket::VideoFormat> supported_formats;
-  supported_formats.push_back(cricket::VideoFormat(320, 240,
-      cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
-  supported_formats.push_back(cricket::VideoFormat(320, 640,
-      cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
-  capturer.ResetSupportedFormats(supported_formats);
-
-  std::vector<cricket::VideoFormat> required_formats;
-  required_formats.push_back(cricket::VideoFormat(320, 240,
-      cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
-  required_formats.push_back(cricket::VideoFormat(320, 200,
-      cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
-  required_formats.push_back(cricket::VideoFormat(320, 180,
-      cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
-  cricket::VideoFormat best;
-  for (size_t i = 0; i < required_formats.size(); ++i) {
-    EXPECT_TRUE(capturer.GetBestCaptureFormat(required_formats[i], &best));
-    EXPECT_EQ(320, best.width);
-    EXPECT_EQ(240, best.height);
-  }
-
-  supported_formats.clear();
-  supported_formats.push_back(cricket::VideoFormat(320, 640,
-      cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
-  supported_formats.push_back(cricket::VideoFormat(320, 240,
-      cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
-  capturer.ResetSupportedFormats(supported_formats);
-
-  for (size_t i = 0; i < required_formats.size(); ++i) {
-    EXPECT_TRUE(capturer.GetBestCaptureFormat(required_formats[i], &best));
-    EXPECT_EQ(320, best.width);
-    EXPECT_EQ(240, best.height);
-  }
-}
-
-// Some cameras support same size with different frame rates. Verify we choose
-// the frame rate properly.
-TEST(VideoCapturerTest, TestSameSizeDifferentFpsFormats) {
-  FakeVideoCapturer capturer;
-  std::vector<cricket::VideoFormat> supported_formats;
-  supported_formats.push_back(cricket::VideoFormat(320, 240,
-      cricket::VideoFormat::FpsToInterval(10), cricket::FOURCC_I420));
-  supported_formats.push_back(cricket::VideoFormat(320, 240,
-      cricket::VideoFormat::FpsToInterval(20), cricket::FOURCC_I420));
-  supported_formats.push_back(cricket::VideoFormat(320, 240,
-      cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
-  capturer.ResetSupportedFormats(supported_formats);
-
-  std::vector<cricket::VideoFormat> required_formats = supported_formats;
-  cricket::VideoFormat best;
-  for (size_t i = 0; i < required_formats.size(); ++i) {
-    EXPECT_TRUE(capturer.GetBestCaptureFormat(required_formats[i], &best));
-    EXPECT_EQ(320, best.width);
-    EXPECT_EQ(240, best.height);
-    EXPECT_EQ(required_formats[i].interval, best.interval);
-  }
-}
-
-// Some cameras support the correct resolution but at a lower fps than
-// we'd like.  This tests we get the expected resolution and fps.
-TEST(VideoCapturerTest, TestFpsFormats) {
-  FakeVideoCapturer capturer;
-  // We have VGA but low fps.  Choose VGA, not HD
-  std::vector<cricket::VideoFormat> supported_formats;
-  supported_formats.push_back(cricket::VideoFormat(1280, 720,
-      cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
-  supported_formats.push_back(cricket::VideoFormat(640, 480,
-      cricket::VideoFormat::FpsToInterval(15), cricket::FOURCC_I420));
-  supported_formats.push_back(cricket::VideoFormat(640, 400,
-      cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
-  supported_formats.push_back(cricket::VideoFormat(640, 360,
-      cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
-  capturer.ResetSupportedFormats(supported_formats);
-
-  std::vector<cricket::VideoFormat> required_formats;
-  required_formats.push_back(cricket::VideoFormat(640, 480,
-      cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_ANY));
-  required_formats.push_back(cricket::VideoFormat(640, 480,
-      cricket::VideoFormat::FpsToInterval(20), cricket::FOURCC_ANY));
-  required_formats.push_back(cricket::VideoFormat(640, 480,
-      cricket::VideoFormat::FpsToInterval(10), cricket::FOURCC_ANY));
-  cricket::VideoFormat best;
-
-  // expect 30 fps to choose 15 fps format
-  EXPECT_TRUE(capturer.GetBestCaptureFormat(required_formats[0], &best));
-  EXPECT_EQ(640, best.width);
-  EXPECT_EQ(480, best.height);
-  EXPECT_EQ(cricket::VideoFormat::FpsToInterval(15), best.interval);
-
-  // expect 20 fps to choose 15 fps format
-  EXPECT_TRUE(capturer.GetBestCaptureFormat(required_formats[1], &best));
-  EXPECT_EQ(640, best.width);
-  EXPECT_EQ(480, best.height);
-  EXPECT_EQ(cricket::VideoFormat::FpsToInterval(15), best.interval);
-
-  // expect 10 fps to choose 15 fps format but set fps to 10
-  EXPECT_TRUE(capturer.GetBestCaptureFormat(required_formats[2], &best));
-  EXPECT_EQ(640, best.width);
-  EXPECT_EQ(480, best.height);
-  EXPECT_EQ(cricket::VideoFormat::FpsToInterval(10), best.interval);
-
-  // We have VGA 60 fps and 15 fps.  Choose best fps.
-  supported_formats.clear();
-  supported_formats.push_back(cricket::VideoFormat(1280, 720,
-      cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
-  supported_formats.push_back(cricket::VideoFormat(640, 480,
-      cricket::VideoFormat::FpsToInterval(60), cricket::FOURCC_MJPG));
-  supported_formats.push_back(cricket::VideoFormat(640, 480,
-      cricket::VideoFormat::FpsToInterval(15), cricket::FOURCC_I420));
-  supported_formats.push_back(cricket::VideoFormat(640, 400,
-      cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
-  supported_formats.push_back(cricket::VideoFormat(640, 360,
-      cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
-  capturer.ResetSupportedFormats(supported_formats);
-
-  // expect 30 fps to choose 60 fps format, but will set best fps to 30
-  EXPECT_TRUE(capturer.GetBestCaptureFormat(required_formats[0], &best));
-  EXPECT_EQ(640, best.width);
-  EXPECT_EQ(480, best.height);
-  EXPECT_EQ(cricket::VideoFormat::FpsToInterval(30), best.interval);
-
-  // expect 20 fps to choose 60 fps format, but will set best fps to 20
-  EXPECT_TRUE(capturer.GetBestCaptureFormat(required_formats[1], &best));
-  EXPECT_EQ(640, best.width);
-  EXPECT_EQ(480, best.height);
-  EXPECT_EQ(cricket::VideoFormat::FpsToInterval(20), best.interval);
-
-  // expect 10 fps to choose 10 fps
-  EXPECT_TRUE(capturer.GetBestCaptureFormat(required_formats[2], &best));
-  EXPECT_EQ(640, best.width);
-  EXPECT_EQ(480, best.height);
-  EXPECT_EQ(cricket::VideoFormat::FpsToInterval(10), best.interval);
-}
-
-TEST(VideoCapturerTest, TestRequest16x10_9) {
-  FakeVideoCapturer capturer;
-  std::vector<cricket::VideoFormat> supported_formats;
-  // We do not support HD, expect 4x3 for 4x3, 16x10, and 16x9 requests.
-  supported_formats.push_back(cricket::VideoFormat(640, 480,
-      cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
-  supported_formats.push_back(cricket::VideoFormat(640, 400,
-      cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
-  supported_formats.push_back(cricket::VideoFormat(640, 360,
-      cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
-  capturer.ResetSupportedFormats(supported_formats);
-
-  std::vector<cricket::VideoFormat> required_formats = supported_formats;
-  cricket::VideoFormat best;
-  // Expect 4x3 for 4x3, 16x10, and 16x9 requests.
-  for (size_t i = 0; i < required_formats.size(); ++i) {
-    EXPECT_TRUE(capturer.GetBestCaptureFormat(required_formats[i], &best));
-    EXPECT_EQ(640, best.width);
-    EXPECT_EQ(480, best.height);
-  }
-
-  // We do not support 16x9 HD, expect 4x3 for 4x3, 16x10, and 16x9 requests.
-  supported_formats.clear();
-  supported_formats.push_back(cricket::VideoFormat(960, 720,
-      cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
-  supported_formats.push_back(cricket::VideoFormat(640, 480,
-      cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
-  supported_formats.push_back(cricket::VideoFormat(640, 400,
-      cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
-  supported_formats.push_back(cricket::VideoFormat(640, 360,
-      cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
-  capturer.ResetSupportedFormats(supported_formats);
-
-  // Expect 4x3 for 4x3, 16x10, and 16x9 requests.
-  for (size_t i = 0; i < required_formats.size(); ++i) {
-    EXPECT_TRUE(capturer.GetBestCaptureFormat(required_formats[i], &best));
-    EXPECT_EQ(640, best.width);
-    EXPECT_EQ(480, best.height);
-  }
-
-  // We support 16x9HD, expect 4x3 for 4x3 and 16x10 requests and expect 16x9
-  // for 16x9 request.
-  supported_formats.clear();
-  supported_formats.push_back(cricket::VideoFormat(1280, 720,
-      cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
-  supported_formats.push_back(cricket::VideoFormat(640, 480,
-      cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
-  supported_formats.push_back(cricket::VideoFormat(640, 400,
-      cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
-  supported_formats.push_back(cricket::VideoFormat(640, 360,
-      cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
-  capturer.ResetSupportedFormats(supported_formats);
-
-  // Expect 4x3 for 4x3 and 16x10 requests.
-  for (size_t i = 0; i < required_formats.size() - 1; ++i) {
-    EXPECT_TRUE(capturer.GetBestCaptureFormat(required_formats[i], &best));
-    EXPECT_EQ(640, best.width);
-    EXPECT_EQ(480, best.height);
-  }
-
-  // Expect 16x9 for 16x9 request.
-  EXPECT_TRUE(capturer.GetBestCaptureFormat(required_formats[2], &best));
-  EXPECT_EQ(640, best.width);
-  EXPECT_EQ(360, best.height);
-}
-
-}  // unnamed namespace
diff --git a/third_party/libjingle/source/talk/session/phone/videocommon.cc b/third_party/libjingle/source/talk/session/phone/videocommon.cc
deleted file mode 100644
index 0d07ef1..0000000
--- a/third_party/libjingle/source/talk/session/phone/videocommon.cc
+++ /dev/null
@@ -1,90 +0,0 @@
-// libjingle
-// Copyright 2010 Google Inc.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-//  1. Redistributions of source code must retain the above copyright notice,
-//     this list of conditions and the following disclaimer.
-//  2. Redistributions in binary form must reproduce the above copyright notice,
-//     this list of conditions and the following disclaimer in the documentation
-//     and/or other materials provided with the distribution.
-//  3. The name of the author may not be used to endorse or promote products
-//     derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include "talk/session/phone/videocommon.h"
-
-#include <sstream>
-
-#include "talk/base/common.h"
-
-namespace cricket {
-
-struct FourCCAliasEntry {
-  uint32 alias;
-  uint32 canonical;
-};
-
-static const FourCCAliasEntry kFourCCAliases[] = {
-  {FOURCC_IYUV, FOURCC_I420},
-  {FOURCC_YU12, FOURCC_I420},
-  {FOURCC_YU16, FOURCC_I422},
-  {FOURCC_YU24, FOURCC_I444},
-  {FOURCC_YUYV, FOURCC_YUY2},
-  {FOURCC_YUVS, FOURCC_YUY2},
-  {FOURCC_HDYC, FOURCC_UYVY},
-  {FOURCC_2VUY, FOURCC_UYVY},
-  {FOURCC_BA81, FOURCC_BGGR},
-  {FOURCC_JPEG, FOURCC_MJPG},  // Note: JPEG has DHT while MJPG does not.
-  {FOURCC_DMB1, FOURCC_MJPG},
-  {FOURCC_RGB3, FOURCC_RAW},
-  {FOURCC_BGR3, FOURCC_24BG},
-};
-
-uint32 CanonicalFourCC(uint32 fourcc) {
-  for (int i = 0; i < ARRAY_SIZE(kFourCCAliases); ++i) {
-    if (kFourCCAliases[i].alias == fourcc) {
-      return kFourCCAliases[i].canonical;
-    }
-  }
-  // Not an alias, so return it as-is.
-  return fourcc;
-}
-
-// The C++ standard requires a namespace-scope definition of static const
-// integral types even when they are initialized in the declaration (see
-// [class.static.data]/4), but MSVC with /Ze is non-conforming and treats that
-// as a multiply defined symbol error (see
-// http://msdn.microsoft.com/en-us/library/34h23df8.aspx).
-#ifndef _MSC_EXTENSIONS
-const int64 VideoFormat::kMinimumInterval;  // Initialized in header.
-#endif
-
-std::string VideoFormat::ToString() const {
-  std::string fourcc_name = GetFourccName(fourcc) + " ";
-  for (std::string::const_iterator i = fourcc_name.begin();
-      i < fourcc_name.end(); ++i) {
-    // Test character is printable; Avoid isprint() which asserts on negatives
-    if (*i < 32 || *i >= 127) {
-      fourcc_name = "";
-      break;
-    }
-  }
-
-  std::ostringstream ss;
-  ss << fourcc_name << width << "x" << height << "x" << IntervalToFps(interval);
-  return ss.str();
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/session/phone/videocommon.h b/third_party/libjingle/source/talk/session/phone/videocommon.h
deleted file mode 100644
index fb1f393..0000000
--- a/third_party/libjingle/source/talk/session/phone/videocommon.h
+++ /dev/null
@@ -1,210 +0,0 @@
-// libjingle
-// Copyright 2004 Google Inc.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-//  1. Redistributions of source code must retain the above copyright notice,
-//     this list of conditions and the following disclaimer.
-//  2. Redistributions in binary form must reproduce the above copyright notice,
-//     this list of conditions and the following disclaimer in the documentation
-//     and/or other materials provided with the distribution.
-//  3. The name of the author may not be used to endorse or promote products
-//     derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Common definition for video, including fourcc and VideoFormat
-
-#ifndef TALK_SESSION_PHONE_VIDEOCOMMON_H_
-#define TALK_SESSION_PHONE_VIDEOCOMMON_H_
-
-#include <string>
-
-#include "talk/base/basictypes.h"
-#include "talk/base/timeutils.h"
-
-namespace cricket {
-
-//////////////////////////////////////////////////////////////////////////////
-// Definition of fourcc.
-//////////////////////////////////////////////////////////////////////////////
-// Convert four characters to a fourcc code.
-// Needs to be a macro otherwise the OS X compiler complains when the kFormat*
-// constants are used in a switch.
-#define FOURCC(a, b, c, d) (\
-    (static_cast<uint32>(a)) | (static_cast<uint32>(b) << 8) | \
-    (static_cast<uint32>(c) << 16) | (static_cast<uint32>(d) << 24))
-
-// Get the name, that is, string with four characters, of a fourcc code.
-inline std::string GetFourccName(uint32 fourcc) {
-  std::string name;
-  name.push_back(static_cast<char>(fourcc & 0xFF));
-  name.push_back(static_cast<char>((fourcc >> 8) & 0xFF));
-  name.push_back(static_cast<char>((fourcc >> 16) & 0xFF));
-  name.push_back(static_cast<char>((fourcc >> 24) & 0xFF));
-  return name;
-}
-
-// FourCC codes used in Google Talk.
-// Some good pages discussing FourCC codes:
-//   http://developer.apple.com/quicktime/icefloe/dispatch020.html
-//   http://www.fourcc.org/yuv.php
-enum FourCC {
-  // Canonical fourcc codes used in our code.
-  FOURCC_I420 = FOURCC('I', '4', '2', '0'),
-  FOURCC_I422 = FOURCC('I', '4', '2', '2'),
-  FOURCC_I444 = FOURCC('I', '4', '4', '4'),
-  FOURCC_YV12 = FOURCC('Y', 'V', '1', '2'),
-  FOURCC_YV16 = FOURCC('Y', 'V', '1', '6'),
-  FOURCC_YV24 = FOURCC('Y', 'V', '2', '4'),
-  FOURCC_YUY2 = FOURCC('Y', 'U', 'Y', '2'),
-  FOURCC_UYVY = FOURCC('U', 'Y', 'V', 'Y'),
-  FOURCC_M420 = FOURCC('M', '4', '2', '0'),
-  FOURCC_Q420 = FOURCC('Q', '4', '2', '0'),
-  FOURCC_24BG = FOURCC('2', '4', 'B', 'G'),
-  FOURCC_ABGR = FOURCC('A', 'B', 'G', 'R'),
-  FOURCC_BGRA = FOURCC('B', 'G', 'R', 'A'),
-  FOURCC_ARGB = FOURCC('A', 'R', 'G', 'B'),
-  FOURCC_MJPG = FOURCC('M', 'J', 'P', 'G'),
-  FOURCC_RAW  = FOURCC('r', 'a', 'w', ' '),
-  FOURCC_NV21 = FOURCC('N', 'V', '2', '1'),
-  FOURCC_NV12 = FOURCC('N', 'V', '1', '2'),
-  // Next four are Bayer RGB formats. The four characters define the order of
-  // the colours in each 2x2 pixel grid, going left-to-right and top-to-bottom.
-  FOURCC_RGGB = FOURCC('R', 'G', 'G', 'B'),
-  FOURCC_BGGR = FOURCC('B', 'G', 'G', 'R'),
-  FOURCC_GRBG = FOURCC('G', 'R', 'B', 'G'),
-  FOURCC_GBRG = FOURCC('G', 'B', 'R', 'G'),
-
-  // Aliases for canonical fourcc codes, replaced with their canonical
-  // equivalents by CanonicalFourCC().
-  FOURCC_IYUV = FOURCC('I', 'Y', 'U', 'V'),  // Alias for I420
-  FOURCC_YU12 = FOURCC('Y', 'U', '1', '2'),  // Alias for I420
-  FOURCC_YU16 = FOURCC('Y', 'U', '1', '6'),  // Alias for I422
-  FOURCC_YU24 = FOURCC('Y', 'U', '2', '4'),  // Alias for I444
-  FOURCC_YUYV = FOURCC('Y', 'U', 'Y', 'V'),  // Alias for YUY2
-  FOURCC_YUVS = FOURCC('y', 'u', 'v', 's'),  // Alias for YUY2 on Mac
-  FOURCC_HDYC = FOURCC('H', 'D', 'Y', 'C'),  // Alias for UYVY
-  FOURCC_2VUY = FOURCC('2', 'v', 'u', 'y'),  // Alias for UYVY
-  FOURCC_JPEG = FOURCC('J', 'P', 'E', 'G'),  // Alias for MJPG
-  FOURCC_DMB1 = FOURCC('d', 'm', 'b', '1'),  // Alias for MJPG on Mac
-  FOURCC_BA81 = FOURCC('B', 'A', '8', '1'),  // Alias for BGGR
-  FOURCC_RGB3 = FOURCC('R', 'G', 'B', '3'),  // Alias for RAW
-  FOURCC_BGR3 = FOURCC('B', 'G', 'R', '3'),  // Alias for 24BG
-
-  // Match any fourcc.
-  FOURCC_ANY  = 0xFFFFFFFF,
-};
-
-// Converts fourcc aliases into canonical ones.
-uint32 CanonicalFourCC(uint32 fourcc);
-
-//////////////////////////////////////////////////////////////////////////////
-// Definition of VideoFormat.
-//////////////////////////////////////////////////////////////////////////////
-
-// VideoFormat with Plain Old Data for global variables
-struct VideoFormatPod {
-  int width;  // in number of pixels
-  int height;  // in number of pixels
-  int framerate;
-  uint32 fourcc;  // color space. FOURCC_ANY means that any color space is OK.
-};
-
-struct VideoFormat {
-  static const int64 kMinimumInterval =
-      talk_base::kNumNanosecsPerSec / 10000;  // 10k fps
-
-  VideoFormat() : width(0), height(0), interval(0), fourcc(0) {}
-
-  VideoFormat(int w, int h, int64 interval_ns, uint32 cc)
-      : width(w),
-        height(h),
-        interval(interval_ns),
-        fourcc(cc) {
-  }
-
-  VideoFormat(const VideoFormat& format)
-      : width(format.width),
-        height(format.height),
-        interval(format.interval),
-        fourcc(format.fourcc) {
-  }
-
-  explicit VideoFormat(const VideoFormatPod& format)
-      : width(format.width),
-        height(format.height),
-        interval(FpsToInterval(format.framerate)),
-        fourcc(format.fourcc) {
-  }
-
-  static int64 FpsToInterval(int fps) {
-    return fps ? talk_base::kNumNanosecsPerSec / fps : kMinimumInterval;
-  }
-
-  static int IntervalToFps(int64 interval) {
-    // Normalize the interval first.
-    interval = talk_base::_max(interval, kMinimumInterval);
-    return static_cast<int>(talk_base::kNumNanosecsPerSec / interval);
-  }
-
-  bool operator==(const VideoFormat& format) const {
-    return width == format.width && height == format.height &&
-        interval == format.interval && fourcc == format.fourcc;
-  }
-
-  bool operator!=(const VideoFormat& format) const {
-    return !(*this == format);
-  }
-
-  bool operator<(const VideoFormat& format) const {
-    return (fourcc < format.fourcc) ||
-        (fourcc == format.fourcc && width < format.width) ||
-        (fourcc == format.fourcc && width == format.width &&
-            height < format.height) ||
-        (fourcc == format.fourcc && width == format.width &&
-            height == format.height && interval > format.interval);
-  }
-
-  int framerate() const { return IntervalToFps(interval); }
-
-  // Check if both width and height are 0.
-  bool IsSize0x0() const { return 0 == width && 0 == height; }
-
-  // Check if this format is less than another one by comparing the resolution
-  // and frame rate.
-  bool IsPixelRateLess(const VideoFormat& format) const {
-    return width * height * framerate() <
-        format.width * format.height * format.framerate();
-  }
-
-  // Get a string presentation in the form of "fourcc width x height x fps"
-  std::string ToString() const;
-
-  int    width;     // in number of pixels
-  int    height;    // in number of pixels
-  int64  interval;  // in nanoseconds
-  uint32 fourcc;    // color space. FOURCC_ANY means that any color space is OK.
-};
-
-// Result of video capturer start.
-enum CaptureResult {
-  CR_SUCCESS,    // The capturer starts successfully.
-  CR_PENDING,    // The capturer is pending to start the capture device.
-  CR_FAILURE,    // The capturer fails to start.
-  CR_NO_DEVICE,  // The capturer has no device and fails to start.
-};
-
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_VIDEOCOMMON_H_
diff --git a/third_party/libjingle/source/talk/session/phone/videocommon_unittest.cc b/third_party/libjingle/source/talk/session/phone/videocommon_unittest.cc
deleted file mode 100644
index eb74c35..0000000
--- a/third_party/libjingle/source/talk/session/phone/videocommon_unittest.cc
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * libjingle
- * Copyright 2008 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/gunit.h"
-#include "talk/session/phone/videocommon.h"
-
-namespace cricket {
-
-TEST(VideoCommonTest, TestCanonicalFourCC) {
-  // Canonical fourccs are not changed.
-  EXPECT_EQ(FOURCC_I420, CanonicalFourCC(FOURCC_I420));
-  // The special FOURCC_ANY value is not changed.
-  EXPECT_EQ(FOURCC_ANY, CanonicalFourCC(FOURCC_ANY));
-  // Aliases are translated to the canonical equivalent.
-  EXPECT_EQ(FOURCC_I420, CanonicalFourCC(FOURCC_IYUV));
-  EXPECT_EQ(FOURCC_I422, CanonicalFourCC(FOURCC_YU16));
-  EXPECT_EQ(FOURCC_I444, CanonicalFourCC(FOURCC_YU24));
-  EXPECT_EQ(FOURCC_24BG, CanonicalFourCC(FOURCC_BGR3));
-  EXPECT_EQ(FOURCC_RAW, CanonicalFourCC(FOURCC_RGB3));
-  EXPECT_EQ(FOURCC_MJPG, CanonicalFourCC(FOURCC_DMB1));
-}
-
-// Test conversion between interval and fps
-TEST(VideoCommonTest, TestVideoFormatFps) {
-  EXPECT_EQ(VideoFormat::kMinimumInterval, VideoFormat::FpsToInterval(0));
-  EXPECT_EQ(talk_base::kNumNanosecsPerSec / 20, VideoFormat::FpsToInterval(20));
-  EXPECT_EQ(20, VideoFormat::IntervalToFps(talk_base::kNumNanosecsPerSec / 20));
-}
-
-// Test IsSize0x0
-TEST(VideoCommonTest, TestVideoFormatIsSize0x0) {
-  VideoFormat format;
-  EXPECT_TRUE(format.IsSize0x0());
-  format.width = 320;
-  EXPECT_FALSE(format.IsSize0x0());
-}
-
-// Test ToString: print fourcc when it is printable.
-TEST(VideoCommonTest, TestVideoFormatToString) {
-  VideoFormat format;
-  EXPECT_EQ("0x0x10000", format.ToString());
-
-  format.fourcc = FOURCC_I420;
-  format.width = 640;
-  format.height = 480;
-  format.interval = VideoFormat::FpsToInterval(20);
-  EXPECT_EQ("I420 640x480x20", format.ToString());
-
-  format.fourcc = FOURCC_ANY;
-  format.width = 640;
-  format.height = 480;
-  format.interval = VideoFormat::FpsToInterval(20);
-  EXPECT_EQ("640x480x20", format.ToString());
-}
-
-// Test comparison.
-TEST(VideoCommonTest, TestVideoFormatCompare) {
-  VideoFormat format(640, 480, VideoFormat::FpsToInterval(20), FOURCC_I420);
-  VideoFormat format2;
-  EXPECT_NE(format, format2);
-
-  // Same pixelrate, different fourcc.
-  format2 = format;
-  format2.fourcc = FOURCC_YUY2;
-  EXPECT_NE(format, format2);
-  EXPECT_FALSE(format.IsPixelRateLess(format2) ||
-               format2.IsPixelRateLess(format2));
-
-  format2 = format;
-  format2.interval /= 2;
-  EXPECT_TRUE(format.IsPixelRateLess(format2));
-
-  format2 = format;
-  format2.width *= 2;
-  EXPECT_TRUE(format.IsPixelRateLess(format2));
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/session/phone/videoframe.cc b/third_party/libjingle/source/talk/session/phone/videoframe.cc
deleted file mode 100644
index 0db3352..0000000
--- a/third_party/libjingle/source/talk/session/phone/videoframe.cc
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * libjingle
- * Copyright 2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/session/phone/videoframe.h"
-
-#include <cstring>
-
-#ifdef HAVE_YUV
-#include "libyuv/planar_functions.h"
-#include "libyuv/scale.h"
-#endif
-
-namespace cricket {
-
-// Round to 2 pixels because Chroma channels are half size.
-#define ROUNDTO2(v) (v & ~1)
-
-// TODO: Handle odd width/height with rounding.
-void VideoFrame::StretchToPlanes(
-    uint8* y, uint8* u, uint8* v,
-    int32 dst_pitch_y, int32 dst_pitch_u, int32 dst_pitch_v,
-    size_t width, size_t height, bool interpolate, bool vert_crop) const {
-#ifdef HAVE_YUV
-  if (!GetYPlane() || !GetUPlane() || !GetVPlane())
-    return;
-
-  const uint8* in_y = GetYPlane();
-  const uint8* in_u = GetUPlane();
-  const uint8* in_v = GetVPlane();
-  int32 iwidth = GetWidth();
-  int32 iheight = GetHeight();
-
-  if (vert_crop) {
-    // Adjust the input width:height ratio to be the same as the output ratio.
-    if (iwidth * height > iheight * width) {
-      // Reduce the input width, but keep size/position aligned for YuvScaler
-      iwidth = ROUNDTO2(iheight * width / height);
-      int32 iwidth_offset = ROUNDTO2((GetWidth() - iwidth) / 2);
-      in_y += iwidth_offset;
-      in_u += iwidth_offset / 2;
-      in_v += iwidth_offset / 2;
-    } else if (iwidth * height < iheight * width) {
-      // Reduce the input height.
-      iheight = iwidth * height / width;
-      int32 iheight_offset = (GetHeight() - iheight) >> 2;
-      iheight_offset <<= 1;  // Ensure that iheight_offset is even.
-      in_y += iheight_offset * GetYPitch();
-      in_u += iheight_offset / 2 * GetUPitch();
-      in_v += iheight_offset / 2 * GetVPitch();
-    }
-  }
-
-  // Scale to the output I420 frame.
-  libyuv::Scale(in_y, in_u, in_v,
-                GetYPitch(),
-                GetUPitch(),
-                GetVPitch(),
-                iwidth, iheight,
-                y, u, v, dst_pitch_y, dst_pitch_u, dst_pitch_v,
-                width, height, interpolate);
-#endif
-}
-
-size_t VideoFrame::StretchToBuffer(size_t w, size_t h,
-                                   uint8* buffer, size_t size,
-                                   bool interpolate,
-                                   bool vert_crop) const {
-  if (!buffer) return 0;
-
-  size_t needed = SizeOf(w, h);
-  if (needed <= size) {
-    uint8* bufy = buffer;
-    uint8* bufu = bufy + w * h;
-    uint8* bufv = bufu + ((w + 1) >> 1) * ((h + 1) >> 1);
-    StretchToPlanes(bufy, bufu, bufv, w, (w + 1) >> 1, (w + 1) >> 1, w, h,
-                    interpolate, vert_crop);
-  }
-  return needed;
-}
-
-void VideoFrame::StretchToFrame(VideoFrame *target,
-                                bool interpolate,
-                                bool vert_crop) const {
-  if (!target) return;
-
-  StretchToPlanes(target->GetYPlane(),
-                  target->GetUPlane(),
-                  target->GetVPlane(),
-                  target->GetYPitch(),
-                  target->GetUPitch(),
-                  target->GetVPitch(),
-                  target->GetWidth(),
-                  target->GetHeight(),
-                  interpolate, vert_crop);
-  target->SetElapsedTime(GetElapsedTime());
-  target->SetTimeStamp(GetTimeStamp());
-}
-
-bool VideoFrame::SetToBlack() {
-#ifdef HAVE_YUV
-  return libyuv::I420Rect(GetYPlane(), GetYPitch(),
-                          GetUPlane(), GetUPitch(),
-                          GetVPlane(), GetVPitch(),
-                          0, 0, GetWidth(), GetHeight(),
-                          16, 128, 128) == 0;
-#else
-  int uv_size = GetUPitch() * GetChromaHeight();
-  memset(GetYPlane(), 16, GetWidth() * GetHeight());
-  memset(GetUPlane(), 128, uv_size);
-  memset(GetVPlane(), 128, uv_size);
-  return true;
-#endif
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/session/phone/videoframe.h b/third_party/libjingle/source/talk/session/phone/videoframe.h
deleted file mode 100644
index 1c5ae5c..0000000
--- a/third_party/libjingle/source/talk/session/phone/videoframe.h
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * libjingle
- * Copyright 2004 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SESSION_PHONE_VIDEOFRAME_H_
-#define TALK_SESSION_PHONE_VIDEOFRAME_H_
-
-#include "talk/base/basictypes.h"
-
-namespace flute {
-class MagicCamVideoRenderer;
-}
-
-namespace cricket {
-
-// Simple rotation constants.
-enum {
-  ROTATION_0 = 0,
-  ROTATION_90 = 90,
-  ROTATION_180 = 180,
-  ROTATION_270 = 270
-};
-
-// Represents a YUV420 (a.k.a. I420) video frame.
-class VideoFrame {
-  friend class flute::MagicCamVideoRenderer;
-
- public:
-  VideoFrame() : rendered_(false) {}
-
-  virtual ~VideoFrame() {}
-
-  virtual size_t GetWidth() const = 0;
-  virtual size_t GetHeight() const = 0;
-  size_t GetChromaWidth() const { return (GetWidth() + 1) / 2; }
-  size_t GetChromaHeight() const { return (GetHeight() + 1) / 2; }
-  virtual const uint8 *GetYPlane() const = 0;
-  virtual const uint8 *GetUPlane() const = 0;
-  virtual const uint8 *GetVPlane() const = 0;
-  virtual uint8 *GetYPlane() = 0;
-  virtual uint8 *GetUPlane() = 0;
-  virtual uint8 *GetVPlane() = 0;
-  virtual int32 GetYPitch() const = 0;
-  virtual int32 GetUPitch() const = 0;
-  virtual int32 GetVPitch() const = 0;
-
-  // For retrieving the aspect ratio of each pixel. Usually this is 1x1, but
-  // the aspect_ratio_idc parameter of H.264 can specify non-square pixels.
-  virtual size_t GetPixelWidth() const = 0;
-  virtual size_t GetPixelHeight() const = 0;
-
-  // TODO: Add a fourcc format here and probably combine VideoFrame
-  // with CapturedFrame.
-  virtual int64 GetElapsedTime() const = 0;
-  virtual int64 GetTimeStamp() const = 0;
-  virtual void SetElapsedTime(int64 elapsed_time) = 0;
-  virtual void SetTimeStamp(int64 time_stamp) = 0;
-
-  // Indicates the rotation angle in degrees.
-  virtual int GetRotation() const = 0;
-
-  // Make a shallow copy of the frame. The frame buffer itself is not copied.
-  // Both the current and new VideoFrame will share a single reference-counted
-  // frame buffer.
-  virtual VideoFrame *Copy() const = 0;
-
-  // Since VideoFrame supports shallow copy and the internal frame buffer might
-  // be shared, in case VideoFrame needs exclusive access of the frame buffer,
-  // user can call MakeExclusive() to make sure the frame buffer is exclusive
-  // accessable to the current object.  This might mean a deep copy of the frame
-  // buffer if it is currently shared by other objects.
-  virtual bool MakeExclusive() = 0;
-
-  // Writes the frame into the given frame buffer, provided that it is of
-  // sufficient size. Returns the frame's actual size, regardless of whether
-  // it was written or not (like snprintf). If there is insufficient space,
-  // nothing is written.
-  virtual size_t CopyToBuffer(uint8 *buffer, size_t size) const = 0;
-
-  // Converts the I420 data to RGB of a certain type such as ARGB and ABGR.
-  // Returns the frame's actual size, regardless of whether it was written or
-  // not (like snprintf). Parameters size and pitch_rgb are in units of bytes.
-  // If there is insufficient space, nothing is written.
-  virtual size_t ConvertToRgbBuffer(uint32 to_fourcc, uint8 *buffer,
-                                    size_t size, size_t pitch_rgb) const = 0;
-
-  // Writes the frame into the given planes, stretched to the given width and
-  // height. The parameter "interpolate" controls whether to interpolate or just
-  // take the nearest-point. The parameter "crop" controls whether to crop this
-  // frame to the aspect ratio of the given dimensions before stretching.
-  virtual void StretchToPlanes(uint8 *y, uint8 *u, uint8 *v,
-                               int32 pitchY, int32 pitchU, int32 pitchV,
-                               size_t width, size_t height,
-                               bool interpolate, bool crop) const;
-
-  // Writes the frame into the given frame buffer, stretched to the given width
-  // and height, provided that it is of sufficient size. Returns the frame's
-  // actual size, regardless of whether it was written or not (like snprintf).
-  // If there is insufficient space, nothing is written. The parameter
-  // "interpolate" controls whether to interpolate or just take the
-  // nearest-point. The parameter "crop" controls whether to crop this frame to
-  // the aspect ratio of the given dimensions before stretching.
-  virtual size_t StretchToBuffer(size_t w, size_t h, uint8 *buffer, size_t size,
-                                 bool interpolate, bool crop) const;
-
-  // Writes the frame into the target VideoFrame, stretched to the size of that
-  // frame. The parameter "interpolate" controls whether to interpolate or just
-  // take the nearest-point. The parameter "crop" controls whether to crop this
-  // frame to the aspect ratio of the target frame before stretching.
-  virtual void StretchToFrame(VideoFrame *target, bool interpolate,
-                              bool crop) const;
-
-  // Stretches the frame to the given size, creating a new VideoFrame object to
-  // hold it. The parameter "interpolate" controls whether to interpolate or
-  // just take the nearest-point. The parameter "crop" controls whether to crop
-  // this frame to the aspect ratio of the given dimensions before stretching.
-  virtual VideoFrame *Stretch(size_t w, size_t h, bool interpolate,
-                              bool crop) const = 0;
-
-  // Set the video frame to black.
-  bool SetToBlack();
-
-  // Size of an I420 image of given dimensions when stored as a frame buffer.
-  static size_t SizeOf(size_t w, size_t h) {
-    return w * h + ((w + 1) / 2) * ((h + 1) / 2) * 2;
-  }
-
- protected:
-  // The frame needs to be rendered to magiccam only once.
-  // TODO: Remove this flag once magiccam rendering is fully replaced
-  // by client3d rendering.
-  mutable bool rendered_;
-};
-
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_VIDEOFRAME_H_
diff --git a/third_party/libjingle/source/talk/session/phone/videoprocessor.h b/third_party/libjingle/source/talk/session/phone/videoprocessor.h
deleted file mode 100644
index d3b6249..0000000
--- a/third_party/libjingle/source/talk/session/phone/videoprocessor.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SESSION_PHONE_VIDEOPROCESSOR_H_
-#define TALK_SESSION_PHONE_VIDEOPROCESSOR_H_
-
-#include "talk/base/sigslot.h"
-#include "talk/session/phone/videoframe.h"
-
-namespace cricket {
-
-class VideoProcessor : public sigslot::has_slots<> {
- public:
-  virtual ~VideoProcessor() {}
-  // Contents of frame may be manipulated by the processor.
-  // The processed data is expected to be the same size as the
-  // original data
-  virtual void OnFrame(uint32 ssrc, VideoFrame* frame) = 0;
-};
-
-}  // namespace cricket
-#endif  // TALK_SESSION_PHONE_VIDEOPROCESSOR_H_
-
diff --git a/third_party/libjingle/source/talk/session/phone/videorenderer.h b/third_party/libjingle/source/talk/session/phone/videorenderer.h
deleted file mode 100644
index f1fe547..0000000
--- a/third_party/libjingle/source/talk/session/phone/videorenderer.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * libjingle
- * Copyright 2004, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SESSION_PHONE_VIDEORENDERER_H_
-#define TALK_SESSION_PHONE_VIDEORENDERER_H_
-
-namespace cricket {
-
-class VideoFrame;
-
-// Abstract interface for rendering VideoFrames.
-class VideoRenderer {
- public:
-  virtual ~VideoRenderer() {}
-  // Called when the video has changed size.
-  virtual bool SetSize(int width, int height, int reserved) = 0;
-  // Called when a new frame is available for display.
-  virtual bool RenderFrame(const VideoFrame *frame) = 0;
-};
-
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_VIDEORENDERER_H_
diff --git a/third_party/libjingle/source/talk/session/phone/videorendererfactory.h b/third_party/libjingle/source/talk/session/phone/videorendererfactory.h
deleted file mode 100644
index 058bf8c..0000000
--- a/third_party/libjingle/source/talk/session/phone/videorendererfactory.h
+++ /dev/null
@@ -1,65 +0,0 @@
-// libjingle
-// Copyright 2010 Google Inc. All Rights Reserved
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-//  1. Redistributions of source code must retain the above copyright notice,
-//     this list of conditions and the following disclaimer.
-//  2. Redistributions in binary form must reproduce the above copyright notice,
-//     this list of conditions and the following disclaimer in the documentation
-//     and/or other materials provided with the distribution.
-//  3. The name of the author may not be used to endorse or promote products
-//     derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// A factory to create a GUI video renderer.
-
-#ifndef TALK_SESSION_PHONE_VIDEORENDERERFACTORY_H_
-#define TALK_SESSION_PHONE_VIDEORENDERERFACTORY_H_
-
-#if defined(LINUX)
-#include "talk/session/phone/gtkvideorenderer.h"
-#elif defined(OSX)
-#include "talk/session/phone/carbonvideorenderer.h"
-#elif defined(WIN32)
-#include "talk/session/phone/gdivideorenderer.h"
-#endif
-
-namespace cricket {
-
-class VideoRendererFactory {
- public:
-  static VideoRenderer* CreateGuiVideoRenderer(int x, int y) {
-  #if defined(LINUX)
-    return new GtkVideoRenderer(x, y);
-  #elif defined(OSX)
-    CarbonVideoRenderer* renderer = new CarbonVideoRenderer(x, y);
-    // Needs to be initialized on the main thread.
-    if (renderer->Initialize()) {
-      return renderer;
-    } else {
-      delete renderer;
-      return NULL;
-    }
-  #elif defined(WIN32)
-    return new GdiVideoRenderer(x, y);
-  #else
-    return NULL;
-  #endif
-  }
-};
-
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_VIDEORENDERERFACTORY_H_
diff --git a/third_party/libjingle/source/talk/session/phone/voicechannel.h b/third_party/libjingle/source/talk/session/phone/voicechannel.h
deleted file mode 100644
index 95de637..0000000
--- a/third_party/libjingle/source/talk/session/phone/voicechannel.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2007, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _VOICECHANNEL_H_
-#define _VOICECHANNEL_H_
-
-#include "talk/session/phone/channel.h"
-
-#endif // _VOICECHANNEL_H_
diff --git a/third_party/libjingle/source/talk/session/phone/voiceprocessor.h b/third_party/libjingle/source/talk/session/phone/voiceprocessor.h
deleted file mode 100644
index 39bcfab..0000000
--- a/third_party/libjingle/source/talk/session/phone/voiceprocessor.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SESSION_PHONE_VOICEPROCESSOR_H_
-#define TALK_SESSION_PHONE_VOICEPROCESSOR_H_
-
-#include "talk/base/basictypes.h"
-#include "talk/base/sigslot.h"
-#include "talk/session/phone/audioframe.h"
-
-namespace cricket {
-
-enum MediaProcessorDirection {
-    MPD_RX = 1 << 0,
-    MPD_TX = 1 << 1,
-    MPD_RX_AND_TX = MPD_RX | MPD_TX,
-};
-
-class VoiceProcessor : public sigslot::has_slots<> {
- public:
-  virtual ~VoiceProcessor() {}
-  // Contents of frame may be manipulated by the processor.
-  // The processed data is expected to be the same size as the
-  // original data
-  virtual void OnFrame(uint32 ssrc, AudioFrame* frame) = 0;
-};
-
-}  // namespace cricket
-#endif  // TALK_SESSION_PHONE_VOICEPROCESSOR_H_
diff --git a/third_party/libjingle/source/talk/session/phone/webrtccommon.h b/third_party/libjingle/source/talk/session/phone/webrtccommon.h
deleted file mode 100644
index 286b049..0000000
--- a/third_party/libjingle/source/talk/session/phone/webrtccommon.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-#ifndef TALK_SESSION_PHONE_WEBRTCCOMMON_H_
-#define TALK_SESSION_PHONE_WEBRTCCOMMON_H_
-
-#ifdef WEBRTC_RELATIVE_PATH
-#include "common_types.h"
-#else
-#include "third_party/webrtc/files/include/common_types.h"
-#endif  // WEBRTC_RELATIVE_PATH
-
-namespace cricket {
-
-// Tracing helpers, for easy logging when WebRTC calls fail.
-// Example: "LOG_RTCERR1(StartSend, channel);" produces the trace
-//          "StartSend(1) failed, err=XXXX"
-// The method GetLastEngineError must be defined in the calling scope.
-#define LOG_RTCERR0(func) \
-    LOG_RTCERR0_EX(func, GetLastEngineError())
-#define LOG_RTCERR1(func, a1) \
-    LOG_RTCERR1_EX(func, a1, GetLastEngineError())
-#define LOG_RTCERR2(func, a1, a2) \
-    LOG_RTCERR2_EX(func, a1, a2, GetLastEngineError())
-#define LOG_RTCERR3(func, a1, a2, a3) \
-    LOG_RTCERR3_EX(func, a1, a2, a3, GetLastEngineError())
-#define LOG_RTCERR4(func, a1, a2, a3, a4) \
-    LOG_RTCERR4_EX(func, a1, a2, a3, a4, GetLastEngineError())
-#define LOG_RTCERR5(func, a1, a2, a3, a4, a5) \
-    LOG_RTCERR5_EX(func, a1, a2, a3, a4, a5, GetLastEngineError())
-#define LOG_RTCERR6(func, a1, a2, a3, a4, a5, a6) \
-    LOG_RTCERR6_EX(func, a1, a2, a3, a4, a5, a6, GetLastEngineError())
-#define LOG_RTCERR0_EX(func, err) LOG(LS_WARNING) \
-    << "" << #func << "() failed, err=" << err
-#define LOG_RTCERR1_EX(func, a1, err) LOG(LS_WARNING) \
-    << "" << #func << "(" << a1 << ") failed, err=" << err
-#define LOG_RTCERR2_EX(func, a1, a2, err) LOG(LS_WARNING) \
-    << "" << #func << "(" << a1 << ", " << a2 << ") failed, err=" \
-    << err
-#define LOG_RTCERR3_EX(func, a1, a2, a3, err) LOG(LS_WARNING) \
-    << "" << #func << "(" << a1 << ", " << a2 << ", " << a3 \
-    << ") failed, err=" << err
-#define LOG_RTCERR4_EX(func, a1, a2, a3, a4, err) LOG(LS_WARNING) \
-    << "" << #func << "(" << a1 << ", " << a2 << ", " << a3 \
-    << ", " << a4 << ") failed, err=" << err
-#define LOG_RTCERR5_EX(func, a1, a2, a3, a4, a5, err) LOG(LS_WARNING) \
-    << "" << #func << "(" << a1 << ", " << a2 << ", " << a3 \
-    << ", " << a4 << ", " << a5 << ") failed, err=" << err
-#define LOG_RTCERR6_EX(func, a1, a2, a3, a4, a5, a6, err) LOG(LS_WARNING) \
-    << "" << #func << "(" << a1 << ", " << a2 << ", " << a3 \
-    << ", " << a4 << ", " << a5 << ", " << a6 << ") failed, err=" << err
-
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_WEBRTCCOMMON_H_
diff --git a/third_party/libjingle/source/talk/session/phone/webrtcmediaengine.h b/third_party/libjingle/source/talk/session/phone/webrtcmediaengine.h
deleted file mode 100644
index 2173d14..0000000
--- a/third_party/libjingle/source/talk/session/phone/webrtcmediaengine.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * libjingle
- * Copyright 2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SESSION_PHONE_WEBRTCMEDIAENGINE_H_
-#define TALK_SESSION_PHONE_WEBRTCMEDIAENGINE_H_
-
-#include "talk/session/phone/mediaengine.h"
-#include "talk/session/phone/webrtcvideoengine.h"
-#include "talk/session/phone/webrtcvoiceengine.h"
-
-namespace webrtc {
-class AudioDeviceModule;
-class VideoCaptureModule;
-}
-
-namespace cricket {
-
-typedef CompositeMediaEngine<WebRtcVoiceEngine, WebRtcVideoEngine>
-        WebRtcCompositeMediaEngine;
-
-class WebRtcMediaEngine : public WebRtcCompositeMediaEngine {
- public:
-  WebRtcMediaEngine(webrtc::AudioDeviceModule* adm,
-      webrtc::AudioDeviceModule* adm_sc, webrtc::VideoCaptureModule* vcm) {
-    voice_.SetAudioDeviceModule(adm, adm_sc);
-    video_.SetVoiceEngine(&voice_);
-    video_.SetCaptureModule(vcm);
-    video_.EnableTimedRender();
-  }
-  // Allow the VCM be set later if not ready during the construction time
-  bool SetVideoCaptureModule(webrtc::VideoCaptureModule* vcm) {
-    return video_.SetCaptureModule(vcm);
-  }
-};
-
-}  // namespace cricket
-#endif  // TALK_SESSION_PHONE_WEBRTCMEDIAENGINE_H_
diff --git a/third_party/libjingle/source/talk/session/phone/webrtcpassthroughrender.cc b/third_party/libjingle/source/talk/session/phone/webrtcpassthroughrender.cc
deleted file mode 100644
index cecaa42..0000000
--- a/third_party/libjingle/source/talk/session/phone/webrtcpassthroughrender.cc
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/session/phone/webrtcpassthroughrender.h"
-
-#include "talk/base/common.h"
-#include "talk/base/logging.h"
-
-namespace cricket {
-
-class PassthroughStream: public webrtc::VideoRenderCallback {
- public:
-  explicit PassthroughStream(const WebRtc_UWord32 stream_id)
-      : stream_id_(stream_id) {
-  }
-  virtual ~PassthroughStream() {
-  }
-  virtual WebRtc_Word32 RenderFrame(const WebRtc_UWord32 stream_id,
-                                    webrtc::VideoFrame& videoFrame) {
-    talk_base::CritScope cs(&stream_critical_);
-    // Send frame for rendering directly
-    if (renderer_) {
-      renderer_->RenderFrame(stream_id, videoFrame);
-    }
-    return 0;
-  }
-  WebRtc_Word32 SetRenderer(VideoRenderCallback* renderer) {
-    talk_base::CritScope cs(&stream_critical_);
-    renderer_ = renderer;
-    return 0;
-  }
-
- private:
-  WebRtc_UWord32 stream_id_;
-  VideoRenderCallback* renderer_;
-  talk_base::CriticalSection stream_critical_;
-};
-
-WebRtcPassthroughRender::WebRtcPassthroughRender()
-    : window_(NULL) {
-}
-
-WebRtcPassthroughRender::~WebRtcPassthroughRender() {
-  while (!stream_render_map_.empty()) {
-    PassthroughStream* stream = stream_render_map_.begin()->second;
-    stream_render_map_.erase(stream_render_map_.begin());
-    delete stream;
-  }
-}
-
-webrtc::VideoRenderCallback* WebRtcPassthroughRender::AddIncomingRenderStream(
-    const WebRtc_UWord32 stream_id,
-    const WebRtc_UWord32 zOrder,
-    const float left, const float top,
-    const float right, const float bottom) {
-  talk_base::CritScope cs(&render_critical_);
-  StreamMap::iterator it;
-  it = stream_render_map_.find(stream_id);
-  if (it != stream_render_map_.end())
-    return NULL;
-
-  PassthroughStream* stream = new PassthroughStream(stream_id);
-  // Store the stream
-  stream_render_map_[stream_id] = stream;
-  return stream;
-}
-
-WebRtc_Word32 WebRtcPassthroughRender::DeleteIncomingRenderStream(
-    const WebRtc_UWord32 stream_id) {
-  talk_base::CritScope cs(&render_critical_);
-  StreamMap::iterator it;
-  it = stream_render_map_.find(stream_id);
-  if (it == stream_render_map_.end()) {
-    LOG(LS_WARNING) << "DeleteIncomingRenderStream failed to find stream_id: "
-                    << stream_id;
-    return -1;
-  }
-  PassthroughStream* stream = it->second;
-  delete stream;
-  stream_render_map_.erase(it);
-  return 0;
-}
-
-WebRtc_Word32 WebRtcPassthroughRender::AddExternalRenderCallback(
-    const WebRtc_UWord32 stream_id,
-    webrtc::VideoRenderCallback* render_object) {
-  talk_base::CritScope cs(&render_critical_);
-  StreamMap::iterator it;
-  it = stream_render_map_.find(stream_id);
-  if (it == stream_render_map_.end()) {
-    LOG(LS_WARNING) << "AddExternalRenderCallback failed to find stream_id: "
-                    << stream_id;
-    return -1;
-  }
-  PassthroughStream* stream = it->second;
-  ASSERT(stream != NULL);
-  return stream->SetRenderer(render_object);
-}
-
-bool WebRtcPassthroughRender::HasIncomingRenderStream(
-    const WebRtc_UWord32 stream_id) const {
-  StreamMap::const_iterator it;
-  it = stream_render_map_.find(stream_id);
-  return (it != stream_render_map_.end());
-}
-
-webrtc::RawVideoType WebRtcPassthroughRender::PreferredVideoType() const {
-  return webrtc::kVideoI420;
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/session/phone/webrtcpassthroughrender.h b/third_party/libjingle/source/talk/session/phone/webrtcpassthroughrender.h
deleted file mode 100644
index 8d2ae90..0000000
--- a/third_party/libjingle/source/talk/session/phone/webrtcpassthroughrender.h
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SESSION_PHONE_WEBRTCPASSTHROUGHRENDER_H_
-#define TALK_SESSION_PHONE_WEBRTCPASSTHROUGHRENDER_H_
-
-#include <map>
-
-#ifdef WEBRTC_RELATIVE_PATH
-#include "modules/video_render/main/interface/video_render.h"
-#else
-#include "third_party/webrtc/files/include/video_render.h"
-#endif
-#include "talk/base/criticalsection.h"
-
-namespace cricket {
-class PassthroughStream;
-
-class WebRtcPassthroughRender : public webrtc::VideoRender {
- public:
-  WebRtcPassthroughRender();
-  virtual ~WebRtcPassthroughRender();
-
-  virtual WebRtc_Word32 Version(WebRtc_Word8* version,
-      WebRtc_UWord32& remainingBufferInBytes,
-      WebRtc_UWord32& position) const {
-    return 0;
-  }
-
-  virtual WebRtc_Word32 ChangeUniqueId(const WebRtc_Word32 id) {
-    return 0;
-  }
-
-  virtual WebRtc_Word32 TimeUntilNextProcess() { return 0; }
-
-  virtual WebRtc_Word32 Process() { return 0; }
-
-  virtual void* Window() {
-    talk_base::CritScope cs(&render_critical_);
-    return window_;
-  }
-
-  virtual WebRtc_Word32 ChangeWindow(void* window) {
-    talk_base::CritScope cs(&render_critical_);
-    window_ = window;
-    return 0;
-  }
-
-  virtual webrtc::VideoRenderCallback* AddIncomingRenderStream(
-      const WebRtc_UWord32 stream_id,
-      const WebRtc_UWord32 zOrder,
-      const float left, const float top,
-      const float right, const float bottom);
-
-  virtual WebRtc_Word32 DeleteIncomingRenderStream(
-      const WebRtc_UWord32 stream_id);
-
-  virtual WebRtc_Word32 AddExternalRenderCallback(
-      const WebRtc_UWord32 stream_id,
-      webrtc::VideoRenderCallback* render_object);
-
-  virtual WebRtc_Word32 GetIncomingRenderStreamProperties(
-      const WebRtc_UWord32 stream_id,
-      WebRtc_UWord32& zOrder,
-      float& left, float& top,
-      float& right, float& bottom) const {
-    return -1;
-  }
-
-  virtual WebRtc_UWord32 GetIncomingFrameRate(
-      const WebRtc_UWord32 stream_id) {
-    return 0;
-  }
-
-  virtual WebRtc_UWord32 GetNumIncomingRenderStreams() const {
-    return stream_render_map_.size();
-  }
-
-  virtual bool HasIncomingRenderStream(const WebRtc_UWord32 stream_id) const;
-
-  virtual WebRtc_Word32 RegisterRawFrameCallback(
-      const WebRtc_UWord32 stream_id,
-      webrtc::VideoRenderCallback* callback_obj) {
-    return -1;
-  }
-
-  virtual WebRtc_Word32 GetLastRenderedFrame(
-      const WebRtc_UWord32 stream_id,
-      webrtc::VideoFrame &frame) const {
-    return -1;
-  }
-
-  virtual WebRtc_Word32 StartRender(
-      const WebRtc_UWord32 stream_id) { return 0; }
-
-  virtual WebRtc_Word32 StopRender(
-      const WebRtc_UWord32 stream_id) { return 0; }
-
-  virtual WebRtc_Word32 ResetRender() { return 0; }
-
-  virtual webrtc::RawVideoType PreferredVideoType() const;
-
-  virtual bool IsFullScreen() { return false; }
-
-  virtual WebRtc_Word32 GetScreenResolution(
-      WebRtc_UWord32& screenWidth,
-      WebRtc_UWord32& screenHeight) const {
-    return -1;
-  }
-
-  virtual WebRtc_UWord32 RenderFrameRate(
-      const WebRtc_UWord32 stream_id) {
-    return 0;
-  }
-
-  virtual WebRtc_Word32 SetStreamCropping(
-      const WebRtc_UWord32 stream_id,
-      const float left, const float top,
-      const float right,
-      const float bottom) {
-    return -1;
-  }
-
-  virtual WebRtc_Word32 ConfigureRenderer(
-      const WebRtc_UWord32 stream_id,
-      const unsigned int zOrder,
-      const float left, const float top,
-      const float right,
-      const float bottom) {
-    return -1;
-  }
-
-  virtual WebRtc_Word32 SetTransparentBackground(const bool enable) {
-    return -1;
-  }
-
-  virtual WebRtc_Word32 FullScreenRender(void* window, const bool enable) {
-    return -1;
-  }
-
-  virtual WebRtc_Word32 SetBitmap(const void* bitMap,
-      const WebRtc_UWord8 pictureId, const void* colorKey,
-      const float left, const float top,
-      const float right, const float bottom) {
-    return -1;
-  }
-
-  virtual WebRtc_Word32 SetText(const WebRtc_UWord8 textId,
-      const WebRtc_UWord8* text,
-      const WebRtc_Word32 textLength,
-      const WebRtc_UWord32 textColorRef,
-      const WebRtc_UWord32 backgroundColorRef,
-      const float left, const float top,
-      const float right, const float bottom) {
-    return -1;
-  }
-
-  virtual WebRtc_Word32 SetStartImage(
-      const WebRtc_UWord32 stream_id,
-      const webrtc::VideoFrame& videoFrame) {
-    return -1;
-  }
-
-  virtual WebRtc_Word32 SetTimeoutImage(
-      const WebRtc_UWord32 stream_id,
-      const webrtc::VideoFrame& videoFrame,
-      const WebRtc_UWord32 timeout) {
-    return -1;
-  }
-
-  virtual WebRtc_Word32 MirrorRenderStream(const int renderId,
-                                           const bool enable,
-                                           const bool mirrorXAxis,
-                                           const bool mirrorYAxis) {
-    return -1;
-  }
-
- private:
-  typedef std::map<WebRtc_UWord32, PassthroughStream*> StreamMap;
-
-  void* window_;
-  StreamMap stream_render_map_;
-  talk_base::CriticalSection render_critical_;
-};
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_WEBRTCPASSTHROUGHRENDER_H_
diff --git a/third_party/libjingle/source/talk/session/phone/webrtcpassthroughrender_unittest.cc b/third_party/libjingle/source/talk/session/phone/webrtcpassthroughrender_unittest.cc
deleted file mode 100644
index b33d38b..0000000
--- a/third_party/libjingle/source/talk/session/phone/webrtcpassthroughrender_unittest.cc
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright 2008 Google Inc. All Rights Reserved,
-//
-// Author: Ronghua Wu (ronghuawu@google.com)
-
-#include <string>
-
-#include "talk/base/gunit.h"
-#include "talk/session/phone/webrtcpassthroughrender.h"
-#include "talk/session/phone/testutils.h"
-
-class WebRtcPassthroughRenderTest : public testing::Test {
- public:
-  class ExternalRenderer : public webrtc::VideoRenderCallback {
-   public:
-    ExternalRenderer() : frame_num_(0) {
-    }
-
-    virtual ~ExternalRenderer() {
-    }
-
-    virtual WebRtc_Word32 RenderFrame(
-        const WebRtc_UWord32 stream_id,
-        webrtc::VideoFrame& videoFrame) {
-      ++frame_num_;
-      LOG(INFO) << "RenderFrame stream_id: " << stream_id
-                << " frame_num: " << frame_num_;
-      return 0;
-    }
-
-    int frame_num() const {
-      return frame_num_;
-    }
-
-   private:
-    int frame_num_;
-  };
-
-  WebRtcPassthroughRenderTest()
-      : renderer_(new cricket::WebRtcPassthroughRender()) {
-  }
-
-  ~WebRtcPassthroughRenderTest() {
-  }
-
-  webrtc::VideoRenderCallback* AddIncomingRenderStream(int stream_id) {
-    return renderer_->AddIncomingRenderStream(stream_id, 0, 0, 0, 0, 0);
-  }
-
-  bool HasIncomingRenderStream(int stream_id) {
-    return renderer_->HasIncomingRenderStream(stream_id);
-  }
-
-  bool DeleteIncomingRenderStream(int stream_id) {
-    return (renderer_->DeleteIncomingRenderStream(stream_id) == 0);
-  }
-
-  bool AddExternalRenderCallback(int stream_id,
-                                 webrtc::VideoRenderCallback* renderer) {
-    return (renderer_->AddExternalRenderCallback(stream_id, renderer) == 0);
-  }
-
- private:
-  talk_base::scoped_ptr<cricket::WebRtcPassthroughRender> renderer_;
-};
-
-TEST_F(WebRtcPassthroughRenderTest, Streams) {
-  const int stream_id1 = 1234;
-  const int stream_id2 = 5678;
-  webrtc::VideoRenderCallback* stream = NULL;
-  // Add a new stream
-  stream = AddIncomingRenderStream(stream_id1);
-  EXPECT_TRUE(stream != NULL);
-  EXPECT_TRUE(HasIncomingRenderStream(stream_id1));
-  // Tried to add a already existed stream should return null
-  stream =AddIncomingRenderStream(stream_id1);
-  EXPECT_TRUE(stream == NULL);
-  stream = AddIncomingRenderStream(stream_id2);
-  EXPECT_TRUE(stream != NULL);
-  EXPECT_TRUE(HasIncomingRenderStream(stream_id2));
-  // Remove the stream
-  EXPECT_TRUE(DeleteIncomingRenderStream(stream_id2));
-  EXPECT_TRUE(!HasIncomingRenderStream(stream_id2));
-  // Add back the removed stream
-  stream = AddIncomingRenderStream(stream_id2);
-  EXPECT_TRUE(stream != NULL);
-  EXPECT_TRUE(HasIncomingRenderStream(stream_id2));
-}
-
-TEST_F(WebRtcPassthroughRenderTest, Renderer) {
-  webrtc::VideoFrame frame;
-  const int stream_id1 = 1234;
-  const int stream_id2 = 5678;
-  webrtc::VideoRenderCallback* stream1 = NULL;
-  webrtc::VideoRenderCallback* stream2 = NULL;
-  // Add two new stream
-  stream1 = AddIncomingRenderStream(stream_id1);
-  EXPECT_TRUE(stream1 != NULL);
-  EXPECT_TRUE(HasIncomingRenderStream(stream_id1));
-  stream2 = AddIncomingRenderStream(stream_id2);
-  EXPECT_TRUE(stream2 != NULL);
-  EXPECT_TRUE(HasIncomingRenderStream(stream_id2));
-  // Register the external renderer
-  WebRtcPassthroughRenderTest::ExternalRenderer renderer1;
-  WebRtcPassthroughRenderTest::ExternalRenderer renderer2;
-  AddExternalRenderCallback(stream_id1, &renderer1);
-  AddExternalRenderCallback(stream_id2, &renderer2);
-  int test_frame_num = 10;
-  for (int i = 0; i < test_frame_num; ++i) {
-    stream1->RenderFrame(stream_id1, frame);
-  }
-  EXPECT_EQ(test_frame_num, renderer1.frame_num());
-  test_frame_num = 30;
-  for (int i = 0; i < test_frame_num; ++i) {
-    stream2->RenderFrame(stream_id2, frame);
-  }
-  EXPECT_EQ(test_frame_num, renderer2.frame_num());
-}
diff --git a/third_party/libjingle/source/talk/session/phone/webrtcvideocapturer.cc b/third_party/libjingle/source/talk/session/phone/webrtcvideocapturer.cc
deleted file mode 100644
index c187238..0000000
--- a/third_party/libjingle/source/talk/session/phone/webrtcvideocapturer.cc
+++ /dev/null
@@ -1,368 +0,0 @@
-// libjingle
-// Copyright 2004--2011 Google Inc.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-//  1. Redistributions of source code must retain the above copyright notice,
-//     this list of conditions and the following disclaimer.
-//  2. Redistributions in binary form must reproduce the above copyright notice,
-//     this list of conditions and the following disclaimer in the documentation
-//     and/or other materials provided with the distribution.
-//  3. The name of the author may not be used to endorse or promote products
-//     derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Implementation of class WebRtcVideoCapturer.
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#ifdef HAVE_WEBRTC_VIDEO
-#include "talk/session/phone/webrtcvideocapturer.h"
-#include "talk/base/logging.h"
-#include "talk/base/thread.h"
-#include "talk/base/timeutils.h"
-#include "talk/session/phone/webrtcvideoframe.h"
-
-#include "talk/base/win32.h"  // Need this to #include the impl files
-#ifdef WEBRTC_RELATIVE_PATH
-#include "modules/video_capture/main/interface/video_capture_factory.h"
-#else
-#include "third_party/webrtc/files/include/video_capture_factory.h"
-#endif
-
-namespace cricket {
-
-struct kVideoFourCCEntry {
-  uint32 fourcc;
-  webrtc::RawVideoType webrtc_type;
-};
-
-// This indicates our format preferences and defines a mapping between
-// webrtc::RawVideoType (from video_capture_defines.h) to our FOURCCs.
-static kVideoFourCCEntry kSupportedFourCCs[] = {
-  { FOURCC_I420, webrtc::kVideoI420 },   // 12 bpp, no conversion
-  { FOURCC_YV12, webrtc::kVideoYV12 },   // 12 bpp, no conversion
-  { FOURCC_NV12, webrtc::kVideoNV12 },   // 12 bpp, fast conversion
-  { FOURCC_NV21, webrtc::kVideoNV21 },   // 12 bpp, fast conversion
-  { FOURCC_YUY2, webrtc::kVideoYUY2 },   // 16 bpp, fast conversion
-  { FOURCC_UYVY, webrtc::kVideoUYVY },   // 16 bpp, fast conversion
-  { FOURCC_MJPG, webrtc::kVideoMJPEG },  // compressed, slow conversion
-  { FOURCC_ARGB, webrtc::kVideoARGB },   // 32 bpp, slow conversion
-  { FOURCC_24BG, webrtc::kVideoRGB24 },  // 32 bpp, slow conversion
-};
-
-class WebRtcVcmFactory : public WebRtcVcmFactoryInterface {
- public:
-  virtual webrtc::VideoCaptureModule* Create(int id,
-                                             const WebRtc_UWord8* device) {
-    return webrtc::VideoCaptureFactory::Create(id, device);
-  }
-  virtual webrtc::VideoCaptureModule::DeviceInfo* CreateDeviceInfo(int id) {
-    return webrtc::VideoCaptureFactory::CreateDeviceInfo(id);
-  }
-  virtual void DestroyDeviceInfo(webrtc::VideoCaptureModule::DeviceInfo* info) {
-    delete info;
-  }
-};
-
-static bool CapabilityToFormat(const webrtc::VideoCaptureCapability& cap,
-                               VideoFormat* format) {
-  uint32 fourcc = 0;
-  for (size_t i = 0; i < ARRAY_SIZE(kSupportedFourCCs); ++i) {
-    if (kSupportedFourCCs[i].webrtc_type == cap.rawType) {
-      fourcc = kSupportedFourCCs[i].fourcc;
-      break;
-    }
-  }
-  if (fourcc == 0) {
-    return false;
-  }
-
-  format->fourcc = fourcc;
-  format->width = cap.width;
-  format->height = cap.height;
-  format->interval = VideoFormat::FpsToInterval(cap.maxFPS);
-  return true;
-}
-
-static bool FormatToCapability(const VideoFormat& format,
-                               webrtc::VideoCaptureCapability* cap) {
-  webrtc::RawVideoType webrtc_type = webrtc::kVideoUnknown;
-  for (size_t i = 0; i < ARRAY_SIZE(kSupportedFourCCs); ++i) {
-    if (kSupportedFourCCs[i].fourcc == format.fourcc) {
-      webrtc_type = kSupportedFourCCs[i].webrtc_type;
-      break;
-    }
-  }
-  if (webrtc_type == webrtc::kVideoUnknown) {
-    return false;
-  }
-
-  cap->width = format.width;
-  cap->height = format.height;
-  cap->maxFPS = VideoFormat::IntervalToFps(format.interval);
-  cap->expectedCaptureDelay = 0;
-  cap->rawType = webrtc_type;
-  cap->codecType = webrtc::kVideoCodecUnknown;
-  cap->interlaced = false;
-  return true;
-}
-
-///////////////////////////////////////////////////////////////////////////
-// Implementation of class WebRtcVideoCapturer
-///////////////////////////////////////////////////////////////////////////
-
-WebRtcVideoCapturer::WebRtcVideoCapturer()
-    : factory_(new WebRtcVcmFactory),
-      module_(NULL),
-      captured_frames_(0) {
-}
-
-WebRtcVideoCapturer::WebRtcVideoCapturer(WebRtcVcmFactoryInterface* factory)
-    : factory_(factory),
-      module_(NULL),
-      captured_frames_(0) {
-}
-
-WebRtcVideoCapturer::~WebRtcVideoCapturer() {
-  if (module_) {
-    module_->Release();
-  }
-}
-
-bool WebRtcVideoCapturer::Init(const Device& device) {
-  if (module_) {
-    LOG(LS_ERROR) << "The capturer is already initialized";
-    return false;
-  }
-
-  webrtc::VideoCaptureModule::DeviceInfo* info = factory_->CreateDeviceInfo(0);
-  if (!info) {
-    return false;
-  }
-
-  // Find the desired camera, by name.
-  // In the future, comparing IDs will be more robust.
-  // TODO: Figure what's needed to allow this.
-  int num_cams = info->NumberOfDevices();
-  WebRtc_UWord8 vcm_id[256] = "";
-  bool found = false;
-  for (int index = 0; index < num_cams; ++index) {
-    WebRtc_UWord8 vcm_name[256];
-    if (info->GetDeviceName(index, vcm_name, ARRAY_SIZE(vcm_name),
-                            vcm_id, ARRAY_SIZE(vcm_id)) != -1) {
-      if (device.name == reinterpret_cast<char*>(vcm_name)) {
-        found = true;
-        break;
-      }
-    }
-  }
-  if (!found) {
-    LOG(LS_WARNING) << "Failed to find capturer for id: " << device.id;
-    factory_->DestroyDeviceInfo(info);
-    return false;
-  }
-
-  // Enumerate the supported formats.
-  // TODO: Find out why this starts/stops the camera...
-  std::vector<VideoFormat> supported;
-  WebRtc_UWord32 num_caps = info->NumberOfCapabilities(vcm_id);
-  for (WebRtc_UWord8 i = 0; i < num_caps; ++i) {
-    webrtc::VideoCaptureCapability cap;
-    if (info->GetCapability(vcm_id, i, cap) != -1) {
-      VideoFormat format;
-      if (CapabilityToFormat(cap, &format)) {
-        supported.push_back(format);
-      } else {
-        LOG(LS_WARNING) << "Ignoring unsupported WebRTC capture format "
-                        << cap.rawType;
-      }
-    }
-  }
-  factory_->DestroyDeviceInfo(info);
-  if (supported.empty()) {
-    LOG(LS_ERROR) << "Failed to find usable formats for id: " << device.id;
-    return false;
-  }
-
-  module_ = factory_->Create(0, vcm_id);
-  if (!module_) {
-    LOG(LS_ERROR) << "Failed to create capturer for id: " << device.id;
-    return false;
-  }
-
-  // It is safe to change member attributes now.
-  module_->AddRef();
-  SetId(device.id);
-  SetSupportedFormats(supported);
-  return true;
-}
-
-bool WebRtcVideoCapturer::Init(webrtc::VideoCaptureModule* module) {
-  if (module_) {
-    LOG(LS_ERROR) << "The capturer is already initialized";
-    return false;
-  }
-  if (!module) {
-    LOG(LS_ERROR) << "Invalid VCM supplied";
-    return false;
-  }
-  // TODO: Set id and formats.
-  (module_ = module)->AddRef();
-  return true;
-}
-
-bool WebRtcVideoCapturer::GetBestCaptureFormat(const VideoFormat& desired,
-                                               VideoFormat* best_format) {
-  if (!best_format) {
-    return false;
-  }
-
-  if (!VideoCapturer::GetBestCaptureFormat(desired, best_format)) {
-    // If the vcm has a list of the supported format, but didn't find the
-    // best match, then we should return fail.
-    if (GetSupportedFormats()) {
-      return false;
-    }
-
-    // We maybe using a manually injected VCM which doesn't support enum.
-    // Use the desired format as the best format.
-    best_format->width = desired.width;
-    best_format->height = desired.height;
-    best_format->fourcc = FOURCC_I420;
-    best_format->interval = desired.interval;
-    LOG(LS_INFO) << "Failed to find best capture format,"
-                 << " fall back to the requested format "
-                 << best_format->ToString();
-  }
-  return true;
-}
-
-CaptureResult WebRtcVideoCapturer::Start(const VideoFormat& capture_format) {
-  if (!module_) {
-    LOG(LS_ERROR) << "The capturer has not been initialized";
-    return CR_NO_DEVICE;
-  }
-
-  if (IsRunning()) {
-    LOG(LS_ERROR) << "The capturer is already running";
-    return CR_FAILURE;
-  }
-
-  SetCaptureFormat(&capture_format);
-
-  webrtc::VideoCaptureCapability cap;
-  if (!FormatToCapability(capture_format, &cap)) {
-    LOG(LS_ERROR) << "Invalid capture format specified";
-    return CR_FAILURE;
-  }
-
-  std::string camera_id(GetId());
-  uint32 start = talk_base::Time();
-  if (module_->RegisterCaptureDataCallback(*this) != 0 ||
-      module_->StartCapture(cap) != 0) {
-    LOG(LS_ERROR) << "Camera '" << camera_id << "' failed to start";
-    return CR_FAILURE;
-  }
-
-  LOG(LS_INFO) << "Camera '" << camera_id << "' started with format "
-               << capture_format.ToString() << ", elapsed time "
-               << talk_base::TimeSince(start) << " ms";
-
-  captured_frames_ = 0;
-  talk_base::Thread::Current()->Post(this);
-  return CR_PENDING;
-}
-
-void WebRtcVideoCapturer::Stop() {
-  if (IsRunning()) {
-    talk_base::Thread::Current()->Clear(this);
-    module_->StopCapture();
-    module_->DeRegisterCaptureDataCallback();
-
-    // TODO: Determine if the VCM exposes any drop stats we can use.
-    double drop_ratio = 0.0;
-    std::string camera_id(GetId());
-    LOG(LS_INFO) << "Camera '" << camera_id << "' stopped after capturing "
-                 << captured_frames_ << " frames and dropping "
-                 << drop_ratio << "%";
-  }
-  SetCaptureFormat(NULL);
-}
-
-bool WebRtcVideoCapturer::IsRunning() {
-  return (module_ != NULL && module_->CaptureStarted());
-}
-
-bool WebRtcVideoCapturer::GetPreferredFourccs(
-    std::vector<uint32>* fourccs) {
-  if (!fourccs) {
-    return false;
-  }
-
-  fourccs->clear();
-  for (size_t i = 0; i < ARRAY_SIZE(kSupportedFourCCs); ++i) {
-    fourccs->push_back(kSupportedFourCCs[i].fourcc);
-  }
-  return true;
-}
-
-void WebRtcVideoCapturer::OnMessage(talk_base::Message* message) {
-  // TODO: Fire SignalCaptureEvent appropriately.
-  SignalStartResult(this, CR_SUCCESS);
-}
-
-void WebRtcVideoCapturer::OnIncomingCapturedFrame(const WebRtc_Word32 id,
-    webrtc::VideoFrame& sample, webrtc::VideoCodecType codec_type) {
-  ASSERT(IsRunning());
-  ASSERT(codec_type == webrtc::kVideoCodecUnknown);
-
-  ++captured_frames_;
-  // Log the size and pixel aspect ratio of the first captured frame.
-  if (1 == captured_frames_) {
-    LOG(LS_INFO) << "Captured frame size "
-                 << sample.Width() << "x" << sample.Height()
-                 << ". Expected format " << GetCaptureFormat()->ToString();
-  }
-
-  // Signal down stream components on captured frame.
-  WebRtcCapturedFrame frame(sample);
-  SignalFrameCaptured(this, &frame);
-}
-
-void WebRtcVideoCapturer::OnCaptureDelayChanged(
-    const WebRtc_Word32 id, const WebRtc_Word32 delay) {
-  LOG(LS_INFO) << "Capture delay changed to " << delay << " ms";
-}
-
-// WebRtcCapturedFrame
-WebRtcCapturedFrame::WebRtcCapturedFrame(const webrtc::VideoFrame& sample) {
-  width = sample.Width();
-  height = sample.Height();
-  fourcc = FOURCC_I420;
-  pixel_width = 1;
-  pixel_height = 1;
-  // convert units from VideoFrame RenderTimeMs
-  // to CapturedFrame (nanoseconds)
-  elapsed_time = sample.RenderTimeMs() * talk_base::kNumNanosecsPerMillisec;
-  time_stamp = elapsed_time;
-  data_size = sample.Length();
-  data = const_cast<WebRtc_UWord8*>(sample.Buffer());
-}
-
-}  // namespace cricket
-
-#endif  // HAVE_WEBRTC_VIDEO
diff --git a/third_party/libjingle/source/talk/session/phone/webrtcvideocapturer.h b/third_party/libjingle/source/talk/session/phone/webrtcvideocapturer.h
deleted file mode 100644
index a9cc3e8..0000000
--- a/third_party/libjingle/source/talk/session/phone/webrtcvideocapturer.h
+++ /dev/null
@@ -1,102 +0,0 @@
-// libjingle
-// Copyright 2004 Google Inc.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-//  1. Redistributions of source code must retain the above copyright notice,
-//     this list of conditions and the following disclaimer.
-//  2. Redistributions in binary form must reproduce the above copyright notice,
-//     this list of conditions and the following disclaimer in the documentation
-//     and/or other materials provided with the distribution.
-//  3. The name of the author may not be used to endorse or promote products
-//     derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef TALK_SESSION_PHONE_WEBRTCVIDEOCAPTURER_H_
-#define TALK_SESSION_PHONE_WEBRTCVIDEOCAPTURER_H_
-
-#ifdef HAVE_WEBRTC_VIDEO
-
-#include <string>
-#include <vector>
-
-#include "talk/base/messagehandler.h"
-#include "talk/session/phone/videocapturer.h"
-#ifdef WEBRTC_RELATIVE_PATH
-#include "modules/video_capture/main/interface/video_capture.h"
-#else
-#include "third_party/webrtc/files/include/video_capture.h"
-#endif
-
-namespace cricket {
-
-// Factory to allow injection of a VCM impl into WebRtcVideoCapturer.
-// DeviceInfos do not have a Release() and therefore need an explicit Destroy().
-class WebRtcVcmFactoryInterface {
- public:
-  virtual ~WebRtcVcmFactoryInterface() {}
-  virtual webrtc::VideoCaptureModule* Create(
-      int id, const WebRtc_UWord8* device) = 0;
-  virtual webrtc::VideoCaptureModule::DeviceInfo* CreateDeviceInfo(int id) = 0;
-  virtual void DestroyDeviceInfo(
-      webrtc::VideoCaptureModule::DeviceInfo* info) = 0;
-};
-
-// WebRTC-based implementation of VideoCapturer.
-class WebRtcVideoCapturer : public VideoCapturer,
-                            public talk_base::MessageHandler,
-                            public webrtc::VideoCaptureDataCallback {
- public:
-  WebRtcVideoCapturer();
-  explicit WebRtcVideoCapturer(WebRtcVcmFactoryInterface* factory);
-  virtual ~WebRtcVideoCapturer();
-
-  bool Init(const Device& device);
-  bool Init(webrtc::VideoCaptureModule* module);
-
-  // Override virtual methods of the parent class VideoCapturer.
-  virtual bool GetBestCaptureFormat(const VideoFormat& desired,
-                                    VideoFormat* best_format);
-  virtual CaptureResult Start(const VideoFormat& capture_format);
-  virtual void Stop();
-  virtual bool IsRunning();
-
- protected:
-  // Override virtual methods of the parent class VideoCapturer.
-  virtual bool GetPreferredFourccs(std::vector<uint32>* fourccs);
-
- private:
-  // Callback for our started event.
-  virtual void OnMessage(talk_base::Message* message);
-  // Callback when a frame is captured by camera.
-  virtual void OnIncomingCapturedFrame(const WebRtc_Word32 id,
-                                       webrtc::VideoFrame& frame,
-                                       webrtc::VideoCodecType type);
-  virtual void OnCaptureDelayChanged(const WebRtc_Word32 id,
-                                     const WebRtc_Word32 delay);
-
-  talk_base::scoped_ptr<WebRtcVcmFactoryInterface> factory_;
-  webrtc::VideoCaptureModule* module_;
-  int captured_frames_;
-};
-
-struct WebRtcCapturedFrame : public CapturedFrame {
- public:
-  explicit WebRtcCapturedFrame(const webrtc::VideoFrame& frame);
-};
-
-}  // namespace cricket
-
-#endif  // HAVE_WEBRTC_VIDEO
-#endif  // TALK_SESSION_PHONE_WEBRTCVIDEOCAPTURER_H_
diff --git a/third_party/libjingle/source/talk/session/phone/webrtcvideocapturer_unittest.cc b/third_party/libjingle/source/talk/session/phone/webrtcvideocapturer_unittest.cc
deleted file mode 100644
index c883844..0000000
--- a/third_party/libjingle/source/talk/session/phone/webrtcvideocapturer_unittest.cc
+++ /dev/null
@@ -1,145 +0,0 @@
-// libjingle
-// Copyright 2004--2011 Google Inc.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-//  1. Redistributions of source code must retain the above copyright notice,
-//     this list of conditions and the following disclaimer.
-//  2. Redistributions in binary form must reproduce the above copyright notice,
-//     this list of conditions and the following disclaimer in the documentation
-//     and/or other materials provided with the distribution.
-//  3. The name of the author may not be used to endorse or promote products
-//     derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include <stdio.h>
-#include <vector>
-#include "talk/base/gunit.h"
-#include "talk/base/logging.h"
-#include "talk/base/stringutils.h"
-#include "talk/base/thread.h"
-#include "talk/session/phone/fakewebrtcvcmfactory.h"
-#include "talk/session/phone/testutils.h"
-#include "talk/session/phone/videocommon.h"
-#include "talk/session/phone/webrtcvideocapturer.h"
-
-using cricket::VideoFormat;
-
-static const std::string kTestDeviceName = "JuberTech FakeCam Q123";
-static const std::string kTestDeviceId = "foo://bar/baz";
-const VideoFormat kDefaultVideoFormat =
-    VideoFormat(640, 400, VideoFormat::FpsToInterval(30), cricket::FOURCC_ANY);
-
-class WebRtcVideoCapturerTest : public testing::Test {
- public:
-  WebRtcVideoCapturerTest()
-      : factory_(new FakeWebRtcVcmFactory),
-        capturer_(new cricket::WebRtcVideoCapturer(factory_)),
-        listener_(capturer_.get()) {
-    factory_->device_info.AddDevice(kTestDeviceName, kTestDeviceId);
-    // add a VGA/I420 capability
-    webrtc::VideoCaptureCapability vga;
-    vga.width = 640;
-    vga.height = 480;
-    vga.maxFPS = 30;
-    vga.rawType = webrtc::kVideoI420;
-    factory_->device_info.AddCapability(kTestDeviceId, vga);
-  }
-
- protected:
-  FakeWebRtcVcmFactory* factory_;  // owned by capturer_
-  talk_base::scoped_ptr<cricket::WebRtcVideoCapturer> capturer_;
-  cricket::VideoCapturerListener listener_;
-};
-
-TEST_F(WebRtcVideoCapturerTest, TestNotOpened) {
-  EXPECT_EQ("", capturer_->GetId());
-  EXPECT_EQ(NULL, capturer_->GetSupportedFormats());
-  EXPECT_TRUE(capturer_->GetCaptureFormat() == NULL);
-  EXPECT_FALSE(capturer_->IsRunning());
-}
-
-TEST_F(WebRtcVideoCapturerTest, TestBadInit) {
-  EXPECT_FALSE(capturer_->Init(cricket::Device("bad-name", "bad-id")));
-  EXPECT_FALSE(capturer_->IsRunning());
-}
-
-TEST_F(WebRtcVideoCapturerTest, TestInit) {
-  EXPECT_TRUE(capturer_->Init(cricket::Device(kTestDeviceName, kTestDeviceId)));
-  EXPECT_EQ(kTestDeviceId, capturer_->GetId());
-  EXPECT_TRUE(NULL != capturer_->GetSupportedFormats());
-  ASSERT_EQ(1U, capturer_->GetSupportedFormats()->size());
-  EXPECT_EQ(640, (*capturer_->GetSupportedFormats())[0].width);
-  EXPECT_EQ(480, (*capturer_->GetSupportedFormats())[0].height);
-  EXPECT_TRUE(capturer_->GetCaptureFormat() == NULL);  // not started yet
-  EXPECT_FALSE(capturer_->IsRunning());
-}
-
-TEST_F(WebRtcVideoCapturerTest, TestInitVcm) {
-  EXPECT_TRUE(capturer_->Init(factory_->Create(0,
-      reinterpret_cast<const WebRtc_UWord8*>(kTestDeviceId.c_str()))));
-}
-
-TEST_F(WebRtcVideoCapturerTest, TestCapture) {
-  EXPECT_TRUE(capturer_->Init(cricket::Device(kTestDeviceName, kTestDeviceId)));
-  cricket::VideoFormat format(
-      capturer_->GetSupportedFormats()->at(0));
-  EXPECT_EQ(cricket::CR_PENDING, capturer_->Start(format));
-  EXPECT_TRUE(capturer_->IsRunning());
-  ASSERT_TRUE(capturer_->GetCaptureFormat() != NULL);
-  EXPECT_EQ(format, *capturer_->GetCaptureFormat());
-  EXPECT_EQ_WAIT(cricket::CR_SUCCESS, listener_.start_result(), 1000);
-  EXPECT_TRUE(factory_->modules[0]->SendFrame(640, 480));
-  EXPECT_TRUE_WAIT(listener_.frame_count() > 0, 5000);
-  EXPECT_EQ(capturer_->GetCaptureFormat()->fourcc, listener_.frame_fourcc());
-  EXPECT_EQ(640, listener_.frame_width());
-  EXPECT_EQ(480, listener_.frame_height());
-  EXPECT_EQ(cricket::CR_FAILURE, capturer_->Start(format));
-  capturer_->Stop();
-  EXPECT_FALSE(capturer_->IsRunning());
-  EXPECT_TRUE(capturer_->GetCaptureFormat() == NULL);
-}
-
-TEST_F(WebRtcVideoCapturerTest, TestCaptureVcm) {
-  EXPECT_TRUE(capturer_->Init(factory_->Create(0,
-      reinterpret_cast<const WebRtc_UWord8*>(kTestDeviceId.c_str()))));
-  EXPECT_FALSE(capturer_->GetSupportedFormats());
-  VideoFormat format;
-  EXPECT_TRUE(capturer_->GetBestCaptureFormat(kDefaultVideoFormat, &format));
-  EXPECT_EQ(kDefaultVideoFormat.width, format.width);
-  EXPECT_EQ(kDefaultVideoFormat.height, format.height);
-  EXPECT_EQ(kDefaultVideoFormat.interval, format.interval);
-  EXPECT_EQ(cricket::FOURCC_I420, format.fourcc);
-  EXPECT_EQ(cricket::CR_PENDING, capturer_->Start(format));
-  EXPECT_TRUE(capturer_->IsRunning());
-  ASSERT_TRUE(capturer_->GetCaptureFormat() != NULL);
-  EXPECT_EQ(format, *capturer_->GetCaptureFormat());
-  EXPECT_EQ_WAIT(cricket::CR_SUCCESS, listener_.start_result(), 1000);
-  EXPECT_TRUE(factory_->modules[0]->SendFrame(640, 480));
-  EXPECT_TRUE_WAIT(listener_.frame_count() > 0, 5000);
-  EXPECT_EQ(capturer_->GetCaptureFormat()->fourcc, listener_.frame_fourcc());
-  EXPECT_EQ(640, listener_.frame_width());
-  EXPECT_EQ(480, listener_.frame_height());
-  EXPECT_EQ(cricket::CR_FAILURE, capturer_->Start(format));
-  capturer_->Stop();
-  EXPECT_FALSE(capturer_->IsRunning());
-  EXPECT_TRUE(capturer_->GetCaptureFormat() == NULL);
-}
-
-TEST_F(WebRtcVideoCapturerTest, TestCaptureWithoutInit) {
-  cricket::VideoFormat format;
-  EXPECT_EQ(cricket::CR_NO_DEVICE, capturer_->Start(format));
-  EXPECT_TRUE(capturer_->GetCaptureFormat() == NULL);
-  EXPECT_FALSE(capturer_->IsRunning());
-}
diff --git a/third_party/libjingle/source/talk/session/phone/webrtcvideoengine.cc b/third_party/libjingle/source/talk/session/phone/webrtcvideoengine.cc
deleted file mode 100644
index 046ae5f..0000000
--- a/third_party/libjingle/source/talk/session/phone/webrtcvideoengine.cc
+++ /dev/null
@@ -1,1615 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#ifdef HAVE_WEBRTC_VIDEO
-
-#include "talk/session/phone/webrtcvideoengine.h"
-
-#include "talk/base/basictypes.h"
-#include "talk/base/common.h"
-#include "talk/base/buffer.h"
-#include "talk/base/byteorder.h"
-#include "talk/base/logging.h"
-#include "talk/base/stringutils.h"
-#include "talk/session/phone/videorenderer.h"
-#include "talk/session/phone/webrtcpassthroughrender.h"
-#include "talk/session/phone/webrtcvoiceengine.h"
-#include "talk/session/phone/webrtcvideocapturer.h"
-#include "talk/session/phone/webrtcvideoframe.h"
-#include "talk/session/phone/webrtcvie.h"
-#include "talk/session/phone/webrtcvoe.h"
-
-// TODO Change video protection calls when WebRTC API has changed.
-#define WEBRTC_VIDEO_AVPF_NACK_ONLY
-
-namespace cricket {
-
-static const int kDefaultLogSeverity = talk_base::LS_WARNING;
-
-static const int kMinVideoBitrate = 100;
-static const int kStartVideoBitrate = 300;
-static const int kMaxVideoBitrate = 2000;
-
-static const int kVideoMtu = 1200;
-
-static const int kVideoRtpBufferSize = 65536;
-
-static const char kVp8PayloadName[] = "VP8";
-static const char kRedPayloadName[] = "red";
-static const char kFecPayloadName[] = "ulpfec";
-
-static const int kDefaultNumberOfTemporalLayers = 3;
-
-static void LogMultiline(talk_base::LoggingSeverity sev, char* text) {
-  const char* delim = "\r\n";
-  for (char* tok = strtok(text, delim); tok; tok = strtok(NULL, delim)) {
-    LOG_V(sev) << tok;
-  }
-}
-
-class WebRtcRenderAdapter : public webrtc::ExternalRenderer {
- public:
-  explicit WebRtcRenderAdapter(VideoRenderer* renderer)
-      : renderer_(renderer), width_(0), height_(0) {
-  }
-  virtual ~WebRtcRenderAdapter() {
-  }
-
-  void SetRenderer(VideoRenderer* renderer) {
-    talk_base::CritScope cs(&crit_);
-    renderer_ = renderer;
-  }
-  // Implementation of webrtc::ExternalRenderer.
-  virtual int FrameSizeChange(unsigned int width, unsigned int height,
-                              unsigned int /*number_of_streams*/) {
-    talk_base::CritScope cs(&crit_);
-    if (renderer_ == NULL) {
-      return 0;
-    }
-    width_ = width;
-    height_ = height;
-    return renderer_->SetSize(width_, height_, 0) ? 0 : -1;
-  }
-  virtual int DeliverFrame(unsigned char* buffer, int buffer_size,
-                           unsigned int time_stamp) {
-    talk_base::CritScope cs(&crit_);
-    frame_rate_tracker_.Update(1);
-    if (renderer_ == NULL) {
-      return 0;
-    }
-    WebRtcVideoFrame video_frame;
-    video_frame.Attach(buffer, buffer_size, width_, height_,
-                       1, 1, 0, time_stamp, 0);
-
-    int ret = renderer_->RenderFrame(&video_frame) ? 0 : -1;
-    uint8* buffer_temp;
-    size_t buffer_size_temp;
-    video_frame.Detach(&buffer_temp, &buffer_size_temp);
-    return ret;
-  }
-
-  unsigned int width() {
-   talk_base::CritScope cs(&crit_);
-   return width_;
-  }
-  unsigned int height() {
-   talk_base::CritScope cs(&crit_);
-   return height_;
-  }
-  int framerate() {
-    talk_base::CritScope cs(&crit_);
-    return frame_rate_tracker_.units_second();
-  }
-
- private:
-  talk_base::CriticalSection crit_;
-  VideoRenderer* renderer_;
-  unsigned int width_;
-  unsigned int height_;
-  talk_base::RateTracker frame_rate_tracker_;
-};
-
-class WebRtcDecoderObserver : public webrtc::ViEDecoderObserver {
- public:
-  WebRtcDecoderObserver(int video_channel)
-       : video_channel_(video_channel),
-         framerate_(0),
-         bitrate_(0),
-         firs_requested_(0) { }
-
-  // virtual functions from VieDecoderObserver.
-  virtual void IncomingCodecChanged(const int videoChannel,
-                                    const webrtc::VideoCodec& videoCodec) { }
-  virtual void IncomingRate(const int videoChannel,
-                            const unsigned int framerate,
-                            const unsigned int bitrate) {
-    ASSERT(video_channel_ == videoChannel);
-    framerate_ = framerate;
-    bitrate_ = bitrate;
-  }
-  virtual void RequestNewKeyFrame(const int videoChannel) {
-    ASSERT(video_channel_ == videoChannel);
-    ++firs_requested_;
-  }
-
-  int framerate() const { return framerate_; }
-  int bitrate() const { return bitrate_; }
-  int firs_requested() const { return firs_requested_; }
-
- private:
-  int video_channel_;
-  int framerate_;
-  int bitrate_;
-  int firs_requested_;
-};
-
-class WebRtcEncoderObserver : public webrtc::ViEEncoderObserver {
- public:
-  WebRtcEncoderObserver(int video_channel)
-       : video_channel_(video_channel), framerate_(0), bitrate_(0) { }
-
-  // virtual functions from VieEncoderObserver.
-  virtual void OutgoingRate(const int videoChannel,
-                            const unsigned int framerate,
-                            const unsigned int bitrate) {
-    ASSERT(video_channel_ == videoChannel);
-    framerate_ = framerate;
-    bitrate_ = bitrate;
-  }
-
-  int framerate() const { return framerate_; }
-  int bitrate() const { return bitrate_; }
-
- private:
-  int video_channel_;
-  int framerate_;
-  int bitrate_;
-};
-
-class LocalStreamInfo {
- public:
-  int width() {
-    talk_base::CritScope cs(&crit_);
-    return width_;
-  }
-  int height() {
-    talk_base::CritScope cs(&crit_);
-    return height_;
-  }
-  int framerate() {
-    talk_base::CritScope cs(&crit_);
-    return rate_tracker_.units_second();
-  }
-
-  void UpdateFrame(int width, int height) {
-    talk_base::CritScope cs(&crit_);
-    width_ = width;
-    height_ = height;
-    rate_tracker_.Update(1);
-  }
-
- private:
-  talk_base::CriticalSection crit_;
-  unsigned int width_;
-  unsigned int height_;
-  talk_base::RateTracker rate_tracker_;
-};
-
-const WebRtcVideoEngine::VideoCodecPref
-    WebRtcVideoEngine::kVideoCodecPrefs[] = {
-    {kVp8PayloadName, 100, 0},
-#ifndef WEBRTC_VIDEO_AVPF_NACK_ONLY
-    {kRedPayloadName, 101, 1},
-    {kFecPayloadName, 102, 2},
-#endif
-};
-
-// The formats are sorted by the descending order of width. We use the order to
-// find the next format for CPU and bandwidth adaptation.
-const VideoFormatPod WebRtcVideoEngine::kVideoFormats[] = {
-  {1280, 800, 30, FOURCC_ANY},
-  {1280, 720, 30, FOURCC_ANY},
-  {960, 600, 30, FOURCC_ANY},
-  {960, 540, 30, FOURCC_ANY},
-  {640, 400, 30, FOURCC_ANY},
-  {640, 360, 30, FOURCC_ANY},
-  {640, 480, 30, FOURCC_ANY},
-  {480, 300, 30, FOURCC_ANY},
-  {480, 270, 30, FOURCC_ANY},
-  {480, 360, 30, FOURCC_ANY},
-  {320, 200, 30, FOURCC_ANY},
-  {320, 180, 30, FOURCC_ANY},
-  {320, 240, 30, FOURCC_ANY},
-  {240, 150, 30, FOURCC_ANY},
-  {240, 135, 30, FOURCC_ANY},
-  {240, 180, 30, FOURCC_ANY},
-  {160, 100, 30, FOURCC_ANY},
-  {160, 90, 30, FOURCC_ANY},
-  {160, 120, 30, FOURCC_ANY},
-};
-
-const VideoFormatPod WebRtcVideoEngine::kDefaultVideoFormat =
-    {640, 400, 30, FOURCC_ANY};
-
-WebRtcVideoEngine::WebRtcVideoEngine() {
-  Construct(new ViEWrapper(), new ViETraceWrapper(), NULL);
-}
-
-WebRtcVideoEngine::WebRtcVideoEngine(WebRtcVoiceEngine* voice_engine,
-                                     ViEWrapper* vie_wrapper) {
-  Construct(vie_wrapper, new ViETraceWrapper(), voice_engine);
-}
-
-WebRtcVideoEngine::WebRtcVideoEngine(WebRtcVoiceEngine* voice_engine,
-                                     ViEWrapper* vie_wrapper,
-                                     ViETraceWrapper* tracing) {
-  Construct(vie_wrapper, tracing, voice_engine);
-}
-
-void WebRtcVideoEngine::Construct(ViEWrapper* vie_wrapper,
-                                  ViETraceWrapper* tracing,
-                                  WebRtcVoiceEngine* voice_engine) {
-  LOG(LS_INFO) << "WebRtcVideoEngine::WebRtcVideoEngine";
-  vie_wrapper_.reset(vie_wrapper);
-  vie_wrapper_base_initialized_ = false;
-  tracing_.reset(tracing);
-  voice_engine_ = voice_engine;
-  initialized_ = false;
-  log_level_ = kDefaultLogSeverity;
-  render_module_.reset(new WebRtcPassthroughRender());
-  local_renderer_w_ = local_renderer_h_ = 0;
-  local_renderer_ = NULL;
-  owns_capturer_ = false;
-  video_capturer_ = NULL;
-  capture_started_ = false;
-
-  ApplyLogging();
-  if (tracing_->SetTraceCallback(this) != 0) {
-    LOG_RTCERR1(SetTraceCallback, this);
-  }
-
-  // Set default quality levels for our supported codecs. We override them here
-  // if we know your cpu performance is low, and they can be updated explicitly
-  // by calling SetDefaultCodec.  For example by a flute preference setting, or
-  // by the server with a jec in response to our reported system info.
-  VideoCodec max_codec(kVideoCodecPrefs[0].payload_type,
-                       kVideoCodecPrefs[0].name,
-                       kDefaultVideoFormat.width,
-                       kDefaultVideoFormat.height,
-                       kDefaultVideoFormat.framerate,
-                       0);
-  if (!SetDefaultCodec(max_codec)) {
-    LOG(LS_ERROR) << "Failed to initialize list of supported codec types";
-  }
-}
-
-WebRtcVideoEngine::~WebRtcVideoEngine() {
-  ClearCapturer();
-  LOG(LS_INFO) << "WebRtcVideoEngine::~WebRtcVideoEngine";
-  if (initialized_) {
-    Terminate();
-  }
-  tracing_->SetTraceCallback(NULL);
-}
-
-bool WebRtcVideoEngine::Init() {
-  LOG(LS_INFO) << "WebRtcVideoEngine::Init";
-  bool result = InitVideoEngine();
-  if (result) {
-    LOG(LS_INFO) << "VideoEngine Init done";
-  } else {
-    LOG(LS_ERROR) << "VideoEngine Init failed, releasing";
-    Terminate();
-  }
-  return result;
-}
-
-bool WebRtcVideoEngine::InitVideoEngine() {
-  LOG(LS_INFO) << "WebRtcVideoEngine::InitVideoEngine";
-
-  // Init WebRTC VideoEngine.
-  if (!vie_wrapper_base_initialized_) {
-    if (vie_wrapper_->base()->Init() != 0) {
-      LOG_RTCERR0(Init);
-      return false;
-    }
-    vie_wrapper_base_initialized_ = true;
-  }
-
-  // Log the VoiceEngine version info.
-  char buffer[1024] = "";
-  if (vie_wrapper_->base()->GetVersion(buffer) != 0) {
-    LOG_RTCERR0(GetVersion);
-    return false;
-  }
-
-  LOG(LS_INFO) << "WebRtc VideoEngine Version:";
-  LogMultiline(talk_base::LS_INFO, buffer);
-
-  // Hook up to VoiceEngine for sync purposes, if supplied.
-  if (!voice_engine_) {
-    LOG(LS_WARNING) << "NULL voice engine";
-  } else if ((vie_wrapper_->base()->SetVoiceEngine(
-      voice_engine_->voe()->engine())) != 0) {
-    LOG_RTCERR0(SetVoiceEngine);
-    return false;
-  }
-
-  // Register for callbacks from the engine.
-  if ((vie_wrapper_->base()->RegisterObserver(*this)) != 0) {
-    LOG_RTCERR0(RegisterObserver);
-    return false;
-  }
-
-  // Register our custom render module.
-  if (vie_wrapper_->render()->RegisterVideoRenderModule(
-      *render_module_.get()) != 0) {
-    LOG_RTCERR0(RegisterVideoRenderModule);
-    return false;
-  }
-
-  initialized_ = true;
-  return true;
-}
-
-void WebRtcVideoEngine::Terminate() {
-  LOG(LS_INFO) << "WebRtcVideoEngine::Terminate";
-  initialized_ = false;
-  SetCapture(false);
-
-  if (vie_wrapper_->render()->DeRegisterVideoRenderModule(
-      *render_module_.get()) != 0) {
-    LOG_RTCERR0(DeRegisterVideoRenderModule);
-  }
-
-  if (vie_wrapper_->base()->DeregisterObserver() != 0) {
-    LOG_RTCERR0(DeregisterObserver);
-  }
-
-  if (vie_wrapper_->base()->SetVoiceEngine(NULL) != 0) {
-    LOG_RTCERR0(SetVoiceEngine);
-  }
-}
-
-int WebRtcVideoEngine::GetCapabilities() {
-  return VIDEO_RECV | VIDEO_SEND;
-}
-
-bool WebRtcVideoEngine::SetOptions(int options) {
-  return true;
-}
-
-bool WebRtcVideoEngine::SetDefaultEncoderConfig(
-    const VideoEncoderConfig& config) {
-  return SetDefaultCodec(config.max_codec);
-}
-
-// SetDefaultCodec may be called while the capturer is running. For example, a
-// test call is started in a page with QVGA default codec, and then a real call
-// is started in another page with VGA default codec. This is the corner case
-// and happens only when a session is started. We ignore this case currently.
-bool WebRtcVideoEngine::SetDefaultCodec(const VideoCodec& codec) {
-  if (!RebuildCodecList(codec)) {
-    LOG(LS_WARNING) << "Failed to RebuildCodecList";
-    return false;
-  }
-
-  default_codec_format_ = VideoFormat(
-      video_codecs_[0].width,
-      video_codecs_[0].height,
-      VideoFormat::FpsToInterval(video_codecs_[0].framerate),
-      FOURCC_ANY);
-  return true;
-}
-
-WebRtcVideoMediaChannel* WebRtcVideoEngine::CreateChannel(
-    VoiceMediaChannel* voice_channel) {
-  WebRtcVideoMediaChannel* channel =
-      new WebRtcVideoMediaChannel(this, voice_channel);
-  if (!channel->Init()) {
-    delete channel;
-    channel = NULL;
-  }
-  return channel;
-}
-
-bool WebRtcVideoEngine::SetCaptureDevice(const Device* device) {
-  if (!device) {
-    ClearCapturer();
-    LOG(LS_INFO) << "Camera set to NULL";
-    return true;
-  }
-  // No-op if the device hasn't changed.
-  if ((video_capturer_ != NULL) && video_capturer_->GetId() == device->id) {
-    return true;
-  }
-  // Create a new capturer for the specified device.
-  VideoCapturer* capturer = CreateVideoCapturer(*device);
-  if (!capturer) {
-    LOG(LS_ERROR) << "Failed to create camera '" << device->name << "', id='"
-                  << device->id << "'";
-    return false;
-  }
-  const bool owns_capturer = true;
-  if (!SetCapturer(capturer, owns_capturer)) {
-    return false;
-  }
-  LOG(LS_INFO) << "Camera set to '" << device->name << "', id='"
-               << device->id << "'";
-  return true;
-}
-
-bool WebRtcVideoEngine::SetCaptureModule(webrtc::VideoCaptureModule* vcm) {
-  if (!vcm) {
-    if ((video_capturer_ != NULL) && video_capturer_->IsRunning()) {
-      LOG(LS_WARNING) << "Failed to set camera to NULL when is running.";
-      return false;
-    } else {
-      ClearCapturer();
-      LOG(LS_INFO) << "Camera set to NULL";
-      return true;
-    }
-  }
-  // Create a new capturer for the specified device.
-  WebRtcVideoCapturer* capturer = new WebRtcVideoCapturer;
-  if (!capturer->Init(vcm)) {
-    LOG(LS_ERROR) << "Failed to create camera from VCM";
-    delete capturer;
-    return false;
-  }
-  const bool owns_capturer = true;
-  if (!SetCapturer(capturer, owns_capturer)) {
-    return false;
-  }
-  LOG(LS_INFO) << "Camera created with VCM";
-  return true;
-}
-
-bool WebRtcVideoEngine::SetVideoCapturer(VideoCapturer* capturer,
-                                         uint32 /*ssrc*/) {
-  const bool capture = (capturer != NULL);
-  const bool owns_capturer = false;
-  CaptureResult res = CR_FAILURE;
-  if (capture) {
-    // Register the capturer before starting to capture.
-    if (!SetCapturer(capturer, owns_capturer)) {
-      return false;
-    }
-    const bool kEnableCapture = true;
-    res = SetCapture(kEnableCapture);
-  } else {
-    // Stop capturing before unregistering the capturer.
-    const bool kDisableCapture = false;
-    res = SetCapture(kDisableCapture);
-    if (!SetCapturer(capturer, owns_capturer)) {
-      return false;
-    }
-  }
-  return (res == CR_SUCCESS) || (res == CR_PENDING);
-}
-
-bool WebRtcVideoEngine::SetLocalRenderer(VideoRenderer* renderer) {
-  local_renderer_w_ = local_renderer_h_ = 0;
-  local_renderer_ = renderer;
-  return true;
-}
-
-CaptureResult WebRtcVideoEngine::SetCapture(bool capture) {
-  bool old_capture = capture_started_;
-  capture_started_ = capture;
-  CaptureResult res = UpdateCapturingState();
-  if (res != CR_SUCCESS && res != CR_PENDING) {
-    capture_started_ = old_capture;
-  }
-  return res;
-}
-
-VideoCapturer* WebRtcVideoEngine::CreateVideoCapturer(const Device& device) {
-  WebRtcVideoCapturer* capturer = new WebRtcVideoCapturer;
-  if (!capturer->Init(device)) {
-    delete capturer;
-    return NULL;
-  }
-  return capturer;
-}
-
-CaptureResult WebRtcVideoEngine::UpdateCapturingState() {
-  CaptureResult result = CR_SUCCESS;
-
-  bool capture = capture_started_;
-  if (!IsCapturing() && capture) {  // Start capturing.
-    if (video_capturer_ == NULL) {
-      return CR_NO_DEVICE;
-    }
-
-    VideoFormat capture_format;
-    if (!video_capturer_->GetBestCaptureFormat(default_codec_format_,
-                                               &capture_format)) {
-      LOG(LS_WARNING) << "Unsupported format:"
-                      << " width=" << default_codec_format_.width
-                      << " height=" << default_codec_format_.height
-                      << ". Supported formats are:";
-      const std::vector<VideoFormat>* formats =
-          video_capturer_->GetSupportedFormats();
-      if (formats) {
-        for (std::vector<VideoFormat>::const_iterator i = formats->begin();
-             i != formats->end(); ++i) {
-          const VideoFormat& format = *i;
-          LOG(LS_WARNING) << "  " << GetFourccName(format.fourcc) << ":"
-                          << format.width << "x" << format.height << "x"
-                          << format.framerate();
-        }
-      }
-      return CR_FAILURE;
-    }
-
-    // Start the video capturer.
-    result = video_capturer_->Start(capture_format);
-    if (CR_SUCCESS != result && CR_PENDING != result) {
-      LOG(LS_ERROR) << "Failed to start the video capturer";
-      return result;
-    }
-  } else if (IsCapturing() && !capture) {  // Stop capturing.
-    video_capturer_->Stop();
-  }
-
-  return result;
-}
-
-bool WebRtcVideoEngine::IsCapturing() const {
-  return (video_capturer_ != NULL) && video_capturer_->IsRunning();
-}
-
-void WebRtcVideoEngine::OnFrameCaptured(VideoCapturer* capturer,
-                                        const CapturedFrame* frame) {
-  // Force 16:10 for now. We'll be smarter with the capture refactor.
-  int cropped_height = frame->width * default_codec_format_.height
-      / default_codec_format_.width;
-  if (cropped_height > frame->height) {
-    // TODO: Once we support horizontal cropping, add cropped_width.
-    cropped_height = frame->height;
-  }
-
-  // This CapturedFrame* will already be in I420. In the future, when
-  // WebRtcVideoFrame has support for independent planes, we can just attach
-  // to it and update the pointers when cropping.
-  WebRtcVideoFrame i420_frame;
-  if (!i420_frame.Init(frame, frame->width, cropped_height)) {
-    LOG(LS_ERROR) << "Couldn't convert to I420! "
-                  << frame->width << " x " << cropped_height;
-    return;
-  }
-
-  // Send I420 frame to the local renderer.
-  if (local_renderer_) {
-    if (local_renderer_w_ != static_cast<int>(i420_frame.GetWidth()) ||
-        local_renderer_h_ != static_cast<int>(i420_frame.GetHeight())) {
-      local_renderer_->SetSize(local_renderer_w_ = i420_frame.GetWidth(),
-                               local_renderer_h_ = i420_frame.GetHeight(), 0);
-    }
-    local_renderer_->RenderFrame(&i420_frame);
-  }
-
-  // Send I420 frame to the registered senders.
-  talk_base::CritScope cs(&channels_crit_);
-  for (VideoChannels::iterator it = channels_.begin();
-      it != channels_.end(); ++it) {
-    if ((*it)->sending()) (*it)->SendFrame(0, &i420_frame);
-  }
-}
-
-const std::vector<VideoCodec>& WebRtcVideoEngine::codecs() const {
-  return video_codecs_;
-}
-
-void WebRtcVideoEngine::SetLogging(int min_sev, const char* filter) {
-  log_level_ = min_sev;
-  ApplyLogging();
-}
-
-int WebRtcVideoEngine::GetLastEngineError() {
-  return vie_wrapper_->error();
-}
-
-// Checks to see whether we comprehend and could receive a particular codec
-bool WebRtcVideoEngine::FindCodec(const VideoCodec& in) {
-  for (int i = 0; i < ARRAY_SIZE(kVideoFormats); ++i) {
-    const VideoFormat fmt(kVideoFormats[i]);
-    if ((in.width == 0 && in.height == 0) ||
-        (fmt.width == in.width && fmt.height == in.height)) {
-      for (int j = 0; j < ARRAY_SIZE(kVideoCodecPrefs); ++j) {
-        VideoCodec codec(kVideoCodecPrefs[j].payload_type,
-                         kVideoCodecPrefs[j].name, 0, 0, 0, 0);
-        if (codec.Matches(in)) {
-          return true;
-        }
-      }
-    }
-  }
-  return false;
-}
-
-// Given the requested codec, returns true if we can send that codec type and
-// updates out with the best quality we could send for that codec. If current is
-// not empty, we constrain out so that its aspect ratio matches current's.
-bool WebRtcVideoEngine::CanSendCodec(const VideoCodec& requested,
-                                     const VideoCodec& current,
-                                     VideoCodec* out) {
-  if (!out) {
-    return false;
-  }
-
-  std::vector<VideoCodec>::const_iterator local_max;
-  for (local_max = video_codecs_.begin();
-       local_max < video_codecs_.end();
-       ++local_max) {
-    // First match codecs by payload type
-    if (!requested.Matches(local_max->id, local_max->name)) {
-      continue;
-    }
-
-    out->id = requested.id;
-    out->name = requested.name;
-    out->preference = requested.preference;
-    out->framerate = talk_base::_min(requested.framerate, local_max->framerate);
-    out->width = 0;
-    out->height = 0;
-
-    if (0 == requested.width && 0 == requested.height) {
-      // Special case with resolution 0. The channel should not send frames.
-      return true;
-    } else if (0 == requested.width || 0 == requested.height) {
-      // 0xn and nx0 are invalid resolutions.
-      return false;
-    }
-
-    // Pick the best quality that is within their and our bounds and has the
-    // correct aspect ratio.
-    for (int j = 0; j < ARRAY_SIZE(kVideoFormats); ++j) {
-      const VideoFormat format(kVideoFormats[j]);
-
-      // Skip any format that is larger than the local or remote maximums, or
-      // smaller than the current best match
-      if (format.width > requested.width || format.height > requested.height ||
-          format.width > local_max->width ||
-          (format.width < out->width && format.height < out->height)) {
-        continue;
-      }
-
-      bool better = false;
-
-      // Check any further constraints on this prospective format
-      if (!out->width || !out->height) {
-        // If we don't have any matches yet, this is the best so far.
-        better = true;
-      } else if (current.width && current.height) {
-        // current is set so format must match its ratio exactly.
-        better =
-            (format.width * current.height == format.height * current.width);
-      } else {
-        // Prefer closer aspect ratios i.e
-        // format.aspect - requested.aspect < out.aspect - requested.aspect
-        better = abs(format.width * requested.height * out->height -
-                     requested.width * format.height * out->height) <
-                 abs(out->width * format.height * requested.height -
-                     requested.width * format.height * out->height);
-      }
-
-      if (better) {
-        out->width = format.width;
-        out->height = format.height;
-      }
-    }
-    if (out->width > 0) {
-      return true;
-    }
-  }
-  return false;
-}
-
-void WebRtcVideoEngine::ConvertToCricketVideoCodec(
-    const webrtc::VideoCodec& in_codec, VideoCodec& out_codec) {
-  out_codec.id = in_codec.plType;
-  out_codec.name = in_codec.plName;
-  out_codec.width = in_codec.width;
-  out_codec.height = in_codec.height;
-  out_codec.framerate = in_codec.maxFramerate;
-}
-
-bool WebRtcVideoEngine::ConvertFromCricketVideoCodec(
-    const VideoCodec& in_codec, webrtc::VideoCodec& out_codec) {
-  bool found = false;
-  int ncodecs = vie_wrapper_->codec()->NumberOfCodecs();
-  for (int i = 0; i < ncodecs; ++i) {
-    if (vie_wrapper_->codec()->GetCodec(i, out_codec) == 0 &&
-      in_codec.name == out_codec.plName) {
-      found = true;
-      break;
-    }
-  }
-
-  if (!found) {
-    LOG(LS_ERROR) << "invalid codec type";
-    return false;
-  }
-
-  if (in_codec.id != 0)
-    out_codec.plType = in_codec.id;
-
-  if (in_codec.width != 0)
-    out_codec.width = in_codec.width;
-
-  if (in_codec.height != 0)
-    out_codec.height = in_codec.height;
-
-  if (in_codec.framerate != 0)
-    out_codec.maxFramerate = in_codec.framerate;
-
-  // Init the codec with the default bandwidth options.
-  out_codec.minBitrate = kMinVideoBitrate;
-  out_codec.startBitrate = kStartVideoBitrate;
-  out_codec.maxBitrate = kMaxVideoBitrate;
-
-  return true;
-}
-
-void WebRtcVideoEngine::RegisterChannel(WebRtcVideoMediaChannel *channel) {
-  talk_base::CritScope cs(&channels_crit_);
-  channels_.push_back(channel);
-}
-
-void WebRtcVideoEngine::UnregisterChannel(WebRtcVideoMediaChannel *channel) {
-  talk_base::CritScope cs(&channels_crit_);
-  channels_.erase(std::remove(channels_.begin(), channels_.end(), channel),
-                  channels_.end());
-}
-
-bool WebRtcVideoEngine::SetVoiceEngine(WebRtcVoiceEngine* voice_engine) {
-  if (initialized_) {
-    LOG(LS_WARNING) << "SetVoiceEngine can not be called after Init.";
-    return false;
-  }
-  voice_engine_ = voice_engine;
-  return true;
-}
-
-bool WebRtcVideoEngine::EnableTimedRender() {
-  if (initialized_) {
-    LOG(LS_WARNING) << "EnableTimedRender can not be called after Init.";
-    return false;
-  }
-  render_module_.reset(webrtc::VideoRender::CreateVideoRender(0, NULL,
-      false, webrtc::kRenderExternal));
-  return true;
-}
-
-void WebRtcVideoEngine::ApplyLogging() {
-  int filter = 0;
-  switch (log_level_) {
-    case talk_base::LS_VERBOSE: filter |= webrtc::kTraceAll;
-    case talk_base::LS_INFO: filter |= webrtc::kTraceStateInfo;
-    case talk_base::LS_WARNING: filter |= webrtc::kTraceWarning;
-    case talk_base::LS_ERROR: filter |=
-        webrtc::kTraceError | webrtc::kTraceCritical;
-  }
-  tracing_->SetTraceFilter(filter);
-}
-
-// Rebuilds the codec list to be only those that are less intensive
-// than the specified codec.
-bool WebRtcVideoEngine::RebuildCodecList(const VideoCodec& in_codec) {
-  if (!FindCodec(in_codec))
-    return false;
-
-  video_codecs_.clear();
-
-  bool found = false;
-  for (size_t i = 0; i < ARRAY_SIZE(kVideoCodecPrefs); ++i) {
-    const VideoCodecPref& pref(kVideoCodecPrefs[i]);
-    if (!found)
-      found = (in_codec.name == pref.name);
-    if (found) {
-      VideoCodec codec(pref.payload_type, pref.name,
-                       in_codec.width, in_codec.height, in_codec.framerate,
-                       ARRAY_SIZE(kVideoCodecPrefs) - i);
-      video_codecs_.push_back(codec);
-    }
-  }
-  ASSERT(found);
-  return true;
-}
-
-bool WebRtcVideoEngine::SetCapturer(VideoCapturer* capturer,
-                                    bool own_capturer) {
-  if (capturer == NULL) {
-    ClearCapturer();
-    return true;
-  }
-  // Hook up signals and install the supplied capturer.
-  SignalCaptureResult.repeat(capturer->SignalStartResult);
-  capturer->SignalFrameCaptured.connect(this,
-      &WebRtcVideoEngine::OnFrameCaptured);
-  ClearCapturer();
-  video_capturer_ = capturer;
-  owns_capturer_ = own_capturer;
-  // Possibly restart the capturer if it is supposed to be running.
-  CaptureResult result = UpdateCapturingState();
-  if (result != CR_SUCCESS && result != CR_PENDING) {
-    LOG(LS_WARNING) << "Camera failed to restart";
-    return false;
-  }
-  return true;
-}
-
-void WebRtcVideoEngine::PerformanceAlarm(const unsigned int cpu_load) {
-  LOG(LS_INFO) << "WebRtcVideoEngine::PerformanceAlarm";
-}
-
-// Ignore spammy trace messages, mostly from the stats API when we haven't
-// gotten RTCP info yet from the remote side.
-bool WebRtcVideoEngine::ShouldIgnoreTrace(const std::string& trace) {
-  static const char* const kTracesToIgnore[] = {
-    NULL
-  };
-  for (const char* const* p = kTracesToIgnore; *p; ++p) {
-    if (trace.find(*p) == 0) {
-      return true;
-    }
-  }
-  return false;
-}
-
-int WebRtcVideoEngine::GetNumOfChannels() {
-  talk_base::CritScope cs(&channels_crit_);
-  return channels_.size();
-}
-
-void WebRtcVideoEngine::Print(const webrtc::TraceLevel level,
-                              const char* trace, const int length) {
-  talk_base::LoggingSeverity sev = talk_base::LS_VERBOSE;
-  if (level == webrtc::kTraceError || level == webrtc::kTraceCritical)
-    sev = talk_base::LS_ERROR;
-  else if (level == webrtc::kTraceWarning)
-    sev = talk_base::LS_WARNING;
-  else if (level == webrtc::kTraceStateInfo || level == webrtc::kTraceInfo)
-    sev = talk_base::LS_INFO;
-
-  if (sev >= log_level_) {
-    // Skip past boilerplate prefix text
-    if (length < 72) {
-      std::string msg(trace, length);
-      LOG(LS_ERROR) << "Malformed webrtc log message: ";
-      LOG_V(sev) << msg;
-    } else {
-      std::string msg(trace + 71, length - 72);
-      if (!ShouldIgnoreTrace(msg) &&
-          (!voice_engine_ || !voice_engine_->ShouldIgnoreTrace(msg))) {
-        LOG_V(sev) << "WebRtc:" << msg;
-      }
-    }
-  }
-}
-
-// TODO: stubs for now
-bool WebRtcVideoEngine::RegisterProcessor(
-    VideoProcessor* video_processor) {
-  return true;
-}
-bool WebRtcVideoEngine::UnregisterProcessor(
-    VideoProcessor* video_processor) {
-  return true;
-}
-
-void WebRtcVideoEngine::ClearCapturer() {
-  if (owns_capturer_) {
-    delete video_capturer_;
-  }
-  video_capturer_ = NULL;
-}
-
-// WebRtcVideoMediaChannel
-
-WebRtcVideoMediaChannel::WebRtcVideoMediaChannel(
-    WebRtcVideoEngine* engine, VoiceMediaChannel* channel)
-    : engine_(engine),
-      voice_channel_(channel),
-      vie_channel_(-1),
-      vie_capture_(-1),
-      external_capture_(NULL),
-      sending_(false),
-      render_started_(false),
-      muted_(false),
-      send_min_bitrate_(kMinVideoBitrate),
-      send_start_bitrate_(kStartVideoBitrate),
-      send_max_bitrate_(kMaxVideoBitrate),
-      local_stream_info_(new LocalStreamInfo()) {
-  engine->RegisterChannel(this);
-}
-
-bool WebRtcVideoMediaChannel::Init() {
-  if (engine_->vie()->base()->CreateChannel(vie_channel_) != 0) {
-    LOG_RTCERR1(CreateChannel, vie_channel_);
-    return false;
-  }
-
-  LOG(LS_INFO) << "WebRtcVideoMediaChannel::Init "
-               << "vie_channel " << vie_channel_ << " created";
-
-  // Connect the voice channel, if there is one.
-  if (voice_channel_) {
-    WebRtcVoiceMediaChannel* channel =
-        static_cast<WebRtcVoiceMediaChannel*>(voice_channel_);
-    if (engine_->vie()->base()->ConnectAudioChannel(
-        vie_channel_, channel->voe_channel()) != 0) {
-      LOG_RTCERR2(ConnectAudioChannel, vie_channel_, channel->voe_channel());
-      LOG(LS_WARNING) << "A/V not synchronized";
-      // Not a fatal error.
-    }
-  }
-
-  // Register external transport.
-  if (engine_->vie()->network()->RegisterSendTransport(
-      vie_channel_, *this) != 0) {
-    LOG_RTCERR1(RegisterSendTransport, vie_channel_);
-    return false;
-  }
-
-  // Set MTU.
-  if (engine_->vie()->network()->SetMTU(vie_channel_, kVideoMtu) != 0) {
-    LOG_RTCERR2(SetMTU, vie_channel_, kVideoMtu);
-    return false;
-  }
-
-  // Register external capture.
-  if (engine()->vie()->capture()->AllocateExternalCaptureDevice(
-      vie_capture_, external_capture_) != 0) {
-    LOG_RTCERR0(AllocateExternalCaptureDevice);
-    return false;
-  }
-
-  // Connect external capture.
-  if (engine()->vie()->capture()->ConnectCaptureDevice(
-      vie_capture_, vie_channel_) != 0) {
-    LOG_RTCERR2(ConnectCaptureDevice, vie_capture_, vie_channel_);
-    return false;
-  }
-
-  // Install render adapter.
-  remote_renderer_.reset(new WebRtcRenderAdapter(NULL));
-  if (engine_->vie()->render()->AddRenderer(vie_channel_,
-      webrtc::kVideoI420, remote_renderer_.get()) != 0) {
-    LOG_RTCERR3(AddRenderer, vie_channel_, webrtc::kVideoI420,
-                remote_renderer_.get());
-    remote_renderer_.reset();
-    return false;
-  }
-
-  // Register decoder observer for incoming framerate and bitrate.
-  decoder_observer_.reset(new WebRtcDecoderObserver(vie_channel_));
-  if (engine()->vie()->codec()->RegisterDecoderObserver(
-      vie_channel_, *decoder_observer_) != 0) {
-    LOG_RTCERR1(RegisterDecoderObserver, decoder_observer_.get());
-    return false;
-  }
-
-  // Register encoder observer for outgoing framerate and bitrate.
-  encoder_observer_.reset(new WebRtcEncoderObserver(vie_channel_));
-  if (engine()->vie()->codec()->RegisterEncoderObserver(
-      vie_channel_, *encoder_observer_) != 0) {
-    LOG_RTCERR1(RegisterEncoderObserver, encoder_observer_.get());
-    return false;
-  }
-
-  // Turn on RTCP and loss feedback reporting.
-  if (!EnableRtcp() ||
-      !EnablePli()) {
-    return false;
-  }
-
-#ifdef WEBRTC_VIDEO_AVPF_NACK_ONLY
-  // Turn on NACK-only loss handling.
-  if (!EnableNack())
-    return false;
-#endif
-
-  // Turn on TMMBR-based BWE reporting.
-  if (!EnableTmmbr()) {
-    return false;
-  }
-
-  return true;
-}
-
-WebRtcVideoMediaChannel::~WebRtcVideoMediaChannel() {
-  if (vie_channel_ != -1) {
-    // Stop sending.
-    SetSend(false);
-    if (engine()->vie()->codec()->DeregisterEncoderObserver(
-        vie_channel_) != 0) {
-      LOG_RTCERR1(DeregisterEncoderObserver, vie_channel_);
-    }
-
-    // Stop the renderer.
-    SetRender(false);
-    if (engine()->vie()->codec()->DeregisterDecoderObserver(
-        vie_channel_) != 0) {
-      LOG_RTCERR1(DeregisterDecoderObserver, vie_channel_);
-    }
-    if (remote_renderer_.get() &&
-        engine()->vie()->render()->RemoveRenderer(vie_channel_) != 0) {
-      LOG_RTCERR1(RemoveRenderer, vie_channel_);
-    }
-
-    // Destroy the external capture interface.
-    if (vie_capture_ != -1) {
-      if (engine()->vie()->capture()->DisconnectCaptureDevice(
-          vie_channel_) != 0) {
-        LOG_RTCERR1(DisconnectCaptureDevice, vie_channel_);
-      }
-      if (engine()->vie()->capture()->ReleaseCaptureDevice(
-          vie_capture_) != 0) {
-        LOG_RTCERR1(ReleaseCaptureDevice, vie_capture_);
-      }
-    }
-
-    // Deregister external transport.
-    if (engine()->vie()->network()->DeregisterSendTransport(
-        vie_channel_) != 0) {
-      LOG_RTCERR1(DeregisterSendTransport, vie_channel_);
-    }
-
-    // Delete the VideoEngine channel.
-    if (engine()->vie()->base()->DeleteChannel(vie_channel_) != 0) {
-      LOG_RTCERR1(DeleteChannel, vie_channel_);
-    }
-  }
-
-  // Unregister the channel from the engine.
-  engine()->UnregisterChannel(this);
-}
-
-bool WebRtcVideoMediaChannel::SetRecvCodecs(
-    const std::vector<VideoCodec>& codecs) {
-  bool ret = true;
-  for (std::vector<VideoCodec>::const_iterator iter = codecs.begin();
-      iter != codecs.end(); ++iter) {
-    if (engine()->FindCodec(*iter)) {
-      webrtc::VideoCodec wcodec;
-      if (engine()->ConvertFromCricketVideoCodec(*iter, wcodec)) {
-        if (engine()->vie()->codec()->SetReceiveCodec(
-            vie_channel_, wcodec) != 0) {
-          LOG_RTCERR2(SetReceiveCodec, vie_channel_, wcodec.plName);
-          ret = false;
-        }
-      }
-    } else {
-      LOG(LS_INFO) << "Unknown codec " << iter->name;
-      ret = false;
-    }
-  }
-
-  // make channel ready to receive packets
-  if (ret) {
-    if (engine()->vie()->base()->StartReceive(vie_channel_) != 0) {
-      LOG_RTCERR1(StartReceive, vie_channel_);
-      ret = false;
-    }
-  }
-  return ret;
-}
-
-bool WebRtcVideoMediaChannel::SetSendCodecs(
-    const std::vector<VideoCodec>& codecs) {
-  // Match with local video codec list.
-  std::vector<webrtc::VideoCodec> send_codecs;
-  int red_type = -1, fec_type = -1;
-  VideoCodec checked_codec;
-  VideoCodec current;  // defaults to 0x0
-  if (sending_) {
-    engine()->ConvertToCricketVideoCodec(*send_codec_, current);
-  }
-  for (std::vector<VideoCodec>::const_iterator iter = codecs.begin();
-      iter != codecs.end(); ++iter) {
-    if (_stricmp(iter->name.c_str(), kRedPayloadName) == 0) {
-      red_type = iter->id;
-    } else if (_stricmp(iter->name.c_str(), kFecPayloadName) == 0) {
-      fec_type = iter->id;
-    } else if (engine()->CanSendCodec(*iter, current, &checked_codec)) {
-      webrtc::VideoCodec wcodec;
-      if (engine()->ConvertFromCricketVideoCodec(checked_codec, wcodec)) {
-        send_codecs.push_back(wcodec);
-      }
-    } else {
-      LOG(LS_WARNING) << "Unknown codec " << iter->name;
-    }
-  }
-
-  // Fail if we don't have a match.
-  if (send_codecs.empty()) {
-    LOG(LS_WARNING) << "No matching codecs avilable";
-    return false;
-  }
-
-#ifndef WEBRTC_VIDEO_AVPF_NACK_ONLY
-  // Configure FEC if enabled.
-  if (!SetNackFec(red_type, fec_type)) {
-    return false;
-  }
-#endif
-
-  // Select the first matched codec.
-  webrtc::VideoCodec& codec(send_codecs[0]);
-
-  // Set the default number of temporal layers for VP8.
-  if (webrtc::kVideoCodecVP8 == codec.codecType) {
-    codec.codecSpecific.VP8.numberOfTemporalLayers =
-        kDefaultNumberOfTemporalLayers;
-  }
-
-  if (!SetSendCodec(
-      codec, send_min_bitrate_, send_start_bitrate_, send_max_bitrate_)) {
-    return false;
-  }
-
-  LOG(LS_INFO) << "Selected video codec " << send_codec_->plName << "/"
-               << send_codec_->width << "x" << send_codec_->height << "x"
-               << static_cast<int>(send_codec_->maxFramerate);
-  if (webrtc::kVideoCodecVP8 == codec.codecType) {
-    LOG(LS_INFO) << "VP8 number of layers: "
-                 << static_cast<int>(
-                    send_codec_->codecSpecific.VP8.numberOfTemporalLayers);
-  }
-  return true;
-}
-
-bool WebRtcVideoMediaChannel::SetRender(bool render) {
-  if (render == render_started_) {
-    return true;  // no action required
-  }
-
-  bool ret = true;
-  if (render) {
-    if (engine()->vie()->render()->StartRender(vie_channel_) != 0) {
-      LOG_RTCERR1(StartRender, vie_channel_);
-      ret = false;
-    }
-  } else {
-    if (engine()->vie()->render()->StopRender(vie_channel_) != 0) {
-      LOG_RTCERR1(StopRender, vie_channel_);
-      ret = false;
-    }
-  }
-  if (ret) {
-    render_started_ = render;
-  }
-
-  return ret;
-}
-
-bool WebRtcVideoMediaChannel::SetSend(bool send) {
-  if (send == sending()) {
-    return true;  // no action required
-  }
-
-  if (send) {
-    // We've been asked to start sending.
-    // SetSendCodecs must have been called already.
-    if (!send_codec_.get()) {
-      return false;
-    }
-
-    if (engine()->vie()->base()->StartSend(vie_channel_) != 0) {
-      LOG_RTCERR1(StartSend, vie_channel_);
-      return false;
-    }
-  } else {
-    // We've been asked to stop sending.
-    if (engine()->vie()->base()->StopSend(vie_channel_) != 0) {
-      LOG_RTCERR1(StopSend, vie_channel_);
-      return false;
-    }
-  }
-
-  sending_ = send;
-  return true;
-}
-
-bool WebRtcVideoMediaChannel::AddStream(uint32 ssrc, uint32 voice_ssrc) {
-  return false;
-}
-
-bool WebRtcVideoMediaChannel::RemoveStream(uint32 ssrc) {
-  return false;
-}
-
-bool WebRtcVideoMediaChannel::SetRenderer(
-    uint32 ssrc, VideoRenderer* renderer) {
-  if (ssrc != 0)
-    return false;
-
-  remote_renderer_->SetRenderer(renderer);
-  return true;
-}
-
-bool WebRtcVideoMediaChannel::GetStats(VideoMediaInfo* info) {
-  // Get basic statistics.
-  unsigned int bytes_sent, packets_sent, bytes_recv, packets_recv;
-  unsigned int ssrc;
-  if (engine_->vie()->rtp()->GetRTPStatistics(vie_channel_,
-          bytes_sent, packets_sent, bytes_recv, packets_recv) != 0) {
-    LOG_RTCERR1(GetRTPStatistics, vie_channel_);
-    return false;
-  }
-
-  // Get sender statistics and build VideoSenderInfo.
-  if (engine_->vie()->rtp()->GetLocalSSRC(vie_channel_, ssrc) == 0) {
-    VideoSenderInfo sinfo;
-    sinfo.ssrc = ssrc;
-    sinfo.codec_name = send_codec_.get() ? send_codec_->plName : "";
-    sinfo.bytes_sent = bytes_sent;
-    sinfo.packets_sent = packets_sent;
-    sinfo.packets_cached = -1;
-    sinfo.packets_lost = -1;
-    sinfo.fraction_lost = -1;
-    sinfo.firs_rcvd = -1;
-    sinfo.nacks_rcvd = -1;
-    sinfo.rtt_ms = -1;
-    sinfo.frame_width = local_stream_info_->width();
-    sinfo.frame_height = local_stream_info_->height();
-    sinfo.framerate_input = local_stream_info_->framerate();
-    sinfo.framerate_sent = encoder_observer_->framerate();
-    sinfo.nominal_bitrate = encoder_observer_->bitrate();
-    sinfo.preferred_bitrate = kMaxVideoBitrate;
-
-    // Get received RTCP statistics for the sender, if available.
-    // It's not a fatal error if we can't, since RTCP may not have arrived yet.
-    uint16 r_fraction_lost;
-    unsigned int r_cumulative_lost;
-    unsigned int r_extended_max;
-    unsigned int r_jitter;
-    int r_rtt_ms;
-    if (engine_->vie()->rtp()->GetReceivedRTCPStatistics(vie_channel_,
-            r_fraction_lost, r_cumulative_lost, r_extended_max,
-            r_jitter, r_rtt_ms) == 0) {
-      // Convert Q8 to float.
-      sinfo.packets_lost = r_cumulative_lost;
-      sinfo.fraction_lost = static_cast<float>(r_fraction_lost) / (1 << 8);
-      sinfo.rtt_ms = r_rtt_ms;
-    }
-    info->senders.push_back(sinfo);
-  } else {
-    LOG_RTCERR1(GetLocalSSRC, vie_channel_);
-  }
-
-  // Get receiver statistics and build VideoReceiverInfo, if we have data.
-  if (engine_->vie()->rtp()->GetRemoteSSRC(vie_channel_, ssrc) == 0) {
-    VideoReceiverInfo rinfo;
-    rinfo.ssrc = ssrc;
-    rinfo.bytes_rcvd = bytes_recv;
-    rinfo.packets_rcvd = packets_recv;
-    rinfo.packets_lost = -1;
-    rinfo.packets_concealed = -1;
-    rinfo.fraction_lost = -1;  // from SentRTCP
-    rinfo.firs_sent = decoder_observer_->firs_requested();
-    rinfo.nacks_sent = -1;
-    rinfo.frame_width = remote_renderer_->width();
-    rinfo.frame_height = remote_renderer_->height();
-    rinfo.framerate_rcvd = decoder_observer_->framerate();
-    int fps = remote_renderer_->framerate();
-    rinfo.framerate_decoded = fps;
-    rinfo.framerate_output = fps;
-
-    // Get sent RTCP statistics.
-    uint16 s_fraction_lost;
-    unsigned int s_cumulative_lost;
-    unsigned int s_extended_max;
-    unsigned int s_jitter;
-    int s_rtt_ms;
-    if (engine_->vie()->rtp()->GetSentRTCPStatistics(vie_channel_,
-            s_fraction_lost, s_cumulative_lost, s_extended_max,
-            s_jitter, s_rtt_ms) == 0) {
-      // Convert Q8 to float.
-      rinfo.packets_lost = s_cumulative_lost;
-      rinfo.fraction_lost = static_cast<float>(s_fraction_lost) / (1 << 8);
-    }
-    info->receivers.push_back(rinfo);
-  }
-
-  // Build BandwidthEstimationInfo.
-  // TODO: Fill in more BWE stats once we have them.
-  unsigned int total_bitrate_sent;
-  unsigned int video_bitrate_sent;
-  unsigned int fec_bitrate_sent;
-  unsigned int nack_bitrate_sent;
-  if (engine_->vie()->rtp()->GetBandwidthUsage(vie_channel_,
-      total_bitrate_sent, video_bitrate_sent,
-      fec_bitrate_sent, nack_bitrate_sent) == 0) {
-    BandwidthEstimationInfo bwe;
-    bwe.actual_enc_bitrate = video_bitrate_sent;
-    bwe.transmit_bitrate = total_bitrate_sent;
-    bwe.retransmit_bitrate = nack_bitrate_sent;
-    info->bw_estimations.push_back(bwe);
-  } else {
-    LOG_RTCERR1(GetBandwidthUsage, vie_channel_);
-  }
-
-  return true;
-}
-
-bool WebRtcVideoMediaChannel::SendIntraFrame() {
-  bool ret = true;
-  if (engine()->vie()->codec()->SendKeyFrame(vie_channel_) != 0) {
-    LOG_RTCERR1(SendKeyFrame, vie_channel_);
-    ret = false;
-  }
-
-  return ret;
-}
-
-bool WebRtcVideoMediaChannel::RequestIntraFrame() {
-  // There is no API exposed to application to request a key frame
-  // ViE does this internally when there are errors from decoder
-  return false;
-}
-
-void WebRtcVideoMediaChannel::OnPacketReceived(talk_base::Buffer* packet) {
-  engine()->vie()->network()->ReceivedRTPPacket(vie_channel_,
-                                                         packet->data(),
-                                                         packet->length());
-}
-
-void WebRtcVideoMediaChannel::OnRtcpReceived(talk_base::Buffer* packet) {
-  engine_->vie()->network()->ReceivedRTCPPacket(vie_channel_,
-                                                         packet->data(),
-                                                         packet->length());
-}
-
-void WebRtcVideoMediaChannel::SetSendSsrc(uint32 id) {
-  if (!sending_) {
-    if (engine()->vie()->rtp()->SetLocalSSRC(vie_channel_, id) != 0) {
-      LOG_RTCERR1(SetLocalSSRC, vie_channel_);
-    }
-  } else {
-    LOG(LS_ERROR) << "Channel already in send state";
-  }
-}
-
-bool WebRtcVideoMediaChannel::SetRtcpCName(const std::string& cname) {
-  if (engine()->vie()->rtp()->SetRTCPCName(vie_channel_,
-                                           cname.c_str()) != 0) {
-    LOG_RTCERR2(SetRTCPCName, vie_channel_, cname.c_str());
-    return false;
-  }
-  return true;
-}
-
-bool WebRtcVideoMediaChannel::Mute(bool on) {
-  muted_ = on;
-  return true;
-}
-
-bool WebRtcVideoMediaChannel::SetSendBandwidth(bool autobw, int bps) {
-  LOG(LS_INFO) << "RtcVideoMediaChanne::SetSendBandwidth";
-
-  if (!send_codec_.get()) {
-    LOG(LS_INFO) << "The send codec has not been set up yet.";
-    return true;
-  }
-
-  int min_bitrate;
-  int start_bitrate;
-  int max_bitrate;
-  if (autobw) {
-    // Use the default values for min bitrate.
-    min_bitrate = kMinVideoBitrate;
-    // Use the default value or the bps for the max
-    max_bitrate = (bps <= 0) ? kMaxVideoBitrate : (bps / 1000);
-    // Maximum start bitrate can be kStartVideoBitrate.
-    start_bitrate = talk_base::_min(kStartVideoBitrate, max_bitrate);
-  } else {
-    // Use the default start or the bps as the target bitrate.
-    int target_bitrate = (bps <= 0) ? kStartVideoBitrate : (bps / 1000);
-    min_bitrate = target_bitrate;
-    start_bitrate = target_bitrate;
-    max_bitrate = target_bitrate;
-  }
-
-  if (!SetSendCodec(*send_codec_, min_bitrate, start_bitrate, max_bitrate)) {
-    return false;
-  }
-
-  return true;
-}
-
-bool WebRtcVideoMediaChannel::SetOptions(int options) {
-  return true;
-}
-
-void WebRtcVideoMediaChannel::SetInterface(NetworkInterface* iface) {
-  MediaChannel::SetInterface(iface);
-  // Set the RTP recv/send buffer to a bigger size
-  if (network_interface_) {
-    network_interface_->SetOption(NetworkInterface::ST_RTP,
-                                  talk_base::Socket::OPT_RCVBUF,
-                                  kVideoRtpBufferSize);
-    network_interface_->SetOption(NetworkInterface::ST_RTP,
-                                  talk_base::Socket::OPT_SNDBUF,
-                                  kVideoRtpBufferSize);
-  }
-}
-
-// TODO: Add unittests to test this function.
-bool WebRtcVideoMediaChannel::SendFrame(uint32 ssrc, const VideoFrame* frame) {
-  if (ssrc != 0 || !sending() || !external_capture_) {
-    return false;
-  }
-
-  // Update local stream statistics.
-  local_stream_info_->UpdateFrame(frame->GetWidth(), frame->GetHeight());
-
-  // If the captured video format is smaller than what we asked for, reset send
-  // codec on video engine.
-  if (send_codec_.get() != NULL &&
-      frame->GetWidth() < send_codec_->width &&
-      frame->GetHeight() < send_codec_->height) {
-    LOG(LS_INFO) << "Captured video frame size changed to: "
-                 << frame->GetWidth() << "x" << frame->GetHeight();
-    webrtc::VideoCodec new_codec = *send_codec_;
-    new_codec.width = frame->GetWidth();
-    new_codec.height = frame->GetHeight();
-    if (!SetSendCodec(
-        new_codec, send_min_bitrate_, send_start_bitrate_, send_max_bitrate_)) {
-      LOG(LS_WARNING) << "Failed to switch to new frame size: "
-                      << frame->GetWidth() << "x" << frame->GetHeight();
-    }
-  }
-  
-  // Blacken the frame if video is muted.
-  const VideoFrame* frame_out = frame;
-  talk_base::scoped_ptr<VideoFrame> black_frame;
-  if (muted_) {
-    black_frame.reset(frame->Copy());
-    black_frame->SetToBlack();
-    frame_out = black_frame.get();
-  }
-
-  webrtc::ViEVideoFrameI420 frame_i420;
-  // TODO: Update the webrtc::ViEVideoFrameI420
-  // to use const unsigned char*
-  frame_i420.y_plane = const_cast<unsigned char*>(frame_out->GetYPlane());
-  frame_i420.u_plane = const_cast<unsigned char*>(frame_out->GetUPlane());
-  frame_i420.v_plane = const_cast<unsigned char*>(frame_out->GetVPlane());
-  frame_i420.y_pitch = frame_out->GetYPitch();
-  frame_i420.u_pitch = frame_out->GetUPitch();
-  frame_i420.v_pitch = frame_out->GetVPitch();
-  frame_i420.width = frame_out->GetWidth();
-  frame_i420.height = frame_out->GetHeight();
-
-  // Convert from nanoseconds to milliseconds.
-  WebRtc_Word64 clocks = frame_out->GetTimeStamp() /
-      talk_base::kNumNanosecsPerMillisec;
-
-  return (external_capture_->IncomingFrameI420(frame_i420, clocks) == 0);
-}
-
-bool WebRtcVideoMediaChannel::EnableRtcp() {
-  if (engine()->vie()->rtp()->SetRTCPStatus(
-          vie_channel_, webrtc::kRtcpCompound_RFC4585) != 0) {
-    LOG_RTCERR2(SetRTCPStatus, vie_channel_, webrtc::kRtcpCompound_RFC4585);
-    return false;
-  }
-  return true;
-}
-
-bool WebRtcVideoMediaChannel::EnablePli() {
-  if (engine_->vie()->rtp()->SetKeyFrameRequestMethod(
-          vie_channel_, webrtc::kViEKeyFrameRequestPliRtcp) != 0) {
-    LOG_RTCERR2(SetRTCPStatus,
-                vie_channel_, webrtc::kViEKeyFrameRequestPliRtcp);
-    return false;
-  }
-  return true;
-}
-
-bool WebRtcVideoMediaChannel::EnableTmmbr() {
-  if (engine_->vie()->rtp()->SetTMMBRStatus(vie_channel_, true) != 0) {
-    LOG_RTCERR1(SetTMMBRStatus, vie_channel_);
-    return false;
-  }
-  return true;
-}
-
-bool WebRtcVideoMediaChannel::EnableNack() {
-  if (engine_->vie()->rtp()->SetNACKStatus(vie_channel_, true) != 0) {
-    LOG_RTCERR1(SetNACKStatus, vie_channel_);
-    return false;
-  }
-  return true;
-}
-
-bool WebRtcVideoMediaChannel::SetNackFec(int red_payload_type,
-                                         int fec_payload_type) {
-  bool enable = (red_payload_type != -1 && fec_payload_type != -1);
-  if (engine_->vie()->rtp()->SetHybridNACKFECStatus(
-          vie_channel_, enable, red_payload_type, fec_payload_type) != 0) {
-    LOG_RTCERR4(SetHybridNACKFECStatus,
-                vie_channel_, enable, red_payload_type, fec_payload_type);
-    return false;
-  }
-  return true;
-}
-
-bool WebRtcVideoMediaChannel::SetSendCodec(const webrtc::VideoCodec& codec,
-                                           int min_bitrate,
-                                           int start_bitrate,
-                                           int max_bitrate) {
-  // Make a copy of the codec
-  webrtc::VideoCodec target_codec = codec;
-  target_codec.startBitrate = start_bitrate;
-  target_codec.minBitrate = min_bitrate;
-  target_codec.maxBitrate = max_bitrate;
-
-  if (engine()->vie()->codec()->SetSendCodec(vie_channel_, target_codec) != 0) {
-    LOG_RTCERR2(SetSendCodec, vie_channel_, send_codec_->plName);
-    return false;
-  }
-
-  // Reset the send_codec_ only if SetSendCodec is success.
-  send_codec_.reset(new webrtc::VideoCodec(target_codec));
-  send_min_bitrate_ = min_bitrate;
-  send_start_bitrate_ = start_bitrate;
-  send_max_bitrate_ = max_bitrate;
-
-  return true;
-}
-
-int WebRtcVideoMediaChannel::SendPacket(int channel, const void* data,
-                                        int len) {
-  if (!network_interface_) {
-    return -1;
-  }
-  talk_base::Buffer packet(data, len, kMaxRtpPacketLen);
-  return network_interface_->SendPacket(&packet) ? len : -1;
-}
-
-int WebRtcVideoMediaChannel::SendRTCPPacket(int channel,
-                                            const void* data,
-                                            int len) {
-  if (!network_interface_) {
-    return -1;
-  }
-  talk_base::Buffer packet(data, len, kMaxRtpPacketLen);
-  return network_interface_->SendRtcp(&packet) ? len : -1;
-}
-
-}  // namespace cricket
-
-#endif  // HAVE_WEBRTC_VIDEO
diff --git a/third_party/libjingle/source/talk/session/phone/webrtcvideoengine.h b/third_party/libjingle/source/talk/session/phone/webrtcvideoengine.h
deleted file mode 100644
index e2d1b7c..0000000
--- a/third_party/libjingle/source/talk/session/phone/webrtcvideoengine.h
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SESSION_PHONE_WEBRTCVIDEOENGINE_H_
-#define TALK_SESSION_PHONE_WEBRTCVIDEOENGINE_H_
-
-#include <vector>
-
-#include "talk/base/scoped_ptr.h"
-#include "talk/session/phone/videocommon.h"
-#include "talk/session/phone/codec.h"
-#include "talk/session/phone/channel.h"
-#include "talk/session/phone/webrtccommon.h"
-#ifdef WEBRTC_RELATIVE_PATH
-#include "video_engine/include/vie_base.h"
-#else
-#include "third_party/webrtc/files/include/vie_base.h"
-#endif  // WEBRTC_RELATIVE_PATH
-
-namespace webrtc {
-class VideoCaptureModule;
-class VideoRender;
-class ViEExternalCapture;
-}
-
-namespace cricket {
-struct CapturedFrame;
-struct Device;
-class LocalStreamInfo;
-class VideoCapturer;
-class VideoFrame;
-class VideoProcessor;
-class VideoRenderer;
-class ViETraceWrapper;
-class ViEWrapper;
-class VoiceMediaChannel;
-class WebRtcRenderAdapter;
-class WebRtcVideoMediaChannel;
-class WebRtcVoiceEngine;
-class WebRtcDecoderObserver;
-class WebRtcEncoderObserver;
-
-class WebRtcVideoEngine : public sigslot::has_slots<>,
-                          public webrtc::ViEBaseObserver,
-                          public webrtc::TraceCallback {
- public:
-  // Creates the WebRtcVideoEngine with internal VideoCaptureModule.
-  WebRtcVideoEngine();
-  // For testing purposes. Allows the WebRtcVoiceEngine and
-  // ViEWrapper to be mocks.
-  // TODO: Remove the 2-arg ctor once fake tracing is implemented.
-  WebRtcVideoEngine(WebRtcVoiceEngine* voice_engine,
-                    ViEWrapper* vie_wrapper);
-  WebRtcVideoEngine(WebRtcVoiceEngine* voice_engine,
-                    ViEWrapper* vie_wrapper,
-                    ViETraceWrapper* tracing);
-  ~WebRtcVideoEngine();
-
-  // Basic video engine implementation.
-  bool Init();
-  void Terminate();
-
-  int GetCapabilities();
-  bool SetOptions(int options);
-  bool SetDefaultEncoderConfig(const VideoEncoderConfig& config);
-
-  WebRtcVideoMediaChannel* CreateChannel(VoiceMediaChannel* voice_channel);
-
-  const std::vector<VideoCodec>& codecs() const;
-  void SetLogging(int min_sev, const char* filter);
-
-  // Capture-related stuff. Will be removed with capture refactor.
-  bool SetCaptureDevice(const Device* device);
-  bool SetCaptureModule(webrtc::VideoCaptureModule* vcm);
-  // If capturer is NULL, unregisters the capturer and stops capturing.
-  // Otherwise sets the capturer and starts capturing.
-  bool SetVideoCapturer(VideoCapturer* capturer, uint32 /*ssrc*/);
-  bool SetLocalRenderer(VideoRenderer* renderer);
-  CaptureResult SetCapture(bool capture);
-  sigslot::repeater2<VideoCapturer*, CaptureResult> SignalCaptureResult;
-  virtual VideoCapturer* CreateVideoCapturer(const Device& device);
-  CaptureResult UpdateCapturingState();
-  bool IsCapturing() const;
-  void OnFrameCaptured(VideoCapturer* capturer, const CapturedFrame* frame);
-
-  // Set the VoiceEngine for A/V sync. This can only be called before Init.
-  bool SetVoiceEngine(WebRtcVoiceEngine* voice_engine);
-  // Enable the render module with timing control.
-  bool EnableTimedRender();
-
-  bool RegisterProcessor(VideoProcessor* video_processor);
-  bool UnregisterProcessor(VideoProcessor* video_processor);
-
-  // Functions called by WebRtcVideoMediaChannel.
-  ViEWrapper* vie() { return vie_wrapper_.get(); }
-  const VideoFormat& default_codec_format() const {
-    return default_codec_format_;
-  }
-  int GetLastEngineError();
-  bool FindCodec(const VideoCodec& in);
-  bool CanSendCodec(const VideoCodec& in, const VideoCodec& current,
-                    VideoCodec* out);
-  void RegisterChannel(WebRtcVideoMediaChannel* channel);
-  void UnregisterChannel(WebRtcVideoMediaChannel* channel);
-  void ConvertToCricketVideoCodec(const webrtc::VideoCodec& in_codec,
-                                  VideoCodec& out_codec);
-  bool ConvertFromCricketVideoCodec(const VideoCodec& in_codec,
-                                    webrtc::VideoCodec& out_codec);
-  // Check whether the supplied trace should be ignored.
-  bool ShouldIgnoreTrace(const std::string& trace);
-  int GetNumOfChannels();
-
- protected:
-  // When a video processor registers with the engine.
-  // SignalMediaFrame will be invoked for every video frame.
-  sigslot::signal2<uint32, VideoFrame*> SignalMediaFrame;
-
- private:
-  typedef std::vector<WebRtcVideoMediaChannel*> VideoChannels;
-  struct VideoCodecPref {
-    const char* name;
-    int payload_type;
-    int pref;
-  };
-
-  static const VideoCodecPref kVideoCodecPrefs[];
-  static const VideoFormatPod kVideoFormats[];
-  static const VideoFormatPod kDefaultVideoFormat;
-
-  void Construct(ViEWrapper* vie_wrapper,
-                 ViETraceWrapper* tracing,
-                 WebRtcVoiceEngine* voice_engine);
-  bool SetDefaultCodec(const VideoCodec& codec);
-  bool RebuildCodecList(const VideoCodec& max_codec);
-  void ApplyLogging();
-  bool InitVideoEngine();
-  bool SetCapturer(VideoCapturer* capturer, bool own_capturer);
-
-  // webrtc::ViEBaseObserver implementation.
-  virtual void PerformanceAlarm(const unsigned int cpu_load);
-  // webrtc::TraceCallback implementation.
-  virtual void Print(const webrtc::TraceLevel level, const char* trace_string,
-                     const int length);
-
-  void ClearCapturer();
-
-  talk_base::scoped_ptr<ViEWrapper> vie_wrapper_;
-  bool vie_wrapper_base_initialized_;
-  talk_base::scoped_ptr<ViETraceWrapper> tracing_;
-  WebRtcVoiceEngine* voice_engine_;
-  int log_level_;
-  talk_base::scoped_ptr<webrtc::VideoRender> render_module_;
-  std::vector<VideoCodec> video_codecs_;
-  VideoFormat default_codec_format_;
-  bool initialized_;
-  talk_base::CriticalSection channels_crit_;
-  VideoChannels channels_;
-
-  bool owns_capturer_;
-  VideoCapturer* video_capturer_;
-  bool capture_started_;
-  int local_renderer_w_;
-  int local_renderer_h_;
-  VideoRenderer* local_renderer_;
-
-  // Critical section to protect the media processor register/unregister
-  // while processing a frame
-  talk_base::CriticalSection signal_media_critical_;
-};
-
-class WebRtcVideoMediaChannel : public VideoMediaChannel,
-                                public webrtc::Transport {
- public:
-  WebRtcVideoMediaChannel(
-      WebRtcVideoEngine* engine, VoiceMediaChannel* voice_channel);
-  ~WebRtcVideoMediaChannel();
-  bool Init();
-
-  WebRtcVideoEngine* engine() { return engine_; }
-  VoiceMediaChannel* voice_channel() { return voice_channel_; }
-  int video_channel() const { return vie_channel_; }
-  bool sending() const { return sending_; }
-
-  // VideoMediaChannel implementation
-  virtual bool SetRecvCodecs(const std::vector<VideoCodec> &codecs);
-  virtual bool SetSendCodecs(const std::vector<VideoCodec> &codecs);
-  virtual bool SetRender(bool render);
-  virtual bool SetSend(bool send);
-  virtual bool AddStream(uint32 ssrc, uint32 voice_ssrc);
-  virtual bool RemoveStream(uint32 ssrc);
-  virtual bool SetRenderer(uint32 ssrc, VideoRenderer* renderer);
-  virtual bool GetStats(VideoMediaInfo* info);
-  virtual bool AddScreencast(uint32 ssrc, talk_base::WindowId id) {
-    return false;
-  }
-  virtual bool RemoveScreencast(uint32 ssrc) {
-    return false;
-  }
-  virtual bool SendIntraFrame();
-  virtual bool RequestIntraFrame();
-
-  virtual void OnPacketReceived(talk_base::Buffer* packet);
-  virtual void OnRtcpReceived(talk_base::Buffer* packet);
-  virtual void SetSendSsrc(uint32 id);
-  virtual bool SetRtcpCName(const std::string& cname);
-  virtual bool Mute(bool on);
-  virtual bool SetRecvRtpHeaderExtensions(
-      const std::vector<RtpHeaderExtension>& extensions) {
-    return false;
-  }
-  virtual bool SetSendRtpHeaderExtensions(
-      const std::vector<RtpHeaderExtension>& extensions) {
-    return false;
-  }
-  virtual bool SetSendBandwidth(bool autobw, int bps);
-  virtual bool SetOptions(int options);
-  virtual void SetInterface(NetworkInterface* iface);
-
-  // Public functions for use by tests and other specialized code.
-  uint32 send_ssrc() const { return 0; }
-  bool GetRenderer(uint32 ssrc, VideoRenderer** renderer) {
-    *renderer = NULL;
-    return false;
-  }
-  bool SendFrame(uint32 ssrc, const VideoFrame* frame);
-
-  // Thunk functions for use with HybridVideoEngine
-  void OnLocalFrame(VideoCapturer* capturer, const VideoFrame* frame) {
-    SendFrame(0, frame);
-  }
-  void OnLocalFrameFormat(VideoCapturer* capturer, const VideoFormat* format) {
-  }
-
- protected:
-  int GetLastEngineError() { return engine()->GetLastEngineError(); }
-  virtual int SendPacket(int channel, const void* data, int len);
-  virtual int SendRTCPPacket(int channel, const void* data, int len);
-
- private:
-  bool EnableRtcp();
-  bool EnablePli();
-  bool EnableTmmbr();
-  bool EnableNack();
-  bool SetNackFec(int red_payload_type, int fec_payload_type);
-  bool SetSendCodec(const webrtc::VideoCodec& codec,
-                    int min_bitrate,
-                    int start_bitrate,
-                    int max_bitrate);
-  bool ResetRecvCodecs(int channel);
-
-  WebRtcVideoEngine* engine_;
-  VoiceMediaChannel* voice_channel_;
-  int vie_channel_;
-  int vie_capture_;
-  webrtc::ViEExternalCapture* external_capture_;
-  bool sending_;
-  bool render_started_;
-  bool muted_;  // Flag to tell if we need to mute video.
-  int send_min_bitrate_;
-  int send_start_bitrate_;
-  int send_max_bitrate_;
-  talk_base::scoped_ptr<webrtc::VideoCodec> send_codec_;
-  talk_base::scoped_ptr<WebRtcRenderAdapter> remote_renderer_;
-  talk_base::scoped_ptr<WebRtcDecoderObserver> decoder_observer_;
-  talk_base::scoped_ptr<WebRtcEncoderObserver> encoder_observer_;
-  talk_base::scoped_ptr<LocalStreamInfo> local_stream_info_;
-};
-
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_WEBRTCVIDEOENGINE_H_
diff --git a/third_party/libjingle/source/talk/session/phone/webrtcvideoengine_unittest.cc b/third_party/libjingle/source/talk/session/phone/webrtcvideoengine_unittest.cc
deleted file mode 100644
index ad11f20..0000000
--- a/third_party/libjingle/source/talk/session/phone/webrtcvideoengine_unittest.cc
+++ /dev/null
@@ -1,673 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/gunit.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/session/phone/fakewebrtcvideocapturemodule.h"
-#include "talk/session/phone/fakewebrtcvideoengine.h"
-#include "talk/session/phone/fakewebrtcvoiceengine.h"
-#include "talk/session/phone/mediasession.h"
-#include "talk/session/phone/videoengine_unittest.h"
-#include "talk/session/phone/webrtcvideocapturer.h"
-#include "talk/session/phone/webrtcvideoengine.h"
-#include "talk/session/phone/webrtcvideoframe.h"
-#include "talk/session/phone/webrtcvoiceengine.h"
-
-// Tests for the WebRtcVideoEngine/VideoChannel code.
-
-static const cricket::VideoCodec kVP8Codec(100, "VP8", 640, 400, 30, 0);
-static const cricket::VideoCodec kRedCodec(101, "red", 0, 0, 0, 0);
-static const cricket::VideoCodec kUlpFecCodec(102, "ulpfec", 0, 0, 0, 0);
-static const cricket::VideoCodec* const kVideoCodecs[] = {
-    &kVP8Codec,
-    &kRedCodec,
-    &kUlpFecCodec
-};
-
-static const unsigned int kMinBandwidthKbps = 100;
-static const unsigned int kStartBandwidthKbps = 300;
-static const unsigned int kMaxBandwidthKbps = 2000;
-
-class FakeViEWrapper : public cricket::ViEWrapper {
- public:
-  explicit FakeViEWrapper(cricket::FakeWebRtcVideoEngine* engine)
-      : cricket::ViEWrapper(engine,  // base
-                            engine,  // codec
-                            engine,  // capture
-                            engine,  // network
-                            engine,  // render
-                            engine,  // rtp
-                            engine) {  // image
-  }
-};
-
-// Test fixture to test WebRtcVideoEngine with a fake webrtc::VideoEngine.
-// Useful for testing failure paths.
-class WebRtcVideoEngineTestFake : public testing::Test {
- public:
-  WebRtcVideoEngineTestFake()
-      : vie_(kVideoCodecs, ARRAY_SIZE(kVideoCodecs)),
-        engine_(NULL,  // cricket::WebRtcVoiceEngine
-                new FakeViEWrapper(&vie_)),
-        channel_(NULL),
-        voice_channel_(NULL) {
-  }
-  bool SetupEngine() {
-    bool result = engine_.Init();
-    if (result) {
-      channel_ = engine_.CreateChannel(voice_channel_);
-      result = (channel_ != NULL);
-    }
-    return result;
-  }
-  virtual void TearDown() {
-    delete channel_;
-    engine_.Terminate();
-  }
-
- protected:
-  cricket::FakeWebRtcVideoEngine vie_;
-  cricket::WebRtcVideoEngine engine_;
-  cricket::WebRtcVideoMediaChannel* channel_;
-  cricket::WebRtcVoiceMediaChannel* voice_channel_;
-};
-
-// Test fixtures to test WebRtcVideoEngine with a real webrtc::VideoEngine.
-class WebRtcVideoEngineTest
-    : public VideoEngineTest<cricket::WebRtcVideoEngine> {
- protected:
-  typedef VideoEngineTest<cricket::WebRtcVideoEngine> Base;
-};
-class WebRtcVideoMediaChannelTest
-    : public VideoMediaChannelTest<
-        cricket::WebRtcVideoEngine, cricket::WebRtcVideoMediaChannel> {
- protected:
-  typedef VideoMediaChannelTest<cricket::WebRtcVideoEngine,
-       cricket::WebRtcVideoMediaChannel> Base;
-  virtual cricket::VideoCodec DefaultCodec() { return kVP8Codec; }
-  virtual void SetUp() {
-    Base::SetUp();
-    // Need to start the capturer to allow us to pump in frames.
-    engine_.SetCapture(true);
-  }
-  virtual void TearDown() {
-    engine_.SetCapture(false);
-    Base::TearDown();
-  }
-};
-
-/////////////////////////
-// Tests with fake ViE //
-/////////////////////////
-
-// Tests that our stub library "works".
-TEST_F(WebRtcVideoEngineTestFake, StartupShutdown) {
-  EXPECT_FALSE(vie_.IsInited());
-  EXPECT_TRUE(engine_.Init());
-  EXPECT_TRUE(vie_.IsInited());
-  engine_.Terminate();
-}
-
-// Tests that we can create and destroy a channel.
-TEST_F(WebRtcVideoEngineTestFake, CreateChannel) {
-  EXPECT_TRUE(engine_.Init());
-  channel_ = engine_.CreateChannel(voice_channel_);
-  EXPECT_TRUE(channel_ != NULL);
-  EXPECT_EQ(1, engine_.GetNumOfChannels());
-  delete channel_;
-  channel_ = NULL;
-  EXPECT_EQ(0, engine_.GetNumOfChannels());
-}
-
-// Tests that we properly handle failures in CreateChannel.
-TEST_F(WebRtcVideoEngineTestFake, CreateChannelFail) {
-  vie_.set_fail_create_channel(true);
-  EXPECT_TRUE(engine_.Init());
-  channel_ = engine_.CreateChannel(voice_channel_);
-  EXPECT_TRUE(channel_ == NULL);
-}
-
-// Tests that we properly handle failures in AllocateExternalCaptureDevice.
-TEST_F(WebRtcVideoEngineTestFake, AllocateExternalCaptureDeviceFail) {
-  vie_.set_fail_alloc_capturer(true);
-  EXPECT_TRUE(engine_.Init());
-  channel_ = engine_.CreateChannel(voice_channel_);
-  EXPECT_TRUE(channel_ == NULL);
-}
-
-// Test that we apply plain old VP8 codecs properly.
-TEST_F(WebRtcVideoEngineTestFake, SetSendCodecs) {
-  EXPECT_TRUE(SetupEngine());
-  int channel_num = vie_.GetLastChannel();
-  std::vector<cricket::VideoCodec> codecs(engine_.codecs());
-  codecs.resize(1);  // toss out red and ulpfec
-  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
-  webrtc::VideoCodec gcodec;
-  EXPECT_EQ(0, vie_.GetSendCodec(channel_num, gcodec));
-  EXPECT_EQ(kVP8Codec.id, gcodec.plType);
-  EXPECT_EQ(kVP8Codec.width, gcodec.width);
-  EXPECT_EQ(kVP8Codec.height, gcodec.height);
-  EXPECT_STREQ(kVP8Codec.name.c_str(), gcodec.plName);
-  EXPECT_EQ(kMinBandwidthKbps, gcodec.minBitrate);
-  EXPECT_EQ(kStartBandwidthKbps, gcodec.startBitrate);
-  EXPECT_EQ(kMaxBandwidthKbps, gcodec.maxBitrate);
-  // TODO: Check HybridNackFecStatus.
-  // TODO: Check RTCP, PLI, TMMBR.
-}
-
-// Test that we constrain send codecs properly.
-TEST_F(WebRtcVideoEngineTestFake, ConstrainSendCodecs) {
-  EXPECT_TRUE(SetupEngine());
-  int channel_num = vie_.GetLastChannel();
-
-  // Set max settings of 640x400x30.
-  EXPECT_TRUE(engine_.SetDefaultEncoderConfig(
-    cricket::VideoEncoderConfig(kVP8Codec)));
-
-  // Send codec format bigger than max setting.
-  cricket::VideoCodec codec(kVP8Codec);
-  codec.width = 1280;
-  codec.height = 800;
-  codec.framerate = 60;
-  std::vector<cricket::VideoCodec> codec_list;
-  codec_list.push_back(codec);
-
-  // Set send codec and verify codec has been constrained.
-  EXPECT_TRUE(channel_->SetSendCodecs(codec_list));
-  webrtc::VideoCodec gcodec;
-  EXPECT_EQ(0, vie_.GetSendCodec(channel_num, gcodec));
-  EXPECT_EQ(kVP8Codec.id, gcodec.plType);
-  EXPECT_EQ(kVP8Codec.width, gcodec.width);
-  EXPECT_EQ(kVP8Codec.height, gcodec.height);
-  EXPECT_EQ(kVP8Codec.framerate, gcodec.maxFramerate);
-  EXPECT_STREQ(kVP8Codec.name.c_str(), gcodec.plName);
-}
-
-// Test that SetSendCodecs rejects bad format.
-TEST_F(WebRtcVideoEngineTestFake, SetSendCodecsRejectBadFormat) {
-  EXPECT_TRUE(SetupEngine());
-  int channel_num = vie_.GetLastChannel();
-
-  // Set w = 0.
-  cricket::VideoCodec codec(kVP8Codec);
-  codec.width = 0;
-  std::vector<cricket::VideoCodec> codec_list;
-  codec_list.push_back(codec);
-
-  // Verify SetSendCodecs failed and send codec is not changed on engine.
-  EXPECT_FALSE(channel_->SetSendCodecs(codec_list));
-  webrtc::VideoCodec gcodec;
-  EXPECT_EQ(0, vie_.GetSendCodec(channel_num, gcodec));
-  EXPECT_EQ(0, gcodec.plType);
-
-  // Set h = 0.
-  codec_list[0].width = 640;
-  codec_list[0].height = 0;
-
-  // Verify SetSendCodecs failed and send codec is not changed on engine.
-  EXPECT_FALSE(channel_->SetSendCodecs(codec_list));
-  EXPECT_EQ(0, vie_.GetSendCodec(channel_num, gcodec));
-  EXPECT_EQ(0, gcodec.plType);
-}
-
-// Test that SetSendCodecs rejects bad codec.
-TEST_F(WebRtcVideoEngineTestFake, SetSendCodecsRejectBadCodec) {
-  EXPECT_TRUE(SetupEngine());
-  int channel_num = vie_.GetLastChannel();
-
-  // Set bad codec name.
-  cricket::VideoCodec codec(kVP8Codec);
-  codec.name = "bad";
-  std::vector<cricket::VideoCodec> codec_list;
-  codec_list.push_back(codec);
-
-  // Verify SetSendCodecs failed and send codec is not changed on engine.
-  EXPECT_FALSE(channel_->SetSendCodecs(codec_list));
-  webrtc::VideoCodec gcodec;
-  EXPECT_EQ(0, vie_.GetSendCodec(channel_num, gcodec));
-  EXPECT_EQ(0, gcodec.plType);
-}
-
-// Test that send codec is reset if the captured frame is smaller.
-TEST_F(WebRtcVideoEngineTestFake, ResetSendCodecOnSmallerFrame) {
-  EXPECT_TRUE(SetupEngine());
-  int channel_num = vie_.GetLastChannel();
-
-  const int old_w = 640;
-  const int old_h = 400;
-  const int new_w = 160;
-  const int new_h = 100;
-
-  // Set send codec and start sending.
-  cricket::VideoCodec codec(kVP8Codec);
-  codec.width = old_w;
-  codec.height = old_h;
-  std::vector<cricket::VideoCodec> codec_list;
-  codec_list.push_back(codec);
-  EXPECT_TRUE(channel_->SetSendCodecs(codec_list));
-  EXPECT_TRUE(channel_->SetSend(true));
-
-  // Capture a smaller frame.
-  cricket::WebRtcVideoFrame frame;
-  uint8 pixel[new_w * new_h * 3 / 2] = { 0 };  // I420
-  EXPECT_TRUE(frame.Init(cricket::FOURCC_I420, new_w, new_h, new_w, new_h,
-                         pixel, sizeof(pixel), 1, 1, 0, 0, 0));
-  EXPECT_TRUE(channel_->SendFrame(0, &frame));
-
-  // Verify the send codec has been reset to the new format.
-  webrtc::VideoCodec gcodec;
-  EXPECT_EQ(0, vie_.GetSendCodec(channel_num, gcodec));
-  EXPECT_EQ(kVP8Codec.id, gcodec.plType);
-  EXPECT_EQ(new_w, gcodec.width);
-  EXPECT_EQ(new_h, gcodec.height);
-}
-
-// Test that we set our inbound codecs properly.
-TEST_F(WebRtcVideoEngineTestFake, SetRecvCodecs) {
-  EXPECT_TRUE(SetupEngine());
-  int channel_num = vie_.GetLastChannel();
-
-  std::vector<cricket::VideoCodec> codecs;
-  codecs.push_back(kVP8Codec);
-  EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
-
-  webrtc::VideoCodec wcodec;
-  EXPECT_TRUE(engine_.ConvertFromCricketVideoCodec(kVP8Codec, wcodec));
-  EXPECT_TRUE(vie_.ReceiveCodecRegistered(channel_num, wcodec));
-}
-
-// Test that channel connects and disconnects external capturer correctly.
-TEST_F(WebRtcVideoEngineTestFake, HasExternalCapturer) {
-  EXPECT_TRUE(SetupEngine());
-  int channel_num = vie_.GetLastChannel();
-
-  EXPECT_EQ(1, vie_.GetNumCapturers());
-  int capture_id = vie_.GetCaptureId(channel_num);
-  EXPECT_EQ(channel_num, vie_.GetCaptureChannelId(capture_id));
-
-  // Delete the channel should disconnect the capturer.
-  delete channel_;
-  channel_ = NULL;
-  EXPECT_EQ(0, vie_.GetNumCapturers());
-}
-
-// Test that channel adds and removes renderer correctly.
-TEST_F(WebRtcVideoEngineTestFake, HasRenderer) {
-  EXPECT_TRUE(SetupEngine());
-  int channel_num = vie_.GetLastChannel();
-
-  EXPECT_TRUE(vie_.GetHasRenderer(channel_num));
-  EXPECT_FALSE(vie_.GetRenderStarted(channel_num));
-}
-
-// Test that rtcp is enabled on the channel.
-TEST_F(WebRtcVideoEngineTestFake, RtcpEnabled) {
-  EXPECT_TRUE(SetupEngine());
-  int channel_num = vie_.GetLastChannel();
-  EXPECT_EQ(webrtc::kRtcpCompound_RFC4585, vie_.GetRtcpStatus(channel_num));
-}
-
-// Test that key frame request method is set on the channel.
-TEST_F(WebRtcVideoEngineTestFake, KeyFrameRequestEnabled) {
-  EXPECT_TRUE(SetupEngine());
-  int channel_num = vie_.GetLastChannel();
-  EXPECT_EQ(webrtc::kViEKeyFrameRequestPliRtcp,
-            vie_.GetKeyFrameRequestMethod(channel_num));
-}
-
-// Test that tmmmbr is enabled on the channel.
-TEST_F(WebRtcVideoEngineTestFake, TmmbrEnabled) {
-  EXPECT_TRUE(SetupEngine());
-  int channel_num = vie_.GetLastChannel();
-  EXPECT_TRUE(vie_.GetTmmbrStatus(channel_num));
-}
-
-// Test that nack is enabled on the channel.
-TEST_F(WebRtcVideoEngineTestFake, NackEnabled) {
-  EXPECT_TRUE(SetupEngine());
-  int channel_num = vie_.GetLastChannel();
-  EXPECT_TRUE(vie_.GetNackStatus(channel_num));
-}
-
-// Test that we can create a channel and start/stop rendering out on it.
-TEST_F(WebRtcVideoEngineTestFake, SetRender) {
-  EXPECT_TRUE(SetupEngine());
-  int channel_num = vie_.GetLastChannel();
-
-  // Verify we can start/stop/start/stop rendering.
-  EXPECT_TRUE(channel_->SetRender(true));
-  EXPECT_TRUE(vie_.GetRenderStarted(channel_num));
-  EXPECT_TRUE(channel_->SetRender(false));
-  EXPECT_FALSE(vie_.GetRenderStarted(channel_num));
-  EXPECT_TRUE(channel_->SetRender(true));
-  EXPECT_TRUE(vie_.GetRenderStarted(channel_num));
-  EXPECT_TRUE(channel_->SetRender(false));
-  EXPECT_FALSE(vie_.GetRenderStarted(channel_num));
-}
-
-// Test that we can create a channel and start/stop sending out on it.
-TEST_F(WebRtcVideoEngineTestFake, SetSend) {
-  EXPECT_TRUE(SetupEngine());
-  int channel_num = vie_.GetLastChannel();
-
-  // Set send codecs on the channel.
-  std::vector<cricket::VideoCodec> codecs;
-  codecs.push_back(kVP8Codec);
-  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
-
-  // Verify we can start/stop/start/stop sending.
-  EXPECT_TRUE(channel_->SetSend(true));
-  EXPECT_TRUE(vie_.GetSend(channel_num));
-  EXPECT_TRUE(channel_->SetSend(false));
-  EXPECT_FALSE(vie_.GetSend(channel_num));
-  EXPECT_TRUE(channel_->SetSend(true));
-  EXPECT_TRUE(vie_.GetSend(channel_num));
-  EXPECT_TRUE(channel_->SetSend(false));
-  EXPECT_FALSE(vie_.GetSend(channel_num));
-}
-
-// TODO: Add test for FEC.
-
-// Test that we set bandwidth properly when using full auto bandwidth mode.
-TEST_F(WebRtcVideoEngineTestFake, SetBandwidthAuto) {
-  EXPECT_TRUE(SetupEngine());
-  int channel_num = vie_.GetLastChannel();
-  EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
-  EXPECT_TRUE(channel_->SetSendBandwidth(true, cricket::kAutoBandwidth));
-  webrtc::VideoCodec gcodec;
-  EXPECT_EQ(0, vie_.GetSendCodec(channel_num, gcodec));
-  EXPECT_EQ(kVP8Codec.id, gcodec.plType);
-  EXPECT_STREQ(kVP8Codec.name.c_str(), gcodec.plName);
-  EXPECT_EQ(kMinBandwidthKbps, gcodec.minBitrate);
-  EXPECT_EQ(kStartBandwidthKbps, gcodec.startBitrate);
-  EXPECT_EQ(kMaxBandwidthKbps, gcodec.maxBitrate);
-}
-
-// Test that we set bandwidth properly when using auto with upper bound.
-TEST_F(WebRtcVideoEngineTestFake, SetBandwidthAutoCapped) {
-  EXPECT_TRUE(SetupEngine());
-  int channel_num = vie_.GetLastChannel();
-  EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
-  EXPECT_TRUE(channel_->SetSendBandwidth(true, 768000));
-  webrtc::VideoCodec gcodec;
-  EXPECT_EQ(0, vie_.GetSendCodec(channel_num, gcodec));
-  EXPECT_EQ(kVP8Codec.id, gcodec.plType);
-  EXPECT_STREQ(kVP8Codec.name.c_str(), gcodec.plName);
-  EXPECT_EQ(kMinBandwidthKbps, gcodec.minBitrate);
-  EXPECT_EQ(kStartBandwidthKbps, gcodec.startBitrate);
-  EXPECT_EQ(768U, gcodec.maxBitrate);
-}
-
-// Test that we set bandwidth properly when using a fixed bandwidth.
-TEST_F(WebRtcVideoEngineTestFake, SetBandwidthFixed) {
-  EXPECT_TRUE(SetupEngine());
-  int channel_num = vie_.GetLastChannel();
-  EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
-  EXPECT_TRUE(channel_->SetSendBandwidth(false, 768000));
-  webrtc::VideoCodec gcodec;
-  EXPECT_EQ(0, vie_.GetSendCodec(channel_num, gcodec));
-  EXPECT_EQ(kVP8Codec.id, gcodec.plType);
-  EXPECT_STREQ(kVP8Codec.name.c_str(), gcodec.plName);
-  EXPECT_EQ(768U, gcodec.minBitrate);
-  EXPECT_EQ(768U, gcodec.startBitrate);
-  EXPECT_EQ(768U, gcodec.maxBitrate);
-}
-
-// Test SetSendSsrc.
-TEST_F(WebRtcVideoEngineTestFake, SetSendSsrc) {
-  EXPECT_TRUE(SetupEngine());
-  int channel_num = vie_.GetLastChannel();
-
-  // Verify ssrc is set correctly.
-  channel_->SetSendSsrc(1234);
-  unsigned int ssrc = 0;
-  EXPECT_EQ(0, vie_.GetLocalSSRC(channel_num, ssrc));
-  EXPECT_EQ(1234U, ssrc);
-}
-
-// Test SetRtcpCName.
-TEST_F(WebRtcVideoEngineTestFake, SetRtcpCName) {
-  EXPECT_TRUE(SetupEngine());
-  int channel_num = vie_.GetLastChannel();
-
-  // Verify rtcp cname is set correctly.
-  EXPECT_TRUE(channel_->SetRtcpCName("cname"));
-  char rtcp_cname[256];
-  EXPECT_EQ(0, vie_.GetRTCPCName(channel_num, rtcp_cname));
-  EXPECT_STREQ("cname", rtcp_cname);
-}
-
-/////////////////////////
-// Tests with real ViE //
-/////////////////////////
-
-// Tests that we can find codecs by name or id.
-TEST_F(WebRtcVideoEngineTest, FindCodec) {
-  // We should not need to init engine in order to get codecs.
-  const std::vector<cricket::VideoCodec>& c = engine_.codecs();
-  EXPECT_EQ(1U, c.size());
-
-  cricket::VideoCodec vp8(104, "VP8", 320, 200, 30, 0);
-  EXPECT_TRUE(engine_.FindCodec(vp8));
-
-  cricket::VideoCodec vp8_ci(104, "vp8", 320, 200, 30, 0);
-  EXPECT_TRUE(engine_.FindCodec(vp8));
-
-  cricket::VideoCodec vp8_diff_fr_diff_pref(104, "VP8", 320, 200, 50, 50);
-  EXPECT_TRUE(engine_.FindCodec(vp8_diff_fr_diff_pref));
-
-  cricket::VideoCodec vp8_diff_id(95, "VP8", 320, 200, 30, 0);
-  EXPECT_FALSE(engine_.FindCodec(vp8_diff_id));
-  vp8_diff_id.id = 97;
-  EXPECT_TRUE(engine_.FindCodec(vp8_diff_id));
-
-  cricket::VideoCodec vp8_diff_res(104, "VP8", 320, 111, 30, 0);
-  EXPECT_FALSE(engine_.FindCodec(vp8_diff_res));
-
-  // PeerConnection doesn't negotiate the resolution at this point.
-  // Test that FindCodec can handle the case when width/height is 0.
-  cricket::VideoCodec vp8_zero_res(104, "VP8", 0, 0, 30, 0);
-  EXPECT_TRUE(engine_.FindCodec(vp8_zero_res));
-
-  // TODO: Re-enable when we re-enable FEC.
-#if 0
-  cricket::VideoCodec red(101, "RED", 0, 0, 30, 0);
-  EXPECT_TRUE(engine_.FindCodec(red));
-
-  cricket::VideoCodec red_ci(101, "red", 0, 0, 30, 0);
-  EXPECT_TRUE(engine_.FindCodec(red));
-
-  cricket::VideoCodec fec(102, "ULPFEC", 0, 0, 30, 0);
-  EXPECT_TRUE(engine_.FindCodec(fec));
-
-  cricket::VideoCodec fec_ci(102, "ulpfec", 0, 0, 30, 0);
-  EXPECT_TRUE(engine_.FindCodec(fec));
-#endif
-}
-
-TEST_F(WebRtcVideoEngineTest, StartupShutdown) {
-  EXPECT_TRUE(engine_.Init());
-  engine_.Terminate();
-}
-
-TEST_PRE_VIDEOENGINE_INIT(WebRtcVideoEngineTest, ConstrainNewCodec)
-TEST_POST_VIDEOENGINE_INIT(WebRtcVideoEngineTest, ConstrainNewCodec)
-
-TEST_PRE_VIDEOENGINE_INIT(WebRtcVideoEngineTest, ConstrainRunningCodec)
-TEST_POST_VIDEOENGINE_INIT(WebRtcVideoEngineTest, ConstrainRunningCodec)
-
-// TODO: Figure out why ViE is munging the COM refcount.
-#ifdef WIN32
-TEST_F(WebRtcVideoEngineTest, DISABLED_CheckCoInitialize) {
-  Base::CheckCoInitialize();
-}
-#endif
-
-TEST_F(WebRtcVideoEngineTest, CreateChannel) {
-  EXPECT_TRUE(engine_.Init());
-  cricket::VideoMediaChannel* channel = engine_.CreateChannel(NULL);
-  EXPECT_TRUE(channel != NULL);
-  delete channel;
-}
-
-TEST_F(WebRtcVideoEngineTest, SetCaptureModule) {
-  // Use 123 to verify there's no assumption to the module id
-  FakeWebRtcVideoCaptureModule* vcm =
-      new FakeWebRtcVideoCaptureModule(NULL, 123);
-  EXPECT_TRUE(engine_.Init());
-  // The ownership of the vcm is transferred to the engine.
-  // Technically we should call vcm->AddRef since we are using the vcm below,
-  // however the FakeWebRtcVideoCaptureModule didn't implemented the refcount.
-  // So for testing, this should be fine.
-  EXPECT_TRUE(engine_.SetCaptureModule(vcm));
-  EXPECT_EQ(cricket::CR_PENDING, engine_.SetCapture(true));
-  EXPECT_EQ(engine_.default_codec_format().width, vcm->cap().width);
-  EXPECT_EQ(engine_.default_codec_format().height, vcm->cap().height);
-  EXPECT_EQ(cricket::VideoFormat::IntervalToFps(
-                engine_.default_codec_format().interval),
-            vcm->cap().maxFPS);
-  EXPECT_EQ(webrtc::kVideoI420, vcm->cap().rawType);
-  EXPECT_EQ(webrtc::kVideoCodecUnknown, vcm->cap().codecType);
-}
-
-TEST_F(WebRtcVideoEngineTest, SetVideoCapturer) {
-  // Use 123 to verify there's no assumption to the module id
-  FakeWebRtcVideoCaptureModule* vcm =
-      new FakeWebRtcVideoCaptureModule(NULL, 123);
-  talk_base::scoped_ptr<cricket::WebRtcVideoCapturer> capturer(
-      new cricket::WebRtcVideoCapturer);
-  EXPECT_TRUE(capturer->Init(vcm));
-  EXPECT_TRUE(engine_.Init());
-  const uint32 ssrc_dummy = 0;
-  EXPECT_TRUE(engine_.SetVideoCapturer(capturer.get(), ssrc_dummy));
-
-  EXPECT_EQ(engine_.default_codec_format().width, vcm->cap().width);
-  EXPECT_EQ(engine_.default_codec_format().height, vcm->cap().height);
-  EXPECT_EQ(cricket::VideoFormat::IntervalToFps(
-      engine_.default_codec_format().interval),
-            vcm->cap().maxFPS);
-  EXPECT_EQ(webrtc::kVideoI420, vcm->cap().rawType);
-  EXPECT_EQ(webrtc::kVideoCodecUnknown, vcm->cap().codecType);
-}
-
-TEST_F(WebRtcVideoMediaChannelTest, SetRecvCodecs) {
-  std::vector<cricket::VideoCodec> codecs;
-  codecs.push_back(kVP8Codec);
-  EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
-}
-TEST_F(WebRtcVideoMediaChannelTest, SetRecvCodecsWrongPayloadType) {
-  std::vector<cricket::VideoCodec> codecs;
-  codecs.push_back(kVP8Codec);
-  codecs[0].id = 99;
-  EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
-}
-TEST_F(WebRtcVideoMediaChannelTest, SetRecvCodecsUnsupportedCodec) {
-  std::vector<cricket::VideoCodec> codecs;
-  codecs.push_back(kVP8Codec);
-  codecs.push_back(cricket::VideoCodec(101, "VP1", 640, 400, 30, 0));
-  EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
-}
-
-TEST_F(WebRtcVideoMediaChannelTest, SetSend) {
-  Base::SetSend();
-}
-TEST_F(WebRtcVideoMediaChannelTest, SetSendWithoutCodecs) {
-  Base::SetSendWithoutCodecs();
-}
-TEST_F(WebRtcVideoMediaChannelTest, SetSendSetsTransportBufferSizes) {
-  Base::SetSendSetsTransportBufferSizes();
-}
-
-TEST_F(WebRtcVideoMediaChannelTest, SendAndReceiveVp8Vga) {
-  SendAndReceive(cricket::VideoCodec(100, "VP8", 640, 400, 30, 0));
-}
-TEST_F(WebRtcVideoMediaChannelTest, SendAndReceiveVp8Qvga) {
-  SendAndReceive(cricket::VideoCodec(100, "VP8", 320, 200, 30, 0));
-}
-TEST_F(WebRtcVideoMediaChannelTest, SendAndReceiveH264SvcQqvga) {
-  SendAndReceive(cricket::VideoCodec(100, "VP8", 160, 100, 30, 0));
-}
-// TODO: Figure out why this test doesn't work.
-TEST_F(WebRtcVideoMediaChannelTest, DISABLED_SendManyResizeOnce) {
-  SendManyResizeOnce();
-}
-
-// TODO: Fix this test to tolerate missing stats.
-TEST_F(WebRtcVideoMediaChannelTest, DISABLED_GetStats) {
-  Base::GetStats();
-}
-// TODO: Restore this test once we support multiple recv streams.
-TEST_F(WebRtcVideoMediaChannelTest, DISABLED_GetStatsMultipleRecvStreams) {
-  Base::GetStatsMultipleRecvStreams();
-}
-// TODO: Restore this test once we support multiple send streams.
-TEST_F(WebRtcVideoMediaChannelTest, DISABLED_GetStatsMultipleSendStreams) {
-  Base::GetStatsMultipleSendStreams();
-}
-
-TEST_F(WebRtcVideoMediaChannelTest, SetSendBandwidth) {
-  Base::SetSendBandwidth();
-}
-TEST_F(WebRtcVideoMediaChannelTest, SetSendSsrc) {
-  Base::SetSendSsrc();
-}
-TEST_F(WebRtcVideoMediaChannelTest, SetSendSsrcAfterSetCodecs) {
-  Base::SetSendSsrcAfterSetCodecs();
-}
-
-// TODO: Restore this test once we support GetRenderer.
-TEST_F(WebRtcVideoMediaChannelTest, DISABLED_SetRenderer) {
-  Base::SetRenderer();
-}
-// TODO: Restore this test once we support multiple recv streams.
-TEST_F(WebRtcVideoMediaChannelTest, DISABLED_AddRemoveRecvStreams) {
-  Base::AddRemoveRecvStreams();
-}
-// TODO: Restore this test once we support multiple recv streams.
-TEST_F(WebRtcVideoMediaChannelTest, DISABLED_SimulateConference) {
-  Base::SimulateConference();
-}
-// TODO: Investigate why this test is flaky.
-TEST_F(WebRtcVideoMediaChannelTest, DISABLED_AdaptResolution16x10) {
-  Base::AdaptResolution16x10();
-}
-// TODO: Investigate why this test is flaky.
-TEST_F(WebRtcVideoMediaChannelTest, DISABLED_AdaptResolution4x3) {
-  Base::AdaptResolution4x3();
-}
-// TODO: Restore this test once we support sending 0 fps.
-TEST_F(WebRtcVideoMediaChannelTest, DISABLED_AdaptDropAllFrames) {
-  Base::AdaptDropAllFrames();
-}
-// TODO: Understand why we get decode errors on this test.
-TEST_F(WebRtcVideoMediaChannelTest, DISABLED_AdaptFramerate) {
-  Base::AdaptFramerate();
-}
-// TODO: Understand why we receive a not-quite-black frame.
-TEST_F(WebRtcVideoMediaChannelTest, DISABLED_Mute) {
-  Base::Mute();
-}
diff --git a/third_party/libjingle/source/talk/session/phone/webrtcvideoframe.cc b/third_party/libjingle/source/talk/session/phone/webrtcvideoframe.cc
deleted file mode 100644
index 2562ed5..0000000
--- a/third_party/libjingle/source/talk/session/phone/webrtcvideoframe.cc
+++ /dev/null
@@ -1,313 +0,0 @@
-/*
- * libjingle
- * Copyright 2011 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/session/phone/webrtcvideoframe.h"
-
-#include "libyuv/planar_functions.h"
-#include "talk/base/logging.h"
-#include "talk/session/phone/videocapturer.h"
-#include "talk/session/phone/videocommon.h"
-
-namespace cricket {
-
-static const int kWatermarkWidth = 8;
-static const int kWatermarkHeight = 8;
-static const int kWatermarkOffsetFromLeft = 8;
-static const int kWatermarkOffsetFromBottom = 8;
-static const unsigned char kWatermarkMaxYValue = 64;
-
-WebRtcVideoFrame::WebRtcVideoFrame() {
-}
-
-WebRtcVideoFrame::~WebRtcVideoFrame() {
-}
-
-bool WebRtcVideoFrame::Init(uint32 format, int w, int h, int dw, int dh,
-                            uint8* sample, size_t sample_size,
-                            size_t pixel_width, size_t pixel_height,
-                            int64 elapsed_time, int64 time_stamp,
-                            int rotation) {
-  // WebRtcVideoFrame currently doesn't support color conversion or rotation.
-  // TODO: Add horizontal cropping support.
-  if (format != FOURCC_I420 || dw != w || dh < 0 || dh > abs(h) ||
-      rotation != 0) {
-    return false;
-  }
-
-  size_t desired_size = SizeOf(dw, dh);
-  uint8* buffer = new uint8[desired_size];
-  Attach(buffer, desired_size, dw, dh, pixel_width, pixel_height,
-         elapsed_time, time_stamp, rotation);
-  if (dh == h) {
-    // Uncropped
-    memcpy(buffer, sample, desired_size);
-  } else {
-    // Cropped
-    // TODO: use I420Copy which supports horizontal crop and vertical
-    // flip.
-    int horiz_crop = ((w - dw) / 2) & ~1;
-    int vert_crop = ((abs(h) - dh) / 2) & ~1;
-    int y_crop_offset = w * vert_crop + horiz_crop;
-    int halfwidth = (w + 1) / 2;
-    int halfheight = (h + 1) / 2;
-    int uv_size = GetChromaSize();
-    int uv_crop_offset = (halfwidth * vert_crop + horiz_crop) / 2;
-    uint8* src_y = sample + y_crop_offset;
-    uint8* src_u = sample + w * h + uv_crop_offset;
-    uint8* src_v = sample + w * h + halfwidth * halfheight + uv_crop_offset;
-    memcpy(GetYPlane(), src_y, dw * dh);
-    memcpy(GetUPlane(), src_u, uv_size);
-    memcpy(GetVPlane(), src_v, uv_size);
-  }
-  return true;
-}
-
-bool WebRtcVideoFrame::Init(const CapturedFrame* frame, int dw, int dh) {
-  return Init(frame->fourcc, frame->width, frame->height, dw, dh,
-              static_cast<uint8*>(frame->data), frame->data_size,
-              frame->pixel_width, frame->pixel_height,
-              frame->elapsed_time, frame->time_stamp, frame->rotation);
-}
-
-bool WebRtcVideoFrame::InitToBlack(int w, int h,
-                                   size_t pixel_width, size_t pixel_height,
-                                   int64 elapsed_time, int64 time_stamp) {
-  CreateBuffer(w, h, pixel_width, pixel_height, elapsed_time, time_stamp);
-  return SetToBlack();
-}
-
-void WebRtcVideoFrame::Attach(uint8* buffer, size_t buffer_size, int w, int h,
-                              size_t pixel_width, size_t pixel_height,
-                              int64 elapsed_time, int64 time_stamp,
-                              int rotation) {
-  video_frame_.Free();
-  WebRtc_UWord8* new_memory = buffer;
-  WebRtc_UWord32 new_length = buffer_size;
-  WebRtc_UWord32 new_size = buffer_size;
-  video_frame_.Swap(new_memory, new_length, new_size);
-  video_frame_.SetWidth(w);
-  video_frame_.SetHeight(h);
-  pixel_width_ = pixel_width;
-  pixel_height_ = pixel_height;
-  elapsed_time_ = elapsed_time;
-  time_stamp_ = time_stamp;
-  rotation_ = rotation;
-}
-
-void WebRtcVideoFrame::Detach(uint8** buffer, size_t* buffer_size) {
-  WebRtc_UWord8* new_memory = NULL;
-  WebRtc_UWord32 new_length = 0;
-  WebRtc_UWord32 new_size = 0;
-  video_frame_.Swap(new_memory, new_length, new_size);
-  *buffer = new_memory;
-  *buffer_size = new_size;
-}
-
-size_t WebRtcVideoFrame::GetWidth() const {
-  return video_frame_.Width();
-}
-
-size_t WebRtcVideoFrame::GetHeight() const {
-  return video_frame_.Height();
-}
-
-const uint8* WebRtcVideoFrame::GetYPlane() const {
-  WebRtc_UWord8* buffer = video_frame_.Buffer();
-  return buffer;
-}
-
-const uint8* WebRtcVideoFrame::GetUPlane() const {
-  WebRtc_UWord8* buffer = video_frame_.Buffer();
-  if (buffer) {
-    buffer += (video_frame_.Width() * video_frame_.Height());
-  }
-  return buffer;
-}
-
-const uint8* WebRtcVideoFrame::GetVPlane() const {
-  WebRtc_UWord8* buffer = video_frame_.Buffer();
-  if (buffer) {
-    int uv_size = GetChromaSize();
-    buffer += video_frame_.Width() * video_frame_.Height() + uv_size;
-  }
-  return buffer;
-}
-
-uint8* WebRtcVideoFrame::GetYPlane() {
-  WebRtc_UWord8* buffer = video_frame_.Buffer();
-  return buffer;
-}
-
-uint8* WebRtcVideoFrame::GetUPlane() {
-  WebRtc_UWord8* buffer = video_frame_.Buffer();
-  if (buffer) {
-    buffer += (video_frame_.Width() * video_frame_.Height());
-  }
-  return buffer;
-}
-
-uint8* WebRtcVideoFrame::GetVPlane() {
-  WebRtc_UWord8* buffer = video_frame_.Buffer();
-  if (buffer) {
-    int uv_size = GetChromaSize();
-    buffer += video_frame_.Width() * video_frame_.Height() + uv_size;
-  }
-  return buffer;
-}
-
-VideoFrame* WebRtcVideoFrame::Copy() const {
-  WebRtc_UWord8* buffer = video_frame_.Buffer();
-  if (!buffer)
-    return NULL;
-
-  size_t new_buffer_size = video_frame_.Length();
-  uint8* new_buffer = new uint8[new_buffer_size];
-  memcpy(new_buffer, buffer, new_buffer_size);
-  WebRtcVideoFrame* copy = new WebRtcVideoFrame();
-  copy->Attach(new_buffer, new_buffer_size,
-               video_frame_.Width(), video_frame_.Height(),
-               pixel_width_, pixel_height_,
-               elapsed_time_, time_stamp_, rotation_);
-  return copy;
-}
-
-bool WebRtcVideoFrame::MakeExclusive() {
-  // WebRtcVideoFrame::Copy makes a deep copy of the frame buffer.  No action
-  // is needed for MakeExclusive.
-  return true;
-}
-
-size_t WebRtcVideoFrame::CopyToBuffer(uint8* buffer, size_t size) const {
-  if (!video_frame_.Buffer()) {
-    return 0;
-  }
-
-  size_t needed = video_frame_.Length();
-  if (needed <= size) {
-    memcpy(buffer, video_frame_.Buffer(), needed);
-  }
-  return needed;
-}
-
-// TODO: Refactor into base class and share with lmi
-size_t WebRtcVideoFrame::ConvertToRgbBuffer(uint32 to_fourcc,
-                                            uint8* buffer,
-                                            size_t size,
-                                            size_t stride_rgb) const {
-  if (!video_frame_.Buffer()) {
-    return 0;
-  }
-
-  size_t width = video_frame_.Width();
-  size_t height = video_frame_.Height();
-  // See http://www.virtualdub.org/blog/pivot/entry.php?id=190 for a good
-  // explanation of pitch and why this is the amount of space we need.
-  // TODO: increase to stride * height to allow padding to be used
-  // to overwrite for efficiency.
-  size_t needed = stride_rgb * (height - 1) + 4 * width;
-
-  if (needed > size) {
-    LOG(LS_WARNING) << "RGB buffer is not large enough";
-    return needed;
-  }
-
-  // TODO: Use libyuv::ConvertFromI420
-  switch (to_fourcc) {
-    case FOURCC_ARGB:
-      libyuv::I420ToARGB(
-          GetYPlane(), GetYPitch(),
-          GetUPlane(), GetUPitch(),
-          GetVPlane(), GetVPitch(),
-          buffer, stride_rgb, width, height);
-      break;
-
-    case FOURCC_BGRA:
-      libyuv::I420ToBGRA(
-          GetYPlane(), GetYPitch(),
-          GetUPlane(), GetUPitch(),
-          GetVPlane(), GetVPitch(),
-          buffer, stride_rgb, width, height);
-      break;
-
-    case FOURCC_ABGR:
-      libyuv::I420ToABGR(
-          GetYPlane(), GetYPitch(),
-          GetUPlane(), GetUPitch(),
-          GetVPlane(), GetVPitch(),
-          buffer, stride_rgb, width, height);
-      break;
-
-    default:
-      needed = 0;
-      LOG(LS_WARNING) << "RGB type not supported: " << to_fourcc;
-      break;
-  }
-  return needed;
-}
-
-VideoFrame* WebRtcVideoFrame::Stretch(size_t w, size_t h,
-    bool interpolate, bool vert_crop) const {
-  WebRtcVideoFrame* frame = new WebRtcVideoFrame();
-  frame->CreateBuffer(w, h, 1, 1, 0, 0);
-  StretchToFrame(frame, interpolate, vert_crop);
-
-  return frame;
-}
-
-void WebRtcVideoFrame::CreateBuffer(int w, int h,
-                                    size_t pixel_width, size_t pixel_height,
-                                    int64 elapsed_time, int64 time_stamp) {
-  size_t buffer_size = VideoFrame::SizeOf(w, h);
-  uint8* buffer = new uint8[buffer_size];
-  Attach(buffer, buffer_size, w, h, pixel_width, pixel_height,
-         elapsed_time, time_stamp, 0);
-}
-
-// Add a square watermark near the left-low corner. clamp Y.
-// Returns false on error.
-bool WebRtcVideoFrame::AddWatermark() {
-  size_t w = GetWidth();
-  size_t h = GetHeight();
-
-  if (w < kWatermarkWidth + kWatermarkOffsetFromLeft ||
-      h < kWatermarkHeight + kWatermarkOffsetFromBottom) {
-    return false;
-  }
-
-  uint8* buffer = GetYPlane();
-  for (size_t x = kWatermarkOffsetFromLeft;
-       x < kWatermarkOffsetFromLeft + kWatermarkWidth; ++x) {
-    for (size_t y = h - kWatermarkOffsetFromBottom - kWatermarkHeight;
-         y < h - kWatermarkOffsetFromBottom; ++y) {
-      buffer[y * w + x] = talk_base::_min(buffer[y * w + x],
-                                          kWatermarkMaxYValue);
-    }
-  }
-  return true;
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/session/phone/webrtcvideoframe.h b/third_party/libjingle/source/talk/session/phone/webrtcvideoframe.h
deleted file mode 100644
index 6519543..0000000
--- a/third_party/libjingle/source/talk/session/phone/webrtcvideoframe.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * libjingle
- * Copyright 2011 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SESSION_PHONE_WEBRTCVIDEOFRAME_H_
-#define TALK_SESSION_PHONE_WEBRTCVIDEOFRAME_H_
-
-#ifdef WEBRTC_RELATIVE_PATH
-#include "common_types.h"
-#include "modules/interface/module_common_types.h"
-#else
-#include "third_party/webrtc/files/include/common_types.h"
-#include "third_party/webrtc/files/include/module_common_types.h"
-#endif
-#include "talk/session/phone/videoframe.h"
-
-namespace cricket {
-
-struct CapturedFrame;
-
-class WebRtcVideoFrame : public VideoFrame {
- public:
-  WebRtcVideoFrame();
-  ~WebRtcVideoFrame();
-
-  // Creates a frame from a raw sample with FourCC "format" and size "w" x "h".
-  // "h" can be negative indicating a vertically flipped image.
-  // "dh" is destination height if cropping is desired and is always positive.
-  // Returns "true" if successful.
-  bool Init(uint32 format, int w, int h, int dw, int dh,
-            uint8* sample, size_t sample_size,
-            size_t pixel_width, size_t pixel_height,
-            int64 elapsed_time, int64 time_stamp, int rotation);
-
-  bool Init(const CapturedFrame* frame, int dw, int dh);
-
-  bool InitToBlack(int w, int h, size_t pixel_width, size_t pixel_height,
-                   int64 elapsed_time, int64 time_stamp);
-
-  void Attach(uint8* buffer, size_t buffer_size, int w, int h,
-              size_t pixel_width, size_t pixel_height,
-              int64 elapsed_time, int64 time_stamp, int rotation);
-  void Detach(uint8** buffer, size_t* buffer_size);
-  bool AddWatermark();
-  webrtc::VideoFrame* frame() { return &video_frame_; }
-
-  // From base class VideoFrame.
-  virtual size_t GetWidth() const;
-  virtual size_t GetHeight() const;
-  virtual const uint8* GetYPlane() const;
-  virtual const uint8* GetUPlane() const;
-  virtual const uint8* GetVPlane() const;
-  virtual uint8* GetYPlane();
-  virtual uint8* GetUPlane();
-  virtual uint8* GetVPlane();
-  virtual int32 GetYPitch() const { return video_frame_.Width(); }
-  virtual int32 GetUPitch() const { return (video_frame_.Width() + 1) / 2; }
-  virtual int32 GetVPitch() const { return (video_frame_.Width() + 1) / 2; }
-
-  virtual size_t GetPixelWidth() const { return pixel_width_; }
-  virtual size_t GetPixelHeight() const { return pixel_height_; }
-  virtual int64 GetElapsedTime() const { return elapsed_time_; }
-  virtual int64 GetTimeStamp() const { return time_stamp_; }
-  virtual void SetElapsedTime(int64 elapsed_time) {
-    elapsed_time_ = elapsed_time;
-  }
-  virtual void SetTimeStamp(int64 time_stamp) {
-    time_stamp_ = time_stamp;
-  }
-
-  virtual int GetRotation() const { return rotation_; }
-
-  virtual VideoFrame* Copy() const;
-  virtual bool MakeExclusive();
-  virtual size_t CopyToBuffer(uint8* buffer, size_t size) const;
-  virtual size_t ConvertToRgbBuffer(uint32 to_fourcc, uint8* buffer,
-                                    size_t size, size_t pitch_rgb) const;
-  virtual VideoFrame* Stretch(size_t w, size_t h, bool interpolate,
-                              bool vert_crop) const;
-
- private:
-  size_t GetChromaSize() const { return GetUPitch() * GetChromaHeight(); }
-  void CreateBuffer(int w, int h, size_t pixel_width, size_t pixel_height,
-                    int64 elapsed_time, int64 time_stamp);
-  webrtc::VideoFrame video_frame_;
-  size_t pixel_width_;
-  size_t pixel_height_;
-  int64 elapsed_time_;
-  int64 time_stamp_;
-  int rotation_;
-};
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_WEBRTCVIDEOFRAME_H_
diff --git a/third_party/libjingle/source/talk/session/phone/webrtcvideoframe_unittest.cc b/third_party/libjingle/source/talk/session/phone/webrtcvideoframe_unittest.cc
deleted file mode 100644
index c4526c0..0000000
--- a/third_party/libjingle/source/talk/session/phone/webrtcvideoframe_unittest.cc
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * libjingle
- * Copyright 2011 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/flags.h"
-#include "talk/session/phone/videoframe_unittest.h"
-#include "talk/session/phone/webrtcvideoframe.h"
-
-extern int FLAG_yuvconverter_repeat; // from lmivideoframe_unittest.cc
-
-class WebRtcVideoFrameTest : public VideoFrameTest<cricket::WebRtcVideoFrame> {
- public:
-  WebRtcVideoFrameTest() {
-    repeat_ = FLAG_yuvconverter_repeat;
-  }
-};
-
-#define TEST_WEBRTCVIDEOFRAME(X) TEST_F(WebRtcVideoFrameTest, X) { \
-  VideoFrameTest<cricket::WebRtcVideoFrame>::X(); \
-}
-
-TEST_WEBRTCVIDEOFRAME(ConstructI420)
-TEST_WEBRTCVIDEOFRAME(ConstructI4201Pixel)
-// TODO: WebRtcVideoFrame does not support horizontal crop.
-// Re-evaluate once it supports 3 independent planes, since we might want to
-// just Init normally and then crop by adjusting pointers.
-// TEST_WEBRTCVIDEOFRAME(ConstructI420CropHorizontal)
-TEST_WEBRTCVIDEOFRAME(ConstructI420CropVertical)
-// TODO: WebRtcVideoFrame is not currently refcounted.
-// TEST_WEBRTCVIDEOFRAME(ConstructCopy)
-// TEST_WEBRTCVIDEOFRAME(ConstructCopyIsRef)
-TEST_WEBRTCVIDEOFRAME(ConstructBlack)
-// TODO: WebRtcVideoFrame does not support odd sizes.
-// Re-evaluate once WebRTC switches to libyuv
-// TEST_LMIVIDEOFRAME(ConstructYuy2AllSizes)
-// TODO: WebRtcVideoFrame currently only supports ARGB output.
-#ifdef HAVE_YUV
-TEST_WEBRTCVIDEOFRAME(ConvertToBGRABuffer)
-TEST_WEBRTCVIDEOFRAME(ConvertToABGRBuffer)
-#endif
-TEST_WEBRTCVIDEOFRAME(ConvertToARGBBuffer)
-//TEST_WEBRTCVIDEOFRAME(ConvertToYUY2Buffer)
-//TEST_WEBRTCVIDEOFRAME(ConvertToI422Buffer)
-TEST_WEBRTCVIDEOFRAME(ConvertARGBToBayerGRBG)
-TEST_WEBRTCVIDEOFRAME(ConvertARGBToBayerGBRG)
-TEST_WEBRTCVIDEOFRAME(ConvertARGBToBayerBGGR)
-TEST_WEBRTCVIDEOFRAME(ConvertARGBToBayerRGGB)
-TEST_WEBRTCVIDEOFRAME(CopyToBuffer)
-TEST_WEBRTCVIDEOFRAME(CopyToBuffer1Pixel)
-TEST_WEBRTCVIDEOFRAME(StretchToFrame)
-TEST_WEBRTCVIDEOFRAME(Copy)
-// TODO: WebRtcVideoFrame is not currently refcounted.
-// TEST_WEBRTCVIDEOFRAME(CopyIsRef)
-TEST_WEBRTCVIDEOFRAME(MakeExclusive)
-
-// These functions test implementation-specific details.
-TEST_F(WebRtcVideoFrameTest, AttachAndRelease) {
-  cricket::WebRtcVideoFrame frame1, frame2;
-  ASSERT_TRUE(LoadFrameNoRepeat(&frame1));
-  const int64 time_stamp = 0x7FFFFFFFFFFFFFF0LL;
-  frame1.SetTimeStamp(time_stamp);
-  EXPECT_EQ(time_stamp, frame1.GetTimeStamp());
-  frame2.Attach(frame1.frame()->Buffer(), frame1.frame()->Size(),
-                kWidth, kHeight, 1, 1,
-                frame1.GetElapsedTime(), frame1.GetTimeStamp(), 0);
-  EXPECT_TRUE(IsEqual(frame1, frame2, 0));
-  uint8* buffer;
-  size_t size;
-  frame2.Detach(&buffer, &size);
-  EXPECT_EQ(frame1.frame()->Buffer(), buffer);
-  EXPECT_EQ(frame1.frame()->Size(), size);
-  EXPECT_TRUE(IsNull(frame2));
-  EXPECT_TRUE(IsSize(frame1, kWidth, kHeight));
-}
-
-TEST_F(WebRtcVideoFrameTest, Transfer) {
-  cricket::WebRtcVideoFrame frame1, frame2;
-  ASSERT_TRUE(LoadFrameNoRepeat(&frame1));
-  uint8* buffer;
-  size_t size;
-  frame1.Detach(&buffer, &size),
-  frame2.Attach(buffer, size, kWidth, kHeight, 1, 1,
-                frame1.GetElapsedTime(), frame1.GetTimeStamp(), 0);
-  EXPECT_TRUE(IsNull(frame1));
-  EXPECT_TRUE(IsSize(frame2, kWidth, kHeight));
-}
-
diff --git a/third_party/libjingle/source/talk/session/phone/webrtcvie.h b/third_party/libjingle/source/talk/session/phone/webrtcvie.h
deleted file mode 100644
index bd2ba71..0000000
--- a/third_party/libjingle/source/talk/session/phone/webrtcvie.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-#ifndef TALK_SESSION_PHONE_WEBRTCVIE_H_
-#define TALK_SESSION_PHONE_WEBRTCVIE_H_
-
-#include "talk/base/common.h"
-#include "talk/session/phone/webrtccommon.h"
-
-#ifdef WEBRTC_RELATIVE_PATH
-#include "common_types.h"
-#include "modules/interface/module_common_types.h"
-#include "modules/video_capture/main/interface/video_capture.h"
-#include "modules/video_render/main/interface/video_render.h"
-#include "video_engine/include/vie_base.h"
-#include "video_engine/include/vie_capture.h"
-#include "video_engine/include/vie_codec.h"
-#include "video_engine/include/vie_errors.h"
-#include "video_engine/include/vie_image_process.h"
-#include "video_engine/include/vie_network.h"
-#include "video_engine/include/vie_render.h"
-#include "video_engine/include/vie_rtp_rtcp.h"
-#else
-#include "third_party/webrtc/files/include/common_types.h"
-#include "third_party/webrtc/files/include/module_common_types.h"
-#include "third_party/webrtc/files/include/video_capture.h"
-#include "third_party/webrtc/files/include/video_render.h"
-#include "third_party/webrtc/files/include/vie_base.h"
-#include "third_party/webrtc/files/include/vie_capture.h"
-#include "third_party/webrtc/files/include/vie_codec.h"
-#include "third_party/webrtc/files/include/vie_errors.h"
-#include "third_party/webrtc/files/include/vie_image_process.h"
-#include "third_party/webrtc/files/include/vie_network.h"
-#include "third_party/webrtc/files/include/vie_render.h"
-#include "third_party/webrtc/files/include/vie_rtp_rtcp.h"
-#endif  // WEBRTC_RELATIVE_PATH
-
-namespace cricket {
-
-// all tracing macros should go to a common file
-
-// automatically handles lifetime of VideoEngine
-class scoped_vie_engine {
- public:
-  explicit scoped_vie_engine(webrtc::VideoEngine* e) : ptr(e) {}
-  // VERIFY, to ensure that there are no leaks at shutdown
-  ~scoped_vie_engine() {
-    if (ptr) {
-      webrtc::VideoEngine::Delete(ptr);
-    }
-  }
-  webrtc::VideoEngine* get() const { return ptr; }
- private:
-  webrtc::VideoEngine* ptr;
-};
-
-// scoped_ptr class to handle obtaining and releasing VideoEngine
-// interface pointers
-template<class T> class scoped_vie_ptr {
- public:
-  explicit scoped_vie_ptr(const scoped_vie_engine& e)
-       : ptr(T::GetInterface(e.get())) {}
-  explicit scoped_vie_ptr(T* p) : ptr(p) {}
-  ~scoped_vie_ptr() { if (ptr) ptr->Release(); }
-  T* operator->() const { return ptr; }
-  T* get() const { return ptr; }
- private:
-  T* ptr;
-};
-
-// Utility class for aggregating the various WebRTC interface.
-// Fake implementations can also be injected for testing.
-class ViEWrapper {
- public:
-  ViEWrapper()
-      : engine_(webrtc::VideoEngine::Create()),
-        base_(engine_), codec_(engine_), capture_(engine_),
-        network_(engine_), render_(engine_), rtp_(engine_),
-        image_(engine_) {
-  }
-
-  ViEWrapper(webrtc::ViEBase* base, webrtc::ViECodec* codec,
-             webrtc::ViECapture* capture, webrtc::ViENetwork* network,
-             webrtc::ViERender* render, webrtc::ViERTP_RTCP* rtp,
-             webrtc::ViEImageProcess* image)
-      : engine_(NULL),
-        base_(base),
-        codec_(codec),
-        capture_(capture),
-        network_(network),
-        render_(render),
-        rtp_(rtp),
-        image_(image) {
-  }
-
-  virtual ~ViEWrapper() {}
-  webrtc::VideoEngine* engine() { return engine_.get(); }
-  webrtc::ViEBase* base() { return base_.get(); }
-  webrtc::ViECodec* codec() { return codec_.get(); }
-  webrtc::ViECapture* capture() { return capture_.get(); }
-  webrtc::ViENetwork* network() { return network_.get(); }
-  webrtc::ViERender* render() { return render_.get(); }
-  webrtc::ViERTP_RTCP* rtp() { return rtp_.get(); }
-  webrtc::ViEImageProcess* sync() { return image_.get(); }
-  int error() { return base_->LastError(); }
-
- private:
-  scoped_vie_engine engine_;
-  scoped_vie_ptr<webrtc::ViEBase> base_;
-  scoped_vie_ptr<webrtc::ViECodec> codec_;
-  scoped_vie_ptr<webrtc::ViECapture> capture_;
-  scoped_vie_ptr<webrtc::ViENetwork> network_;
-  scoped_vie_ptr<webrtc::ViERender> render_;
-  scoped_vie_ptr<webrtc::ViERTP_RTCP> rtp_;
-  scoped_vie_ptr<webrtc::ViEImageProcess> image_;
-};
-
-// Adds indirection to static WebRtc functions, allowing them to be mocked.
-class ViETraceWrapper {
- public:
-  virtual ~ViETraceWrapper() {}
-
-  virtual int SetTraceFilter(const unsigned int filter) {
-    return webrtc::VideoEngine::SetTraceFilter(filter);
-  }
-  virtual int SetTraceFile(const char* fileNameUTF8) {
-    return webrtc::VideoEngine::SetTraceFile(fileNameUTF8);
-  }
-  virtual int SetTraceCallback(webrtc::TraceCallback* callback) {
-    return webrtc::VideoEngine::SetTraceCallback(callback);
-  }
-};
-
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_WEBRTCVIE_H_
diff --git a/third_party/libjingle/source/talk/session/phone/webrtcvoe.h b/third_party/libjingle/source/talk/session/phone/webrtcvoe.h
deleted file mode 100644
index 709b3d6..0000000
--- a/third_party/libjingle/source/talk/session/phone/webrtcvoe.h
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-#ifndef TALK_SESSION_PHONE_WEBRTCVOE_H_
-#define TALK_SESSION_PHONE_WEBRTCVOE_H_
-
-#include "talk/base/common.h"
-#include "talk/session/phone/webrtccommon.h"
-
-#ifdef WEBRTC_RELATIVE_PATH
-#include "common_types.h"
-#include "modules/audio_device/main/interface/audio_device.h"
-#include "voice_engine/main/interface/voe_audio_processing.h"
-#include "voice_engine/main/interface/voe_base.h"
-#include "voice_engine/main/interface/voe_codec.h"
-#include "voice_engine/main/interface/voe_dtmf.h"
-#include "voice_engine/main/interface/voe_errors.h"
-#include "voice_engine/main/interface/voe_external_media.h"
-#include "voice_engine/main/interface/voe_file.h"
-#include "voice_engine/main/interface/voe_hardware.h"
-#include "voice_engine/main/interface/voe_neteq_stats.h"
-#include "voice_engine/main/interface/voe_network.h"
-#include "voice_engine/main/interface/voe_rtp_rtcp.h"
-#include "voice_engine/main/interface/voe_video_sync.h"
-#include "voice_engine/main/interface/voe_volume_control.h"
-#else
-#include "third_party/webrtc/files/include/audio_device.h"
-#include "third_party/webrtc/files/include/common_types.h"
-#include "third_party/webrtc/files/include/voe_audio_processing.h"
-#include "third_party/webrtc/files/include/voe_base.h"
-#include "third_party/webrtc/files/include/voe_codec.h"
-#include "third_party/webrtc/files/include/voe_dtmf.h"
-#include "third_party/webrtc/files/include/voe_errors.h"
-#include "third_party/webrtc/files/include/voe_external_media.h"
-#include "third_party/webrtc/files/include/voe_file.h"
-#include "third_party/webrtc/files/include/voe_hardware.h"
-#include "third_party/webrtc/files/include/voe_neteq_stats.h"
-#include "third_party/webrtc/files/include/voe_network.h"
-#include "third_party/webrtc/files/include/voe_rtp_rtcp.h"
-#include "third_party/webrtc/files/include/voe_video_sync.h"
-#include "third_party/webrtc/files/include/voe_volume_control.h"
-#endif  // WEBRTC_RELATIVE_PATH
-
-namespace cricket {
-// automatically handles lifetime of WebRtc VoiceEngine
-class scoped_voe_engine {
- public:
-  explicit scoped_voe_engine(webrtc::VoiceEngine* e) : ptr(e) {}
-  // VERIFY, to ensure that there are no leaks at shutdown
-  ~scoped_voe_engine() { if (ptr) VERIFY(webrtc::VoiceEngine::Delete(ptr)); }
-  // Releases the current pointer.
-  void reset() {
-    if (ptr) {
-      VERIFY(webrtc::VoiceEngine::Delete(ptr));
-      ptr = NULL;
-    }
-  }
-  webrtc::VoiceEngine* get() const { return ptr; }
- private:
-  webrtc::VoiceEngine* ptr;
-};
-
-// scoped_ptr class to handle obtaining and releasing WebRTC interface pointers
-template<class T>
-class scoped_voe_ptr {
- public:
-  explicit scoped_voe_ptr(const scoped_voe_engine& e)
-      : ptr(T::GetInterface(e.get())) {}
-  explicit scoped_voe_ptr(T* p) : ptr(p) {}
-  ~scoped_voe_ptr() { if (ptr) ptr->Release(); }
-  T* operator->() const { return ptr; }
-  T* get() const { return ptr; }
-
-  // Releases the current pointer.
-  void reset() {
-    if (ptr) {
-      ptr->Release();
-      ptr = NULL;
-    }
-  }
-
- private:
-  T* ptr;
-};
-
-// Utility class for aggregating the various WebRTC interface.
-// Fake implementations can also be injected for testing.
-class VoEWrapper {
- public:
-  VoEWrapper()
-      : engine_(webrtc::VoiceEngine::Create()), processing_(engine_),
-        base_(engine_), codec_(engine_), dtmf_(engine_), file_(engine_),
-        hw_(engine_), media_(engine_), neteq_(engine_), network_(engine_),
-        rtp_(engine_), sync_(engine_), volume_(engine_) {
-  }
-  VoEWrapper(webrtc::VoEAudioProcessing* processing,
-             webrtc::VoEBase* base,
-             webrtc::VoECodec* codec,
-             webrtc::VoEDtmf* dtmf,
-             webrtc::VoEFile* file,
-             webrtc::VoEHardware* hw,
-             webrtc::VoEExternalMedia* media,
-             webrtc::VoENetEqStats* neteq,
-             webrtc::VoENetwork* network,
-             webrtc::VoERTP_RTCP* rtp,
-             webrtc::VoEVideoSync* sync,
-             webrtc::VoEVolumeControl* volume)
-      : engine_(NULL),
-        processing_(processing),
-        base_(base),
-        codec_(codec),
-        dtmf_(dtmf),
-        file_(file),
-        hw_(hw),
-        media_(media),
-        neteq_(neteq),
-        network_(network),
-        rtp_(rtp),
-        sync_(sync),
-        volume_(volume) {
-  }
-  ~VoEWrapper() {}
-  webrtc::VoiceEngine* engine() const { return engine_.get(); }
-  webrtc::VoEAudioProcessing* processing() const { return processing_.get(); }
-  webrtc::VoEBase* base() const { return base_.get(); }
-  webrtc::VoECodec* codec() const { return codec_.get(); }
-  webrtc::VoEDtmf* dtmf() const { return dtmf_.get(); }
-  webrtc::VoEFile* file() const { return file_.get(); }
-  webrtc::VoEHardware* hw() const { return hw_.get(); }
-  webrtc::VoEExternalMedia* media() const { return media_.get(); }
-  webrtc::VoENetEqStats* neteq() const { return neteq_.get(); }
-  webrtc::VoENetwork* network() const { return network_.get(); }
-  webrtc::VoERTP_RTCP* rtp() const { return rtp_.get(); }
-  webrtc::VoEVideoSync* sync() const { return sync_.get(); }
-  webrtc::VoEVolumeControl* volume() const { return volume_.get(); }
-  int error() { return base_->LastError(); }
-
- private:
-  scoped_voe_engine engine_;
-  scoped_voe_ptr<webrtc::VoEAudioProcessing> processing_;
-  scoped_voe_ptr<webrtc::VoEBase> base_;
-  scoped_voe_ptr<webrtc::VoECodec> codec_;
-  scoped_voe_ptr<webrtc::VoEDtmf> dtmf_;
-  scoped_voe_ptr<webrtc::VoEFile> file_;
-  scoped_voe_ptr<webrtc::VoEHardware> hw_;
-  scoped_voe_ptr<webrtc::VoEExternalMedia> media_;
-  scoped_voe_ptr<webrtc::VoENetEqStats> neteq_;
-  scoped_voe_ptr<webrtc::VoENetwork> network_;
-  scoped_voe_ptr<webrtc::VoERTP_RTCP> rtp_;
-  scoped_voe_ptr<webrtc::VoEVideoSync> sync_;
-  scoped_voe_ptr<webrtc::VoEVolumeControl> volume_;
-};
-
-// Adds indirection to static WebRtc functions, allowing them to be mocked.
-class VoETraceWrapper {
- public:
-  virtual ~VoETraceWrapper() {}
-
-  virtual int SetTraceFilter(const unsigned int filter) {
-    return webrtc::VoiceEngine::SetTraceFilter(filter);
-  }
-  virtual int SetTraceFile(const char* fileNameUTF8) {
-    return webrtc::VoiceEngine::SetTraceFile(fileNameUTF8);
-  }
-  virtual int SetTraceCallback(webrtc::TraceCallback* callback) {
-    return webrtc::VoiceEngine::SetTraceCallback(callback);
-  }
-};
-
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_WEBRTCVOE_H_
diff --git a/third_party/libjingle/source/talk/session/phone/webrtcvoiceengine.cc b/third_party/libjingle/source/talk/session/phone/webrtcvoiceengine.cc
deleted file mode 100644
index 561c13c..0000000
--- a/third_party/libjingle/source/talk/session/phone/webrtcvoiceengine.cc
+++ /dev/null
@@ -1,2256 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#ifdef HAVE_WEBRTC_VOICE
-
-#include "talk/session/phone/webrtcvoiceengine.h"
-
-#include <algorithm>
-#include <cstdio>
-#include <string>
-#include <vector>
-
-#include "talk/base/base64.h"
-#include "talk/base/byteorder.h"
-#include "talk/base/common.h"
-#include "talk/base/helpers.h"
-#include "talk/base/logging.h"
-#include "talk/base/stringencode.h"
-#include "talk/base/stringutils.h"
-#include "talk/session/phone/voiceprocessor.h"
-#include "talk/session/phone/webrtcvoe.h"
-
-#ifdef WIN32
-#include <objbase.h>  // NOLINT
-#endif
-
-namespace cricket {
-
-// For Linux/Mac, using the default device is done by specifying index 0 for
-// VoE 4.0 and not -1 (which was the case for VoE 3.5).
-//
-// On Windows Vista and newer, Microsoft introduced the concept of "Default
-// Communications Device". This means that there are two types of default
-// devices (old Wave Audio style default and Default Communications Device).
-//
-// On Windows systems which only support Wave Audio style default, uses either
-// -1 or 0 to select the default device.
-//
-// On Windows systems which support both "Default Communication Device" and
-// old Wave Audio style default, use -1 for Default Communications Device and
-// -2 for Wave Audio style default, which is what we want to use for clips.
-// It's not clear yet whether the -2 index is handled properly on other OSes.
-
-#ifdef WIN32
-static const int kDefaultAudioDeviceId = -1;
-static const int kDefaultSoundclipDeviceId = -2;
-#else
-static const int kDefaultAudioDeviceId = 0;
-#endif
-
-// extension header for audio levels, as defined in
-// http://tools.ietf.org/html/draft-ietf-avtext-client-to-mixer-audio-level-03
-static const char kRtpAudioLevelHeaderExtension[] =
-    "urn:ietf:params:rtp-hdrext:ssrc-audio-level";
-
-static const char kIsacCodecName[] = "ISAC";
-static const char kL16CodecName[] = "L16";
-
-// Dumps an AudioCodec in RFC 2327-ish format.
-static std::string ToString(const AudioCodec& codec) {
-  std::stringstream ss;
-  ss << codec.name << "/" << codec.clockrate << "/" << codec.channels
-     << " (" << codec.id << ")";
-  return ss.str();
-}
-static std::string ToString(const webrtc::CodecInst& codec) {
-  std::stringstream ss;
-  ss << codec.plname << "/" << codec.plfreq << "/" << codec.channels
-     << " (" << codec.pltype << ")";
-  return ss.str();
-}
-
-static void LogMultiline(talk_base::LoggingSeverity sev, char* text) {
-  const char* delim = "\r\n";
-  for (char* tok = strtok(text, delim); tok; tok = strtok(NULL, delim)) {
-    LOG_V(sev) << tok;
-  }
-}
-
-// WebRtcVoiceEngine
-const WebRtcVoiceEngine::CodecPref WebRtcVoiceEngine::kCodecPrefs[] = {
-  { "ISAC",   16000,  103 },
-  { "ISAC",   32000,  104 },
-  { "speex",  16000,  107 },
-  { "G722",   16000,  9 },
-  { "ILBC",   8000,   102 },
-  { "speex",  8000,   108 },
-  { "PCMU",   8000,   0 },
-  { "PCMA",   8000,   8 },
-  { "CN",     32000,  106 },
-  { "CN",     16000,  105 },
-  { "CN",     8000,   13 },
-  { "red",    8000,   127 },
-  { "telephone-event", 8000, 126 },
-};
-
-class WebRtcSoundclipMedia : public SoundclipMedia {
- public:
-  explicit WebRtcSoundclipMedia(WebRtcVoiceEngine *engine)
-      : engine_(engine), webrtc_channel_(-1) {
-    engine_->RegisterSoundclip(this);
-  }
-
-  virtual ~WebRtcSoundclipMedia() {
-    engine_->UnregisterSoundclip(this);
-    if (webrtc_channel_ != -1) {
-      // We shouldn't have to call Disable() here. DeleteChannel() should call
-      // StopPlayout() while deleting the channel.  We should fix the bug
-      // inside WebRTC and remove the Disable() call bellow.  This work is
-      // tracked by bug http://b/issue?id=5382855.
-      PlaySound(NULL, 0, 0);
-      Disable();
-      if (engine_->voe_sc()->base()->DeleteChannel(webrtc_channel_)
-          == -1) {
-        LOG_RTCERR1(DeleteChannel, webrtc_channel_);
-      }
-    }
-  }
-
-  bool Init() {
-    webrtc_channel_ = engine_->voe_sc()->base()->CreateChannel();
-    if (webrtc_channel_ == -1) {
-      LOG_RTCERR0(CreateChannel);
-      return false;
-    }
-    return true;
-  }
-
-  bool Enable() {
-    if (engine_->voe_sc()->base()->StartPlayout(webrtc_channel_) == -1) {
-      LOG_RTCERR1(StartPlayout, webrtc_channel_);
-      return false;
-    }
-    return true;
-  }
-
-  bool Disable() {
-    if (engine_->voe_sc()->base()->StopPlayout(webrtc_channel_) == -1) {
-      LOG_RTCERR1(StopPlayout, webrtc_channel_);
-      return false;
-    }
-    return true;
-  }
-
-  virtual bool PlaySound(const char *buf, int len, int flags) {
-    // Must stop playing the current sound (if any), because we are about to
-    // modify the stream.
-    if (engine_->voe_sc()->file()->StopPlayingFileLocally(webrtc_channel_)
-        == -1) {
-      LOG_RTCERR1(StopPlayingFileLocally, webrtc_channel_);
-      return false;
-    }
-
-    if (buf) {
-      stream_.reset(new WebRtcSoundclipStream(buf, len));
-      stream_->set_loop((flags & SF_LOOP) != 0);
-      stream_->Rewind();
-
-      // Play it.
-      if (engine_->voe_sc()->file()->StartPlayingFileLocally(
-          webrtc_channel_, stream_.get()) == -1) {
-        LOG_RTCERR2(StartPlayingFileLocally, webrtc_channel_, stream_.get());
-        LOG(LS_ERROR) << "Unable to start soundclip";
-        return false;
-      }
-    } else {
-      stream_.reset();
-    }
-    return true;
-  }
-
-  int GetLastEngineError() const { return engine_->voe_sc()->error(); }
-
- private:
-  WebRtcVoiceEngine *engine_;
-  int webrtc_channel_;
-  talk_base::scoped_ptr<WebRtcSoundclipStream> stream_;
-};
-
-WebRtcVoiceEngine::WebRtcVoiceEngine()
-    : voe_wrapper_(new VoEWrapper()),
-      voe_wrapper_sc_(new VoEWrapper()),
-      tracing_(new VoETraceWrapper()),
-      adm_(NULL),
-      adm_sc_(NULL),
-      log_level_(kDefaultLogSeverity),
-      is_dumping_aec_(false),
-      desired_local_monitor_enable_(false) {
-  Construct();
-}
-
-WebRtcVoiceEngine::WebRtcVoiceEngine(VoEWrapper* voe_wrapper,
-                                     VoEWrapper* voe_wrapper_sc,
-                                     VoETraceWrapper* tracing)
-    : voe_wrapper_(voe_wrapper),
-      voe_wrapper_sc_(voe_wrapper_sc),
-      tracing_(tracing),
-      adm_(NULL),
-      adm_sc_(NULL),
-      log_level_(kDefaultLogSeverity),
-      is_dumping_aec_(false),
-      desired_local_monitor_enable_(false) {
-  Construct();
-}
-
-void WebRtcVoiceEngine::Construct() {
-  initialized_ = false;
-  LOG(LS_VERBOSE) << "WebRtcVoiceEngine::WebRtcVoiceEngine";
-  ApplyLogging("");
-  if (tracing_->SetTraceCallback(this) == -1) {
-    LOG_RTCERR0(SetTraceCallback);
-  }
-  if (voe_wrapper_->base()->RegisterVoiceEngineObserver(*this) == -1) {
-    LOG_RTCERR0(RegisterVoiceEngineObserver);
-  }
-  // Clear the default agc state.
-  memset(&default_agc_config_, 0, sizeof(default_agc_config_));
-
-  // Load our audio codec list.
-  ConstructCodecs();
-}
-
-void WebRtcVoiceEngine::ConstructCodecs() {
-  LOG(LS_INFO) << "WebRtc VoiceEngine codecs:";
-  int ncodecs = voe_wrapper_->codec()->NumOfCodecs();
-  for (int i = 0; i < ncodecs; ++i) {
-    webrtc::CodecInst voe_codec;
-    if (voe_wrapper_->codec()->GetCodec(i, voe_codec) != -1) {
-      // Skip uncompressed formats.
-      if (_stricmp(voe_codec.plname, kL16CodecName) == 0) {
-        continue;
-      }
-
-      const CodecPref* pref = NULL;
-      for (size_t j = 0; j < ARRAY_SIZE(kCodecPrefs); ++j) {
-        if (_stricmp(kCodecPrefs[j].name, voe_codec.plname) == 0 &&
-            kCodecPrefs[j].clockrate == voe_codec.plfreq) {
-          pref = &kCodecPrefs[j];
-          break;
-        }
-      }
-
-      if (pref) {
-        // Use the payload type that we've configured in our pref table;
-        // use the offset in our pref table to determine the sort order.
-        AudioCodec codec(pref->payload_type, voe_codec.plname, voe_codec.plfreq,
-                         voe_codec.rate, voe_codec.channels,
-                         ARRAY_SIZE(kCodecPrefs) - (pref - kCodecPrefs));
-        LOG(LS_INFO) << ToString(codec);
-        // For ISAC, use 0 to indicate auto bandwidth in our signaling.
-        if (_stricmp(codec.name.c_str(), kIsacCodecName) == 0) {
-          codec.bitrate = 0;
-        }
-        codecs_.push_back(codec);
-      } else {
-        LOG(LS_WARNING) << "Unexpected codec: " << ToString(voe_codec);
-      }
-    }
-  }
-  // Make sure they are in local preference order.
-  std::sort(codecs_.begin(), codecs_.end(), &AudioCodec::Preferable);
-}
-
-WebRtcVoiceEngine::~WebRtcVoiceEngine() {
-  LOG(LS_VERBOSE) << "WebRtcVoiceEngine::~WebRtcVoiceEngine";
-  if (voe_wrapper_->base()->DeRegisterVoiceEngineObserver() == -1) {
-    LOG_RTCERR0(DeRegisterVoiceEngineObserver);
-  }
-  if (adm_) {
-    voe_wrapper_.reset();
-    adm_->Release();
-    adm_ = NULL;
-  }
-  if (adm_sc_) {
-    voe_wrapper_sc_.reset();
-    adm_sc_->Release();
-    adm_sc_ = NULL;
-  }
-
-  // Test to see if the media processor was deregistered properly
-  ASSERT(SignalRxMediaFrame.is_empty());
-  ASSERT(SignalTxMediaFrame.is_empty());
-
-  tracing_->SetTraceCallback(NULL);
-}
-
-bool WebRtcVoiceEngine::Init() {
-  LOG(LS_INFO) << "WebRtcVoiceEngine::Init";
-  bool res = InitInternal();
-  if (res) {
-    LOG(LS_INFO) << "WebRtcVoiceEngine::Init Done!";
-  } else {
-    LOG(LS_ERROR) << "WebRtcVoiceEngine::Init failed";
-    Terminate();
-  }
-  return res;
-}
-
-bool WebRtcVoiceEngine::InitInternal() {
-  // Temporarily turn logging level up for the Init call
-  int old_level = log_level_;
-  log_level_ = talk_base::_min(log_level_,
-                               static_cast<int>(talk_base::LS_INFO));
-  ApplyLogging("");
-
-  // Init WebRtc VoiceEngine, enabling AEC logging if specified in SetLogging.
-  if (voe_wrapper_->base()->Init(adm_) == -1) {
-    LOG_RTCERR0_EX(Init, voe_wrapper_->error());
-    return false;
-  }
-
-  // Restore the previous log level and apply the log filter.
-  log_level_ = old_level;
-  ApplyLogging(log_filter_);
-
-  // Log the VoiceEngine version info
-  char buffer[1024] = "";
-  voe_wrapper_->base()->GetVersion(buffer);
-  LOG(LS_INFO) << "WebRtc VoiceEngine Version:";
-  LogMultiline(talk_base::LS_INFO, buffer);
-
-  // Turn on AEC and AGC by default.
-  if (!SetOptions(
-      MediaEngineInterface::ECHO_CANCELLATION |
-      MediaEngineInterface::AUTO_GAIN_CONTROL)) {
-    return false;
-  }
-
-  // Save the default AGC configuration settings.
-  if (voe_wrapper_->processing()->SetAgcConfig(default_agc_config_) == -1) {
-    LOG_RTCERR0(GetAGCConfig);
-    return false;
-  }
-
-  // Print our codec list again for the call diagnostic log
-  LOG(LS_INFO) << "WebRtc VoiceEngine codecs:";
-  for (std::vector<AudioCodec>::const_iterator it = codecs_.begin();
-      it != codecs_.end(); ++it) {
-    LOG(LS_INFO) << ToString(*it);
-  }
-
-#if defined(LINUX) && !defined(HAVE_LIBPULSE)
-  voe_wrapper_sc_->hw()->SetAudioDeviceLayer(webrtc::kAudioLinuxAlsa);
-#endif
-
-  // Initialize the VoiceEngine instance that we'll use to play out sound clips.
-  if (voe_wrapper_sc_->base()->Init(adm_sc_) == -1) {
-    LOG_RTCERR0_EX(Init, voe_wrapper_sc_->error());
-    return false;
-  }
-
-  // On Windows, tell it to use the default sound (not communication) devices.
-  // First check whether there is a valid sound device for playback.
-  // TODO: Clean this up when we support setting the soundclip device.
-#ifdef WIN32
-  int num_of_devices = 0;
-  if (voe_wrapper_sc_->hw()->GetNumOfPlayoutDevices(num_of_devices) != -1 &&
-      num_of_devices > 0) {
-    if (voe_wrapper_sc_->hw()->SetPlayoutDevice(kDefaultSoundclipDeviceId)
-        == -1) {
-      LOG_RTCERR1_EX(SetPlayoutDevice, kDefaultSoundclipDeviceId,
-                      voe_wrapper_sc_->error());
-      return false;
-    }
-  } else {
-    LOG(LS_WARNING) << "No valid sound playout device found.";
-  }
-#endif
-
-  initialized_ = true;
-  return true;
-}
-
-void WebRtcVoiceEngine::Terminate() {
-  LOG(LS_INFO) << "WebRtcVoiceEngine::Terminate";
-  initialized_ = false;
-
-  if (is_dumping_aec_) {
-    if (voe_wrapper_->processing()->StopDebugRecording() == -1) {
-      LOG_RTCERR0(StopDebugRecording);
-    }
-    is_dumping_aec_ = false;
-  }
-
-  voe_wrapper_sc_->base()->Terminate();
-  voe_wrapper_->base()->Terminate();
-  desired_local_monitor_enable_ = false;
-}
-
-int WebRtcVoiceEngine::GetCapabilities() {
-  return AUDIO_SEND | AUDIO_RECV;
-}
-
-VoiceMediaChannel *WebRtcVoiceEngine::CreateChannel() {
-  WebRtcVoiceMediaChannel* ch = new WebRtcVoiceMediaChannel(this);
-  if (!ch->valid()) {
-    delete ch;
-    ch = NULL;
-  }
-  return ch;
-}
-
-SoundclipMedia *WebRtcVoiceEngine::CreateSoundclip() {
-  WebRtcSoundclipMedia *soundclip = new WebRtcSoundclipMedia(this);
-  if (!soundclip->Init() || !soundclip->Enable()) {
-    delete soundclip;
-    return NULL;
-  }
-  return soundclip;
-}
-
-bool WebRtcVoiceEngine::SetOptions(int options) {
-  // NS and typing detection are always on, if supported.
-  bool aec = (options & MediaEngineInterface::ECHO_CANCELLATION) ? true : false;
-  bool agc = (options & MediaEngineInterface::AUTO_GAIN_CONTROL) ? true : false;
-#if !defined(IOS) && !defined(ANDROID)
-  if (voe_wrapper_->processing()->SetEcStatus(aec) == -1) {
-    LOG_RTCERR1(SetEcStatus, aec);
-    return false;
-  }
-  if (aec) {
-    if (voe_wrapper_->processing()->SetEcMetricsStatus(true) == -1) {
-      LOG_RTCERR1(SetEcMetricsStatus, true);
-      return false;
-    }
-  }
-
-  if (voe_wrapper_->processing()->SetAgcStatus(agc) == -1) {
-    LOG_RTCERR1(SetAgcStatus, agc);
-    return false;
-  }
-
-  if (voe_wrapper_->processing()->SetNsStatus(true) == -1) {
-    LOG_RTCERR1(SetNsStatus, true);
-    return false;
-  }
-
-  if (voe_wrapper_->processing()->SetTypingDetectionStatus(true) == -1) {
-    // In case of error, log the info and continue
-    LOG_RTCERR1(SetTypingDetectionStatus, true);
-  }
-#else
-  if (voe_wrapper_->processing()->SetEcStatus(aec, kEcAecm) == -1) {
-    LOG_RTCERR2(SetEcStatus, aec, kEcAecm);
-    return false;
-  }
-
-  if (aec) {
-    // Use speakerphone mode with comfort noise generation for mobile.
-    if (voe_wrapper_->processing()->SetAecmMode(kAecmSpeakerphone, true) != 0) {
-      LOG_RTCERR2(SetAecmMode, kAecmSpeakerphone, true);
-    }
-  }
-
-  // On mobile, GIPS recommends fixed AGC (not adaptive)
-  if (voe_wrapper_->processing()->SetAgcStatus(agc, kAgcFixedDigital) == -1) {
-    LOG_RTCERR2(SetAgcStatus, agc, kAgcFixedDigital);
-    return false;
-  }
-
-  // On mobile, GIPS recommends moderate aggressiveness.
-  if (voe_wrapper_->processing()->SetNsStatus(true,
-      kNsModerateSuppression) == -1) {
-    LOG_RTCERR2(SetNsStatus, ns, kNsModerateSuppression);
-    return false;
-  }
-
-  // No typing detection support on iOS or Android.
-#endif // !IOS && !ANDROID
-
-  return true;
-}
-
-struct ResumeEntry {
-  ResumeEntry(WebRtcVoiceMediaChannel *c, bool p, SendFlags s)
-      : channel(c),
-        playout(p),
-        send(s) {
-  }
-
-  WebRtcVoiceMediaChannel *channel;
-  bool playout;
-  SendFlags send;
-};
-
-// TODO: Refactor this so that the core logic can be used to set the
-// soundclip device. At that time, reinstate the soundclip pause/resume code.
-bool WebRtcVoiceEngine::SetDevices(const Device* in_device,
-                                   const Device* out_device) {
-#if !defined(IOS) && !defined(ANDROID)
-  int in_id = in_device ? talk_base::FromString<int>(in_device->id) :
-      kDefaultAudioDeviceId;
-  int out_id = out_device ? talk_base::FromString<int>(out_device->id) :
-      kDefaultAudioDeviceId;
-  // The device manager uses -1 as the default device, which was the case for
-  // VoE 3.5. VoE 4.0, however, uses 0 as the default in Linux and Mac.
-#ifndef WIN32
-  if (-1 == in_id) {
-    in_id = kDefaultAudioDeviceId;
-  }
-  if (-1 == out_id) {
-    out_id = kDefaultAudioDeviceId;
-  }
-#endif
-
-  std::string in_name = (in_id != kDefaultAudioDeviceId) ?
-      in_device->name : "Default device";
-  std::string out_name = (out_id != kDefaultAudioDeviceId) ?
-      out_device->name : "Default device";
-  LOG(LS_INFO) << "Setting microphone to (id=" << in_id << ", name=" << in_name
-            << ") and speaker to (id=" << out_id << ", name=" << out_name
-            << ")";
-
-  // If we're running the local monitor, we need to stop it first.
-  bool ret = true;
-  if (!PauseLocalMonitor()) {
-    LOG(LS_WARNING) << "Failed to pause local monitor";
-    ret = false;
-  }
-
-  // Must also pause all audio playback and capture.
-  for (ChannelList::const_iterator i = channels_.begin();
-       i != channels_.end(); ++i) {
-    WebRtcVoiceMediaChannel *channel = *i;
-    if (!channel->PausePlayout()) {
-      LOG(LS_WARNING) << "Failed to pause playout";
-      ret = false;
-    }
-    if (!channel->PauseSend()) {
-      LOG(LS_WARNING) << "Failed to pause send";
-      ret = false;
-    }
-  }
-
-  // Find the recording device id in VoiceEngine and set recording device.
-  if (!FindWebRtcAudioDeviceId(true, in_name, in_id, &in_id)) {
-    ret = false;
-  }
-  if (ret) {
-    if (voe_wrapper_->hw()->SetRecordingDevice(in_id) == -1) {
-      LOG_RTCERR2(SetRecordingDevice, in_device->name, in_id);
-      ret = false;
-    }
-  }
-
-  // Find the playout device id in VoiceEngine and set playout device.
-  if (!FindWebRtcAudioDeviceId(false, out_name, out_id, &out_id)) {
-    LOG(LS_WARNING) << "Failed to find VoiceEngine device id for " << out_name;
-    ret = false;
-  }
-  if (ret) {
-    if (voe_wrapper_->hw()->SetPlayoutDevice(out_id) == -1) {
-      LOG_RTCERR2(SetPlayoutDevice, out_device->name, out_id);
-      ret = false;
-    }
-  }
-
-  // Resume all audio playback and capture.
-  for (ChannelList::const_iterator i = channels_.begin();
-       i != channels_.end(); ++i) {
-    WebRtcVoiceMediaChannel *channel = *i;
-    if (!channel->ResumePlayout()) {
-      LOG(LS_WARNING) << "Failed to resume playout";
-      ret = false;
-    }
-    if (!channel->ResumeSend()) {
-      LOG(LS_WARNING) << "Failed to resume send";
-      ret = false;
-    }
-  }
-
-  // Resume local monitor.
-  if (!ResumeLocalMonitor()) {
-    LOG(LS_WARNING) << "Failed to resume local monitor";
-    ret = false;
-  }
-
-  if (ret) {
-    LOG(LS_INFO) << "Set microphone to (id=" << in_id <<" name=" << in_name
-                 << ") and speaker to (id="<< out_id << " name=" << out_name
-                 << ")";
-  }
-
-  return ret;
-#else
-  return true;
-#endif  // !IOS && !ANDROID
-}
-
-bool WebRtcVoiceEngine::FindWebRtcAudioDeviceId(
-  bool is_input, const std::string& dev_name, int dev_id, int* rtc_id) {
-  // In Linux, VoiceEngine uses the same device dev_id as the device manager.
-#ifdef LINUX
-  *rtc_id = dev_id;
-  return true;
-#else
-  // In Windows and Mac, we need to find the VoiceEngine device id by name
-  // unless the input dev_id is the default device id.
-  if (kDefaultAudioDeviceId == dev_id) {
-    *rtc_id = dev_id;
-    return true;
-  }
-
-  // Get the number of VoiceEngine audio devices.
-  int count = 0;
-  if (is_input) {
-    if (-1 == voe_wrapper_->hw()->GetNumOfRecordingDevices(count)) {
-      LOG_RTCERR0(GetNumOfRecordingDevices);
-      return false;
-    }
-  } else {
-    if (-1 == voe_wrapper_->hw()->GetNumOfPlayoutDevices(count)) {
-      LOG_RTCERR0(GetNumOfPlayoutDevices);
-      return false;
-    }
-  }
-
-  for (int i = 0; i < count; ++i) {
-    char name[128];
-    char guid[128];
-    if (is_input) {
-      voe_wrapper_->hw()->GetRecordingDeviceName(i, name, guid);
-      LOG(LS_VERBOSE) << "VoiceEngine microphone " << i << ": " << name;
-    } else {
-      voe_wrapper_->hw()->GetPlayoutDeviceName(i, name, guid);
-      LOG(LS_VERBOSE) << "VoiceEngine speaker " << i << ": " << name;
-    }
-
-    std::string webrtc_name(name);
-    if (dev_name.compare(0, webrtc_name.size(), webrtc_name) == 0) {
-      *rtc_id = i;
-      return true;
-    }
-  }
-  LOG(LS_WARNING) << "VoiceEngine cannot find device: " << dev_name;
-  return false;
-#endif
-}
-
-bool WebRtcVoiceEngine::GetOutputVolume(int* level) {
-  unsigned int ulevel;
-  if (voe_wrapper_->volume()->GetSpeakerVolume(ulevel) == -1) {
-    LOG_RTCERR1(GetSpeakerVolume, level);
-    return false;
-  }
-  *level = ulevel;
-  return true;
-}
-
-bool WebRtcVoiceEngine::SetOutputVolume(int level) {
-  ASSERT(level >= 0 && level <= 255);
-  if (voe_wrapper_->volume()->SetSpeakerVolume(level) == -1) {
-    LOG_RTCERR1(SetSpeakerVolume, level);
-    return false;
-  }
-  return true;
-}
-
-int WebRtcVoiceEngine::GetInputLevel() {
-  unsigned int ulevel;
-  return (voe_wrapper_->volume()->GetSpeechInputLevel(ulevel) != -1) ?
-      static_cast<int>(ulevel) : -1;
-}
-
-bool WebRtcVoiceEngine::SetLocalMonitor(bool enable) {
-  desired_local_monitor_enable_ = enable;
-  return ChangeLocalMonitor(desired_local_monitor_enable_);
-}
-
-bool WebRtcVoiceEngine::ChangeLocalMonitor(bool enable) {
-  if (enable && !monitor_.get()) {
-    monitor_.reset(new WebRtcMonitorStream);
-    if (voe_wrapper_->file()->StartRecordingMicrophone(monitor_.get()) == -1) {
-      LOG_RTCERR1(StartRecordingMicrophone, monitor_.get());
-      // Must call Stop() because there are some cases where Start will report
-      // failure but still change the state, and if we leave VE in the on state
-      // then it could crash later when trying to invoke methods on our monitor.
-      voe_wrapper_->file()->StopRecordingMicrophone();
-      monitor_.reset();
-      return false;
-    }
-  } else if (!enable && monitor_.get()) {
-    voe_wrapper_->file()->StopRecordingMicrophone();
-    monitor_.reset();
-  }
-  return true;
-}
-
-bool WebRtcVoiceEngine::PauseLocalMonitor() {
-  return ChangeLocalMonitor(false);
-}
-
-bool WebRtcVoiceEngine::ResumeLocalMonitor() {
-  return ChangeLocalMonitor(desired_local_monitor_enable_);
-}
-
-const std::vector<AudioCodec>& WebRtcVoiceEngine::codecs() {
-  return codecs_;
-}
-
-bool WebRtcVoiceEngine::FindCodec(const AudioCodec& in) {
-  return FindWebRtcCodec(in, NULL);
-}
-
-// Get the VoiceEngine codec that matches |in|, with the supplied settings.
-bool WebRtcVoiceEngine::FindWebRtcCodec(const AudioCodec& in,
-                                        webrtc::CodecInst* out) {
-  int ncodecs = voe_wrapper_->codec()->NumOfCodecs();
-  for (int i = 0; i < ncodecs; ++i) {
-    webrtc::CodecInst voe_codec;
-    if (voe_wrapper_->codec()->GetCodec(i, voe_codec) != -1) {
-      AudioCodec codec(voe_codec.pltype, voe_codec.plname, voe_codec.plfreq,
-                       voe_codec.rate, voe_codec.channels, 0);
-      // Allow arbitrary rates for ISAC to be specified.
-      if (_stricmp(codec.name.c_str(), kIsacCodecName) == 0) {
-        codec.bitrate = 0;
-      }
-      if (codec.Matches(in)) {
-        if (out) {
-          // Fixup the payload type.
-          voe_codec.pltype = in.id;
-          // If ISAC is being used, and an explicit bitrate is not specified,
-          // enable auto bandwidth adjustment.
-          if (_stricmp(codec.name.c_str(), kIsacCodecName) == 0) {
-            voe_codec.rate = (in.bitrate > 0) ? in.bitrate : -1;
-          }
-          *out = voe_codec;
-        }
-        return true;
-      }
-    }
-  }
-  return false;
-}
-
-void WebRtcVoiceEngine::SetLogging(int min_sev, const char* filter) {
-  // if min_sev == -1, we keep the current log level.
-  if (min_sev >= 0) {
-    log_level_ = min_sev;
-  }
-  log_filter_ = filter;
-  ApplyLogging(initialized_ ? log_filter_ : "");
-}
-
-int WebRtcVoiceEngine::GetLastEngineError() {
-  return voe_wrapper_->error();
-}
-
-// We suppport three different logging settings for VoiceEngine:
-// 1. Observer callback that goes into talk diagnostic logfile.
-//    Use --logfile and --loglevel
-//
-// 2. Encrypted VoiceEngine log for debugging VoiceEngine.
-//    Use --voice_loglevel --voice_logfilter "tracefile file_name"
-//
-// 3. EC log and dump for debugging QualityEngine.
-//    Use --voice_loglevel --voice_logfilter "recordEC file_name"
-//
-// For more details see: "https://sites.google.com/a/google.com/wavelet/Home/
-//    Magic-Flute--RTC-Engine-/Magic-Flute-Command-Line-Parameters"
-void WebRtcVoiceEngine::ApplyLogging(const std::string& log_filter) {
-  // Set log level.
-  int filter = 0;
-  switch (log_level_) {
-    case talk_base::LS_VERBOSE:
-      filter |= webrtc::kTraceAll;      // fall through
-    case talk_base::LS_INFO:
-      filter |= webrtc::kTraceStateInfo;  // fall through
-    case talk_base::LS_WARNING:
-      filter |= (webrtc::kTraceInfo | webrtc::kTraceWarning);  // fall through
-    case talk_base::LS_ERROR:
-      filter |= (webrtc::kTraceError | webrtc::kTraceCritical);
-  }
-  tracing_->SetTraceFilter(filter);
-
-  // Set encrypted trace file.
-  std::vector<std::string> opts;
-  talk_base::tokenize(log_filter, ' ', '"', '"', &opts);
-  std::vector<std::string>::iterator tracefile =
-      std::find(opts.begin(), opts.end(), "tracefile");
-  if (tracefile != opts.end() && ++tracefile != opts.end()) {
-    // Write encrypted debug output (at same loglevel) to file
-    // EncryptedTraceFile no longer supported.
-    if (tracing_->SetTraceFile(tracefile->c_str()) == -1) {
-      LOG_RTCERR1(SetTraceFile, *tracefile);
-    }
-  }
-
-  // Set AEC dump file
-  std::vector<std::string>::iterator recordEC =
-      std::find(opts.begin(), opts.end(), "recordEC");
-  if (recordEC != opts.end()) {
-    ++recordEC;
-    if (recordEC != opts.end() && !is_dumping_aec_) {
-      // Start dumping AEC when we are not dumping and recordEC has a filename.
-      if (voe_wrapper_->processing()->StartDebugRecording(
-          recordEC->c_str()) == -1) {
-        LOG_RTCERR0(StartDebugRecording);
-      } else {
-        is_dumping_aec_ = true;
-      }
-    } else if (recordEC == opts.end() && is_dumping_aec_) {
-      // Stop dumping EC when we are dumping and recordEC has no filename.
-      if (voe_wrapper_->processing()->StopDebugRecording() == -1) {
-        LOG_RTCERR0(StopDebugRecording);
-      }
-      is_dumping_aec_ = false;
-    }
-  }
-}
-
-// Ignore spammy trace messages, mostly from the stats API when we haven't
-// gotten RTCP info yet from the remote side.
-bool WebRtcVoiceEngine::ShouldIgnoreTrace(const std::string& trace) {
-  static const char* kTracesToIgnore[] = {
-    "\tfailed to GetReportBlockInformation",
-    "GetRecCodec() failed to get received codec",
-    "GetReceivedRtcpStatistics: Could not get received RTP statistics",
-    "GetRemoteRTCPData() failed to measure statistics due to lack of received RTP and/or RTCP packets",  // NOLINT
-    "GetRemoteRTCPData() failed to retrieve sender info for remote side",
-    "GetRTPStatistics() failed to measure RTT since no RTP packets have been received yet",  // NOLINT
-    "GetRTPStatistics() failed to read RTP statistics from the RTP/RTCP module",
-    "GetRTPStatistics() failed to retrieve RTT from the RTP/RTCP module",
-    "SenderInfoReceived No received SR",
-    "StatisticsRTP() no statisitics availble",
-    NULL
-  };
-  for (const char* const* p = kTracesToIgnore; *p; ++p) {
-    if (trace.find(*p) == 0) {
-      return true;
-    }
-  }
-  return false;
-}
-
-void WebRtcVoiceEngine::Print(const webrtc::TraceLevel level,
-                              const char* trace, const int length) {
-  talk_base::LoggingSeverity sev = talk_base::LS_VERBOSE;
-  if (level == webrtc::kTraceError || level == webrtc::kTraceCritical)
-    sev = talk_base::LS_ERROR;
-  else if (level == webrtc::kTraceWarning)
-    sev = talk_base::LS_WARNING;
-  else if (level == webrtc::kTraceStateInfo || level == webrtc::kTraceInfo)
-    sev = talk_base::LS_INFO;
-
-  if (sev >= log_level_) {
-    // Skip past boilerplate prefix text
-    if (length < 72) {
-      std::string msg(trace, length);
-      LOG(LS_ERROR) << "Malformed webrtc log message: ";
-      LOG_V(sev) << msg;
-    } else {
-      std::string msg(trace + 71, length - 72);
-      if (!ShouldIgnoreTrace(msg)) {
-        LOG_V(sev) << "WebRtc:" << msg;
-      }
-    }
-  }
-}
-
-void WebRtcVoiceEngine::CallbackOnError(const int channel_num,
-                                        const int err_code) {
-  talk_base::CritScope lock(&channels_cs_);
-  WebRtcVoiceMediaChannel* channel = NULL;
-  uint32 ssrc = 0;
-  LOG(LS_WARNING) << "VoiceEngine error " << err_code << " reported on channel "
-                  << channel_num << ".";
-  if (FindChannelAndSsrc(channel_num, &channel, &ssrc)) {
-    ASSERT(channel != NULL);
-    channel->OnError(ssrc, err_code);
-  } else {
-    LOG(LS_ERROR) << "VoiceEngine channel " << channel_num
-                  << " could not be found in channel list when error reported.";
-  }
-}
-
-bool WebRtcVoiceEngine::FindChannelAndSsrc(
-    int channel_num, WebRtcVoiceMediaChannel** channel, uint32* ssrc) const {
-  ASSERT(channel != NULL && ssrc != NULL);
-
-  *channel = NULL;
-  *ssrc = 0;
-  // Find corresponding channel and ssrc
-  for (ChannelList::const_iterator it = channels_.begin();
-      it != channels_.end(); ++it) {
-    ASSERT(*it != NULL);
-    if ((*it)->FindSsrc(channel_num, ssrc)) {
-      *channel = *it;
-      return true;
-    }
-  }
-
-  return false;
-}
-
-// This method will search through the WebRtcVoiceMediaChannels and
-// obtain the voice engine's channel number.
-bool WebRtcVoiceEngine::FindChannelNumFromSsrc(
-    uint32 ssrc, MediaProcessorDirection direction, int* channel_num) {
-  ASSERT(channel_num != NULL);
-
-  *channel_num = -1;
-  // Find corresponding channel for ssrc.
-  for (ChannelList::const_iterator it = channels_.begin();
-      it != channels_.end(); ++it) {
-    ASSERT(*it != NULL);
-    uint32 local_ssrc;
-    if (voe()->rtp()->GetLocalSSRC((*it)->voe_channel(), local_ssrc) != -1) {
-      if (ssrc == local_ssrc) {
-        *channel_num = (*it)->voe_channel();
-      }
-    }
-    if (*channel_num == -1 && (direction & MPD_RX) != 0) {
-      *channel_num = (*it)->GetChannelNum(ssrc);
-    }
-    if (*channel_num != -1) {
-      return true;
-    }
-  }
-  LOG(LS_WARNING) << "FindChannelFromSsrc. No Channel Found for Ssrc: " << ssrc;
-  return false;
-}
-
-void WebRtcVoiceEngine::RegisterChannel(WebRtcVoiceMediaChannel *channel) {
-  talk_base::CritScope lock(&channels_cs_);
-  channels_.push_back(channel);
-}
-
-void WebRtcVoiceEngine::UnregisterChannel(WebRtcVoiceMediaChannel *channel) {
-  talk_base::CritScope lock(&channels_cs_);
-  ChannelList::iterator i = std::find(channels_.begin(),
-                                      channels_.end(),
-                                      channel);
-  if (i != channels_.end()) {
-    channels_.erase(i);
-  }
-}
-
-void WebRtcVoiceEngine::RegisterSoundclip(WebRtcSoundclipMedia *soundclip) {
-  soundclips_.push_back(soundclip);
-}
-
-void WebRtcVoiceEngine::UnregisterSoundclip(WebRtcSoundclipMedia *soundclip) {
-  SoundclipList::iterator i = std::find(soundclips_.begin(),
-                                        soundclips_.end(),
-                                        soundclip);
-  if (i != soundclips_.end()) {
-    soundclips_.erase(i);
-  }
-}
-
-// Adjusts the default AGC target level by the specified delta.
-// NB: If we start messing with other config fields, we'll want
-// to save the current webrtc::AgcConfig as well.
-bool WebRtcVoiceEngine::AdjustAgcLevel(int delta) {
-  webrtc::AgcConfig config = default_agc_config_;
-  config.targetLeveldBOv += delta;
-
-  LOG(LS_INFO) << "Adjusting AGC level from default -"
-               << default_agc_config_.targetLeveldBOv << "dB to -"
-               << config.targetLeveldBOv << "dB";
-
-  if (voe_wrapper_->processing()->SetAgcConfig(config) == -1) {
-    LOG_RTCERR1(SetAgcConfig, config.targetLeveldBOv);
-    return false;
-  }
-  return true;
-}
-
-// Configures echo cancellation and noise suppression modes according to
-// whether or not we are in a multi-point conference.
-bool WebRtcVoiceEngine::SetConferenceMode(bool enable) {
-// Only use EC_AECM for mobile.
-#if defined(IOS) || defined(ANDROID)
-  return true;
-#endif
-
-  LOG(LS_INFO) << (enable ? "Enabling" : "Disabling")
-               << " Conference Mode noise reduction";
-
-  // We always configure noise suppression on, so just toggle the mode.
-  const webrtc::NsModes ns_mode = enable ? webrtc::kNsConference
-                                         : webrtc::kNsDefault;
-  if (voe_wrapper_->processing()->SetNsStatus(true, ns_mode) == -1) {
-    LOG_RTCERR2(SetNsStatus, true, ns_mode);
-    return false;
-  }
-
-  // Echo-cancellation is a user-option, so preserve the enable state and
-  // just toggle the mode.
-  bool aec;
-  webrtc::EcModes ec_mode;
-  if (voe_wrapper_->processing()->GetEcStatus(aec, ec_mode) == -1) {
-    LOG_RTCERR0(GetEcStatus);
-    return false;
-  }
-  ec_mode = enable ? webrtc::kEcConference : webrtc::kEcDefault;
-  if (voe_wrapper_->processing()->SetEcStatus(aec, ec_mode) == -1) {
-    LOG_RTCERR2(SetEcStatus, aec, ec_mode);
-    return false;
-  }
-  return true;
-}
-
-bool WebRtcVoiceEngine::SetAudioDeviceModule(webrtc::AudioDeviceModule* adm,
-    webrtc::AudioDeviceModule* adm_sc) {
-  if (initialized_) {
-    LOG(LS_WARNING) << "SetAudioDeviceModule can not be called after Init.";
-    return false;
-  }
-  if (adm_) {
-    adm_->Release();
-    adm_ = NULL;
-  }
-  if (adm) {
-    adm_ = adm;
-    adm_->AddRef();
-  }
-
-  if (adm_sc_) {
-    adm_sc_->Release();
-    adm_sc_ = NULL;
-  }
-  if (adm_sc) {
-    adm_sc_ = adm_sc;
-    adm_sc_->AddRef();
-  }
-  return true;
-}
-
-bool WebRtcVoiceEngine::RegisterProcessor(
-    uint32 ssrc,
-    VoiceProcessor* voice_processor,
-    MediaProcessorDirection direction) {
-  bool register_with_webrtc = false;
-  int channel_id = -1;
-  bool success = false;
-  bool found_channel = FindChannelNumFromSsrc(ssrc, direction, &channel_id);
-  if (voice_processor == NULL || !found_channel) {
-    LOG(LS_WARNING) << "Media Processing Registration Failed. ssrc: " << ssrc
-        << " foundChannel: " << found_channel;
-    return false;
-  }
-  talk_base::CritScope cs(&signal_media_critical_);
-  webrtc::ProcessingTypes processing_type;
-  if (direction == MPD_RX) {
-    processing_type = webrtc::kPlaybackAllChannelsMixed;
-    if (SignalRxMediaFrame.is_empty()) {
-      register_with_webrtc = true;
-    }
-    SignalRxMediaFrame.connect(voice_processor,
-                               &VoiceProcessor::OnFrame);
-  } else {
-    processing_type = webrtc::kRecordingPerChannel;
-    if (SignalTxMediaFrame.is_empty()) {
-      register_with_webrtc = true;
-    }
-    SignalTxMediaFrame.connect(voice_processor,
-                               &VoiceProcessor::OnFrame);
-  }
-  if (register_with_webrtc) {
-    if (voe()->media()->
-        RegisterExternalMediaProcessing(channel_id,
-                                        processing_type,
-                                        *this) == -1) {
-      LOG_RTCERR2(RegisterExternalMediaProcessing,
-                  channel_id,
-                  processing_type);
-      success = false;
-    } else {
-      LOG(LS_INFO) << "Media Processing Registration Succeeded. channel:"
-                   << channel_id;
-      success = true;
-    }
-  } else {
-    // If we don't have to register with the engine, we just needed to
-    // connect a new processor, set success to true;
-    success = true;
-  }
-  return success;
-}
-
-bool WebRtcVoiceEngine::UnregisterProcessor(
-    uint32 ssrc,
-    VoiceProcessor* voice_processor,
-    MediaProcessorDirection direction) {
-  int channel_id = -1;
-  bool found_channel = FindChannelNumFromSsrc(ssrc, direction, &channel_id);
-  bool success = true;
-  if (voice_processor == NULL || !found_channel) {
-    LOG(LS_WARNING) << "Media Processing Deregistration Failed. ssrc: "
-                    << ssrc
-                    << " foundChannel: "
-                    << found_channel;
-    return false;
-  }
-  talk_base::CritScope cs(&signal_media_critical_);
-  if ((direction & MPD_RX) != 0) {
-    SignalRxMediaFrame.disconnect(voice_processor);
-    if (SignalRxMediaFrame.is_empty()) {
-      if (voe()->media()->DeRegisterExternalMediaProcessing(channel_id,
-          webrtc::kPlaybackAllChannelsMixed) != -1) {
-        LOG(LS_INFO) << "Media Processing DeRegistration Succeeded. channel:"
-                     << channel_id;
-      } else {
-        LOG_RTCERR2(DeRegisterExternalMediaProcessing,
-                    channel_id,
-                    webrtc::kPlaybackAllChannelsMixed);
-        success = false;
-      }
-    }
-  }
-  if ((direction & MPD_TX) != 0) {
-    SignalTxMediaFrame.disconnect(voice_processor);
-    if (SignalTxMediaFrame.is_empty()) {
-      if (voe()->media()->DeRegisterExternalMediaProcessing(channel_id,
-          webrtc::kRecordingPerChannel) != -1) {
-        LOG(LS_INFO) << "Media Processing DeRegistration Succeeded. channel:"
-                     << channel_id;
-      } else {
-        LOG_RTCERR2(DeRegisterExternalMediaProcessing,
-                    channel_id,
-                    webrtc::kRecordingPerChannel);
-        success = false;
-      }
-    }
-  }
-  return success;
-}
-
-// Implementing method from WebRtc VoEMediaProcess interface
-void WebRtcVoiceEngine::Process(const int channel,
-                                const webrtc::ProcessingTypes type,
-                                WebRtc_Word16 audio10ms[],
-                                const int length,
-                                const int sampling_freq,
-                                const bool is_stereo) {
-  uint32 ssrc;
-  WebRtcVoiceMediaChannel* media_channel;
-
-  if (FindChannelAndSsrc(channel, &media_channel, &ssrc)) {
-    talk_base::CritScope cs(&signal_media_critical_);
-    AudioFrame frame(audio10ms, length, sampling_freq, is_stereo);
-    if (type == webrtc::kPlaybackAllChannelsMixed) {
-      SignalRxMediaFrame(ssrc, &frame);
-    } else if (type == webrtc::kRecordingPerChannel) {
-      SignalTxMediaFrame(ssrc, &frame);
-    }
-  } else {
-    LOG(LS_WARNING) << "MediaProcess Callback invoked with unexpected channel: "
-                    << channel;
-  }
-}
-
-// WebRtcVoiceMediaChannel
-WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel(WebRtcVoiceEngine *engine)
-    : WebRtcMediaChannel<VoiceMediaChannel, WebRtcVoiceEngine>(
-          engine,
-          engine->voe()->base()->CreateChannel()),
-      channel_options_(0),
-      agc_adjusted_(false),
-      dtmf_allowed_(false),
-      desired_playout_(false),
-      playout_(false),
-      desired_send_(SEND_NOTHING),
-      send_(SEND_NOTHING) {
-  engine->RegisterChannel(this);
-  LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel "
-                  << voe_channel();
-
-  // Register external transport
-  if (engine->voe()->network()->RegisterExternalTransport(
-      voe_channel(), *static_cast<Transport*>(this)) == -1) {
-    LOG_RTCERR2(RegisterExternalTransport, voe_channel(), this);
-  }
-
-  // Enable RTCP (for quality stats and feedback messages)
-  EnableRtcp(voe_channel());
-
-  // Create a random but nonzero send SSRC
-  SetSendSsrc(talk_base::CreateRandomNonZeroId());
-
-  // Reset all recv codecs; they will be enabled via SetRecvCodecs.
-  ResetRecvCodecs(voe_channel());
-}
-
-WebRtcVoiceMediaChannel::~WebRtcVoiceMediaChannel() {
-  LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::~WebRtcVoiceMediaChannel "
-                  << voe_channel();
-
-  // DeRegister external transport
-  if (engine()->voe()->network()->DeRegisterExternalTransport(
-      voe_channel()) == -1) {
-    LOG_RTCERR1(DeRegisterExternalTransport, voe_channel());
-  }
-
-  // Unregister ourselves from the engine.
-  engine()->UnregisterChannel(this);
-  // Remove any remaining streams.
-  while (!mux_channels_.empty()) {
-    RemoveStream(mux_channels_.begin()->first);
-  }
-
-  // Delete the primary channel.
-  if (engine()->voe()->base()->DeleteChannel(voe_channel()) == -1) {
-    LOG_RTCERR1(DeleteChannel, voe_channel());
-  }
-}
-
-bool WebRtcVoiceMediaChannel::SetOptions(int flags) {
-  // Always accept flags that are unchanged.
-  if (channel_options_ == flags) {
-    return true;
-  }
-
-  // Reject new options if we're already sending.
-  if (send_ != SEND_NOTHING) {
-    return false;
-  }
-
-  // Save the options, to be interpreted where appropriate.
-  channel_options_ = flags;
-  return true;
-}
-
-bool WebRtcVoiceMediaChannel::SetRecvCodecs(
-    const std::vector<AudioCodec>& codecs) {
-  // Set the payload types to be used for incoming media.
-  bool ret = true;
-  LOG(LS_INFO) << "Setting receive voice codecs:";
-  for (std::vector<AudioCodec>::const_iterator it = codecs.begin();
-       it != codecs.end() && ret; ++it) {
-    webrtc::CodecInst voe_codec;
-    if (engine()->FindWebRtcCodec(*it, &voe_codec)) {
-      LOG(LS_INFO) << ToString(*it);
-      voe_codec.pltype = it->id;
-      if (engine()->voe()->codec()->SetRecPayloadType(
-          voe_channel(), voe_codec) == -1) {
-        LOG_RTCERR2(SetRecPayloadType, voe_channel(), ToString(voe_codec));
-        ret = false;
-      }
-    } else {
-      LOG(LS_WARNING) << "Unknown codec " << ToString(*it);
-      ret = false;
-    }
-  }
-
-  return ret;
-}
-
-bool WebRtcVoiceMediaChannel::SetSendCodecs(
-    const std::vector<AudioCodec>& codecs) {
-  // Disable DTMF, VAD, and FEC unless we know the other side wants them.
-  dtmf_allowed_ = false;
-  engine()->voe()->codec()->SetVADStatus(voe_channel(), false);
-  engine()->voe()->rtp()->SetFECStatus(voe_channel(), false);
-
-  // Scan through the list to figure out the codec to use for sending, along
-  // with the proper configuration for VAD and DTMF.
-  bool first = true;
-  webrtc::CodecInst send_codec;
-  memset(&send_codec, 0, sizeof(send_codec));
-
-  for (std::vector<AudioCodec>::const_iterator it = codecs.begin();
-       it != codecs.end(); ++it) {
-    // Ignore codecs we don't know about. The negotiation step should prevent
-    // this, but double-check to be sure.
-    webrtc::CodecInst voe_codec;
-    if (!engine()->FindWebRtcCodec(*it, &voe_codec)) {
-      LOG(LS_WARNING) << "Unknown codec " << ToString(voe_codec);
-      continue;
-    }
-
-    // Find the DTMF telephone event "codec" and tell VoiceEngine about it.
-    if (_stricmp(it->name.c_str(), "telephone-event") == 0 ||
-        _stricmp(it->name.c_str(), "audio/telephone-event") == 0) {
-      engine()->voe()->dtmf()->SetSendTelephoneEventPayloadType(
-          voe_channel(), it->id);
-      dtmf_allowed_ = true;
-    }
-
-    // Turn voice activity detection/comfort noise on if supported.
-    // Set the wideband CN payload type appropriately.
-    // (narrowband always uses the static payload type 13).
-    if (_stricmp(it->name.c_str(), "CN") == 0) {
-      webrtc::PayloadFrequencies cn_freq;
-      switch (it->clockrate) {
-        case 8000:
-          cn_freq = webrtc::kFreq8000Hz;
-          break;
-        case 16000:
-          cn_freq = webrtc::kFreq16000Hz;
-          break;
-        case 32000:
-          cn_freq = webrtc::kFreq32000Hz;
-          break;
-        default:
-          LOG(LS_WARNING) << "CN frequency " << it->clockrate
-                          << " not supported.";
-          continue;
-      }
-      engine()->voe()->codec()->SetVADStatus(voe_channel(), true);
-      if (cn_freq != webrtc::kFreq8000Hz) {
-        engine()->voe()->codec()->SetSendCNPayloadType(voe_channel(),
-                                                       it->id, cn_freq);
-      }
-    }
-
-    // We'll use the first codec in the list to actually send audio data.
-    // Be sure to use the payload type requested by the remote side.
-    // "red", for FEC audio, is a special case where the actual codec to be
-    // used is specified in params.
-    if (first) {
-      if (_stricmp(it->name.c_str(), "red") == 0) {
-        // Parse out the RED parameters. If we fail, just ignore RED;
-        // we don't support all possible params/usage scenarios.
-        if (!GetRedSendCodec(*it, codecs, &send_codec)) {
-          continue;
-        }
-
-        // Enable redundant encoding of the specified codec. Treat any
-        // failure as a fatal internal error.
-        LOG(LS_INFO) << "Enabling FEC";
-        if (engine()->voe()->rtp()->SetFECStatus(voe_channel(),
-                                                 true, it->id) == -1) {
-          LOG_RTCERR3(SetFECStatus, voe_channel(), true, it->id);
-          return false;
-        }
-      } else {
-        send_codec = voe_codec;
-      }
-      first = false;
-    }
-  }
-
-  // If we're being asked to set an empty list of codecs, due to a buggy client,
-  // choose the most common format: PCMU
-  if (first) {
-    LOG(LS_WARNING) << "Received empty list of codecs; using PCMU/8000";
-    AudioCodec codec(0, "PCMU", 8000, 0, 1, 0);
-    engine()->FindWebRtcCodec(codec, &send_codec);
-  }
-
-  // Set the codec.
-  LOG(LS_INFO) << "Selected voice codec " << ToString(send_codec)
-               << ", bitrate=" << send_codec.rate;
-  if (engine()->voe()->codec()->SetSendCodec(voe_channel(),
-                                             send_codec) == -1) {
-    LOG_RTCERR2(SetSendCodec, voe_channel(), ToString(send_codec));
-    return false;
-  }
-
-  send_codec_.reset(new webrtc::CodecInst(send_codec));
-  return true;
-}
-
-bool WebRtcVoiceMediaChannel::SetRecvRtpHeaderExtensions(
-    const std::vector<RtpHeaderExtension>& extensions) {
-  // We don't support any incoming extensions headers right now.
-  return true;
-}
-
-bool WebRtcVoiceMediaChannel::SetSendRtpHeaderExtensions(
-    const std::vector<RtpHeaderExtension>& extensions) {
-  // Enable the audio level extension header if requested.
-  std::vector<RtpHeaderExtension>::const_iterator it;
-  for (it = extensions.begin(); it != extensions.end(); ++it) {
-    if (it->uri == kRtpAudioLevelHeaderExtension) {
-      break;
-    }
-  }
-
-  bool enable = (it != extensions.end());
-  int id = 0;
-
-  if (enable) {
-    id = it->id;
-    if (id < kMinRtpHeaderExtensionId ||
-        id > kMaxRtpHeaderExtensionId) {
-      LOG(LS_WARNING) << "Invalid RTP header extension id " << id;
-      return false;
-    }
-  }
-
-// This api call is not available in iOS version of VoiceEngine currently.
-#if !defined(IOS) && !defined(ANDROID)
-  if (engine()->voe()->rtp()->SetRTPAudioLevelIndicationStatus(
-      voe_channel(), enable, id) == -1) {
-    LOG_RTCERR3(SetRTPAudioLevelIndicationStatus, voe_channel(), enable, id);
-    return false;
-  }
-#endif
-
-  return true;
-}
-
-bool WebRtcVoiceMediaChannel::SetPlayout(bool playout) {
-  desired_playout_ = playout;
-  return ChangePlayout(desired_playout_);
-}
-
-bool WebRtcVoiceMediaChannel::PausePlayout() {
-  return ChangePlayout(false);
-}
-
-bool WebRtcVoiceMediaChannel::ResumePlayout() {
-  return ChangePlayout(desired_playout_);
-}
-
-bool WebRtcVoiceMediaChannel::ChangePlayout(bool playout) {
-  if (playout_ == playout) {
-    return true;
-  }
-
-  bool result = true;
-  if (mux_channels_.empty()) {
-    // Only toggle the default channel if we don't have any other channels.
-    result = SetPlayout(voe_channel(), playout);
-  }
-  for (ChannelMap::iterator it = mux_channels_.begin();
-       it != mux_channels_.end() && result; ++it) {
-    if (!SetPlayout(it->second, playout)) {
-      LOG(LS_ERROR) << "SetPlayout " << playout << " on channel " << it->second
-                    << " failed";
-      result = false;
-    }
-  }
-
-  if (result) {
-    playout_ = playout;
-  }
-  return result;
-}
-
-bool WebRtcVoiceMediaChannel::SetSend(SendFlags send) {
-  desired_send_ = send;
-  return ChangeSend(desired_send_);
-}
-
-bool WebRtcVoiceMediaChannel::PauseSend() {
-  return ChangeSend(SEND_NOTHING);
-}
-
-bool WebRtcVoiceMediaChannel::ResumeSend() {
-  return ChangeSend(desired_send_);
-}
-
-bool WebRtcVoiceMediaChannel::ChangeSend(SendFlags send) {
-  if (send_ == send) {
-    return true;
-  }
-
-  if (send == SEND_MICROPHONE) {
-#ifdef CHROMEOS
-    // Conference mode doesn't work well on ChromeOS.
-    if (!engine()->SetConferenceMode(false)) {
-      LOG_RTCERR1(SetConferenceMode, voe_channel());
-      return false;
-    }
-#else
-    // Multi-point conferences use conference-mode noise filtering.
-    if (!engine()->SetConferenceMode(
-        0 != (channel_options_ & OPT_CONFERENCE))) {
-      LOG_RTCERR1(SetConferenceMode, voe_channel());
-      return false;
-    }
-#endif  // CHROMEOS
-
-    if ((channel_options_ & OPT_AGC_MINUS_10DB) && !agc_adjusted_) {
-      if (engine()->AdjustAgcLevel(kMinus10DbAdjustment)) {
-        agc_adjusted_ = true;
-      }
-    }
-
-    // VoiceEngine resets sequence number when StopSend is called. This
-    // sometimes causes libSRTP to complain about packets being
-    // replayed. To get around this we store the last sent sequence
-    // number and initializes the channel with the next to continue on
-    // the same sequence.
-    if (sequence_number() != -1) {
-      LOG(LS_INFO) << "WebRtcVoiceMediaChannel restores seqnum="
-                   << sequence_number() + 1;
-      if (engine()->voe()->sync()->SetInitSequenceNumber(
-              voe_channel(), sequence_number() + 1) == -1) {
-        LOG_RTCERR2(SetInitSequenceNumber, voe_channel(),
-                    sequence_number() + 1);
-      }
-    }
-    if (engine()->voe()->base()->StartSend(voe_channel()) == -1) {
-      LOG_RTCERR1(StartSend, voe_channel());
-      return false;
-    }
-    if (engine()->voe()->file()->StopPlayingFileAsMicrophone(
-        voe_channel()) == -1) {
-      LOG_RTCERR1(StopPlayingFileAsMicrophone, voe_channel());
-      return false;
-    }
-  } else if (send == SEND_RINGBACKTONE) {
-    ASSERT(ringback_tone_.get() != NULL);
-    if (!ringback_tone_.get()) {
-      return false;
-    }
-    if (engine()->voe()->file()->StartPlayingFileAsMicrophone(
-        voe_channel(), ringback_tone_.get(), false) == -1) {
-      LOG_RTCERR3(StartPlayingFileAsMicrophone, voe_channel(),
-                  ringback_tone_.get(), false);
-      return false;
-    }
-    // VoiceEngine resets sequence number when StopSend is called. This
-    // sometimes causes libSRTP to complain about packets being
-    // replayed. To get around this we store the last sent sequence
-    // number and initializes the channel with the next to continue on
-    // the same sequence.
-    if (sequence_number() != -1) {
-      LOG(LS_INFO) << "WebRtcVoiceMediaChannel restores seqnum="
-                   << sequence_number() + 1;
-      if (engine()->voe()->sync()->SetInitSequenceNumber(
-              voe_channel(), sequence_number() + 1) == -1) {
-        LOG_RTCERR2(SetInitSequenceNumber, voe_channel(),
-                    sequence_number() + 1);
-      }
-    }
-    if (engine()->voe()->base()->StartSend(voe_channel()) == -1) {
-      LOG_RTCERR1(StartSend, voe_channel());
-      return false;
-    }
-  } else {  // SEND_NOTHING
-    if (engine()->voe()->base()->StopSend(voe_channel()) == -1) {
-      LOG_RTCERR1(StopSend, voe_channel());
-    }
-
-    // Reset the AGC level, if it was set.
-    if (agc_adjusted_) {
-      if (engine()->AdjustAgcLevel(0)) {
-        agc_adjusted_ = false;
-      }
-    }
-
-    // Disable conference-mode noise filtering.
-    if (!engine()->SetConferenceMode(false)) {
-      LOG_RTCERR1(SetConferenceMode, voe_channel());
-    }
-  }
-  send_ = send;
-  return true;
-}
-
-bool WebRtcVoiceMediaChannel::AddStream(uint32 ssrc) {
-  talk_base::CritScope lock(&mux_channels_cs_);
-
-  if (mux_channels_.find(ssrc) != mux_channels_.end()) {
-    return false;
-  }
-
-  // Create a new channel for receiving audio data.
-  int channel = engine()->voe()->base()->CreateChannel();
-  if (channel == -1) {
-    LOG_RTCERR0(CreateChannel);
-    return false;
-  }
-
-  // Configure to use external transport, like our default channel.
-  if (engine()->voe()->network()->RegisterExternalTransport(
-          channel, *this) == -1) {
-    LOG_RTCERR2(SetExternalTransport, channel, this);
-    return false;
-  }
-
-  // Use the same SSRC as our default channel (so the RTCP reports are correct).
-  unsigned int send_ssrc;
-  webrtc::VoERTP_RTCP* rtp = engine()->voe()->rtp();
-  if (rtp->GetLocalSSRC(voe_channel(), send_ssrc) == -1) {
-    LOG_RTCERR2(GetSendSSRC, channel, send_ssrc);
-    return false;
-  }
-  if (rtp->SetLocalSSRC(channel, send_ssrc) == -1) {
-    LOG_RTCERR2(SetSendSSRC, channel, send_ssrc);
-    return false;
-  }
-
-  // Use the same recv payload types as our default channel.
-  ResetRecvCodecs(channel);
-  int ncodecs = engine()->voe()->codec()->NumOfCodecs();
-  for (int i = 0; i < ncodecs; ++i) {
-    webrtc::CodecInst voe_codec;
-    if (engine()->voe()->codec()->GetCodec(i, voe_codec) != -1) {
-      voe_codec.rate = 0;  // Needed to make GetRecPayloadType work for ISAC
-      if (engine()->voe()->codec()->GetRecPayloadType(
-          voe_channel(), voe_codec) != -1) {
-        if (engine()->voe()->codec()->SetRecPayloadType(
-            channel, voe_codec) == -1) {
-          LOG_RTCERR2(SetRecPayloadType, channel, ToString(voe_codec));
-          return false;
-        }
-      }
-    }
-  }
-
-  if (mux_channels_.empty() && playout_) {
-    // This is the first stream in a multi user meeting. We can now
-    // disable playback of the default stream. This since the default
-    // stream will probably have received some initial packets before
-    // the new stream was added. This will mean that the CN state from
-    // the default channel will be mixed in with the other streams
-    // throughout the whole meeting, which might be disturbing.
-    LOG(LS_INFO) << "Disabling playback on the default voice channel";
-    SetPlayout(voe_channel(), false);
-  }
-
-  mux_channels_[ssrc] = channel;
-
-  // TODO: We should rollback the add if SetPlayout fails.
-  LOG(LS_INFO) << "New audio stream " << ssrc
-            << " registered to VoiceEngine channel #"
-            << channel << ".";
-  return SetPlayout(channel, playout_);
-}
-
-bool WebRtcVoiceMediaChannel::RemoveStream(uint32 ssrc) {
-  talk_base::CritScope lock(&mux_channels_cs_);
-  ChannelMap::iterator it = mux_channels_.find(ssrc);
-
-  if (it != mux_channels_.end()) {
-    if (engine()->voe()->network()->DeRegisterExternalTransport(
-        it->second) == -1) {
-      LOG_RTCERR1(DeRegisterExternalTransport, it->second);
-    }
-
-    LOG(LS_INFO) << "Removing audio stream " << ssrc
-              << " with VoiceEngine channel #"
-              << it->second << ".";
-    if (engine()->voe()->base()->DeleteChannel(it->second) == -1) {
-      LOG_RTCERR1(DeleteChannel, voe_channel());
-      return false;
-    }
-
-    mux_channels_.erase(it);
-    if (mux_channels_.empty() && playout_) {
-      // The last stream was removed. We can now enable the default
-      // channel for new channels to be played out immediately without
-      // waiting for AddStream messages.
-      // TODO: Does the default channel still have it's CN state?
-      LOG(LS_INFO) << "Enabling playback on the default voice channel";
-      SetPlayout(voe_channel(), true);
-    }
-  }
-  return true;
-}
-
-bool WebRtcVoiceMediaChannel::GetActiveStreams(
-    AudioInfo::StreamList* actives) {
-  actives->clear();
-  for (ChannelMap::iterator it = mux_channels_.begin();
-       it != mux_channels_.end(); ++it) {
-    int level = GetOutputLevel(it->second);
-    if (level > 0) {
-      actives->push_back(std::make_pair(it->first, level));
-    }
-  }
-  return true;
-}
-
-int WebRtcVoiceMediaChannel::GetOutputLevel() {
-  // return the highest output level of all streams
-  int highest = GetOutputLevel(voe_channel());
-  for (ChannelMap::iterator it = mux_channels_.begin();
-       it != mux_channels_.end(); ++it) {
-    int level = GetOutputLevel(it->second);
-    highest = talk_base::_max(level, highest);
-  }
-  return highest;
-}
-
-
-bool WebRtcVoiceMediaChannel::SetOutputScaling(
-    uint32 ssrc, double left, double right) {
-  talk_base::CritScope lock(&mux_channels_cs_);
-  // Collect the channels to scale the output volume.
-  std::vector<int> channels;
-  if (0 == ssrc) {  // Collect all channels, including the default one.
-    channels.push_back(voe_channel());
-    for (ChannelMap::const_iterator it = mux_channels_.begin();
-        it != mux_channels_.end(); ++it) {
-      channels.push_back(it->second);
-    }
-  } else {  // Collect only the channel of the specified ssrc.
-    int channel = GetChannelNum(ssrc);
-    if (-1 == channel) {
-      LOG(LS_WARNING) << "Cannot find channel for ssrc:" << ssrc;
-      return false;
-    }
-    channels.push_back(channel);
-  }
-
-  // Scale the output volume for the collected channels. We first normalize to
-  // scale the volume and then set the left and right pan.
-  float scale = static_cast<float>(talk_base::_max(left, right));
-  if (scale > 0.0001f) {
-    left /= scale;
-    right /= scale;
-  }
-  for (std::vector<int>::const_iterator it = channels.begin();
-      it != channels.end(); ++it) {
-    if (-1 == engine()->voe()->volume()->SetChannelOutputVolumeScaling(
-        *it, scale)) {
-      LOG_RTCERR2(SetChannelOutputVolumeScaling, *it, scale);
-      return false;
-    }
-    if (-1 == engine()->voe()->volume()->SetOutputVolumePan(
-        *it, static_cast<float>(left), static_cast<float>(right))) {
-      LOG_RTCERR3(SetOutputVolumePan, *it, left, right);
-      // Do not return if fails. SetOutputVolumePan is not available for all
-      // pltforms.
-    }
-    LOG(LS_INFO) << "SetOutputScaling to left=" << left * scale
-                 << " right=" << right * scale
-                 << " for channel " << *it << " and ssrc " << ssrc;
-  }
-  return true;
-}
-
-bool WebRtcVoiceMediaChannel::GetOutputScaling(
-    uint32 ssrc, double* left, double* right) {
-  if (!left || !right) return false;
-
-  talk_base::CritScope lock(&mux_channels_cs_);
-  // Determine which channel based on ssrc.
-  int channel = (0 == ssrc) ? voe_channel() : GetChannelNum(ssrc);
-  if (channel == -1) {
-    LOG(LS_WARNING) << "Cannot find channel for ssrc:" << ssrc;
-    return false;
-  }
-
-  float scaling;
-  if (-1 == engine()->voe()->volume()->GetChannelOutputVolumeScaling(
-      channel, scaling)) {
-    LOG_RTCERR2(GetChannelOutputVolumeScaling, channel, scaling);
-    return false;
-  }
-
-  float left_pan;
-  float right_pan;
-  if (-1 == engine()->voe()->volume()->GetOutputVolumePan(
-      channel, left_pan, right_pan)) {
-    LOG_RTCERR3(GetOutputVolumePan, channel, left_pan, right_pan);
-    // If GetOutputVolumePan fails, we use the default left and right pan.
-    left_pan = 1.0f;
-    right_pan = 1.0f;
-  }
-
-  *left = scaling * left_pan;
-  *right = scaling * right_pan;
-  return true;
-}
-
-bool WebRtcVoiceMediaChannel::SetRingbackTone(const char *buf, int len) {
-  ringback_tone_.reset(new WebRtcSoundclipStream(buf, len));
-  return true;
-}
-
-bool WebRtcVoiceMediaChannel::PlayRingbackTone(uint32 ssrc,
-                                             bool play, bool loop) {
-  if (!ringback_tone_.get()) {
-    return false;
-  }
-
-  // Determine which VoiceEngine channel to play on.
-  int channel = (ssrc == 0) ? voe_channel() : GetChannelNum(ssrc);
-  if (channel == -1) {
-    return false;
-  }
-
-  // Make sure the ringtone is cued properly, and play it out.
-  if (play) {
-    ringback_tone_->set_loop(loop);
-    ringback_tone_->Rewind();
-    if (engine()->voe()->file()->StartPlayingFileLocally(channel,
-        ringback_tone_.get()) == -1) {
-      LOG_RTCERR2(StartPlayingFileLocally, channel, ringback_tone_.get());
-      LOG(LS_ERROR) << "Unable to start ringback tone";
-      return false;
-    }
-    ringback_channels_.insert(channel);
-    LOG(LS_INFO) << "Started ringback on channel " << channel;
-  } else {
-    if (engine()->voe()->file()->IsPlayingFileLocally(channel) == 1 &&
-        engine()->voe()->file()->StopPlayingFileLocally(channel) == -1) {
-      LOG_RTCERR1(StopPlayingFileLocally, channel);
-      return false;
-    }
-    LOG(LS_INFO) << "Stopped ringback on channel " << channel;
-    ringback_channels_.erase(channel);
-  }
-
-  return true;
-}
-
-bool WebRtcVoiceMediaChannel::PressDTMF(int event, bool playout) {
-  if (!dtmf_allowed_) {
-    return false;
-  }
-
-  // Enable or disable DTMF playout of this tone as requested. This will linger
-  // until the next call to this method, but that's OK.
-  if (engine()->voe()->dtmf()->SetDtmfFeedbackStatus(playout) == -1) {
-    LOG_RTCERR2(SendDTMF, voe_channel(), playout);
-    return false;
-  }
-
-  // Send DTMF using out-of-band DTMF. ("true", as 3rd arg)
-  if (engine()->voe()->dtmf()->SendTelephoneEvent(voe_channel(), event,
-      true) == -1) {
-    LOG_RTCERR3(SendDTMF, voe_channel(), event, true);
-    return false;
-  }
-
-  return true;
-}
-
-void WebRtcVoiceMediaChannel::OnPacketReceived(talk_base::Buffer* packet) {
-  // Pick which channel to send this packet to. If this packet doesn't match
-  // any multiplexed streams, just send it to the default channel. Otherwise,
-  // send it to the specific decoder instance for that stream.
-  int which_channel = GetChannelNum(
-      ParseSsrc(packet->data(), packet->length(), false));
-  if (which_channel == -1) {
-    which_channel = voe_channel();
-  }
-
-  // Stop any ringback that might be playing on the channel.
-  // It's possible the ringback has already stopped, ih which case we'll just
-  // use the opportunity to remove the channel from ringback_channels_.
-  const std::set<int>::iterator it = ringback_channels_.find(which_channel);
-  if (it != ringback_channels_.end()) {
-    if (engine()->voe()->file()->IsPlayingFileLocally(
-        which_channel) == 1) {
-      engine()->voe()->file()->StopPlayingFileLocally(which_channel);
-      LOG(LS_INFO) << "Stopped ringback on channel " << which_channel
-                   << " due to incoming media";
-    }
-    ringback_channels_.erase(which_channel);
-  }
-
-  // Pass it off to the decoder.
-  engine()->voe()->network()->ReceivedRTPPacket(which_channel,
-                                                   packet->data(),
-                                                   packet->length());
-}
-
-void WebRtcVoiceMediaChannel::OnRtcpReceived(talk_base::Buffer* packet) {
-  // See above.
-  int which_channel = GetChannelNum(
-      ParseSsrc(packet->data(), packet->length(), true));
-  if (which_channel == -1) {
-    which_channel = voe_channel();
-  }
-
-  engine()->voe()->network()->ReceivedRTCPPacket(which_channel,
-                                                    packet->data(),
-                                                    packet->length());
-}
-
-void WebRtcVoiceMediaChannel::SetSendSsrc(uint32 ssrc) {
-  if (engine()->voe()->rtp()->SetLocalSSRC(voe_channel(), ssrc)
-      == -1) {
-     LOG_RTCERR2(SetSendSSRC, voe_channel(), ssrc);
-  }
-}
-
-bool WebRtcVoiceMediaChannel::SetRtcpCName(const std::string& cname) {
-  if (engine()->voe()->rtp()->SetRTCP_CNAME(voe_channel(),
-                                                    cname.c_str()) == -1) {
-     LOG_RTCERR2(SetRTCP_CNAME, voe_channel(), cname);
-     return false;
-  }
-  return true;
-}
-
-bool WebRtcVoiceMediaChannel::Mute(bool muted) {
-  if (engine()->voe()->volume()->SetInputMute(voe_channel(),
-      muted) == -1) {
-    LOG_RTCERR2(SetInputMute, voe_channel(), muted);
-    return false;
-  }
-  return true;
-}
-
-bool WebRtcVoiceMediaChannel::GetStats(VoiceMediaInfo* info) {
-  // In VoiceEngine 3.5, GetRTCPStatistics will return 0 even when it fails,
-  // causing the stats to contain garbage information. To prevent this, we
-  // zero the stats structure before calling this API.
-  // TODO: Remove this workaround.
-  webrtc::CallStatistics cs;
-  unsigned int ssrc;
-  webrtc::CodecInst codec;
-  unsigned int level;
-
-  // Fill in the sender info, based on what we know, and what the
-  // remote side told us it got from its RTCP report.
-  VoiceSenderInfo sinfo;
-
-  // Data we obtain locally.
-  memset(&cs, 0, sizeof(cs));
-  if (engine()->voe()->rtp()->GetRTCPStatistics(voe_channel(), cs) == -1 ||
-      engine()->voe()->rtp()->GetLocalSSRC(voe_channel(), ssrc) == -1) {
-    return false;
-  }
-
-  sinfo.ssrc = ssrc;
-  sinfo.codec_name = send_codec_.get() ? send_codec_->plname : "";
-  sinfo.bytes_sent = cs.bytesSent;
-  sinfo.packets_sent = cs.packetsSent;
-  // RTT isn't known until a RTCP report is received. Until then, VoiceEngine
-  // returns 0 to indicate an error value.
-  sinfo.rtt_ms = (cs.rttMs > 0) ? cs.rttMs : -1;
-
-  // Data from the last remote RTCP report.
-  unsigned int ntp_high, ntp_low, timestamp, ptimestamp, jitter;
-  unsigned short loss;  // NOLINT
-  if (engine()->voe()->rtp()->GetRemoteRTCPData(voe_channel(),
-          ntp_high, ntp_low, timestamp, ptimestamp, &jitter, &loss) != -1 &&
-      engine()->voe()->codec()->GetSendCodec(voe_channel(),
-          codec) != -1) {
-    // Convert Q8 to floating point.
-    sinfo.fraction_lost = static_cast<float>(loss) / (1 << 8);
-    // Convert samples to milliseconds.
-    if (codec.plfreq / 1000 > 0) {
-      sinfo.jitter_ms = jitter / (codec.plfreq / 1000);
-    }
-  } else {
-    sinfo.fraction_lost = -1;
-    sinfo.jitter_ms = -1;
-  }
-  // TODO: Figure out how to get remote packets_lost, ext_seqnum
-  sinfo.packets_lost = -1;
-  sinfo.ext_seqnum = -1;
-
-  // Local speech level.
-  sinfo.audio_level = (engine()->voe()->volume()->
-      GetSpeechInputLevelFullRange(level) != -1) ? level : -1;
-
-  bool echo_metrics_on = false;
-  // These can take on valid negative values, so use the lowest possible level
-  // as default rather than -1.
-  sinfo.echo_return_loss = -100;
-  sinfo.echo_return_loss_enhancement = -100;
-  // These can also be negative, but in practice -1 is only used to signal
-  // insufficient data, since the resolution is limited to multiples of 4 ms.
-  sinfo.echo_delay_median_ms = -1;
-  sinfo.echo_delay_std_ms = -1;
-  if (engine()->voe()->processing()->GetEcMetricsStatus(echo_metrics_on) !=
-      -1 && echo_metrics_on) {
-
-    // TODO: we may want to use VoECallReport::GetEchoMetricsSummary
-    // here, but it appears to be unsuitable currently. Revisit after this is
-    // investigated: http://b/issue?id=5666755
-    int erl, erle, rerl, anlp;
-    if (engine()->voe()->processing()->GetEchoMetrics(erl, erle, rerl, anlp) !=
-        -1) {
-      sinfo.echo_return_loss = erl;
-      sinfo.echo_return_loss_enhancement = erle;
-    }
-
-    int median, std;
-    if (engine()->voe()->processing()->GetEcDelayMetrics(median, std) != -1) {
-      sinfo.echo_delay_median_ms = median;
-      sinfo.echo_delay_std_ms = std;
-    }
-  }
-
-  info->senders.push_back(sinfo);
-
-  // Build the list of receivers, one for each mux channel, or 1 in a 1:1 call.
-  std::vector<int> channels;
-  for (ChannelMap::const_iterator it = mux_channels_.begin();
-       it != mux_channels_.end(); ++it) {
-    channels.push_back(it->second);
-  }
-  if (channels.empty()) {
-    channels.push_back(voe_channel());
-  }
-
-  // Get the SSRC and stats for each receiver, based on our own calculations.
-  for (std::vector<int>::const_iterator it = channels.begin();
-       it != channels.end(); ++it) {
-    memset(&cs, 0, sizeof(cs));
-    if (engine()->voe()->rtp()->GetRemoteSSRC(*it, ssrc) != -1 &&
-        engine()->voe()->rtp()->GetRTCPStatistics(*it, cs) != -1 &&
-        engine()->voe()->codec()->GetRecCodec(*it, codec) != -1) {
-      VoiceReceiverInfo rinfo;
-      rinfo.ssrc = ssrc;
-      rinfo.bytes_rcvd = cs.bytesReceived;
-      rinfo.packets_rcvd = cs.packetsReceived;
-      // The next four fields are from the most recently sent RTCP report.
-      // Convert Q8 to floating point.
-      rinfo.fraction_lost = static_cast<float>(cs.fractionLost) / (1 << 8);
-      rinfo.packets_lost = cs.cumulativeLost;
-      rinfo.ext_seqnum = cs.extendedMax;
-      // Convert samples to milliseconds.
-      if (codec.plfreq / 1000 > 0) {
-        rinfo.jitter_ms = cs.jitterSamples / (codec.plfreq / 1000);
-      }
-
-      // Get jitter buffer and total delay (alg + jitter + playout) stats.
-      webrtc::NetworkStatistics ns;
-      if (engine()->voe()->neteq() &&
-          engine()->voe()->neteq()->GetNetworkStatistics(
-              *it, ns) != -1) {
-        rinfo.jitter_buffer_ms = ns.currentBufferSize;
-        rinfo.jitter_buffer_preferred_ms = ns.preferredBufferSize;
-      }
-      if (engine()->voe()->sync()) {
-        engine()->voe()->sync()->GetDelayEstimate(*it,
-            rinfo.delay_estimate_ms);
-      }
-
-      // Get speech level.
-      rinfo.audio_level = (engine()->voe()->volume()->
-          GetSpeechOutputLevelFullRange(*it, level) != -1) ? level : -1;
-      info->receivers.push_back(rinfo);
-    }
-  }
-
-  return true;
-}
-
-void WebRtcVoiceMediaChannel::GetLastMediaError(
-    uint32* ssrc, VoiceMediaChannel::Error* error) {
-  ASSERT(ssrc != NULL);
-  ASSERT(error != NULL);
-  FindSsrc(voe_channel(), ssrc);
-  *error = WebRtcErrorToChannelError(GetLastEngineError());
-}
-
-bool WebRtcVoiceMediaChannel::FindSsrc(int channel_num, uint32* ssrc) {
-  talk_base::CritScope lock(&mux_channels_cs_);
-  ASSERT(ssrc != NULL);
-  if (channel_num == voe_channel()) {
-    unsigned local_ssrc = 0;
-    // This is a sending channel.
-    if (engine()->voe()->rtp()->GetLocalSSRC(
-        channel_num, local_ssrc) != -1) {
-      *ssrc = local_ssrc;
-    }
-    return true;
-  } else if (channel_num == -1 && send_ != SEND_NOTHING) {
-    // Sometimes the VoiceEngine core will throw error with channel_num = -1.
-    // This means the error is not limited to a specific channel.  Signal the
-    // message using ssrc=0.  If the current channel is sending, use this
-    // channel for sending the message.
-    *ssrc = 0;
-    return true;
-  } else {
-    // Check whether this is a receiving channel.
-    for (ChannelMap::const_iterator it = mux_channels_.begin();
-        it != mux_channels_.end(); ++it) {
-      if (it->second == channel_num) {
-        *ssrc = it->first;
-        return true;
-      }
-    }
-  }
-  return false;
-}
-
-void WebRtcVoiceMediaChannel::OnError(uint32 ssrc, int error) {
-  SignalMediaError(ssrc, WebRtcErrorToChannelError(error));
-}
-
-int WebRtcVoiceMediaChannel::GetOutputLevel(int channel) {
-  unsigned int ulevel;
-  int ret =
-      engine()->voe()->volume()->GetSpeechOutputLevel(channel, ulevel);
-  return (ret == 0) ? static_cast<int>(ulevel) : -1;
-}
-
-int WebRtcVoiceMediaChannel::GetChannelNum(uint32 ssrc) {
-  ChannelMap::iterator it = mux_channels_.find(ssrc);
-  return (it != mux_channels_.end()) ? it->second : -1;
-}
-
-bool WebRtcVoiceMediaChannel::GetRedSendCodec(const AudioCodec& red_codec,
-    const std::vector<AudioCodec>& all_codecs, webrtc::CodecInst* send_codec) {
-  // Get the RED encodings from the parameter with no name. This may
-  // change based on what is discussed on the Jingle list.
-  // The encoding parameter is of the form "a/b"; we only support where
-  // a == b. Verify this and parse out the value into red_pt.
-  // If the parameter value is absent (as it will be until we wire up the
-  // signaling of this message), use the second codec specified (i.e. the
-  // one after "red") as the encoding parameter.
-  int red_pt = -1;
-  std::string red_params;
-  CodecParameterMap::const_iterator it = red_codec.params.find("");
-  if (it != red_codec.params.end()) {
-    red_params = it->second;
-    std::vector<std::string> red_pts;
-    if (talk_base::split(red_params, '/', &red_pts) != 2 ||
-        red_pts[0] != red_pts[1] ||
-        !talk_base::FromString(red_pts[0], &red_pt)) {
-      LOG(LS_WARNING) << "RED params " << red_params << " not supported.";
-      return false;
-    }
-  } else if (red_codec.params.empty()) {
-    LOG(LS_WARNING) << "RED params not present, using defaults";
-    if (all_codecs.size() > 1) {
-      red_pt = all_codecs[1].id;
-    }
-  }
-
-  // Try to find red_pt in |codecs|.
-  std::vector<AudioCodec>::const_iterator codec;
-  for (codec = all_codecs.begin(); codec != all_codecs.end(); ++codec) {
-    if (codec->id == red_pt)
-      break;
-  }
-
-  // If we find the right codec, that will be the codec we pass to
-  // SetSendCodec, with the desired payload type.
-  if (codec != all_codecs.end() &&
-    engine()->FindWebRtcCodec(*codec, send_codec)) {
-  } else {
-    LOG(LS_WARNING) << "RED params " << red_params << " are invalid.";
-    return false;
-  }
-
-  return true;
-}
-
-bool WebRtcVoiceMediaChannel::EnableRtcp(int channel) {
-  if (engine()->voe()->rtp()->SetRTCPStatus(channel, true) == -1) {
-    LOG_RTCERR2(SetRTCPStatus, voe_channel(), 1);
-    return false;
-  }
-  // TODO: Enable VQMon and RTCP XR reports, once we know what
-  // what we want to do with them.
-  // engine()->voe().EnableVQMon(voe_channel(), true);
-  // engine()->voe().EnableRTCP_XR(voe_channel(), true);
-  return true;
-}
-
-bool WebRtcVoiceMediaChannel::ResetRecvCodecs(int channel) {
-  int ncodecs = engine()->voe()->codec()->NumOfCodecs();
-  for (int i = 0; i < ncodecs; ++i) {
-    webrtc::CodecInst voe_codec;
-    if (engine()->voe()->codec()->GetCodec(i, voe_codec) != -1) {
-      voe_codec.pltype = -1;
-      if (engine()->voe()->codec()->SetRecPayloadType(
-          channel, voe_codec) == -1) {
-        LOG_RTCERR2(SetRecPayloadType, channel, ToString(voe_codec));
-        return false;
-      }
-    }
-  }
-  return true;
-}
-
-bool WebRtcVoiceMediaChannel::SetPlayout(int channel, bool playout) {
-  if (playout) {
-    LOG(LS_INFO) << "Starting playout for channel #" << channel;
-    if (engine()->voe()->base()->StartPlayout(channel) == -1) {
-      LOG_RTCERR1(StartPlayout, channel);
-      return false;
-    }
-  } else {
-    LOG(LS_INFO) << "Stopping playout for channel #" << channel;
-    engine()->voe()->base()->StopPlayout(channel);
-  }
-  return true;
-}
-
-uint32 WebRtcVoiceMediaChannel::ParseSsrc(const void* data, size_t len,
-                                        bool rtcp) {
-  size_t ssrc_pos = (!rtcp) ? 8 : 4;
-  uint32 ssrc = 0;
-  if (len >= (ssrc_pos + sizeof(ssrc))) {
-    ssrc = talk_base::GetBE32(static_cast<const char*>(data) + ssrc_pos);
-  }
-  return ssrc;
-}
-
-// Convert VoiceEngine error code into VoiceMediaChannel::Error enum.
-VoiceMediaChannel::Error
-    WebRtcVoiceMediaChannel::WebRtcErrorToChannelError(int err_code) {
-  switch (err_code) {
-    case 0:
-      return ERROR_NONE;
-    case VE_CANNOT_START_RECORDING:
-    case VE_MIC_VOL_ERROR:
-    case VE_GET_MIC_VOL_ERROR:
-    case VE_CANNOT_ACCESS_MIC_VOL:
-      return ERROR_REC_DEVICE_OPEN_FAILED;
-    case VE_SATURATION_WARNING:
-      return ERROR_REC_DEVICE_SATURATION;
-    case VE_REC_DEVICE_REMOVED:
-      return ERROR_REC_DEVICE_REMOVED;
-    case VE_RUNTIME_REC_WARNING:
-    case VE_RUNTIME_REC_ERROR:
-      return ERROR_REC_RUNTIME_ERROR;
-    case VE_CANNOT_START_PLAYOUT:
-    case VE_SPEAKER_VOL_ERROR:
-    case VE_GET_SPEAKER_VOL_ERROR:
-    case VE_CANNOT_ACCESS_SPEAKER_VOL:
-      return ERROR_PLAY_DEVICE_OPEN_FAILED;
-    case VE_RUNTIME_PLAY_WARNING:
-    case VE_RUNTIME_PLAY_ERROR:
-      return ERROR_PLAY_RUNTIME_ERROR;
-    case VE_TYPING_NOISE_WARNING:
-      return ERROR_REC_TYPING_NOISE_DETECTED;
-    default:
-      return VoiceMediaChannel::ERROR_OTHER;
-  }
-}
-
-int WebRtcSoundclipStream::Read(void *buf, int len) {
-  size_t res = 0;
-  mem_.Read(buf, len, &res, NULL);
-  return res;
-}
-
-int WebRtcSoundclipStream::Rewind() {
-  mem_.Rewind();
-  // Return -1 to keep VoiceEngine from looping.
-  return (loop_) ? 0 : -1;
-}
-
-}  // namespace cricket
-
-#endif  // HAVE_WEBRTC_VOICE
diff --git a/third_party/libjingle/source/talk/session/phone/webrtcvoiceengine.h b/third_party/libjingle/source/talk/session/phone/webrtcvoiceengine.h
deleted file mode 100644
index ef677d8..0000000
--- a/third_party/libjingle/source/talk/session/phone/webrtcvoiceengine.h
+++ /dev/null
@@ -1,366 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SESSION_PHONE_WEBRTCVOICEENGINE_H_
-#define TALK_SESSION_PHONE_WEBRTCVOICEENGINE_H_
-
-#include <map>
-#include <set>
-#include <string>
-#include <vector>
-
-#include "talk/base/buffer.h"
-#include "talk/base/byteorder.h"
-#include "talk/base/logging.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/base/stream.h"
-#include "talk/session/phone/channel.h"
-#include "talk/session/phone/rtputils.h"
-#include "talk/session/phone/webrtccommon.h"
-#include "talk/session/phone/webrtcvoe.h"
-#ifdef WEBRTC_RELATIVE_PATH
-#include "voice_engine/main/interface/voe_base.h"
-#else
-#include "third_party/webrtc/files/include/voe_base.h"
-#endif  // WEBRTC_RELATIVE_PATH
-
-namespace cricket {
-
-// WebRtcSoundclipStream is an adapter object that allows a memory stream to be
-// passed into WebRtc, and support looping.
-class WebRtcSoundclipStream : public webrtc::InStream {
- public:
-  WebRtcSoundclipStream(const char* buf, size_t len)
-      : mem_(buf, len), loop_(true) {
-  }
-  void set_loop(bool loop) { loop_ = loop; }
-  virtual int Read(void* buf, int len);
-  virtual int Rewind();
-
- private:
-  talk_base::MemoryStream mem_;
-  bool loop_;
-};
-
-// WebRtcMonitorStream is used to monitor a stream coming from WebRtc.
-// For now we just dump the data.
-class WebRtcMonitorStream : public webrtc::OutStream {
-  virtual bool Write(const void *buf, int len) {
-    return true;
-  }
-};
-
-class AudioDeviceModule;
-class VoETraceWrapper;
-class VoEWrapper;
-class VoiceProcessor;
-class WebRtcSoundclipMedia;
-class WebRtcVoiceMediaChannel;
-
-// WebRtcVoiceEngine is a class to be used with CompositeMediaEngine.
-// It uses the WebRtc VoiceEngine library for audio handling.
-class WebRtcVoiceEngine
-    : public webrtc::VoiceEngineObserver,
-      public webrtc::TraceCallback,
-      public webrtc::VoEMediaProcess  {
- public:
-  WebRtcVoiceEngine();
-  // Dependency injection for testing.
-  WebRtcVoiceEngine(VoEWrapper* voe_wrapper,
-                    VoEWrapper* voe_wrapper_sc,
-                    VoETraceWrapper* tracing);
-  ~WebRtcVoiceEngine();
-  bool Init();
-  void Terminate();
-
-  int GetCapabilities();
-  VoiceMediaChannel* CreateChannel();
-
-  SoundclipMedia* CreateSoundclip();
-
-  bool SetOptions(int options);
-  bool SetDevices(const Device* in_device, const Device* out_device);
-  bool GetOutputVolume(int* level);
-  bool SetOutputVolume(int level);
-  int GetInputLevel();
-  bool SetLocalMonitor(bool enable);
-
-  const std::vector<AudioCodec>& codecs();
-  bool FindCodec(const AudioCodec& codec);
-  bool FindWebRtcCodec(const AudioCodec& codec, webrtc::CodecInst* gcodec);
-
-  void SetLogging(int min_sev, const char* filter);
-
-  bool RegisterProcessor(uint32 ssrc,
-                         VoiceProcessor* voice_processor,
-                         MediaProcessorDirection direction);
-  bool UnregisterProcessor(uint32 ssrc,
-                           VoiceProcessor* voice_processor,
-                           MediaProcessorDirection direction);
-
-  // Method from webrtc::VoEMediaProcess
-  virtual void Process(const int channel,
-                       const webrtc::ProcessingTypes type,
-                       WebRtc_Word16 audio10ms[],
-                       const int length,
-                       const int sampling_freq,
-                       const bool is_stereo);
-
-  // For tracking WebRtc channels. Needed because we have to pause them
-  // all when switching devices.
-  // May only be called by WebRtcVoiceMediaChannel.
-  void RegisterChannel(WebRtcVoiceMediaChannel *channel);
-  void UnregisterChannel(WebRtcVoiceMediaChannel *channel);
-
-  // May only be called by WebRtcSoundclipMedia.
-  void RegisterSoundclip(WebRtcSoundclipMedia *channel);
-  void UnregisterSoundclip(WebRtcSoundclipMedia *channel);
-
-  // Called by WebRtcVoiceMediaChannel to set a gain offset from
-  // the default AGC target level.
-  bool AdjustAgcLevel(int delta);
-
-  // Called by WebRtcVoiceMediaChannel to configure echo cancellation
-  // and noise suppression modes.
-  bool SetConferenceMode(bool enable);
-
-  VoEWrapper* voe() { return voe_wrapper_.get(); }
-  VoEWrapper* voe_sc() { return voe_wrapper_sc_.get(); }
-  int GetLastEngineError();
-
-  // Set the external ADMs. This can only be called before Init.
-  bool SetAudioDeviceModule(webrtc::AudioDeviceModule* adm,
-                            webrtc::AudioDeviceModule* adm_sc);
-
-  // Check whether the supplied trace should be ignored.
-  bool ShouldIgnoreTrace(const std::string& trace);
-
- private:
-  typedef std::vector<WebRtcSoundclipMedia *> SoundclipList;
-  typedef std::vector<WebRtcVoiceMediaChannel *> ChannelList;
-
-  struct CodecPref {
-    const char* name;
-    int clockrate;
-    int payload_type;
-  };
-
-  void Construct();
-  void ConstructCodecs();
-  bool InitInternal();
-  void ApplyLogging(const std::string& log_filter);
-  virtual void Print(const webrtc::TraceLevel level,
-                     const char* trace_string, const int length);
-  virtual void CallbackOnError(const int channel, const int errCode);
-  // Given the device type, name, and id, find device id. Return true and
-  // set the output parameter rtc_id if successful.
-  bool FindWebRtcAudioDeviceId(
-      bool is_input, const std::string& dev_name, int dev_id, int* rtc_id);
-  bool FindChannelAndSsrc(int channel_num,
-                          WebRtcVoiceMediaChannel** channel,
-                          uint32* ssrc) const;
-  bool FindChannelNumFromSsrc(uint32 ssrc,
-                              MediaProcessorDirection direction,
-                              int* channel_num);
-  bool ChangeLocalMonitor(bool enable);
-  bool PauseLocalMonitor();
-  bool ResumeLocalMonitor();
-
-  // When a voice processor registers with the engine, it is connected
-  // to either the Rx or Tx signals, based on the direction parameter.
-  // SignalXXMediaFrame will be invoked for every audio packet.
-  sigslot::signal2<uint32, AudioFrame*> SignalRxMediaFrame;
-  sigslot::signal2<uint32, AudioFrame*> SignalTxMediaFrame;
-
-  static const int kDefaultLogSeverity = talk_base::LS_WARNING;
-  static const CodecPref kCodecPrefs[];
-
-  // The primary instance of WebRtc VoiceEngine.
-  talk_base::scoped_ptr<VoEWrapper> voe_wrapper_;
-  // A secondary instance, for playing out soundclips (on the 'ring' device).
-  talk_base::scoped_ptr<VoEWrapper> voe_wrapper_sc_;
-  talk_base::scoped_ptr<VoETraceWrapper> tracing_;
-  // The external audio device manager
-  webrtc::AudioDeviceModule* adm_;
-  webrtc::AudioDeviceModule* adm_sc_;
-  int log_level_;
-  std::string log_filter_;
-  bool is_dumping_aec_;
-  std::vector<AudioCodec> codecs_;
-  bool desired_local_monitor_enable_;
-  talk_base::scoped_ptr<WebRtcMonitorStream> monitor_;
-  SoundclipList soundclips_;
-  ChannelList channels_;
-  // channels_ can be read from WebRtc callback thread. We need a lock on that
-  // callback as well as the RegisterChannel/UnregisterChannel.
-  talk_base::CriticalSection channels_cs_;
-  webrtc::AgcConfig default_agc_config_;
-  bool initialized_;
-
-  talk_base::CriticalSection signal_media_critical_;
-};
-
-// WebRtcMediaChannel is a class that implements the common WebRtc channel
-// functionality.
-template <class T, class E>
-class WebRtcMediaChannel : public T, public webrtc::Transport {
- public:
-  WebRtcMediaChannel(E *engine, int channel)
-      : engine_(engine), voe_channel_(channel), sequence_number_(-1) {}
-  E *engine() { return engine_; }
-  int voe_channel() const { return voe_channel_; }
-  bool valid() const { return voe_channel_ != -1; }
-
- protected:
-  // implements Transport interface
-  virtual int SendPacket(int channel, const void *data, int len) {
-    if (!T::network_interface_) {
-      return -1;
-    }
-
-    // We need to store the sequence number to be able to pick up
-    // the same sequence when the device is restarted.
-    // TODO: Remove when WebRtc has fixed the problem.
-    int seq_num;
-    if (!GetRtpSeqNum(data, len, &seq_num)) {
-      return -1;
-    }
-    if (sequence_number() == -1) {
-      LOG(INFO) << "WebRtcVoiceMediaChannel sends first packet seqnum="
-                << seq_num;
-    }
-    sequence_number_ = seq_num;
-
-    talk_base::Buffer packet(data, len, kMaxRtpPacketLen);
-    return T::network_interface_->SendPacket(&packet) ? len : -1;
-  }
-  virtual int SendRTCPPacket(int channel, const void *data, int len) {
-    if (!T::network_interface_) {
-      return -1;
-    }
-
-    talk_base::Buffer packet(data, len, kMaxRtpPacketLen);
-    return T::network_interface_->SendRtcp(&packet) ? len : -1;
-  }
-  int sequence_number() const {
-    return sequence_number_;
-  }
-
- private:
-  E *engine_;
-  int voe_channel_;
-  int sequence_number_;
-};
-
-// WebRtcVoiceMediaChannel is an implementation of VoiceMediaChannel that uses
-// WebRtc Voice Engine.
-class WebRtcVoiceMediaChannel
-    : public WebRtcMediaChannel<VoiceMediaChannel, WebRtcVoiceEngine> {
- public:
-  explicit WebRtcVoiceMediaChannel(WebRtcVoiceEngine *engine);
-  virtual ~WebRtcVoiceMediaChannel();
-  virtual bool SetOptions(int options);
-  virtual bool SetRecvCodecs(const std::vector<AudioCodec> &codecs);
-  virtual bool SetSendCodecs(const std::vector<AudioCodec> &codecs);
-  virtual bool SetRecvRtpHeaderExtensions(
-      const std::vector<RtpHeaderExtension>& extensions);
-  virtual bool SetSendRtpHeaderExtensions(
-      const std::vector<RtpHeaderExtension>& extensions);
-  virtual bool SetPlayout(bool playout);
-  bool PausePlayout();
-  bool ResumePlayout();
-  virtual bool SetSend(SendFlags send);
-  bool PauseSend();
-  bool ResumeSend();
-  virtual bool AddStream(uint32 ssrc);
-  virtual bool RemoveStream(uint32 ssrc);
-  virtual bool GetActiveStreams(AudioInfo::StreamList* actives);
-  virtual int GetOutputLevel();
-  virtual bool SetOutputScaling(uint32 ssrc, double left, double right);
-  virtual bool GetOutputScaling(uint32 ssrc, double* left, double* right);
-
-  virtual bool SetRingbackTone(const char *buf, int len);
-  virtual bool PlayRingbackTone(uint32 ssrc, bool play, bool loop);
-  virtual bool PressDTMF(int event, bool playout);
-
-  virtual void OnPacketReceived(talk_base::Buffer* packet);
-  virtual void OnRtcpReceived(talk_base::Buffer* packet);
-  virtual void SetSendSsrc(uint32 id);
-  virtual bool SetRtcpCName(const std::string& cname);
-  virtual bool Mute(bool mute);
-  virtual bool SetSendBandwidth(bool autobw, int bps) { return false; }
-  virtual bool GetStats(VoiceMediaInfo* info);
-  // Gets last reported error from WebRtc voice engine.  This should be only
-  // called in response a failure.
-  virtual void GetLastMediaError(uint32* ssrc,
-                                 VoiceMediaChannel::Error* error);
-  bool FindSsrc(int channel_num, uint32* ssrc);
-  void OnError(uint32 ssrc, int error);
-
-  bool sending() const { return send_ != SEND_NOTHING; }
-  int GetChannelNum(uint32 ssrc);
-
- protected:
-  int GetLastEngineError() { return engine()->GetLastEngineError(); }
-  int GetOutputLevel(int channel);
-  bool GetRedSendCodec(const AudioCodec& red_codec,
-                       const std::vector<AudioCodec>& all_codecs,
-                       webrtc::CodecInst* send_codec);
-  bool EnableRtcp(int channel);
-  bool ResetRecvCodecs(int channel);
-  bool SetPlayout(int channel, bool playout);
-  static uint32 ParseSsrc(const void* data, size_t len, bool rtcp);
-  static Error WebRtcErrorToChannelError(int err_code);
-
- private:
-  // A -10dB gain adjustment is actually +10 in
-  // AgcConfig.targetLeveldBOv
-  static const int kMinus10DbAdjustment = 10;
-
-  bool ChangePlayout(bool playout);
-  bool ChangeSend(SendFlags send);
-
-  typedef std::map<uint32, int> ChannelMap;
-  talk_base::scoped_ptr<WebRtcSoundclipStream> ringback_tone_;
-  std::set<int> ringback_channels_;  // channels playing ringback
-  talk_base::scoped_ptr<webrtc::CodecInst> send_codec_;
-  int channel_options_;
-  bool agc_adjusted_;
-  bool dtmf_allowed_;
-  bool desired_playout_;
-  bool playout_;
-  SendFlags desired_send_;
-  SendFlags send_;
-  ChannelMap mux_channels_;  // for multiple sources
-  // mux_channels_ can be read from WebRtc callback thread.  Accesses off the
-  // WebRtc thread must be synchronized with edits on the worker thread.  Reads
-  // on the worker thread are ok.
-  mutable talk_base::CriticalSection mux_channels_cs_;
-};
-}
-
-#endif  // TALK_SESSION_PHONE_WEBRTCVOICEENGINE_H_
diff --git a/third_party/libjingle/source/talk/session/phone/webrtcvoiceengine_unittest.cc b/third_party/libjingle/source/talk/session/phone/webrtcvoiceengine_unittest.cc
deleted file mode 100644
index 6bcc04e..0000000
--- a/third_party/libjingle/source/talk/session/phone/webrtcvoiceengine_unittest.cc
+++ /dev/null
@@ -1,1328 +0,0 @@
-// Copyright 2008 Google Inc. All Rights Reserved.
-//
-// Author: Justin Uberti (juberti@google.com)
-
-#include "talk/base/byteorder.h"
-#include "talk/base/gunit.h"
-#include "talk/p2p/base/fakesession.h"
-#include "talk/session/phone/channel.h"
-#include "talk/session/phone/fakemediaengine.h"
-#include "talk/session/phone/fakemediaprocessor.h"
-#include "talk/session/phone/fakertp.h"
-#include "talk/session/phone/fakewebrtcvoiceengine.h"
-#include "talk/session/phone/webrtcvoiceengine.h"
-
-// Tests for the WebRtcVoiceEngine/VoiceChannel code.
-
-static const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1, 0);
-static const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1, 0);
-static const cricket::AudioCodec kRedCodec(117, "red", 8000, 0, 1, 0);
-static const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1, 0);
-static const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1, 0);
-static const cricket::AudioCodec
-    kTelephoneEventCodec(106, "telephone-event", 8000, 0, 1, 0);
-static const cricket::AudioCodec* const kAudioCodecs[] = {
-    &kPcmuCodec, &kIsacCodec, &kRedCodec, &kCn8000Codec, &kCn16000Codec,
-    &kTelephoneEventCodec,
-};
-const char kRingbackTone[] = "RIFF____WAVE____ABCD1234";
-
-class FakeVoEWrapper : public cricket::VoEWrapper {
- public:
-  explicit FakeVoEWrapper(cricket::FakeWebRtcVoiceEngine* engine)
-      : cricket::VoEWrapper(engine,  // processing
-                            engine,  // base
-                            engine,  // codec
-                            engine,  // dtmf
-                            engine,  // file
-                            engine,  // hw
-                            engine,  // media
-                            engine,  // neteq
-                            engine,  // network
-                            engine,  // rtp
-                            engine,  // sync
-                            engine) {  // volume
-  }
-};
-
-class NullVoETraceWrapper : public cricket::VoETraceWrapper {
- public:
-  virtual int SetTraceFilter(const unsigned int filter) {
-    return 0;
-  }
-  virtual int SetTraceFile(const char* fileNameUTF8) {
-    return 0;
-  }
-  virtual int SetTraceCallback(webrtc::TraceCallback* callback) {
-    return 0;
-  }
-};
-
-class WebRtcVoiceEngineTestFake : public testing::Test {
- public:
-  class ChannelErrorListener : public sigslot::has_slots<> {
-   public:
-    explicit ChannelErrorListener(cricket::VoiceMediaChannel* channel)
-        : ssrc_(0), error_(cricket::VoiceMediaChannel::ERROR_NONE) {
-      ASSERT(channel != NULL);
-      channel->SignalMediaError.connect(
-          this, &ChannelErrorListener::OnVoiceChannelError);
-    }
-    void OnVoiceChannelError(uint32 ssrc,
-                             cricket::VoiceMediaChannel::Error error) {
-      ssrc_ = ssrc;
-      error_ = error;
-    }
-    void Reset() {
-      ssrc_ = 0;
-      error_ = cricket::VoiceMediaChannel::ERROR_NONE;
-    }
-    uint32 ssrc() const {
-      return ssrc_;
-    }
-    cricket::VoiceMediaChannel::Error error() const {
-      return error_;
-    }
-
-   private:
-    uint32 ssrc_;
-    cricket::VoiceMediaChannel::Error error_;
-  };
-
-  WebRtcVoiceEngineTestFake()
-      : voe_(kAudioCodecs, ARRAY_SIZE(kAudioCodecs)),
-        voe_sc_(kAudioCodecs, ARRAY_SIZE(kAudioCodecs)),
-        engine_(new FakeVoEWrapper(&voe_),
-                new FakeVoEWrapper(&voe_sc_),
-                new NullVoETraceWrapper()),
-        channel_(NULL), soundclip_(NULL) {
-  }
-  bool SetupEngine() {
-    bool result = engine_.Init();
-    if (result) {
-      channel_ = engine_.CreateChannel();
-      result = (channel_ != NULL);
-    }
-    return result;
-  }
-  void DeliverPacket(const void* data, int len) {
-    talk_base::Buffer packet(data, len);
-    channel_->OnPacketReceived(&packet);
-  }
-  virtual void TearDown() {
-    delete soundclip_;
-    delete channel_;
-    engine_.Terminate();
-  }
-
- protected:
-  cricket::FakeWebRtcVoiceEngine voe_;
-  cricket::FakeWebRtcVoiceEngine voe_sc_;
-  cricket::WebRtcVoiceEngine engine_;
-  cricket::VoiceMediaChannel* channel_;
-  cricket::SoundclipMedia* soundclip_;
-};
-
-// Tests that our stub library "works".
-TEST_F(WebRtcVoiceEngineTestFake, StartupShutdown) {
-  EXPECT_FALSE(voe_.IsInited());
-  EXPECT_FALSE(voe_sc_.IsInited());
-  EXPECT_TRUE(engine_.Init());
-  EXPECT_TRUE(voe_.IsInited());
-  EXPECT_TRUE(voe_sc_.IsInited());
-  engine_.Terminate();
-  EXPECT_FALSE(voe_.IsInited());
-  EXPECT_FALSE(voe_sc_.IsInited());
-}
-
-// Tests that we can create and destroy a channel.
-TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
-  EXPECT_TRUE(engine_.Init());
-  channel_ = engine_.CreateChannel();
-  EXPECT_TRUE(channel_ != NULL);
-}
-
-// Tests that we properly handle failures in CreateChannel.
-TEST_F(WebRtcVoiceEngineTestFake, CreateChannelFail) {
-  voe_.set_fail_create_channel(true);
-  EXPECT_TRUE(engine_.Init());
-  channel_ = engine_.CreateChannel();
-  EXPECT_TRUE(channel_ == NULL);
-}
-
-// Tests that the list of supported codecs is created properly and ordered
-// correctly
-TEST_F(WebRtcVoiceEngineTestFake, CodecPreference) {
-  const std::vector<cricket::AudioCodec>& codecs = engine_.codecs();
-  ASSERT_FALSE(codecs.empty());
-  EXPECT_EQ("ISAC", codecs[0].name);
-  EXPECT_EQ(16000, codecs[0].clockrate);
-  EXPECT_EQ(0, codecs[0].bitrate);
-  int pref = codecs[0].preference;
-  for (size_t i = 1; i < codecs.size(); ++i) {
-    EXPECT_GT(pref, codecs[i].preference);
-    pref = codecs[i].preference;
-  }
-}
-
-// Tests that we can find codecs by name or id, and that we interpret the
-// clockrate and bitrate fields properly.
-TEST_F(WebRtcVoiceEngineTestFake, FindCodec) {
-  cricket::AudioCodec codec;
-  webrtc::CodecInst codec_inst;
-  // Find PCMU with explicit clockrate and bitrate.
-  EXPECT_TRUE(engine_.FindWebRtcCodec(kPcmuCodec, &codec_inst));
-  // Find ISAC with explicit clockrate and 0 bitrate.
-  EXPECT_TRUE(engine_.FindWebRtcCodec(kIsacCodec, &codec_inst));
-  // Find telephone-event with explicit clockrate and 0 bitrate.
-  EXPECT_TRUE(engine_.FindWebRtcCodec(kTelephoneEventCodec, &codec_inst));
-  // Find ISAC with a different payload id.
-  codec = kIsacCodec;
-  codec.id = 127;
-  EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
-  EXPECT_EQ(codec.id, codec_inst.pltype);
-  // Find PCMU with a 0 clockrate.
-  codec = kPcmuCodec;
-  codec.clockrate = 0;
-  EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
-  EXPECT_EQ(codec.id, codec_inst.pltype);
-  EXPECT_EQ(8000, codec_inst.plfreq);
-  // Find PCMU with a 0 bitrate.
-  codec = kPcmuCodec;
-  codec.bitrate = 0;
-  EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
-  EXPECT_EQ(codec.id, codec_inst.pltype);
-  EXPECT_EQ(64000, codec_inst.rate);
-  // Find ISAC with an explicit bitrate.
-  codec = kIsacCodec;
-  codec.bitrate = 32000;
-  EXPECT_TRUE(engine_.FindWebRtcCodec(codec, &codec_inst));
-  EXPECT_EQ(codec.id, codec_inst.pltype);
-  EXPECT_EQ(32000, codec_inst.rate);
-}
-
-// Test that we set our inbound codecs properly, including changing PT.
-TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
-  EXPECT_TRUE(SetupEngine());
-  int channel_num = voe_.GetLastChannel();
-  std::vector<cricket::AudioCodec> codecs;
-  codecs.push_back(kIsacCodec);
-  codecs.push_back(kPcmuCodec);
-  codecs.push_back(kTelephoneEventCodec);
-  codecs[0].id = 106;  // collide with existing telephone-event
-  codecs[2].id = 126;
-  EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
-  webrtc::CodecInst gcodec;
-  talk_base::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "ISAC");
-  gcodec.plfreq = 16000;
-  EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
-  EXPECT_EQ(106, gcodec.pltype);
-  EXPECT_STREQ("ISAC", gcodec.plname);
-  talk_base::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname),
-      "telephone-event");
-  gcodec.plfreq = 8000;
-  EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
-  EXPECT_EQ(126, gcodec.pltype);
-  EXPECT_STREQ("telephone-event", gcodec.plname);
-}
-
-// Test that we fail to set an unknown inbound codec.
-TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
-  EXPECT_TRUE(SetupEngine());
-  std::vector<cricket::AudioCodec> codecs;
-  codecs.push_back(kIsacCodec);
-  codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1, 0));
-  EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
-}
-
-// Test that we fail if we have duplicate types in the inbound list.
-TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
-  EXPECT_TRUE(SetupEngine());
-  std::vector<cricket::AudioCodec> codecs;
-  codecs.push_back(kIsacCodec);
-  codecs.push_back(kCn16000Codec);
-  codecs[1].id = kIsacCodec.id;
-  EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
-}
-
-// Test that changes to recv codecs are applied to all streams.
-TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
-  EXPECT_TRUE(SetupEngine());
-  std::vector<cricket::AudioCodec> codecs;
-  codecs.push_back(kIsacCodec);
-  codecs.push_back(kPcmuCodec);
-  codecs.push_back(kTelephoneEventCodec);
-  codecs[0].id = 106;  // collide with existing telephone-event
-  codecs[2].id = 126;
-  EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
-  EXPECT_TRUE(channel_->AddStream(2));
-  int channel_num2 = voe_.GetLastChannel();
-  webrtc::CodecInst gcodec;
-  talk_base::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname), "ISAC");
-  gcodec.plfreq = 16000;
-  EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
-  EXPECT_EQ(106, gcodec.pltype);
-  EXPECT_STREQ("ISAC", gcodec.plname);
-  talk_base::strcpyn(gcodec.plname, ARRAY_SIZE(gcodec.plname),
-      "telephone-event");
-  gcodec.plfreq = 8000;
-  EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
-  EXPECT_EQ(126, gcodec.pltype);
-  EXPECT_STREQ("telephone-event", gcodec.plname);
-}
-
-// Test that we apply codecs properly.
-TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
-  EXPECT_TRUE(SetupEngine());
-  int channel_num = voe_.GetLastChannel();
-  std::vector<cricket::AudioCodec> codecs;
-  codecs.push_back(kIsacCodec);
-  codecs.push_back(kPcmuCodec);
-  codecs.push_back(kRedCodec);
-  codecs[0].id = 96;
-  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
-  webrtc::CodecInst gcodec;
-  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
-  EXPECT_EQ(96, gcodec.pltype);
-  EXPECT_STREQ("ISAC", gcodec.plname);
-  EXPECT_FALSE(voe_.GetVAD(channel_num));
-  EXPECT_FALSE(voe_.GetFEC(channel_num));
-  EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
-  EXPECT_EQ(105, voe_.GetSendCNPayloadType(channel_num, true));
-  EXPECT_EQ(106, voe_.GetSendTelephoneEventPayloadType(channel_num));
-}
-
-// Test that we handle various ways of specifying bitrate.
-TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
-  EXPECT_TRUE(SetupEngine());
-  int channel_num = voe_.GetLastChannel();
-  std::vector<cricket::AudioCodec> codecs;
-  codecs.push_back(kIsacCodec);  // bitrate == 32000
-  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
-  webrtc::CodecInst gcodec;
-  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
-  EXPECT_EQ(103, gcodec.pltype);
-  EXPECT_STREQ("ISAC", gcodec.plname);
-  EXPECT_EQ(32000, gcodec.rate);
-  codecs[0].bitrate = 0;         // bitrate == default
-  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
-  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
-  EXPECT_EQ(103, gcodec.pltype);
-  EXPECT_STREQ("ISAC", gcodec.plname);
-  EXPECT_EQ(-1, gcodec.rate);
-  codecs[0].bitrate = 28000;     // bitrate == 28000
-  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
-  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
-  EXPECT_EQ(103, gcodec.pltype);
-  EXPECT_STREQ("ISAC", gcodec.plname);
-  EXPECT_EQ(28000, gcodec.rate);
-  codecs[0] = kPcmuCodec;        // bitrate == 64000
-  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
-  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
-  EXPECT_EQ(0, gcodec.pltype);
-  EXPECT_STREQ("PCMU", gcodec.plname);
-  EXPECT_EQ(64000, gcodec.rate);
-  codecs[0].bitrate = 0;         // bitrate == default
-  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
-  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
-  EXPECT_EQ(0, gcodec.pltype);
-  EXPECT_STREQ("PCMU", gcodec.plname);
-  EXPECT_EQ(64000, gcodec.rate);
-}
-
-// Test that we fall back to PCMU if no codecs are specified.
-TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
-  EXPECT_TRUE(SetupEngine());
-  int channel_num = voe_.GetLastChannel();
-  std::vector<cricket::AudioCodec> codecs;
-  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
-  webrtc::CodecInst gcodec;
-  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
-  EXPECT_EQ(0, gcodec.pltype);
-  EXPECT_STREQ("PCMU", gcodec.plname);
-  EXPECT_FALSE(voe_.GetVAD(channel_num));
-  EXPECT_FALSE(voe_.GetFEC(channel_num));
-  EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
-  EXPECT_EQ(105, voe_.GetSendCNPayloadType(channel_num, true));
-  EXPECT_EQ(106, voe_.GetSendTelephoneEventPayloadType(channel_num));
-}
-
-// Test that we set VAD and DTMF types correctly.
-TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMF) {
-  EXPECT_TRUE(SetupEngine());
-  int channel_num = voe_.GetLastChannel();
-  std::vector<cricket::AudioCodec> codecs;
-  codecs.push_back(kIsacCodec);
-  codecs.push_back(kPcmuCodec);
-  // TODO: cn 32000
-  codecs.push_back(kCn16000Codec);
-  codecs.push_back(kCn8000Codec);
-  codecs.push_back(kTelephoneEventCodec);
-  codecs.push_back(kRedCodec);
-  codecs[0].id = 96;
-  codecs[2].id = 97;  // wideband CN
-  codecs[4].id = 98;  // DTMF
-  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
-  webrtc::CodecInst gcodec;
-  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
-  EXPECT_EQ(96, gcodec.pltype);
-  EXPECT_STREQ("ISAC", gcodec.plname);
-  EXPECT_TRUE(voe_.GetVAD(channel_num));
-  EXPECT_FALSE(voe_.GetFEC(channel_num));
-  EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
-  EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
-  EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
-}
-
-// Test that we perform case-insensitive matching of codec names.
-TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
-  EXPECT_TRUE(SetupEngine());
-  int channel_num = voe_.GetLastChannel();
-  std::vector<cricket::AudioCodec> codecs;
-  codecs.push_back(kIsacCodec);
-  codecs.push_back(kPcmuCodec);
-  codecs.push_back(kCn16000Codec);
-  codecs.push_back(kCn8000Codec);
-  codecs.push_back(kTelephoneEventCodec);
-  codecs.push_back(kRedCodec);
-  codecs[0].name = "iSaC";
-  codecs[0].id = 96;
-  codecs[2].id = 97;  // wideband CN
-  codecs[4].id = 98;  // DTMF
-  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
-  webrtc::CodecInst gcodec;
-  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
-  EXPECT_EQ(96, gcodec.pltype);
-  EXPECT_STREQ("ISAC", gcodec.plname);
-  EXPECT_TRUE(voe_.GetVAD(channel_num));
-  EXPECT_FALSE(voe_.GetFEC(channel_num));
-  EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
-  EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
-  EXPECT_EQ(98, voe_.GetSendTelephoneEventPayloadType(channel_num));
-}
-
-// Test that we set up FEC correctly.
-TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsRED) {
-  EXPECT_TRUE(SetupEngine());
-  int channel_num = voe_.GetLastChannel();
-  std::vector<cricket::AudioCodec> codecs;
-  codecs.push_back(kRedCodec);
-  codecs.push_back(kIsacCodec);
-  codecs.push_back(kPcmuCodec);
-  codecs[0].id = 127;
-  codecs[0].params[""] = "96/96";
-  codecs[1].id = 96;
-  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
-  webrtc::CodecInst gcodec;
-  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
-  EXPECT_EQ(96, gcodec.pltype);
-  EXPECT_STREQ("ISAC", gcodec.plname);
-  EXPECT_TRUE(voe_.GetFEC(channel_num));
-  EXPECT_EQ(127, voe_.GetSendFECPayloadType(channel_num));
-}
-
-// Test that we set up FEC correctly if params are omitted.
-TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDNoParams) {
-  EXPECT_TRUE(SetupEngine());
-  int channel_num = voe_.GetLastChannel();
-  std::vector<cricket::AudioCodec> codecs;
-  codecs.push_back(kRedCodec);
-  codecs.push_back(kIsacCodec);
-  codecs.push_back(kPcmuCodec);
-  codecs[0].id = 127;
-  codecs[1].id = 96;
-  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
-  webrtc::CodecInst gcodec;
-  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
-  EXPECT_EQ(96, gcodec.pltype);
-  EXPECT_STREQ("ISAC", gcodec.plname);
-  EXPECT_TRUE(voe_.GetFEC(channel_num));
-  EXPECT_EQ(127, voe_.GetSendFECPayloadType(channel_num));
-}
-
-// Test that we ignore RED if the parameters aren't named the way we expect.
-TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED1) {
-  EXPECT_TRUE(SetupEngine());
-  int channel_num = voe_.GetLastChannel();
-  std::vector<cricket::AudioCodec> codecs;
-  codecs.push_back(kRedCodec);
-  codecs.push_back(kIsacCodec);
-  codecs.push_back(kPcmuCodec);
-  codecs[0].id = 127;
-  codecs[0].params["ABC"] = "96/96";
-  codecs[1].id = 96;
-  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
-  webrtc::CodecInst gcodec;
-  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
-  EXPECT_EQ(96, gcodec.pltype);
-  EXPECT_STREQ("ISAC", gcodec.plname);
-  EXPECT_FALSE(voe_.GetFEC(channel_num));
-}
-
-// Test that we ignore RED if it uses different primary/secondary encoding.
-TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED2) {
-  EXPECT_TRUE(SetupEngine());
-  int channel_num = voe_.GetLastChannel();
-  std::vector<cricket::AudioCodec> codecs;
-  codecs.push_back(kRedCodec);
-  codecs.push_back(kIsacCodec);
-  codecs.push_back(kPcmuCodec);
-  codecs[0].id = 127;
-  codecs[0].params[""] = "96/0";
-  codecs[1].id = 96;
-  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
-  webrtc::CodecInst gcodec;
-  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
-  EXPECT_EQ(96, gcodec.pltype);
-  EXPECT_STREQ("ISAC", gcodec.plname);
-  EXPECT_FALSE(voe_.GetFEC(channel_num));
-}
-
-// Test that we ignore RED if it uses more than 2 encodings.
-TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED3) {
-  EXPECT_TRUE(SetupEngine());
-  int channel_num = voe_.GetLastChannel();
-  std::vector<cricket::AudioCodec> codecs;
-  codecs.push_back(kRedCodec);
-  codecs.push_back(kIsacCodec);
-  codecs.push_back(kPcmuCodec);
-  codecs[0].id = 127;
-  codecs[0].params[""] = "96/96/96";
-  codecs[1].id = 96;
-  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
-  webrtc::CodecInst gcodec;
-  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
-  EXPECT_EQ(96, gcodec.pltype);
-  EXPECT_STREQ("ISAC", gcodec.plname);
-  EXPECT_FALSE(voe_.GetFEC(channel_num));
-}
-
-// Test that we ignore RED if it has bogus codec ids.
-TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED4) {
-  EXPECT_TRUE(SetupEngine());
-  int channel_num = voe_.GetLastChannel();
-  std::vector<cricket::AudioCodec> codecs;
-  codecs.push_back(kRedCodec);
-  codecs.push_back(kIsacCodec);
-  codecs.push_back(kPcmuCodec);
-  codecs[0].id = 127;
-  codecs[0].params[""] = "ABC/ABC";
-  codecs[1].id = 96;
-  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
-  webrtc::CodecInst gcodec;
-  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
-  EXPECT_EQ(96, gcodec.pltype);
-  EXPECT_STREQ("ISAC", gcodec.plname);
-  EXPECT_FALSE(voe_.GetFEC(channel_num));
-}
-
-// Test that we ignore RED if it refers to a codec that is not present.
-TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED5) {
-  EXPECT_TRUE(SetupEngine());
-  int channel_num = voe_.GetLastChannel();
-  std::vector<cricket::AudioCodec> codecs;
-  codecs.push_back(kRedCodec);
-  codecs.push_back(kIsacCodec);
-  codecs.push_back(kPcmuCodec);
-  codecs[0].id = 127;
-  codecs[0].params[""] = "97/97";
-  codecs[1].id = 96;
-  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
-  webrtc::CodecInst gcodec;
-  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
-  EXPECT_EQ(96, gcodec.pltype);
-  EXPECT_STREQ("ISAC", gcodec.plname);
-  EXPECT_FALSE(voe_.GetFEC(channel_num));
-}
-
-// Test that we support setting an empty list of recv header extensions.
-TEST_F(WebRtcVoiceEngineTestFake, SetRecvRtpHeaderExtensions) {
-  EXPECT_TRUE(SetupEngine());
-  std::vector<cricket::RtpHeaderExtension> extensions;
-  int channel_num = voe_.GetLastChannel();
-  bool enable = false;
-  unsigned char id = 0;
-
-  // An empty list shouldn't cause audio-level headers to be enabled.
-  EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
-  EXPECT_EQ(0, voe_.GetRTPAudioLevelIndicationStatus(
-      channel_num, enable, id));
-  EXPECT_FALSE(enable);
-
-  // Nor should indicating we can receive the audio-level header.
-  extensions.push_back(cricket::RtpHeaderExtension(
-      "urn:ietf:params:rtp-hdrext:ssrc-audio-level", 8));
-  EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
-  EXPECT_EQ(0, voe_.GetRTPAudioLevelIndicationStatus(
-      channel_num, enable, id));
-  EXPECT_FALSE(enable);
-}
-
-// Test that we support setting certain send header extensions.
-TEST_F(WebRtcVoiceEngineTestFake, SetSendRtpHeaderExtensions) {
-  EXPECT_TRUE(SetupEngine());
-  std::vector<cricket::RtpHeaderExtension> extensions;
-  int channel_num = voe_.GetLastChannel();
-  bool enable = false;
-  unsigned char id = 0;
-
-  // Ensure audio levels are off by default.
-  EXPECT_EQ(0, voe_.GetRTPAudioLevelIndicationStatus(
-      channel_num, enable, id));
-  EXPECT_FALSE(enable);
-
-  // Ensure audio levels stay off with an empty list of headers.
-  EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
-  EXPECT_EQ(0, voe_.GetRTPAudioLevelIndicationStatus(
-      channel_num, enable, id));
-  EXPECT_FALSE(enable);
-
-  // Ensure audio levels are enabled if the audio-level header is specified.
-  extensions.push_back(cricket::RtpHeaderExtension(
-      "urn:ietf:params:rtp-hdrext:ssrc-audio-level", 8));
-  EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
-  EXPECT_EQ(0, voe_.GetRTPAudioLevelIndicationStatus(
-      channel_num, enable, id));
-  EXPECT_TRUE(enable);
-  EXPECT_EQ(8, id);
-
-  // Ensure audio levels go back off with an empty list.
-  extensions.clear();
-  EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
-  EXPECT_EQ(0, voe_.GetRTPAudioLevelIndicationStatus(
-      channel_num, enable, id));
-  EXPECT_FALSE(enable);
-}
-
-// Test that we can create a channel and start sending/playing out on it.
-TEST_F(WebRtcVoiceEngineTestFake, SendAndPlayout) {
-  EXPECT_TRUE(SetupEngine());
-  int channel_num = voe_.GetLastChannel();
-  std::vector<cricket::AudioCodec> codecs;
-  codecs.push_back(kPcmuCodec);
-  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
-  EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
-  EXPECT_TRUE(voe_.GetSend(channel_num));
-  EXPECT_TRUE(channel_->SetPlayout(true));
-  EXPECT_TRUE(voe_.GetPlayout(channel_num));
-  EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
-  EXPECT_FALSE(voe_.GetSend(channel_num));
-  EXPECT_TRUE(channel_->SetPlayout(false));
-  EXPECT_FALSE(voe_.GetPlayout(channel_num));
-}
-
-// Test that we can add and remove streams, and do proper send/playout.
-// We can receive on multiple streams, but will only send on one.
-TEST_F(WebRtcVoiceEngineTestFake, SendAndPlayoutWithMultipleStreams) {
-  EXPECT_TRUE(SetupEngine());
-  int channel_num1 = voe_.GetLastChannel();
-
-  // Start playout on the default channel.
-  EXPECT_TRUE(channel_->SetPlayout(true));
-  EXPECT_TRUE(voe_.GetPlayout(channel_num1));
-
-  // Adding another stream should disable playout on the default channel.
-  EXPECT_TRUE(channel_->AddStream(2));
-  int channel_num2 = voe_.GetLastChannel();
-  std::vector<cricket::AudioCodec> codecs;
-  codecs.push_back(kPcmuCodec);
-  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
-  EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
-  EXPECT_TRUE(voe_.GetSend(channel_num1));
-  EXPECT_FALSE(voe_.GetSend(channel_num2));
-
-  // Make sure only the new channel is played out.
-  EXPECT_FALSE(voe_.GetPlayout(channel_num1));
-  EXPECT_TRUE(voe_.GetPlayout(channel_num2));
-
-  // Adding yet another stream should have stream 2 and 3 enabled for playout.
-  EXPECT_TRUE(channel_->AddStream(3));
-  int channel_num3 = voe_.GetLastChannel();
-  EXPECT_FALSE(voe_.GetPlayout(channel_num1));
-  EXPECT_TRUE(voe_.GetPlayout(channel_num2));
-  EXPECT_TRUE(voe_.GetPlayout(channel_num3));
-  EXPECT_FALSE(voe_.GetSend(channel_num3));
-
-  // Stop sending.
-  EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
-  EXPECT_FALSE(voe_.GetSend(channel_num1));
-  EXPECT_FALSE(voe_.GetSend(channel_num2));
-  EXPECT_FALSE(voe_.GetSend(channel_num3));
-
-  // Stop playout.
-  EXPECT_TRUE(channel_->SetPlayout(false));
-  EXPECT_FALSE(voe_.GetPlayout(channel_num1));
-  EXPECT_FALSE(voe_.GetPlayout(channel_num2));
-  EXPECT_FALSE(voe_.GetPlayout(channel_num3));
-
-  // Restart playout and make sure the default channel still is not played out.
-  EXPECT_TRUE(channel_->SetPlayout(true));
-  EXPECT_FALSE(voe_.GetPlayout(channel_num1));
-  EXPECT_TRUE(voe_.GetPlayout(channel_num2));
-  EXPECT_TRUE(voe_.GetPlayout(channel_num3));
-
-  // Now remove the new streams and verify that the default channel is
-  // played out again.
-  EXPECT_TRUE(channel_->RemoveStream(3));
-  EXPECT_TRUE(channel_->RemoveStream(2));
-
-  EXPECT_TRUE(voe_.GetPlayout(channel_num1));
-}
-
-// Test that we can set the devices to use.
-TEST_F(WebRtcVoiceEngineTestFake, SetDevices) {
-  EXPECT_TRUE(SetupEngine());
-  int channel_num = voe_.GetLastChannel();
-  std::vector<cricket::AudioCodec> codecs;
-  codecs.push_back(kPcmuCodec);
-  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
-
-  cricket::Device default_dev(cricket::kFakeDefaultDeviceName,
-                              cricket::kFakeDefaultDeviceId);
-  cricket::Device dev(cricket::kFakeDeviceName,
-                      cricket::kFakeDeviceId);
-
-  // Test SetDevices() while not sending or playing.
-  EXPECT_TRUE(engine_.SetDevices(&default_dev, &default_dev));
-
-  // Test SetDevices() while sending and playing.
-  EXPECT_TRUE(engine_.SetLocalMonitor(true));
-  EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
-  EXPECT_TRUE(channel_->SetPlayout(true));
-  EXPECT_TRUE(voe_.GetRecordingMicrophone());
-  EXPECT_TRUE(voe_.GetSend(channel_num));
-  EXPECT_TRUE(voe_.GetPlayout(channel_num));
-
-  EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
-
-  EXPECT_TRUE(voe_.GetRecordingMicrophone());
-  EXPECT_TRUE(voe_.GetSend(channel_num));
-  EXPECT_TRUE(voe_.GetPlayout(channel_num));
-
-  // Test that failure to open newly selected devices does not prevent opening
-  // ones after that.
-  voe_.set_fail_start_recording_microphone(true);
-  voe_.set_playout_fail_channel(channel_num);
-  voe_.set_send_fail_channel(channel_num);
-
-  EXPECT_FALSE(engine_.SetDevices(&default_dev, &default_dev));
-
-  EXPECT_FALSE(voe_.GetRecordingMicrophone());
-  EXPECT_FALSE(voe_.GetSend(channel_num));
-  EXPECT_FALSE(voe_.GetPlayout(channel_num));
-
-  voe_.set_fail_start_recording_microphone(false);
-  voe_.set_playout_fail_channel(-1);
-  voe_.set_send_fail_channel(-1);
-
-  EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
-
-  EXPECT_TRUE(voe_.GetRecordingMicrophone());
-  EXPECT_TRUE(voe_.GetSend(channel_num));
-  EXPECT_TRUE(voe_.GetPlayout(channel_num));
-}
-
-// Test that we can set the devices to use even if we failed to
-// open the initial ones.
-TEST_F(WebRtcVoiceEngineTestFake, SetDevicesWithInitiallyBadDevices) {
-  EXPECT_TRUE(SetupEngine());
-  int channel_num = voe_.GetLastChannel();
-  std::vector<cricket::AudioCodec> codecs;
-  codecs.push_back(kPcmuCodec);
-  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
-
-  cricket::Device default_dev(cricket::kFakeDefaultDeviceName,
-                              cricket::kFakeDefaultDeviceId);
-  cricket::Device dev(cricket::kFakeDeviceName,
-                      cricket::kFakeDeviceId);
-
-  // Test that failure to open devices selected before starting
-  // send/play does not prevent opening newly selected ones after that.
-  voe_.set_fail_start_recording_microphone(true);
-  voe_.set_playout_fail_channel(channel_num);
-  voe_.set_send_fail_channel(channel_num);
-
-  EXPECT_TRUE(engine_.SetDevices(&default_dev, &default_dev));
-
-  EXPECT_FALSE(engine_.SetLocalMonitor(true));
-  EXPECT_FALSE(channel_->SetSend(cricket::SEND_MICROPHONE));
-  EXPECT_FALSE(channel_->SetPlayout(true));
-  EXPECT_FALSE(voe_.GetRecordingMicrophone());
-  EXPECT_FALSE(voe_.GetSend(channel_num));
-  EXPECT_FALSE(voe_.GetPlayout(channel_num));
-
-  voe_.set_fail_start_recording_microphone(false);
-  voe_.set_playout_fail_channel(-1);
-  voe_.set_send_fail_channel(-1);
-
-  EXPECT_TRUE(engine_.SetDevices(&dev, &dev));
-
-  EXPECT_TRUE(voe_.GetRecordingMicrophone());
-  EXPECT_TRUE(voe_.GetSend(channel_num));
-  EXPECT_TRUE(voe_.GetPlayout(channel_num));
-}
-
-// Test that we can create a channel configured for multi-point conferences,
-// and start sending/playing out on it.
-TEST_F(WebRtcVoiceEngineTestFake, ConferenceSendAndPlayout) {
-  EXPECT_TRUE(SetupEngine());
-  int channel_num = voe_.GetLastChannel();
-  EXPECT_TRUE(channel_->SetOptions(cricket::OPT_CONFERENCE));
-  std::vector<cricket::AudioCodec> codecs;
-  codecs.push_back(kPcmuCodec);
-  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
-  EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
-  EXPECT_TRUE(voe_.GetSend(channel_num));
-
-  bool enabled;
-  webrtc::EcModes ec_mode;
-  webrtc::NsModes ns_mode;
-  EXPECT_EQ(0, voe_.GetEcStatus(enabled, ec_mode));
-#ifdef CHROMEOS
-  EXPECT_EQ(webrtc::kEcDefault, ec_mode);
-#else
-  EXPECT_EQ(webrtc::kEcConference, ec_mode);
-#endif
-  EXPECT_EQ(0, voe_.GetNsStatus(enabled, ns_mode));
-  EXPECT_TRUE(enabled);
-#ifdef CHROMEOS
-  EXPECT_EQ(webrtc::kNsDefault, ns_mode);
-#else
-  EXPECT_EQ(webrtc::kNsConference, ns_mode);
-#endif
-
-  EXPECT_TRUE(channel_->SetPlayout(true));
-  EXPECT_TRUE(voe_.GetPlayout(channel_num));
-  EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
-  EXPECT_FALSE(voe_.GetSend(channel_num));
-
-  EXPECT_EQ(0, voe_.GetEcStatus(enabled, ec_mode));
-  EXPECT_EQ(webrtc::kEcDefault, ec_mode);
-  EXPECT_EQ(0, voe_.GetNsStatus(enabled, ns_mode));
-  EXPECT_EQ(webrtc::kNsDefault, ns_mode);
-
-  EXPECT_TRUE(channel_->SetPlayout(false));
-  EXPECT_FALSE(voe_.GetPlayout(channel_num));
-}
-
-// Test that we can create a channel configured for Codian bridges,
-// and start sending/playing out on it.
-TEST_F(WebRtcVoiceEngineTestFake, CodianSendAndPlayout) {
-  EXPECT_TRUE(SetupEngine());
-  int channel_num = voe_.GetLastChannel();
-  webrtc::AgcConfig agc_config;
-  EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
-  EXPECT_EQ(0, agc_config.targetLeveldBOv);
-  EXPECT_TRUE(channel_->SetOptions(cricket::OPT_AGC_MINUS_10DB));
-  std::vector<cricket::AudioCodec> codecs;
-  codecs.push_back(kPcmuCodec);
-  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
-  EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
-  EXPECT_TRUE(voe_.GetSend(channel_num));
-  EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
-  EXPECT_GT(agc_config.targetLeveldBOv, 0);  // level was attenuated
-  EXPECT_TRUE(channel_->SetPlayout(true));
-  EXPECT_TRUE(voe_.GetPlayout(channel_num));
-  EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
-  EXPECT_FALSE(voe_.GetSend(channel_num));
-  EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
-  EXPECT_EQ(0, agc_config.targetLeveldBOv);  // level was restored
-  EXPECT_TRUE(channel_->SetPlayout(false));
-  EXPECT_FALSE(voe_.GetPlayout(channel_num));
-}
-
-// Test that we can set the outgoing SSRC properly.
-TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
-  EXPECT_TRUE(SetupEngine());
-  int channel_num = voe_.GetLastChannel();
-  unsigned int send_ssrc;
-  EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num, send_ssrc));
-  EXPECT_NE(0U, send_ssrc);
-  channel_->SetSendSsrc(0x99);
-  EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num, send_ssrc));
-  EXPECT_EQ(0x99U, send_ssrc);
-}
-
-// Test that we can set the outgoing SSRC properly with multiple streams.
-TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
-  EXPECT_TRUE(SetupEngine());
-  int channel_num1 = voe_.GetLastChannel();
-  unsigned int send_ssrc;
-  channel_->SetSendSsrc(0x99);
-  EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num1, send_ssrc));
-  EXPECT_EQ(0x99U, send_ssrc);
-  EXPECT_TRUE(channel_->AddStream(2));
-  int channel_num2 = voe_.GetLastChannel();
-  EXPECT_EQ(0, voe_.GetLocalSSRC(channel_num2, send_ssrc));
-  EXPECT_EQ(0x99U, send_ssrc);
-}
-
-// Test that we can properly receive packets.
-TEST_F(WebRtcVoiceEngineTestFake, Recv) {
-  EXPECT_TRUE(SetupEngine());
-  int channel_num = voe_.GetLastChannel();
-  DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
-  EXPECT_TRUE(voe_.CheckPacket(channel_num, kPcmuFrame,
-                               sizeof(kPcmuFrame)));
-}
-
-// Test that we can properly receive packets on multiple streams.
-TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
-  EXPECT_TRUE(SetupEngine());
-  EXPECT_TRUE(channel_->AddStream(1));
-  int channel_num1 = voe_.GetLastChannel();
-  EXPECT_TRUE(channel_->AddStream(2));
-  int channel_num2 = voe_.GetLastChannel();
-  EXPECT_TRUE(channel_->AddStream(3));
-  int channel_num3 = voe_.GetLastChannel();
-  // Create packets with the right SSRCs.
-  char packets[4][sizeof(kPcmuFrame)];
-  for (size_t i = 0; i < ARRAY_SIZE(packets); ++i) {
-    memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
-    talk_base::SetBE32(packets[i] + 8, i);
-  }
-  EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
-  EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
-  EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
-  DeliverPacket(packets[0], sizeof(packets[0]));
-  EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
-  EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
-  EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
-  DeliverPacket(packets[1], sizeof(packets[1]));
-  EXPECT_TRUE(voe_.CheckPacket(channel_num1, packets[1],
-                               sizeof(packets[1])));
-  EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
-  EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
-  DeliverPacket(packets[2], sizeof(packets[2]));
-  EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
-  EXPECT_TRUE(voe_.CheckPacket(channel_num2, packets[2],
-                               sizeof(packets[2])));
-  EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
-  DeliverPacket(packets[3], sizeof(packets[3]));
-  EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
-  EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
-  EXPECT_TRUE(voe_.CheckPacket(channel_num3, packets[3],
-                               sizeof(packets[3])));
-  EXPECT_TRUE(channel_->RemoveStream(3));
-  EXPECT_TRUE(channel_->RemoveStream(2));
-  EXPECT_TRUE(channel_->RemoveStream(1));
-}
-
-// Test that we properly handle failures to add a stream.
-TEST_F(WebRtcVoiceEngineTestFake, AddStreamFail) {
-  EXPECT_TRUE(SetupEngine());
-  voe_.set_fail_create_channel(true);
-  EXPECT_FALSE(channel_->AddStream(2));
-}
-
-// Test that we properly clean up any streams that were added, even if
-// not explicitly removed.
-TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
-  EXPECT_TRUE(SetupEngine());
-  EXPECT_TRUE(channel_->AddStream(1));
-  EXPECT_TRUE(channel_->AddStream(2));
-  EXPECT_EQ(3, voe_.GetNumChannels());  // default channel + 2 added
-  delete channel_;
-  channel_ = NULL;
-  EXPECT_EQ(0, voe_.GetNumChannels());
-}
-
-// Test that we can send DTMF properly, but only if the other side supports
-// telephone-event.
-TEST_F(WebRtcVoiceEngineTestFake, SendDtmf) {
-  EXPECT_TRUE(SetupEngine());
-  std::vector<cricket::AudioCodec> codecs;
-  codecs.push_back(kPcmuCodec);
-  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
-  EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
-  EXPECT_FALSE(channel_->PressDTMF(1, true));
-  codecs.push_back(kTelephoneEventCodec);
-  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
-  EXPECT_TRUE(channel_->PressDTMF(1, true));
-}
-
-// Test that we can play a ringback tone properly in a single-stream call.
-TEST_F(WebRtcVoiceEngineTestFake, PlayRingback) {
-  EXPECT_TRUE(SetupEngine());
-  int channel_num = voe_.GetLastChannel();
-  EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
-  // Check we fail if no ringback tone specified.
-  EXPECT_FALSE(channel_->PlayRingbackTone(0, true, true));
-  EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
-  // Check we can set and play a ringback tone.
-  EXPECT_TRUE(channel_->SetRingbackTone(kRingbackTone, strlen(kRingbackTone)));
-  EXPECT_TRUE(channel_->PlayRingbackTone(0, true, true));
-  EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
-  // Check we can stop the tone manually.
-  EXPECT_TRUE(channel_->PlayRingbackTone(0, false, false));
-  EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
-  // Check we stop the tone if a packet arrives.
-  EXPECT_TRUE(channel_->PlayRingbackTone(0, true, true));
-  EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
-  DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
-  EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
-}
-
-// Test that we can play a ringback tone properly in a multi-stream call.
-TEST_F(WebRtcVoiceEngineTestFake, PlayRingbackWithMultipleStreams) {
-  EXPECT_TRUE(SetupEngine());
-  EXPECT_TRUE(channel_->AddStream(1));
-  EXPECT_TRUE(channel_->AddStream(2));
-  int channel_num = voe_.GetLastChannel();
-  EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
-  // Check we fail if no ringback tone specified.
-  EXPECT_FALSE(channel_->PlayRingbackTone(2, true, true));
-  EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
-  // Check we can set and play a ringback tone on the correct ssrc.
-  EXPECT_TRUE(channel_->SetRingbackTone(kRingbackTone, strlen(kRingbackTone)));
-  EXPECT_FALSE(channel_->PlayRingbackTone(77, true, true));
-  EXPECT_TRUE(channel_->PlayRingbackTone(2, true, true));
-  EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
-  // Check we can stop the tone manually.
-  EXPECT_TRUE(channel_->PlayRingbackTone(2, false, false));
-  EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
-  // Check we stop the tone if a packet arrives, but only with the right SSRC.
-  EXPECT_TRUE(channel_->PlayRingbackTone(2, true, true));
-  EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
-  // Send a packet with SSRC 1; the tone should not stop.
-  DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
-  EXPECT_EQ(1, voe_.IsPlayingFileLocally(channel_num));
-  // Send a packet with SSRC 2; the tone should stop.
-  char packet[sizeof(kPcmuFrame)];
-  memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
-  talk_base::SetBE32(packet + 8, 2);
-  DeliverPacket(packet, sizeof(packet));
-  EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
-}
-
-// Tests creating soundclips, and make sure they come from the right engine.
-TEST_F(WebRtcVoiceEngineTestFake, CreateSoundclip) {
-  EXPECT_TRUE(engine_.Init());
-  soundclip_ = engine_.CreateSoundclip();
-  ASSERT_TRUE(soundclip_ != NULL);
-  EXPECT_EQ(0, voe_.GetNumChannels());
-  EXPECT_EQ(1, voe_sc_.GetNumChannels());
-  int channel_num = voe_sc_.GetLastChannel();
-  EXPECT_TRUE(voe_sc_.GetPlayout(channel_num));
-  delete soundclip_;
-  soundclip_ = NULL;
-  EXPECT_EQ(0, voe_sc_.GetNumChannels());
-}
-
-// Tests playing out a fake sound.
-TEST_F(WebRtcVoiceEngineTestFake, PlaySoundclip) {
-  static const char kZeroes[16000] = {};
-  EXPECT_TRUE(engine_.Init());
-  soundclip_ = engine_.CreateSoundclip();
-  ASSERT_TRUE(soundclip_ != NULL);
-  EXPECT_TRUE(soundclip_->PlaySound(kZeroes, sizeof(kZeroes), 0));
-}
-
-TEST_F(WebRtcVoiceEngineTestFake, MediaEngineCallbackOnError) {
-  talk_base::scoped_ptr<ChannelErrorListener> listener;
-  cricket::WebRtcVoiceMediaChannel* media_channel;
-  unsigned int ssrc = 0;
-
-  EXPECT_TRUE(SetupEngine());
-  EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
-
-  media_channel = reinterpret_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
-  listener.reset(new ChannelErrorListener(channel_));
-
-  // Test on WebRtc VoE channel.
-  voe_.TriggerCallbackOnError(media_channel->voe_channel(),
-                              VE_SATURATION_WARNING);
-  EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_DEVICE_SATURATION,
-            listener->error());
-  EXPECT_NE(-1, voe_.GetLocalSSRC(voe_.GetLastChannel(), ssrc));
-  EXPECT_EQ(ssrc, listener->ssrc());
-
-  listener->Reset();
-  voe_.TriggerCallbackOnError(-1, VE_TYPING_NOISE_WARNING);
-  EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_TYPING_NOISE_DETECTED,
-            listener->error());
-  EXPECT_EQ(0U, listener->ssrc());
-
-  // Add another stream and test on that.
-  ++ssrc;
-  EXPECT_TRUE(channel_->AddStream(ssrc));
-  listener->Reset();
-  voe_.TriggerCallbackOnError(voe_.GetLastChannel(),
-                              VE_SATURATION_WARNING);
-  EXPECT_EQ(cricket::VoiceMediaChannel::ERROR_REC_DEVICE_SATURATION,
-            listener->error());
-  EXPECT_EQ(ssrc, listener->ssrc());
-
-  // Testing a non-existing channel.
-  listener->Reset();
-  voe_.TriggerCallbackOnError(voe_.GetLastChannel() + 2,
-                              VE_SATURATION_WARNING);
-  EXPECT_EQ(0, listener->error());
-}
-
-TEST_F(WebRtcVoiceEngineTestFake, TestSetPlayoutError) {
-  EXPECT_TRUE(SetupEngine());
-  std::vector<cricket::AudioCodec> codecs;
-  codecs.push_back(kPcmuCodec);
-  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
-  EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
-  EXPECT_TRUE(channel_->AddStream(2));
-  EXPECT_TRUE(channel_->AddStream(3));
-  EXPECT_TRUE(channel_->SetPlayout(true));
-  voe_.set_playout_fail_channel(voe_.GetLastChannel() - 1);
-  EXPECT_TRUE(channel_->SetPlayout(false));
-  EXPECT_FALSE(channel_->SetPlayout(true));
-}
-
-// Test that the Registering/Unregistering with the
-// webrtcvoiceengine works as expected
-TEST_F(WebRtcVoiceEngineTestFake, RegisterVoiceProcessor) {
-  EXPECT_TRUE(SetupEngine());
-  uint32 ssrc = 0;
-  voe_.GetLocalSSRC(0,ssrc);
-  cricket::FakeMediaProcessor vp_1;
-  cricket::FakeMediaProcessor vp_2;
-
-  EXPECT_TRUE(engine_.RegisterProcessor(ssrc, &vp_1, cricket::MPD_RX));
-  EXPECT_TRUE(engine_.RegisterProcessor(ssrc, &vp_2, cricket::MPD_RX));
-  voe_.TriggerProcessPacket(cricket::MPD_RX);
-  voe_.TriggerProcessPacket(cricket::MPD_TX);
-
-  EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
-  EXPECT_EQ(1, vp_1.voice_frame_count());
-  EXPECT_EQ(1, vp_2.voice_frame_count());
-
-  EXPECT_TRUE(engine_.UnregisterProcessor(ssrc,
-                                          &vp_2,
-                                          cricket::MPD_RX));
-  voe_.TriggerProcessPacket(cricket::MPD_RX);
-  EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
-  EXPECT_EQ(1, vp_2.voice_frame_count());
-  EXPECT_EQ(2, vp_1.voice_frame_count());
-
-  EXPECT_TRUE(engine_.UnregisterProcessor(ssrc,
-                                          &vp_1,
-                                          cricket::MPD_RX));
-  voe_.TriggerProcessPacket(cricket::MPD_RX);
-  EXPECT_FALSE(voe_.IsExternalMediaProcessorRegistered());
-  EXPECT_EQ(2, vp_1.voice_frame_count());
-
-  EXPECT_TRUE(engine_.RegisterProcessor(ssrc, &vp_1, cricket::MPD_TX));
-  voe_.TriggerProcessPacket(cricket::MPD_RX);
-  voe_.TriggerProcessPacket(cricket::MPD_TX);
-  EXPECT_TRUE(voe_.IsExternalMediaProcessorRegistered());
-  EXPECT_EQ(3, vp_1.voice_frame_count());
-
-  EXPECT_TRUE(engine_.UnregisterProcessor(ssrc,
-                                          &vp_1,
-                                          cricket::MPD_RX_AND_TX));
-  voe_.TriggerProcessPacket(cricket::MPD_TX);
-  EXPECT_FALSE(voe_.IsExternalMediaProcessorRegistered());
-  EXPECT_EQ(3, vp_1.voice_frame_count());
-
-  // The following tests test that FindChannelNumFromSsrc is doing
-  // what we expect.
-  // pick an invalid ssrc and make sure we can't register
-  EXPECT_FALSE(engine_.RegisterProcessor(0,
-                                         &vp_1,
-                                         cricket::MPD_RX));
-  channel_->AddStream(1);
-  EXPECT_TRUE(engine_.RegisterProcessor(1,
-                                        &vp_1,
-                                        cricket::MPD_RX));
-  EXPECT_TRUE(engine_.UnregisterProcessor(1,
-                                          &vp_1,
-                                          cricket::MPD_RX));
-  EXPECT_FALSE(engine_.RegisterProcessor(1,
-                                         &vp_1,
-                                         cricket::MPD_TX));
-  channel_->RemoveStream(1);
-}
-
-// Tests for the actual WebRtc VoE library.
-
-// Tests that the library initializes and shuts down properly.
-TEST(WebRtcVoiceEngineTest, StartupShutdown) {
-  cricket::WebRtcVoiceEngine engine;
-  EXPECT_TRUE(engine.Init());
-  cricket::VoiceMediaChannel* channel = engine.CreateChannel();
-  EXPECT_TRUE(channel != NULL);
-  delete channel;
-  engine.Terminate();
-
-  // Reinit to catch regression where VoiceEngineObserver reference is lost
-  EXPECT_TRUE(engine.Init());
-  engine.Terminate();
-}
-
-// Tests that the logging from the library is cleartext.
-TEST(WebRtcVoiceEngineTest, DISABLED_HasUnencryptedLogging) {
-  cricket::WebRtcVoiceEngine engine;
-  talk_base::scoped_ptr<talk_base::MemoryStream> stream(
-      new talk_base::MemoryStream);
-  size_t size = 0;
-  bool cleartext = true;
-  talk_base::LogMessage::AddLogToStream(stream.get(), talk_base::LS_VERBOSE);
-  engine.SetLogging(talk_base::LS_VERBOSE, "");
-  EXPECT_TRUE(engine.Init());
-  EXPECT_TRUE(stream->GetSize(&size));
-  EXPECT_GT(size, 0U);
-  engine.Terminate();
-  talk_base::LogMessage::RemoveLogToStream(stream.get());
-  const char* buf = stream->GetBuffer();
-  for (size_t i = 0; i < size && cleartext; ++i) {
-    int ch = static_cast<int>(buf[i]);
-    ASSERT_GE(ch, 0) << "Out of bounds character in WebRtc VoE log: "
-                     << std::hex << ch;
-    cleartext = (isprint(ch) || isspace(ch));
-  }
-  EXPECT_TRUE(cleartext);
-}
-
-// Tests we do not see any references to a monitor thread being spun up
-// when initiating the engine.
-TEST(WebRtcVoiceEngineTest, HasNoMonitorThread) {
-  cricket::WebRtcVoiceEngine engine;
-  talk_base::scoped_ptr<talk_base::MemoryStream> stream(
-      new talk_base::MemoryStream);
-  talk_base::LogMessage::AddLogToStream(stream.get(), talk_base::LS_VERBOSE);
-  engine.SetLogging(talk_base::LS_VERBOSE, "");
-  EXPECT_TRUE(engine.Init());
-  engine.Terminate();
-  talk_base::LogMessage::RemoveLogToStream(stream.get());
-
-  size_t size = 0;
-  EXPECT_TRUE(stream->GetSize(&size));
-  EXPECT_GT(size, 0U);
-  const std::string logs(stream->GetBuffer());
-  EXPECT_NE(std::string::npos, logs.find("ProcessThread"));
-}
-
-// Tests that the library is configured with the codecs we want.
-TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) {
-  cricket::WebRtcVoiceEngine engine;
-  // Check codecs by name.
-  EXPECT_TRUE(engine.FindCodec(
-      cricket::AudioCodec(96, "ISAC", 16000, 0, 1, 0)));
-  EXPECT_TRUE(engine.FindCodec(
-      cricket::AudioCodec(96, "ISAC", 32000, 0, 1, 0)));
-  // Check that name matching is case-insensitive.
-  EXPECT_TRUE(engine.FindCodec(
-      cricket::AudioCodec(96, "ILBC", 8000, 0, 1, 0)));
-  EXPECT_TRUE(engine.FindCodec(
-      cricket::AudioCodec(96, "iLBC", 8000, 0, 1, 0)));
-  EXPECT_TRUE(engine.FindCodec(
-      cricket::AudioCodec(96, "PCMU", 8000, 0, 1, 0)));
-  EXPECT_TRUE(engine.FindCodec(
-      cricket::AudioCodec(96, "PCMA", 8000, 0, 1, 0)));
-  EXPECT_TRUE(engine.FindCodec(
-      cricket::AudioCodec(96, "speex", 16000, 0, 1, 0)));
-  EXPECT_TRUE(engine.FindCodec(
-      cricket::AudioCodec(96, "speex", 8000, 0, 1, 0)));
-  EXPECT_TRUE(engine.FindCodec(
-      cricket::AudioCodec(96, "G722", 16000, 0, 1, 0)));
-  EXPECT_TRUE(engine.FindCodec(
-      cricket::AudioCodec(96, "red", 8000, 0, 1, 0)));
-  EXPECT_TRUE(engine.FindCodec(
-      cricket::AudioCodec(96, "CN", 32000, 0, 1, 0)));
-  EXPECT_TRUE(engine.FindCodec(
-      cricket::AudioCodec(96, "CN", 16000, 0, 1, 0)));
-  EXPECT_TRUE(engine.FindCodec(
-      cricket::AudioCodec(96, "CN", 8000, 0, 1, 0)));
-  EXPECT_TRUE(engine.FindCodec(
-      cricket::AudioCodec(96, "telephone-event", 8000, 0, 1, 0)));
-  // Check codecs with an id by id.
-  EXPECT_TRUE(engine.FindCodec(
-      cricket::AudioCodec(0, "", 8000, 0, 1, 0)));   // PCMU
-  EXPECT_TRUE(engine.FindCodec(
-      cricket::AudioCodec(8, "", 8000, 0, 1, 0)));   // PCMA
-  EXPECT_TRUE(engine.FindCodec(
-      cricket::AudioCodec(9, "", 16000, 0, 1, 0)));  // G722
-  EXPECT_TRUE(engine.FindCodec(
-      cricket::AudioCodec(13, "", 8000, 0, 1, 0)));  // CN
-  // Check sample/bitrate matching.
-  EXPECT_TRUE(engine.FindCodec(
-      cricket::AudioCodec(0, "PCMU", 8000, 64000, 1, 0)));
-  // Check that bad codecs fail.
-  EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(99, "ABCD", 0, 0, 1, 0)));
-  EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(88, "", 0, 0, 1, 0)));
-  EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 0, 0, 2, 0)));
-  EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 5000, 0, 1, 0)));
-  EXPECT_FALSE(engine.FindCodec(cricket::AudioCodec(0, "", 0, 5000, 1, 0)));
-  // Check that there aren't any extra codecs lying around.
-  EXPECT_EQ(13U, engine.codecs().size());
-  // Verify the payload id of common audio codecs, including CN, ISAC, and G722.
-  for (std::vector<cricket::AudioCodec>::const_iterator it =
-      engine.codecs().begin(); it != engine.codecs().end(); ++it) {
-    if (it->name == "CN" && it->clockrate == 16000) {
-      EXPECT_EQ(105, it->id);
-    } else if (it->name == "CN" && it->clockrate == 32000) {
-      EXPECT_EQ(106, it->id);
-    } else if (it->name == "ISAC" && it->clockrate == 16000) {
-      EXPECT_EQ(103, it->id);
-    } else if (it->name == "ISAC" && it->clockrate == 32000) {
-      EXPECT_EQ(104, it->id);
-    } else if (it->name == "G722" && it->clockrate == 16000) {
-      EXPECT_EQ(9, it->id);
-    } else if (it->name == "telephone-event") {
-      EXPECT_EQ(126, it->id);
-    } else if (it->name == "red") {
-      EXPECT_EQ(127, it->id);
-    }
-  }
-
-  engine.Terminate();
-}
-
-// Tests that VoE supports at least 32 channels
-TEST(WebRtcVoiceEngineTest, Has32Channels) {
-  cricket::WebRtcVoiceEngine engine;
-  EXPECT_TRUE(engine.Init());
-
-  cricket::VoiceMediaChannel* channels[32];
-  int num_channels = 0;
-
-  while (num_channels < ARRAY_SIZE(channels)) {
-    cricket::VoiceMediaChannel* channel = engine.CreateChannel();
-    if (!channel)
-      break;
-
-    channels[num_channels++] = channel;
-  }
-
-  int expected = ARRAY_SIZE(channels);
-  EXPECT_EQ(expected, num_channels);
-
-  while (num_channels > 0) {
-    delete channels[--num_channels];
-  }
-
-  engine.Terminate();
-}
-
-#ifdef WIN32
-// Test our workarounds to WebRtc VoE' munging of the coinit count
-TEST(WebRtcVoiceEngineTest, CoInitialize) {
-  cricket::WebRtcVoiceEngine* engine = new cricket::WebRtcVoiceEngine();
-
-  // Initial refcount should be 0.
-  EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_MULTITHREADED));
-
-  // Engine should start even with COM already inited.
-  EXPECT_TRUE(engine->Init());
-  engine->Terminate();
-  EXPECT_TRUE(engine->Init());
-  engine->Terminate();
-
-  // Refcount after terminate should be 1 (in reality 3); test if it is nonzero.
-  EXPECT_EQ(S_FALSE, CoInitializeEx(NULL, COINIT_MULTITHREADED));
-  // Decrement refcount to (hopefully) 0.
-  CoUninitialize();
-  CoUninitialize();
-  delete engine;
-
-  // Ensure refcount is 0.
-  EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_MULTITHREADED));
-  CoUninitialize();
-}
-#endif
diff --git a/third_party/libjingle/source/talk/session/phone/win32devicemanager.cc b/third_party/libjingle/source/talk/session/phone/win32devicemanager.cc
deleted file mode 100644
index f8a928e..0000000
--- a/third_party/libjingle/source/talk/session/phone/win32devicemanager.cc
+++ /dev/null
@@ -1,405 +0,0 @@
-/*
- * libjingle
- * Copyright 2004 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/session/phone/win32devicemanager.h"
-
-#include <atlbase.h>
-#include <dbt.h>
-#include <strmif.h>  // must come before ks.h
-#include <ks.h>
-#include <ksmedia.h>
-#define INITGUID  // For PKEY_AudioEndpoint_GUID
-#include <mmdeviceapi.h>
-#include <mmsystem.h>
-#include <functiondiscoverykeys_devpkey.h>
-#include <uuids.h>
-
-#include "talk/base/win32.h"  // ToUtf8
-#include "talk/base/win32window.h"
-#include "talk/base/logging.h"
-#include "talk/base/stringutils.h"
-#include "talk/base/thread.h"
-#include "talk/session/phone/mediacommon.h"
-#ifdef HAVE_LOGITECH_HEADERS
-#include "third_party/logitech/files/logitechquickcam.h"
-#endif
-
-namespace cricket {
-
-DeviceManagerInterface* DeviceManagerFactory::Create() {
-  return new Win32DeviceManager();
-}
-
-class Win32DeviceWatcher
-    : public DeviceWatcher,
-      public talk_base::Win32Window {
- public:
-  explicit Win32DeviceWatcher(Win32DeviceManager* dm);
-  virtual ~Win32DeviceWatcher();
-  virtual bool Start();
-  virtual void Stop();
-
- private:
-  HDEVNOTIFY Register(REFGUID guid);
-  void Unregister(HDEVNOTIFY notify);
-  virtual bool OnMessage(UINT msg, WPARAM wp, LPARAM lp, LRESULT& result);
-
-  Win32DeviceManager* manager_;
-  HDEVNOTIFY audio_notify_;
-  HDEVNOTIFY video_notify_;
-};
-
-static const char* kFilteredAudioDevicesName[] = {
-    NULL,
-};
-static const char* const kFilteredVideoDevicesName[] =  {
-    "Google Camera Adapter",   // Our own magiccams
-    "Asus virtual Camera",     // Bad Asus desktop virtual cam
-    "Bluetooth Video",         // Bad Sony viao bluetooth sharing driver
-    NULL,
-};
-static const wchar_t kFriendlyName[] = L"FriendlyName";
-static const wchar_t kDevicePath[] = L"DevicePath";
-static const char kUsbDevicePathPrefix[] = "\\\\?\\usb";
-static bool GetDevices(const CLSID& catid, std::vector<Device>* out);
-static bool GetCoreAudioDevices(bool input, std::vector<Device>* devs);
-static bool GetWaveDevices(bool input, std::vector<Device>* devs);
-
-Win32DeviceManager::Win32DeviceManager()
-    : need_couninitialize_(false) {
-  set_watcher(new Win32DeviceWatcher(this));
-}
-
-Win32DeviceManager::~Win32DeviceManager() {
-  if (initialized()) {
-    Terminate();
-  }
-}
-
-bool Win32DeviceManager::Init() {
-  if (!initialized()) {
-    HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
-    need_couninitialize_ = SUCCEEDED(hr);
-    if (FAILED(hr)) {
-      LOG(LS_ERROR) << "CoInitialize failed, hr=" << hr;
-      if (hr != RPC_E_CHANGED_MODE) {
-        return false;
-      }
-    }
-    if (!watcher()->Start()) {
-      return false;
-    }
-    set_initialized(true);
-  }
-  return true;
-}
-
-void Win32DeviceManager::Terminate() {
-  if (initialized()) {
-    watcher()->Stop();
-    if (need_couninitialize_) {
-      CoUninitialize();
-      need_couninitialize_ = false;
-    }
-    set_initialized(false);
-  }
-}
-
-bool Win32DeviceManager::GetDefaultVideoCaptureDevice(Device* device) {
-  bool ret = false;
-  // If there are multiple capture devices, we want the first USB one.
-  // This avoids issues with defaulting to virtual cameras or grabber cards.
-  std::vector<Device> devices;
-  ret = (GetVideoCaptureDevices(&devices) && !devices.empty());
-  if (ret) {
-    *device = devices[0];
-    for (size_t i = 0; i < devices.size(); ++i) {
-      if (strnicmp(devices[i].id.c_str(), kUsbDevicePathPrefix,
-                   ARRAY_SIZE(kUsbDevicePathPrefix) - 1) == 0) {
-        *device = devices[i];
-        break;
-      }
-    }
-  }
-  return ret;
-}
-
-bool Win32DeviceManager::GetAudioDevices(bool input,
-                                         std::vector<Device>* devs) {
-  devs->clear();
-
-  if (talk_base::IsWindowsVistaOrLater()) {
-    if (!GetCoreAudioDevices(input, devs))
-      return false;
-  } else {
-    if (!GetWaveDevices(input, devs))
-      return false;
-  }
-  return FilterDevices(devs, kFilteredAudioDevicesName);
-}
-
-bool Win32DeviceManager::GetVideoCaptureDevices(std::vector<Device>* devices) {
-  devices->clear();
-  if (!GetDevices(CLSID_VideoInputDeviceCategory, devices)) {
-    return false;
-  }
-  return FilterDevices(devices, kFilteredVideoDevicesName);
-}
-
-bool GetDevices(const CLSID& catid, std::vector<Device>* devices) {
-  HRESULT hr;
-
-  // CComPtr is a scoped pointer that will be auto released when going
-  // out of scope. CoUninitialize must not be called before the
-  // release.
-  CComPtr<ICreateDevEnum> sys_dev_enum;
-  CComPtr<IEnumMoniker> cam_enum;
-  if (FAILED(hr = sys_dev_enum.CoCreateInstance(CLSID_SystemDeviceEnum)) ||
-      FAILED(hr = sys_dev_enum->CreateClassEnumerator(catid, &cam_enum, 0))) {
-    LOG(LS_ERROR) << "Failed to create device enumerator, hr="  << hr;
-    return false;
-  }
-
-  // Only enum devices if CreateClassEnumerator returns S_OK. If there are no
-  // devices available, S_FALSE will be returned, but enumMk will be NULL.
-  if (hr == S_OK) {
-    CComPtr<IMoniker> mk;
-    while (cam_enum->Next(1, &mk, NULL) == S_OK) {
-#ifdef HAVE_LOGITECH_HEADERS
-      // Initialize Logitech device if applicable
-      MaybeLogitechDeviceReset(mk);
-#endif
-      CComPtr<IPropertyBag> bag;
-      if (SUCCEEDED(mk->BindToStorage(NULL, NULL,
-          __uuidof(bag), reinterpret_cast<void**>(&bag)))) {
-        CComVariant name, path;
-        std::string name_str, path_str;
-        if (SUCCEEDED(bag->Read(kFriendlyName, &name, 0)) &&
-            name.vt == VT_BSTR) {
-          name_str = talk_base::ToUtf8(name.bstrVal);
-          // Get the device id if one exists.
-          if (SUCCEEDED(bag->Read(kDevicePath, &path, 0)) &&
-              path.vt == VT_BSTR) {
-            path_str = talk_base::ToUtf8(path.bstrVal);
-          }
-
-          devices->push_back(Device(name_str, path_str));
-        }
-      }
-      mk = NULL;
-    }
-  }
-
-  return true;
-}
-
-HRESULT GetStringProp(IPropertyStore* bag, PROPERTYKEY key, std::string* out) {
-  out->clear();
-  PROPVARIANT var;
-  PropVariantInit(&var);
-
-  HRESULT hr = bag->GetValue(key, &var);
-  if (SUCCEEDED(hr)) {
-    if (var.pwszVal)
-      *out = talk_base::ToUtf8(var.pwszVal);
-    else
-      hr = E_FAIL;
-  }
-
-  PropVariantClear(&var);
-  return hr;
-}
-
-// Adapted from http://msdn.microsoft.com/en-us/library/dd370812(v=VS.85).aspx
-HRESULT CricketDeviceFromImmDevice(IMMDevice* device, Device* out) {
-  CComPtr<IPropertyStore> props;
-
-  HRESULT hr = device->OpenPropertyStore(STGM_READ, &props);
-  if (FAILED(hr)) {
-    return hr;
-  }
-
-  // Get the endpoint's name and id.
-  std::string name, guid;
-  hr = GetStringProp(props, PKEY_Device_FriendlyName, &name);
-  if (SUCCEEDED(hr)) {
-    hr = GetStringProp(props, PKEY_AudioEndpoint_GUID, &guid);
-
-    if (SUCCEEDED(hr)) {
-      out->name = name;
-      out->id = guid;
-    }
-  }
-  return hr;
-}
-
-bool GetCoreAudioDevices(
-    bool input, std::vector<Device>* devs) {
-  HRESULT hr = S_OK;
-  CComPtr<IMMDeviceEnumerator> enumerator;
-
-  hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL,
-      __uuidof(IMMDeviceEnumerator), reinterpret_cast<void**>(&enumerator));
-  if (SUCCEEDED(hr)) {
-    CComPtr<IMMDeviceCollection> devices;
-    hr = enumerator->EnumAudioEndpoints((input ? eCapture : eRender),
-                                        DEVICE_STATE_ACTIVE, &devices);
-    if (SUCCEEDED(hr)) {
-      unsigned int count;
-      hr = devices->GetCount(&count);
-
-      if (SUCCEEDED(hr)) {
-        for (unsigned int i = 0; i < count; i++) {
-          CComPtr<IMMDevice> device;
-
-          // Get pointer to endpoint number i.
-          hr = devices->Item(i, &device);
-          if (FAILED(hr)) {
-            break;
-          }
-
-          Device dev;
-          hr = CricketDeviceFromImmDevice(device, &dev);
-          if (SUCCEEDED(hr)) {
-            devs->push_back(dev);
-          } else {
-            LOG(LS_WARNING) << "Unable to query IMM Device, skipping.  HR="
-                            << hr;
-            hr = S_FALSE;
-          }
-        }
-      }
-    }
-  }
-
-  if (FAILED(hr)) {
-    LOG(LS_WARNING) << "GetCoreAudioDevices failed with hr " << hr;
-    return false;
-  }
-  return true;
-}
-
-bool GetWaveDevices(bool input, std::vector<Device>* devs) {
-  // Note, we don't use the System Device Enumerator interface here since it
-  // adds lots of pseudo-devices to the list, such as DirectSound and Wave
-  // variants of the same device.
-  if (input) {
-    int num_devs = waveInGetNumDevs();
-    for (int i = 0; i < num_devs; ++i) {
-      WAVEINCAPS caps;
-      if (waveInGetDevCaps(i, &caps, sizeof(caps)) == MMSYSERR_NOERROR &&
-          caps.wChannels > 0) {
-        devs->push_back(Device(talk_base::ToUtf8(caps.szPname),
-                               talk_base::ToString(i)));
-      }
-    }
-  } else {
-    int num_devs = waveOutGetNumDevs();
-    for (int i = 0; i < num_devs; ++i) {
-      WAVEOUTCAPS caps;
-      if (waveOutGetDevCaps(i, &caps, sizeof(caps)) == MMSYSERR_NOERROR &&
-          caps.wChannels > 0) {
-        devs->push_back(Device(talk_base::ToUtf8(caps.szPname), i));
-      }
-    }
-  }
-  return true;
-}
-
-Win32DeviceWatcher::Win32DeviceWatcher(Win32DeviceManager* manager)
-    : DeviceWatcher(manager),
-      manager_(manager),
-      audio_notify_(NULL),
-      video_notify_(NULL) {
-}
-
-Win32DeviceWatcher::~Win32DeviceWatcher() {
-}
-
-bool Win32DeviceWatcher::Start() {
-  if (!Create(NULL, _T("libjingle Win32DeviceWatcher Window"),
-              0, 0, 0, 0, 0, 0)) {
-    return false;
-  }
-
-  audio_notify_ = Register(KSCATEGORY_AUDIO);
-  if (!audio_notify_) {
-    Stop();
-    return false;
-  }
-
-  video_notify_ = Register(KSCATEGORY_VIDEO);
-  if (!video_notify_) {
-    Stop();
-    return false;
-  }
-
-  return true;
-}
-
-void Win32DeviceWatcher::Stop() {
-  UnregisterDeviceNotification(video_notify_);
-  video_notify_ = NULL;
-  UnregisterDeviceNotification(audio_notify_);
-  audio_notify_ = NULL;
-  Destroy();
-}
-
-HDEVNOTIFY Win32DeviceWatcher::Register(REFGUID guid) {
-  DEV_BROADCAST_DEVICEINTERFACE dbdi;
-  dbdi.dbcc_size = sizeof(dbdi);
-  dbdi.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
-  dbdi.dbcc_classguid = guid;
-  dbdi.dbcc_name[0] = '\0';
-  return RegisterDeviceNotification(handle(), &dbdi,
-                                    DEVICE_NOTIFY_WINDOW_HANDLE);
-}
-
-void Win32DeviceWatcher::Unregister(HDEVNOTIFY handle) {
-  UnregisterDeviceNotification(handle);
-}
-
-bool Win32DeviceWatcher::OnMessage(UINT uMsg, WPARAM wParam, LPARAM lParam,
-                              LRESULT& result) {
-  if (uMsg == WM_DEVICECHANGE) {
-    if (wParam == DBT_DEVICEARRIVAL ||
-        wParam == DBT_DEVICEREMOVECOMPLETE) {
-      DEV_BROADCAST_DEVICEINTERFACE* dbdi =
-          reinterpret_cast<DEV_BROADCAST_DEVICEINTERFACE*>(lParam);
-      if (dbdi->dbcc_classguid == KSCATEGORY_AUDIO ||
-        dbdi->dbcc_classguid == KSCATEGORY_VIDEO) {
-        manager_->SignalDevicesChange();
-      }
-    }
-    result = 0;
-    return true;
-  }
-
-  return false;
-}
-
-};  // namespace cricket
diff --git a/third_party/libjingle/source/talk/session/phone/win32devicemanager.h b/third_party/libjingle/source/talk/session/phone/win32devicemanager.h
deleted file mode 100644
index 98e73c1..0000000
--- a/third_party/libjingle/source/talk/session/phone/win32devicemanager.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * libjingle
- * Copyright 2004 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SESSION_PHONE_WIN32DEVICEMANAGER_H_
-#define TALK_SESSION_PHONE_WIN32DEVICEMANAGER_H_
-
-#include <string>
-#include <vector>
-
-#include "talk/base/sigslot.h"
-#include "talk/base/stringencode.h"
-#include "talk/session/phone/devicemanager.h"
-
-namespace cricket {
-
-class Win32DeviceManager : public DeviceManager {
- public:
-  Win32DeviceManager();
-  virtual ~Win32DeviceManager();
-
-  // Initialization
-  virtual bool Init();
-  virtual void Terminate();
-
-  virtual bool GetVideoCaptureDevices(std::vector<Device>* devs);
-
- private:
-  virtual bool GetAudioDevices(bool input, std::vector<Device>* devs);
-  virtual bool GetDefaultVideoCaptureDevice(Device* device);
-
-  bool need_couninitialize_;
-};
-
-}  // namespace cricket
-
-#endif  // TALK_SESSION_PHONE_WIN32DEVICEMANAGER_H_
diff --git a/third_party/libjingle/source/talk/session/tunnel/pseudotcpchannel.cc b/third_party/libjingle/source/talk/session/tunnel/pseudotcpchannel.cc
deleted file mode 100644
index c81db58..0000000
--- a/third_party/libjingle/source/talk/session/tunnel/pseudotcpchannel.cc
+++ /dev/null
@@ -1,592 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2006, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string>
-#include "talk/base/basictypes.h"
-#include "talk/base/common.h"
-#include "talk/base/logging.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/base/stringutils.h"
-#include "talk/p2p/base/candidate.h"
-#include "talk/p2p/base/transportchannel.h"
-#include "pseudotcpchannel.h"
-
-using namespace talk_base;
-
-namespace cricket {
-
-extern const talk_base::ConstantLabel SESSION_STATES[];
-
-// MSG_WK_* - worker thread messages
-// MSG_ST_* - stream thread messages
-// MSG_SI_* - signal thread messages
-
-enum {
-  MSG_WK_CLOCK = 1,
-  MSG_WK_PURGE,
-  MSG_ST_EVENT,
-  MSG_SI_DESTROYCHANNEL,
-  MSG_SI_DESTROY,
-};
-
-struct EventData : public MessageData {
-  int event, error;
-  EventData(int ev, int err = 0) : event(ev), error(err) { }
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// PseudoTcpChannel::InternalStream
-///////////////////////////////////////////////////////////////////////////////
-
-class PseudoTcpChannel::InternalStream : public StreamInterface {
-public:
-  InternalStream(PseudoTcpChannel* parent);
-  virtual ~InternalStream();
-
-  virtual StreamState GetState() const;
-  virtual StreamResult Read(void* buffer, size_t buffer_len,
-                                       size_t* read, int* error);
-  virtual StreamResult Write(const void* data, size_t data_len,
-                                        size_t* written, int* error);
-  virtual void Close();
-
-private:
-  // parent_ is accessed and modified exclusively on the event thread, to
-  // avoid thread contention.  This means that the PseudoTcpChannel cannot go
-  // away until after it receives a Close() from TunnelStream.
-  PseudoTcpChannel* parent_;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// PseudoTcpChannel
-// Member object lifetime summaries:
-//   session_ - passed in constructor, cleared when channel_ goes away.
-//   channel_ - created in Connect, destroyed when session_ or tcp_ goes away.
-//   tcp_ - created in Connect, destroyed when channel_ goes away, or connection
-//     closes.
-//   worker_thread_ - created when channel_ is created, purged when channel_ is
-//     destroyed.
-//   stream_ - created in GetStream, destroyed by owner at arbitrary time.
-//   this - created in constructor, destroyed when worker_thread_ and stream_
-//     are both gone.
-///////////////////////////////////////////////////////////////////////////////
-
-//
-// Signal thread methods
-//
-
-PseudoTcpChannel::PseudoTcpChannel(Thread* stream_thread, Session* session)
-  : signal_thread_(session->session_manager()->signaling_thread()),
-    worker_thread_(NULL),
-    stream_thread_(stream_thread),
-    session_(session), channel_(NULL), tcp_(NULL), stream_(NULL),
-    stream_readable_(false), pending_read_event_(false),
-    ready_to_connect_(false) {
-  ASSERT(signal_thread_->IsCurrent());
-  ASSERT(NULL != session_);
-}
-
-PseudoTcpChannel::~PseudoTcpChannel() {
-  ASSERT(signal_thread_->IsCurrent());
-  ASSERT(worker_thread_ == NULL);
-  ASSERT(session_ == NULL);
-  ASSERT(channel_ == NULL);
-  ASSERT(stream_ == NULL);
-  ASSERT(tcp_ == NULL);
-}
-
-bool PseudoTcpChannel::Connect(const std::string& content_name,
-                               const std::string& channel_name) {
-  ASSERT(signal_thread_->IsCurrent());
-  CritScope lock(&cs_);
-
-  if (channel_)
-    return false;
-
-  ASSERT(session_ != NULL);
-  worker_thread_ = session_->session_manager()->worker_thread();
-  content_name_ = content_name;
-  channel_ = session_->CreateChannel(content_name, channel_name);
-  channel_name_ = channel_name;
-  channel_->SetOption(Socket::OPT_DONTFRAGMENT, 1);
-
-  channel_->SignalDestroyed.connect(this,
-    &PseudoTcpChannel::OnChannelDestroyed);
-  channel_->SignalWritableState.connect(this,
-    &PseudoTcpChannel::OnChannelWritableState);
-  channel_->SignalReadPacket.connect(this,
-    &PseudoTcpChannel::OnChannelRead);
-  channel_->SignalRouteChange.connect(this,
-    &PseudoTcpChannel::OnChannelConnectionChanged);
-
-  ASSERT(tcp_ == NULL);
-  tcp_ = new PseudoTcp(this, 0);
-  if (session_->initiator()) {
-    // Since we may try several protocols and network adapters that won't work,
-    // waiting until we get our first writable notification before initiating
-    // TCP negotiation.
-    ready_to_connect_ = true;
-  }
-
-  return true;
-}
-
-StreamInterface* PseudoTcpChannel::GetStream() {
-  ASSERT(signal_thread_->IsCurrent());
-  CritScope lock(&cs_);
-  ASSERT(NULL != session_);
-  if (!stream_)
-    stream_ = new PseudoTcpChannel::InternalStream(this);
-  //TODO("should we disallow creation of new stream at some point?");
-  return stream_;
-}
-
-void PseudoTcpChannel::OnChannelDestroyed(TransportChannel* channel) {
-  LOG_F(LS_INFO) << "(" << channel->name() << ")";
-  ASSERT(signal_thread_->IsCurrent());
-  CritScope lock(&cs_);
-  ASSERT(channel == channel_);
-  signal_thread_->Clear(this, MSG_SI_DESTROYCHANNEL);
-  // When MSG_WK_PURGE is received, we know there will be no more messages from
-  // the worker thread.
-  worker_thread_->Clear(this, MSG_WK_CLOCK);
-  worker_thread_->Post(this, MSG_WK_PURGE);
-  session_ = NULL;
-  channel_ = NULL;
-  if ((stream_ != NULL)
-      && ((tcp_ == NULL) || (tcp_->State() != PseudoTcp::TCP_CLOSED)))
-    stream_thread_->Post(this, MSG_ST_EVENT, new EventData(SE_CLOSE, 0));
-  if (tcp_) {
-    tcp_->Close(true);
-    AdjustClock();
-  }
-  SignalChannelClosed(this);
-}
-
-void PseudoTcpChannel::OnSessionTerminate(Session* session) {
-  // When the session terminates before we even connected
-  CritScope lock(&cs_);
-  if (session_ != NULL && channel_ == NULL) {
-    ASSERT(session == session_);
-    ASSERT(worker_thread_ == NULL);
-    ASSERT(tcp_ == NULL);
-    LOG(LS_INFO) << "Destroying unconnected PseudoTcpChannel";
-    session_ = NULL;
-    if (stream_ != NULL)
-      stream_thread_->Post(this, MSG_ST_EVENT, new EventData(SE_CLOSE, -1));
-  }
-
-  // Even though session_ is being destroyed, we mustn't clear the pointer,
-  // since we'll need it to tear down channel_.
-  //
-  // TODO: Is it always the case that if channel_ != NULL then we'll get
-  // a channel-destroyed notification?
-}
-
-void PseudoTcpChannel::GetOption(PseudoTcp::Option opt, int* value) {
-  ASSERT(signal_thread_->IsCurrent());
-  CritScope lock(&cs_);
-  ASSERT(tcp_ != NULL);
-  tcp_->GetOption(opt, value);
-}
-
-void PseudoTcpChannel::SetOption(PseudoTcp::Option opt, int value) {
-  ASSERT(signal_thread_->IsCurrent());
-  CritScope lock(&cs_);
-  ASSERT(tcp_ != NULL);
-  tcp_->SetOption(opt, value);
-}
-
-//
-// Stream thread methods
-//
-
-StreamState PseudoTcpChannel::GetState() const {
-  ASSERT(stream_ != NULL && stream_thread_->IsCurrent());
-  CritScope lock(&cs_);
-  if (!session_)
-    return SS_CLOSED;
-  if (!tcp_)
-    return SS_OPENING;
-  switch (tcp_->State()) {
-    case PseudoTcp::TCP_LISTEN:
-    case PseudoTcp::TCP_SYN_SENT:
-    case PseudoTcp::TCP_SYN_RECEIVED:
-      return SS_OPENING;
-    case PseudoTcp::TCP_ESTABLISHED:
-      return SS_OPEN;
-    case PseudoTcp::TCP_CLOSED:
-    default:
-      return SS_CLOSED;
-  }
-}
-
-StreamResult PseudoTcpChannel::Read(void* buffer, size_t buffer_len,
-                                    size_t* read, int* error) {
-  ASSERT(stream_ != NULL && stream_thread_->IsCurrent());
-  CritScope lock(&cs_);
-  if (!tcp_)
-    return SR_BLOCK;
-
-  stream_readable_ = false;
-  int result = tcp_->Recv(static_cast<char*>(buffer), buffer_len);
-  //LOG_F(LS_VERBOSE) << "Recv returned: " << result;
-  if (result > 0) {
-    if (read)
-      *read = result;
-    // PseudoTcp doesn't currently support repeated Readable signals.  Simulate
-    // them here.
-    stream_readable_ = true;
-    if (!pending_read_event_) {
-      pending_read_event_ = true;
-      stream_thread_->Post(this, MSG_ST_EVENT, new EventData(SE_READ), true);
-    }
-    return SR_SUCCESS;
-  } else if (IsBlockingError(tcp_->GetError())) {
-    return SR_BLOCK;
-  } else {
-    if (error)
-      *error = tcp_->GetError();
-    return SR_ERROR;
-  }
-  // This spot is never reached.
-}
-
-StreamResult PseudoTcpChannel::Write(const void* data, size_t data_len,
-                                     size_t* written, int* error) {
-  ASSERT(stream_ != NULL && stream_thread_->IsCurrent());
-  CritScope lock(&cs_);
-  if (!tcp_)
-    return SR_BLOCK;
-  int result = tcp_->Send(static_cast<const char*>(data), data_len);
-  //LOG_F(LS_VERBOSE) << "Send returned: " << result;
-  if (result > 0) {
-    if (written)
-      *written = result;
-    return SR_SUCCESS;
-  } else if (IsBlockingError(tcp_->GetError())) {
-    return SR_BLOCK;
-  } else {
-    if (error)
-      *error = tcp_->GetError();
-    return SR_ERROR;
-  }
-  // This spot is never reached.
-}
-
-void PseudoTcpChannel::Close() {
-  ASSERT(stream_ != NULL && stream_thread_->IsCurrent());
-  CritScope lock(&cs_);
-  stream_ = NULL;
-  // Clear out any pending event notifications
-  stream_thread_->Clear(this, MSG_ST_EVENT);
-  if (tcp_) {
-    tcp_->Close(false);
-    AdjustClock();
-  } else {
-    CheckDestroy();
-  }
-}
-
-//
-// Worker thread methods
-//
-
-void PseudoTcpChannel::OnChannelWritableState(TransportChannel* channel) {
-  LOG_F(LS_VERBOSE) << "[" << channel_name_ << "]";
-  ASSERT(worker_thread_->IsCurrent());
-  CritScope lock(&cs_);
-  if (!channel_) {
-    LOG_F(LS_WARNING) << "NULL channel";
-    return;
-  }
-  ASSERT(channel == channel_);
-  if (!tcp_) {
-    LOG_F(LS_WARNING) << "NULL tcp";
-    return;
-  }
-  if (!ready_to_connect_ || !channel->writable())
-    return;
-
-  ready_to_connect_ = false;
-  tcp_->Connect();
-  AdjustClock();
-}
-
-void PseudoTcpChannel::OnChannelRead(TransportChannel* channel,
-                                     const char* data, size_t size) {
-  //LOG_F(LS_VERBOSE) << "(" << size << ")";
-  ASSERT(worker_thread_->IsCurrent());
-  CritScope lock(&cs_);
-  if (!channel_) {
-    LOG_F(LS_WARNING) << "NULL channel";
-    return;
-  }
-  ASSERT(channel == channel_);
-  if (!tcp_) {
-    LOG_F(LS_WARNING) << "NULL tcp";
-    return;
-  }
-  tcp_->NotifyPacket(data, size);
-  AdjustClock();
-}
-
-void PseudoTcpChannel::OnChannelConnectionChanged(TransportChannel* channel,
-                                                  const Candidate& candidate) {
-  LOG_F(LS_VERBOSE) << "[" << channel_name_ << "]";
-  ASSERT(worker_thread_->IsCurrent());
-  CritScope lock(&cs_);
-  if (!channel_) {
-    LOG_F(LS_WARNING) << "NULL channel";
-    return;
-  }
-  ASSERT(channel == channel_);
-  if (!tcp_) {
-    LOG_F(LS_WARNING) << "NULL tcp";
-    return;
-  }
-
-  uint16 mtu = 1280;  // safe default
-  talk_base::scoped_ptr<Socket> mtu_socket(
-      worker_thread_->socketserver()->CreateSocket(SOCK_DGRAM));
-  if (mtu_socket->Connect(candidate.address()) < 0 ||
-      mtu_socket->EstimateMTU(&mtu) < 0) {
-    LOG_F(LS_WARNING) << "Failed to estimate MTU, error="
-                      << mtu_socket->GetError();
-  }
-
-  LOG_F(LS_VERBOSE) << "Using MTU of " << mtu << " bytes";
-  tcp_->NotifyMTU(mtu);
-  AdjustClock();
-}
-
-void PseudoTcpChannel::OnTcpOpen(PseudoTcp* tcp) {
-  LOG_F(LS_VERBOSE) << "[" << channel_name_ << "]";
-  ASSERT(cs_.CurrentThreadIsOwner());
-  ASSERT(worker_thread_->IsCurrent());
-  ASSERT(tcp == tcp_);
-  if (stream_) {
-    stream_readable_ = true;
-    pending_read_event_ = true;
-    stream_thread_->Post(this, MSG_ST_EVENT,
-                         new EventData(SE_OPEN | SE_READ | SE_WRITE));
-  }
-}
-
-void PseudoTcpChannel::OnTcpReadable(PseudoTcp* tcp) {
-  //LOG_F(LS_VERBOSE);
-  ASSERT(cs_.CurrentThreadIsOwner());
-  ASSERT(worker_thread_->IsCurrent());
-  ASSERT(tcp == tcp_);
-  if (stream_) {
-    stream_readable_ = true;
-    if (!pending_read_event_) {
-      pending_read_event_ = true;
-      stream_thread_->Post(this, MSG_ST_EVENT, new EventData(SE_READ));
-    }
-  }
-}
-
-void PseudoTcpChannel::OnTcpWriteable(PseudoTcp* tcp) {
-  //LOG_F(LS_VERBOSE);
-  ASSERT(cs_.CurrentThreadIsOwner());
-  ASSERT(worker_thread_->IsCurrent());
-  ASSERT(tcp == tcp_);
-  if (stream_)
-    stream_thread_->Post(this, MSG_ST_EVENT, new EventData(SE_WRITE));
-}
-
-void PseudoTcpChannel::OnTcpClosed(PseudoTcp* tcp, uint32 nError) {
-  LOG_F(LS_VERBOSE) << "[" << channel_name_ << "]";
-  ASSERT(cs_.CurrentThreadIsOwner());
-  ASSERT(worker_thread_->IsCurrent());
-  ASSERT(tcp == tcp_);
-  if (stream_)
-    stream_thread_->Post(this, MSG_ST_EVENT, new EventData(SE_CLOSE, nError));
-}
-
-//
-// Multi-thread methods
-//
-
-void PseudoTcpChannel::OnMessage(Message* pmsg) {
-  if (pmsg->message_id == MSG_WK_CLOCK) {
-
-    ASSERT(worker_thread_->IsCurrent());
-    //LOG(LS_INFO) << "PseudoTcpChannel::OnMessage(MSG_WK_CLOCK)";
-    CritScope lock(&cs_);
-    if (tcp_) {
-      tcp_->NotifyClock(PseudoTcp::Now());
-      AdjustClock(false);
-    }
-
-  } else if (pmsg->message_id == MSG_WK_PURGE) {
-
-    ASSERT(worker_thread_->IsCurrent());
-    LOG_F(LS_INFO) << "(MSG_WK_PURGE)";
-    // At this point, we know there are no additional worker thread messages.
-    CritScope lock(&cs_);
-    ASSERT(NULL == session_);
-    ASSERT(NULL == channel_);
-    worker_thread_ = NULL;
-    CheckDestroy();
-
-  } else if (pmsg->message_id == MSG_ST_EVENT) {
-
-    ASSERT(stream_thread_->IsCurrent());
-    //LOG(LS_INFO) << "PseudoTcpChannel::OnMessage(MSG_ST_EVENT, "
-    //             << data->event << ", " << data->error << ")";
-    ASSERT(stream_ != NULL);
-    EventData* data = static_cast<EventData*>(pmsg->pdata);
-    if (data->event & SE_READ) {
-      CritScope lock(&cs_);
-      pending_read_event_ = false;
-    }
-    stream_->SignalEvent(stream_, data->event, data->error);
-    delete data;
-
-  } else if (pmsg->message_id == MSG_SI_DESTROYCHANNEL) {
-
-    ASSERT(signal_thread_->IsCurrent());
-    LOG_F(LS_INFO) << "(MSG_SI_DESTROYCHANNEL)";
-    ASSERT(session_ != NULL);
-    ASSERT(channel_ != NULL);
-    session_->DestroyChannel(content_name_, channel_->name());
-
-  } else if (pmsg->message_id == MSG_SI_DESTROY) {
-
-    ASSERT(signal_thread_->IsCurrent());
-    LOG_F(LS_INFO) << "(MSG_SI_DESTROY)";
-    // The message queue is empty, so it is safe to destroy ourselves.
-    delete this;
-
-  } else {
-    ASSERT(false);
-  }
-}
-
-IPseudoTcpNotify::WriteResult PseudoTcpChannel::TcpWritePacket(
-    PseudoTcp* tcp, const char* buffer, size_t len) {
-  ASSERT(cs_.CurrentThreadIsOwner());
-  ASSERT(tcp == tcp_);
-  ASSERT(NULL != channel_);
-  int sent = channel_->SendPacket(buffer, len);
-  if (sent > 0) {
-    //LOG_F(LS_VERBOSE) << "(" << sent << ") Sent";
-    return IPseudoTcpNotify::WR_SUCCESS;
-  } else if (IsBlockingError(channel_->GetError())) {
-    LOG_F(LS_VERBOSE) << "Blocking";
-    return IPseudoTcpNotify::WR_SUCCESS;
-  } else if (channel_->GetError() == EMSGSIZE) {
-    LOG_F(LS_ERROR) << "EMSGSIZE";
-    return IPseudoTcpNotify::WR_TOO_LARGE;
-  } else {
-    PLOG(LS_ERROR, channel_->GetError()) << "PseudoTcpChannel::TcpWritePacket";
-    ASSERT(false);
-    return IPseudoTcpNotify::WR_FAIL;
-  }
-}
-
-void PseudoTcpChannel::AdjustClock(bool clear) {
-  ASSERT(cs_.CurrentThreadIsOwner());
-  ASSERT(NULL != tcp_);
-
-  long timeout = 0;
-  if (tcp_->GetNextClock(PseudoTcp::Now(), timeout)) {
-    ASSERT(NULL != channel_);
-    // Reset the next clock, by clearing the old and setting a new one.
-    if (clear)
-      worker_thread_->Clear(this, MSG_WK_CLOCK);
-    worker_thread_->PostDelayed(_max(timeout, 0L), this, MSG_WK_CLOCK);
-    return;
-  }
-
-  delete tcp_;
-  tcp_ = NULL;
-  ready_to_connect_ = false;
-
-  if (channel_) {
-    // If TCP has failed, no need for channel_ anymore
-    signal_thread_->Post(this, MSG_SI_DESTROYCHANNEL);
-  }
-}
-
-void PseudoTcpChannel::CheckDestroy() {
-  ASSERT(cs_.CurrentThreadIsOwner());
-  if ((worker_thread_ != NULL) || (stream_ != NULL))
-    return;
-  signal_thread_->Post(this, MSG_SI_DESTROY);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// PseudoTcpChannel::InternalStream
-///////////////////////////////////////////////////////////////////////////////
-
-PseudoTcpChannel::InternalStream::InternalStream(PseudoTcpChannel* parent)
-  : parent_(parent) {
-}
-
-PseudoTcpChannel::InternalStream::~InternalStream() {
-  Close();
-}
-
-StreamState PseudoTcpChannel::InternalStream::GetState() const {
-  if (!parent_)
-    return SS_CLOSED;
-  return parent_->GetState();
-}
-
-StreamResult PseudoTcpChannel::InternalStream::Read(
-    void* buffer, size_t buffer_len, size_t* read, int* error) {
-  if (!parent_) {
-    if (error)
-      *error = ENOTCONN;
-    return SR_ERROR;
-  }
-  return parent_->Read(buffer, buffer_len, read, error);
-}
-
-StreamResult PseudoTcpChannel::InternalStream::Write(
-    const void* data, size_t data_len,  size_t* written, int* error) {
-  if (!parent_) {
-    if (error)
-      *error = ENOTCONN;
-    return SR_ERROR;
-  }
-  return parent_->Write(data, data_len, written, error);
-}
-
-void PseudoTcpChannel::InternalStream::Close() {
-  if (!parent_)
-    return;
-  parent_->Close();
-  parent_ = NULL;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-} // namespace cricket
diff --git a/third_party/libjingle/source/talk/session/tunnel/pseudotcpchannel.h b/third_party/libjingle/source/talk/session/tunnel/pseudotcpchannel.h
deleted file mode 100644
index d18ed45..0000000
--- a/third_party/libjingle/source/talk/session/tunnel/pseudotcpchannel.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2006, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __PSEUDOTCPCHANNEL_H__
-#define __PSEUDOTCPCHANNEL_H__
-
-#include "talk/base/criticalsection.h"
-#include "talk/base/messagequeue.h"
-#include "talk/base/stream.h"
-#include "talk/p2p/base/pseudotcp.h"
-#include "talk/p2p/base/session.h"
-
-namespace talk_base {
-class Thread;
-}
-
-namespace cricket {
-
-class Candidate;
-class TransportChannel;
-
-///////////////////////////////////////////////////////////////////////////////
-// PseudoTcpChannel
-// Note: The PseudoTcpChannel must persist until both of:
-// 1) The StreamInterface provided via GetStream has been closed.
-//    This is tracked via non-null stream_.
-// 2) The PseudoTcp session has completed.
-//    This is tracked via non-null worker_thread_.  When PseudoTcp is done,
-//    the TransportChannel is signalled to tear-down.  Once the channel is
-//    torn down, the worker thread is purged.
-// These indicators are checked by CheckDestroy, invoked whenever one of them
-// changes.
-///////////////////////////////////////////////////////////////////////////////
-// PseudoTcpChannel::GetStream
-// Note: The stream pointer returned by GetStream is owned by the caller.
-// They can close & immediately delete the stream while PseudoTcpChannel still
-// has cleanup work to do.  They can also close the stream but not delete it
-// until long after PseudoTcpChannel has finished.  We must cope with both.
-///////////////////////////////////////////////////////////////////////////////
-
-class PseudoTcpChannel
-  : public IPseudoTcpNotify,
-    public talk_base::MessageHandler,
-    public sigslot::has_slots<> {
-public:
-  // Signal thread methods
-  PseudoTcpChannel(talk_base::Thread* stream_thread,
-                   Session* session);
-
-  bool Connect(const std::string& content_name,
-               const std::string& channel_name);
-  talk_base::StreamInterface* GetStream();
-
-  sigslot::signal1<PseudoTcpChannel*> SignalChannelClosed;
-
-  // Call this when the Session used to create this channel is being torn
-  // down, to ensure that things get cleaned up properly.
-  void OnSessionTerminate(Session* session);
-
-  // See the PseudoTcp class for available options.
-  void GetOption(PseudoTcp::Option opt, int* value);
-  void SetOption(PseudoTcp::Option opt, int value);
-
-private:
-  class InternalStream;
-  friend class InternalStream;
-
-  virtual ~PseudoTcpChannel();
-
-  // Stream thread methods
-  talk_base::StreamState GetState() const;
-  talk_base::StreamResult Read(void* buffer, size_t buffer_len,
-                               size_t* read, int* error);
-  talk_base::StreamResult Write(const void* data, size_t data_len,
-                                size_t* written, int* error);
-  void Close();
-
-  // Multi-thread methods
-  void OnMessage(talk_base::Message* pmsg);
-  void AdjustClock(bool clear = true);
-  void CheckDestroy();
-
-  // Signal thread methods
-  void OnChannelDestroyed(TransportChannel* channel);
-
-  // Worker thread methods
-  void OnChannelWritableState(TransportChannel* channel);
-  void OnChannelRead(TransportChannel* channel, const char* data, size_t size);
-  void OnChannelConnectionChanged(TransportChannel* channel,
-                                  const Candidate& candidate);
-
-  virtual void OnTcpOpen(PseudoTcp* ptcp);
-  virtual void OnTcpReadable(PseudoTcp* ptcp);
-  virtual void OnTcpWriteable(PseudoTcp* ptcp);
-  virtual void OnTcpClosed(PseudoTcp* ptcp, uint32 nError);
-  virtual IPseudoTcpNotify::WriteResult TcpWritePacket(PseudoTcp* tcp,
-                                                       const char* buffer,
-                                                       size_t len);
-
-  talk_base::Thread* signal_thread_, * worker_thread_, * stream_thread_;
-  Session* session_;
-  TransportChannel* channel_;
-  std::string content_name_;
-  std::string channel_name_;
-  PseudoTcp* tcp_;
-  InternalStream* stream_;
-  bool stream_readable_, pending_read_event_;
-  bool ready_to_connect_;
-  mutable talk_base::CriticalSection cs_;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-
-} // namespace cricket
-
-#endif // __PSEUDOTCPCHANNEL_H__
diff --git a/third_party/libjingle/source/talk/session/tunnel/securetunnelsessionclient.cc b/third_party/libjingle/source/talk/session/tunnel/securetunnelsessionclient.cc
deleted file mode 100644
index 71f38aa..0000000
--- a/third_party/libjingle/source/talk/session/tunnel/securetunnelsessionclient.cc
+++ /dev/null
@@ -1,383 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2008, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// SecureTunnelSessionClient and SecureTunnelSession implementation.
-
-#include "talk/session/tunnel/securetunnelsessionclient.h"
-#include "talk/base/basicdefs.h"
-#include "talk/base/basictypes.h"
-#include "talk/base/common.h"
-#include "talk/base/helpers.h"
-#include "talk/base/logging.h"
-#include "talk/base/stringutils.h"
-#include "talk/base/sslidentity.h"
-#include "talk/base/sslstreamadapter.h"
-#include "talk/p2p/base/transportchannel.h"
-#include "talk/xmllite/xmlelement.h"
-#include "talk/session/tunnel/pseudotcpchannel.h"
-
-namespace cricket {
-
-// XML elements and namespaces for XMPP stanzas used in content exchanges.
-
-const char NS_SECURE_TUNNEL[] = "http://www.google.com/talk/securetunnel";
-const buzz::StaticQName QN_SECURE_TUNNEL_DESCRIPTION =
-    { NS_SECURE_TUNNEL, "description" };
-const buzz::StaticQName QN_SECURE_TUNNEL_TYPE =
-    { NS_SECURE_TUNNEL, "type" };
-const buzz::StaticQName QN_SECURE_TUNNEL_CLIENT_CERT =
-    { NS_SECURE_TUNNEL, "client-cert" };
-const buzz::StaticQName QN_SECURE_TUNNEL_SERVER_CERT =
-    { NS_SECURE_TUNNEL, "server-cert" };
-const char CN_SECURE_TUNNEL[] = "securetunnel";
-
-// SecureTunnelContentDescription
-
-// TunnelContentDescription is extended to hold string forms of the
-// client and server certificate, PEM encoded.
-
-struct SecureTunnelContentDescription : public ContentDescription {
-  std::string description;
-  std::string client_pem_certificate;
-  std::string server_pem_certificate;
-
-  SecureTunnelContentDescription(const std::string& desc,
-                                 const std::string& client_pem_cert,
-                                 const std::string& server_pem_cert)
-      : description(desc),
-        client_pem_certificate(client_pem_cert),
-        server_pem_certificate(server_pem_cert) {
-  }
-};
-
-// SecureTunnelSessionClient
-
-SecureTunnelSessionClient::SecureTunnelSessionClient(
-    const buzz::Jid& jid, SessionManager* manager)
-    : TunnelSessionClient(jid, manager, NS_SECURE_TUNNEL) {
-}
-
-void SecureTunnelSessionClient::SetIdentity(talk_base::SSLIdentity* identity) {
-  ASSERT(identity_.get() == NULL);
-  identity_.reset(identity);
-}
-
-bool SecureTunnelSessionClient::GenerateIdentity() {
-  ASSERT(identity_.get() == NULL);
-  identity_.reset(talk_base::SSLIdentity::Generate(
-      // The name on the certificate does not matter: the peer will
-      // make sure the cert it gets during SSL negotiation matches the
-      // one it got from XMPP. It would be neat to put something
-      // recognizable in there such as the JID, except this will show
-      // in clear during the SSL negotiation and so it could be a
-      // privacy issue. Specifying an empty string here causes
-      // it to use a random string.
-#ifdef _DEBUG
-      jid().Str()
-#else
-      ""
-#endif
-      ));
-  if (identity_.get() == NULL) {
-    LOG(LS_ERROR) << "Failed to generate SSL identity";
-    return false;
-  }
-  return true;
-}
-
-talk_base::SSLIdentity& SecureTunnelSessionClient::GetIdentity() const {
-  ASSERT(identity_.get() != NULL);
-  return *identity_;
-}
-
-// Parses a certificate from a PEM encoded string.
-// Returns NULL on failure.
-// The caller is responsible for freeing the returned object.
-static talk_base::SSLCertificate* ParseCertificate(
-    const std::string& pem_cert) {
-  if (pem_cert.empty())
-    return NULL;
-  return talk_base::SSLCertificate::FromPEMString(pem_cert, NULL);
-}
-
-TunnelSession* SecureTunnelSessionClient::MakeTunnelSession(
-    Session* session, talk_base::Thread* stream_thread,
-    TunnelSessionRole role) {
-  return new SecureTunnelSession(this, session, stream_thread, role);
-}
-
-bool FindSecureTunnelContent(const cricket::SessionDescription* sdesc,
-                             std::string* name,
-                             const SecureTunnelContentDescription** content) {
-  const ContentInfo* cinfo = sdesc->FirstContentByType(NS_SECURE_TUNNEL);
-  if (cinfo == NULL)
-    return false;
-
-  *name = cinfo->name;
-  *content = static_cast<const SecureTunnelContentDescription*>(
-      cinfo->description);
-  return true;
-}
-
-void SecureTunnelSessionClient::OnIncomingTunnel(const buzz::Jid &jid,
-                                                 Session *session) {
-  std::string content_name;
-  const SecureTunnelContentDescription* content = NULL;
-  if (!FindSecureTunnelContent(session->remote_description(),
-                               &content_name, &content)) {
-    ASSERT(false);
-  }
-
-  // Validate the certificate
-  talk_base::scoped_ptr<talk_base::SSLCertificate> peer_cert(
-      ParseCertificate(content->client_pem_certificate));
-  if (peer_cert.get() == NULL) {
-    LOG(LS_ERROR)
-        << "Rejecting incoming secure tunnel with invalid cetificate";
-    DeclineTunnel(session);
-    return;
-  }
-  // If there were a convenient place we could have cached the
-  // peer_cert so as not to have to parse it a second time when
-  // configuring the tunnel.
-  SignalIncomingTunnel(this, jid, content->description, session);
-}
-
-// The XML representation of a session initiation request (XMPP IQ),
-// containing the initiator's SecureTunnelContentDescription,
-// looks something like this:
-// <iq from="INITIATOR@gmail.com/pcpE101B7F4"
-//       to="RECIPIENT@gmail.com/pcp8B87F0A3"
-//       type="set" id="3">
-//   <session xmlns="http://www.google.com/session"
-//       type="initiate" id="2508605813"
-//       initiator="INITIATOR@gmail.com/pcpE101B7F4">
-//     <description xmlns="http://www.google.com/talk/securetunnel">
-//       <type>send:filename</type>
-//       <client-cert>
-//         -----BEGIN CERTIFICATE-----
-//         INITIATOR'S CERTIFICATE IN PERM FORMAT (ASCII GIBBERISH)
-//         -----END CERTIFICATE-----
-//       </client-cert>
-//     </description>
-//     <transport xmlns="http://www.google.com/transport/p2p"/>
-//   </session>
-// </iq>
-
-// The session accept iq, containing the recipient's certificate and
-// echoing the initiator's certificate, looks something like this:
-// <iq from="RECIPIENT@gmail.com/pcpE101B7F4"
-//     to="INITIATOR@gmail.com/pcpE101B7F4"
-//     type="set" id="5">
-//   <session xmlns="http://www.google.com/session"
-//       type="accept" id="2508605813"
-//       initiator="sdoyon911@gmail.com/pcpE101B7F4">
-//     <description xmlns="http://www.google.com/talk/securetunnel">
-//       <type>send:FILENAME</type>
-//       <client-cert>
-//         -----BEGIN CERTIFICATE-----
-//         INITIATOR'S CERTIFICATE IN PERM FORMAT (ASCII GIBBERISH)
-//         -----END CERTIFICATE-----
-//       </client-cert>
-//       <server-cert>
-//         -----BEGIN CERTIFICATE-----
-//         RECIPIENT'S CERTIFICATE IN PERM FORMAT (ASCII GIBBERISH)
-//         -----END CERTIFICATE-----
-//       </server-cert>
-//     </description>
-//   </session>
-// </iq>
-
-
-bool SecureTunnelSessionClient::ParseContent(SignalingProtocol protocol,
-                                             const buzz::XmlElement* elem,
-                                             const ContentDescription** content,
-                                             ParseError* error) {
-  const buzz::XmlElement* type_elem = elem->FirstNamed(QN_SECURE_TUNNEL_TYPE);
-
-  if (type_elem == NULL)
-    // Missing mandatory XML element.
-    return false;
-
-  // Here we consider the certificate components to be optional. In
-  // practice the client certificate is always present, and the server
-  // certificate is initially missing from the session description
-  // sent during session initiation. OnAccept() will enforce that we
-  // have a certificate for our peer.
-  const buzz::XmlElement* client_cert_elem =
-      elem->FirstNamed(QN_SECURE_TUNNEL_CLIENT_CERT);
-  const buzz::XmlElement* server_cert_elem =
-      elem->FirstNamed(QN_SECURE_TUNNEL_SERVER_CERT);
-  *content = new SecureTunnelContentDescription(
-      type_elem->BodyText(),
-      client_cert_elem ? client_cert_elem->BodyText() : "",
-      server_cert_elem ? server_cert_elem->BodyText() : "");
-  return true;
-}
-
-bool SecureTunnelSessionClient::WriteContent(
-    SignalingProtocol protocol, const ContentDescription* untyped_content,
-    buzz::XmlElement** elem, WriteError* error) {
-  const SecureTunnelContentDescription* content =
-      static_cast<const SecureTunnelContentDescription*>(untyped_content);
-
-  buzz::XmlElement* root =
-      new buzz::XmlElement(QN_SECURE_TUNNEL_DESCRIPTION, true);
-  buzz::XmlElement* type_elem = new buzz::XmlElement(QN_SECURE_TUNNEL_TYPE);
-  type_elem->SetBodyText(content->description);
-  root->AddElement(type_elem);
-  if (!content->client_pem_certificate.empty()) {
-    buzz::XmlElement* client_cert_elem =
-        new buzz::XmlElement(QN_SECURE_TUNNEL_CLIENT_CERT);
-    client_cert_elem->SetBodyText(content->client_pem_certificate);
-    root->AddElement(client_cert_elem);
-  }
-  if (!content->server_pem_certificate.empty()) {
-    buzz::XmlElement* server_cert_elem =
-        new buzz::XmlElement(QN_SECURE_TUNNEL_SERVER_CERT);
-    server_cert_elem->SetBodyText(content->server_pem_certificate);
-    root->AddElement(server_cert_elem);
-  }
-  *elem = root;
-  return true;
-}
-
-SessionDescription* NewSecureTunnelSessionDescription(
-    const std::string& content_name, const ContentDescription* content) {
-  SessionDescription* sdesc = new SessionDescription();
-  sdesc->AddContent(content_name, NS_SECURE_TUNNEL, content);
-  return sdesc;
-}
-
-SessionDescription* SecureTunnelSessionClient::CreateOffer(
-    const buzz::Jid &jid, const std::string &description) {
-  // We are the initiator so we are the client. Put our cert into the
-  // description.
-  std::string pem_cert = GetIdentity().certificate().ToPEMString();
-  return NewSecureTunnelSessionDescription(
-      CN_SECURE_TUNNEL,
-      new SecureTunnelContentDescription(description, pem_cert, ""));
-}
-
-SessionDescription* SecureTunnelSessionClient::CreateAnswer(
-    const SessionDescription* offer) {
-  std::string content_name;
-  const SecureTunnelContentDescription* offer_tunnel = NULL;
-  if (!FindSecureTunnelContent(offer, &content_name, &offer_tunnel))
-    return NULL;
-
-  // We are accepting a session request. We need to add our cert, the
-  // server cert, into the description. The client cert was validated
-  // in OnIncomingTunnel().
-  ASSERT(!offer_tunnel->client_pem_certificate.empty());
-  return NewSecureTunnelSessionDescription(
-      content_name,
-      new SecureTunnelContentDescription(
-          offer_tunnel->description,
-          offer_tunnel->client_pem_certificate,
-          GetIdentity().certificate().ToPEMString()));
-}
-
-// SecureTunnelSession
-
-SecureTunnelSession::SecureTunnelSession(
-    SecureTunnelSessionClient* client, Session* session,
-    talk_base::Thread* stream_thread, TunnelSessionRole role)
-    : TunnelSession(client, session, stream_thread),
-      role_(role) {
-}
-
-talk_base::StreamInterface* SecureTunnelSession::MakeSecureStream(
-    talk_base::StreamInterface* stream) {
-  talk_base::SSLStreamAdapter* ssl_stream =
-      talk_base::SSLStreamAdapter::Create(stream);
-  talk_base::SSLIdentity* identity =
-      static_cast<SecureTunnelSessionClient*>(client_)->
-      GetIdentity().GetReference();
-  ssl_stream->SetIdentity(identity);
-  if (role_ == RESPONDER)
-    ssl_stream->SetServerRole();
-  ssl_stream->StartSSLWithPeer();
-
-  // SSL negotiation will start on the stream as soon as it
-  // opens. However our SSLStreamAdapter still hasn't been told what
-  // certificate to allow for our peer. If we are the initiator, we do
-  // not have the peer's certificate yet: we will obtain it from the
-  // session accept message which we will receive later (see
-  // OnAccept()). We won't Connect() the PseudoTcpChannel until we get
-  // that, so the stream will stay closed until then.  Keep a handle
-  // on the streem so we can configure the peer certificate later.
-  ssl_stream_reference_.reset(new talk_base::StreamReference(ssl_stream));
-  return ssl_stream_reference_->NewReference();
-}
-
-talk_base::StreamInterface* SecureTunnelSession::GetStream() {
-  ASSERT(channel_ != NULL);
-  ASSERT(ssl_stream_reference_.get() == NULL);
-  return MakeSecureStream(channel_->GetStream());
-}
-
-void SecureTunnelSession::OnAccept() {
-  // We have either sent or received a session accept: it's time to
-  // connect the tunnel. First we must set the peer certificate.
-  ASSERT(channel_ != NULL);
-  ASSERT(session_ != NULL);
-  std::string content_name;
-  const SecureTunnelContentDescription* remote_tunnel = NULL;
-  if (!FindSecureTunnelContent(session_->remote_description(),
-                               &content_name, &remote_tunnel)) {
-    session_->Reject(STR_TERMINATE_INCOMPATIBLE_PARAMETERS);
-    return;
-  }
-
-  const std::string& cert_pem =
-      role_ == INITIATOR ? remote_tunnel->server_pem_certificate :
-                           remote_tunnel->client_pem_certificate;
-  talk_base::SSLCertificate* peer_cert =
-      ParseCertificate(cert_pem);
-  if (peer_cert == NULL) {
-    ASSERT(role_ == INITIATOR);  // when RESPONDER we validated it earlier
-    LOG(LS_ERROR)
-        << "Rejecting secure tunnel accept with invalid cetificate";
-    session_->Reject(STR_TERMINATE_INCOMPATIBLE_PARAMETERS);
-    return;
-  }
-  ASSERT(ssl_stream_reference_.get() != NULL);
-  talk_base::SSLStreamAdapter* ssl_stream =
-      static_cast<talk_base::SSLStreamAdapter*>(
-          ssl_stream_reference_->GetStream());
-  ssl_stream->SetPeerCertificate(peer_cert);  // pass ownership of certificate.
-  // We no longer need our handle to the ssl stream.
-  ssl_stream_reference_.reset();
-  LOG(LS_INFO) << "Connecting tunnel";
-  // This will try to connect the PseudoTcpChannel. If and when that
-  // succeeds, then ssl negotiation will take place, and when that
-  // succeeds, the tunnel stream will finally open.
-  VERIFY(channel_->Connect(content_name, "tcp"));
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/session/tunnel/securetunnelsessionclient.h b/third_party/libjingle/source/talk/session/tunnel/securetunnelsessionclient.h
deleted file mode 100644
index cb9a99c..0000000
--- a/third_party/libjingle/source/talk/session/tunnel/securetunnelsessionclient.h
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2008, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// SecureTunnelSessionClient and SecureTunnelSession.
-// SecureTunnelSessionClient extends TunnelSessionClient to exchange
-// certificates as part of the session description.
-// SecureTunnelSession is a TunnelSession that wraps the underlying
-// tunnel stream into an SSLStreamAdapter.
-
-#ifndef TALK_SESSION_TUNNEL_SECURETUNNELSESSIONCLIENT_H_
-#define TALK_SESSION_TUNNEL_SECURETUNNELSESSIONCLIENT_H_
-
-#include <string>
-
-#include "talk/base/sslidentity.h"
-#include "talk/base/sslstreamadapter.h"
-#include "talk/session/tunnel/tunnelsessionclient.h"
-
-namespace cricket {
-
-class SecureTunnelSession;  // below
-
-// SecureTunnelSessionClient
-
-// This TunnelSessionClient establishes secure tunnels protected by
-// SSL/TLS. The PseudoTcpChannel stream is wrapped with an
-// SSLStreamAdapter. An SSLIdentity must be set or generated.
-//
-// The TunnelContentDescription is extended to include the client and
-// server certificates. The initiator acts as the client. The session
-// initiate stanza carries a description that contains the client's
-// certificate, and the session accept response's description has the
-// server certificate added to it.
-
-class SecureTunnelSessionClient : public TunnelSessionClient {
- public:
-  // The jid is used as the name for sessions for outgoing tunnels.
-  // manager is the SessionManager to which we register this client
-  // and its sessions.
-  SecureTunnelSessionClient(const buzz::Jid& jid, SessionManager* manager);
-
-  // Configures this client to use a preexisting SSLIdentity.
-  // The client takes ownership of the identity object.
-  // Use either SetIdentity or GenerateIdentity, and only once.
-  void SetIdentity(talk_base::SSLIdentity* identity);
-
-  // Generates an identity from nothing.
-  // Returns true if generation was successful.
-  // Use either SetIdentity or GenerateIdentity, and only once.
-  bool GenerateIdentity();
-
-  // Returns our identity for SSL purposes, as either set by
-  // SetIdentity() or generated by GenerateIdentity(). Call this
-  // method only after our identity has been successfully established
-  // by one of those methods.
-  talk_base::SSLIdentity& GetIdentity() const;
-
-  // Inherited methods
-  virtual void OnIncomingTunnel(const buzz::Jid& jid, Session *session);
-  virtual bool ParseContent(SignalingProtocol protocol,
-                            const buzz::XmlElement* elem,
-                            const ContentDescription** content,
-                            ParseError* error);
-  virtual bool WriteContent(SignalingProtocol protocol,
-                            const ContentDescription* content,
-                            buzz::XmlElement** elem,
-                            WriteError* error);
-  virtual SessionDescription* CreateOffer(
-      const buzz::Jid &jid, const std::string &description);
-  virtual SessionDescription* CreateAnswer(
-      const SessionDescription* offer);
-
- protected:
-  virtual TunnelSession* MakeTunnelSession(
-      Session* session, talk_base::Thread* stream_thread,
-      TunnelSessionRole role);
-
- private:
-  // Our identity (key and certificate) for SSL purposes. The
-  // certificate part will be communicated within the session
-  // description. The identity will be passed to the SSLStreamAdapter
-  // and used for SSL authentication.
-  talk_base::scoped_ptr<talk_base::SSLIdentity> identity_;
-
-  DISALLOW_EVIL_CONSTRUCTORS(SecureTunnelSessionClient);
-};
-
-// SecureTunnelSession:
-// A TunnelSession represents one session for one client. It
-// provides the actual tunnel stream and handles state changes.
-// A SecureTunnelSession is a TunnelSession that wraps the underlying
-// tunnel stream into an SSLStreamAdapter.
-
-class SecureTunnelSession : public TunnelSession {
- public:
-  // This TunnelSession will tie together the given client and session.
-  // stream_thread is passed to the PseudoTCPChannel: it's the thread
-  // designated to interact with the tunnel stream.
-  // role is either INITIATOR or RESPONDER, depending on who is
-  // initiating the session.
-  SecureTunnelSession(SecureTunnelSessionClient* client, Session* session,
-                      talk_base::Thread* stream_thread,
-                      TunnelSessionRole role);
-
-  // Returns the stream that implements the actual P2P tunnel.
-  // This may be called only once. Caller is responsible for freeing
-  // the returned object.
-  virtual talk_base::StreamInterface* GetStream();
-
- protected:
-  // Inherited method: callback on accepting a session.
-  virtual void OnAccept();
-
-  // Helper method for GetStream() that Instantiates the
-  // SSLStreamAdapter to wrap the PseudoTcpChannel's stream, and
-  // configures it with our identity and role.
-  talk_base::StreamInterface* MakeSecureStream(
-      talk_base::StreamInterface* stream);
-
-  // Our role in requesting the tunnel: INITIATOR or
-  // RESPONDER. Translates to our role in SSL negotiation:
-  // respectively client or server. Also indicates which slot of the
-  // SecureTunnelContentDescription our cert goes into: client-cert or
-  // server-cert respectively.
-  TunnelSessionRole role_;
-
-  // This is the stream representing the usable tunnel endpoint.  It's
-  // a StreamReference wrapping the SSLStreamAdapter instance, which
-  // further wraps a PseudoTcpChannel::InternalStream. The
-  // StreamReference is because in the case of CreateTunnel(), the
-  // stream endpoint is returned early, but we need to keep a handle
-  // on it so we can setup the peer certificate when we receive it
-  // later.
-  talk_base::scoped_ptr<talk_base::StreamReference> ssl_stream_reference_;
-
-  DISALLOW_EVIL_CONSTRUCTORS(SecureTunnelSession);
-};
-
-}  // namespace cricket
-
-#endif  // TALK_SESSION_TUNNEL_SECURETUNNELSESSIONCLIENT_H_
diff --git a/third_party/libjingle/source/talk/session/tunnel/tunnelsessionclient.cc b/third_party/libjingle/source/talk/session/tunnel/tunnelsessionclient.cc
deleted file mode 100644
index 05cc757..0000000
--- a/third_party/libjingle/source/talk/session/tunnel/tunnelsessionclient.cc
+++ /dev/null
@@ -1,398 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2008, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/basicdefs.h"
-#include "talk/base/basictypes.h"
-#include "talk/base/common.h"
-#include "talk/base/helpers.h"
-#include "talk/base/logging.h"
-#include "talk/base/stringutils.h"
-#include "talk/p2p/base/constants.h"
-#include "talk/p2p/base/transportchannel.h"
-#include "talk/xmllite/xmlelement.h"
-#include "pseudotcpchannel.h"
-#include "tunnelsessionclient.h"
-
-namespace cricket {
-
-const char NS_TUNNEL[] = "http://www.google.com/talk/tunnel";
-const buzz::StaticQName QN_TUNNEL_DESCRIPTION = { NS_TUNNEL, "description" };
-const buzz::StaticQName QN_TUNNEL_TYPE = { NS_TUNNEL, "type" };
-const char CN_TUNNEL[] = "tunnel";
-
-enum {
-  MSG_CLOCK = 1,
-  MSG_DESTROY,
-  MSG_TERMINATE,
-  MSG_EVENT,
-  MSG_CREATE_TUNNEL,
-};
-
-struct EventData : public talk_base::MessageData {
-  int event, error;
-  EventData(int ev, int err = 0) : event(ev), error(err) { }
-};
-
-struct CreateTunnelData : public talk_base::MessageData {
-  buzz::Jid jid;
-  std::string description;
-  talk_base::Thread* thread;
-  talk_base::StreamInterface* stream;
-};
-
-extern const talk_base::ConstantLabel SESSION_STATES[];
-
-const talk_base::ConstantLabel SESSION_STATES[] = {
-  KLABEL(Session::STATE_INIT),
-  KLABEL(Session::STATE_SENTINITIATE),
-  KLABEL(Session::STATE_RECEIVEDINITIATE),
-  KLABEL(Session::STATE_SENTACCEPT),
-  KLABEL(Session::STATE_RECEIVEDACCEPT),
-  KLABEL(Session::STATE_SENTMODIFY),
-  KLABEL(Session::STATE_RECEIVEDMODIFY),
-  KLABEL(Session::STATE_SENTREJECT),
-  KLABEL(Session::STATE_RECEIVEDREJECT),
-  KLABEL(Session::STATE_SENTREDIRECT),
-  KLABEL(Session::STATE_SENTTERMINATE),
-  KLABEL(Session::STATE_RECEIVEDTERMINATE),
-  KLABEL(Session::STATE_INPROGRESS),
-  KLABEL(Session::STATE_DEINIT),
-  LASTLABEL
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// TunnelContentDescription
-///////////////////////////////////////////////////////////////////////////////
-
-struct TunnelContentDescription : public ContentDescription {
-  std::string description;
-
-  TunnelContentDescription(const std::string& desc) : description(desc) { }
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// TunnelSessionClientBase
-///////////////////////////////////////////////////////////////////////////////
-
-TunnelSessionClientBase::TunnelSessionClientBase(const buzz::Jid& jid,
-                                SessionManager* manager, const std::string &ns)
-  : jid_(jid), session_manager_(manager), namespace_(ns), shutdown_(false) {
-  session_manager_->AddClient(namespace_, this);
-}
-
-TunnelSessionClientBase::~TunnelSessionClientBase() {
-  shutdown_ = true;
-  for (std::vector<TunnelSession*>::iterator it = sessions_.begin();
-       it != sessions_.end();
-       ++it) {
-     Session* session = (*it)->ReleaseSession(true);
-     session_manager_->DestroySession(session);
-  }
-  session_manager_->RemoveClient(namespace_);
-}
-
-void TunnelSessionClientBase::OnSessionCreate(Session* session, bool received) {
-  LOG(LS_INFO) << "TunnelSessionClientBase::OnSessionCreate: received=" 
-               << received;
-  ASSERT(session_manager_->signaling_thread()->IsCurrent());
-  if (received)
-    sessions_.push_back(
-        MakeTunnelSession(session, talk_base::Thread::Current(), RESPONDER));
-}
-
-void TunnelSessionClientBase::OnSessionDestroy(Session* session) {
-  LOG(LS_INFO) << "TunnelSessionClientBase::OnSessionDestroy";
-  ASSERT(session_manager_->signaling_thread()->IsCurrent());
-  if (shutdown_)
-    return;
-  for (std::vector<TunnelSession*>::iterator it = sessions_.begin();
-       it != sessions_.end();
-       ++it) {
-    if ((*it)->HasSession(session)) {
-      VERIFY((*it)->ReleaseSession(false) == session);
-      sessions_.erase(it);
-      return;
-    }
-  }
-}
-
-talk_base::StreamInterface* TunnelSessionClientBase::CreateTunnel(
-    const buzz::Jid& to, const std::string& description) {
-  // Valid from any thread
-  CreateTunnelData data;
-  data.jid = to;
-  data.description = description;
-  data.thread = talk_base::Thread::Current();
-  session_manager_->signaling_thread()->Send(this, MSG_CREATE_TUNNEL, &data);
-  return data.stream;
-}
-
-talk_base::StreamInterface* TunnelSessionClientBase::AcceptTunnel(
-    Session* session) {
-  ASSERT(session_manager_->signaling_thread()->IsCurrent());
-  TunnelSession* tunnel = NULL;
-  for (std::vector<TunnelSession*>::iterator it = sessions_.begin();
-       it != sessions_.end();
-       ++it) {
-    if ((*it)->HasSession(session)) {
-      tunnel = *it;
-      break;
-    }
-  }
-  ASSERT(tunnel != NULL);
-
-  SessionDescription* answer = CreateAnswer(session->remote_description());
-  if (answer == NULL)
-    return NULL;
-
-  session->Accept(answer);
-  return tunnel->GetStream();
-}
-
-void TunnelSessionClientBase::DeclineTunnel(Session* session) {
-  ASSERT(session_manager_->signaling_thread()->IsCurrent());
-  session->Reject(STR_TERMINATE_DECLINE);
-}
-
-void TunnelSessionClientBase::OnMessage(talk_base::Message* pmsg) {
-  if (pmsg->message_id == MSG_CREATE_TUNNEL) {
-    ASSERT(session_manager_->signaling_thread()->IsCurrent());
-    CreateTunnelData* data = static_cast<CreateTunnelData*>(pmsg->pdata);
-    Session* session = session_manager_->CreateSession(jid_.Str(), namespace_);
-    TunnelSession* tunnel = MakeTunnelSession(session, data->thread,
-                                              INITIATOR);
-    sessions_.push_back(tunnel);
-    SessionDescription* offer = CreateOffer(data->jid, data->description);
-    session->Initiate(data->jid.Str(), offer);
-    data->stream = tunnel->GetStream();
-  }
-}
-
-TunnelSession* TunnelSessionClientBase::MakeTunnelSession(
-    Session* session, talk_base::Thread* stream_thread,
-    TunnelSessionRole /*role*/) {
-  return new TunnelSession(this, session, stream_thread);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// TunnelSessionClient
-///////////////////////////////////////////////////////////////////////////////
-
-TunnelSessionClient::TunnelSessionClient(const buzz::Jid& jid,
-                                         SessionManager* manager,
-                                         const std::string &ns)
-    : TunnelSessionClientBase(jid, manager, ns) {
-}
-
-TunnelSessionClient::TunnelSessionClient(const buzz::Jid& jid,
-                                         SessionManager* manager)
-    : TunnelSessionClientBase(jid, manager, NS_TUNNEL) {
-}
-
-TunnelSessionClient::~TunnelSessionClient() {
-}
-
-
-bool TunnelSessionClient::ParseContent(SignalingProtocol protocol,
-                                       const buzz::XmlElement* elem,
-                                       const ContentDescription** content,
-                                       ParseError* error) {
-  if (const buzz::XmlElement* type_elem = elem->FirstNamed(QN_TUNNEL_TYPE)) {
-    *content = new TunnelContentDescription(type_elem->BodyText());
-    return true;
-  }
-  return false;
-}
-
-bool TunnelSessionClient::WriteContent(
-    SignalingProtocol protocol,
-    const ContentDescription* untyped_content,
-    buzz::XmlElement** elem, WriteError* error) {
-  const TunnelContentDescription* content =
-      static_cast<const TunnelContentDescription*>(untyped_content);
-
-  buzz::XmlElement* root = new buzz::XmlElement(QN_TUNNEL_DESCRIPTION, true);
-  buzz::XmlElement* type_elem = new buzz::XmlElement(QN_TUNNEL_TYPE);
-  type_elem->SetBodyText(content->description);
-  root->AddElement(type_elem);
-  *elem = root;
-  return true;
-}
-
-SessionDescription* NewTunnelSessionDescription(
-    const std::string& content_name, const ContentDescription* content) {
-  SessionDescription* sdesc = new SessionDescription();
-  sdesc->AddContent(content_name, NS_TUNNEL, content);
-  return sdesc;
-}
-
-bool FindTunnelContent(const cricket::SessionDescription* sdesc,
-                       std::string* name,
-                       const TunnelContentDescription** content) {
-  const ContentInfo* cinfo = sdesc->FirstContentByType(NS_TUNNEL);
-  if (cinfo == NULL)
-    return false;
-
-  *name = cinfo->name;
-  *content = static_cast<const TunnelContentDescription*>(
-      cinfo->description);
-  return true;
-}
-
-void TunnelSessionClient::OnIncomingTunnel(const buzz::Jid &jid,
-                                           Session *session) {
-  std::string content_name;
-  const TunnelContentDescription* content = NULL;
-  if (!FindTunnelContent(session->remote_description(),
-                         &content_name, &content)) {
-    session->Reject(STR_TERMINATE_INCOMPATIBLE_PARAMETERS);
-    return;
-  }
-
-  SignalIncomingTunnel(this, jid, content->description, session);
-}
-
-SessionDescription* TunnelSessionClient::CreateOffer(
-    const buzz::Jid &jid, const std::string &description) {
-  return NewTunnelSessionDescription(
-      CN_TUNNEL, new TunnelContentDescription(description));
-}
-
-SessionDescription* TunnelSessionClient::CreateAnswer(
-    const SessionDescription* offer) {
-  std::string content_name;
-  const TunnelContentDescription* offer_tunnel = NULL;
-  if (!FindTunnelContent(offer, &content_name, &offer_tunnel))
-    return NULL;
-
-  return NewTunnelSessionDescription(
-      content_name, new TunnelContentDescription(offer_tunnel->description));
-}
-///////////////////////////////////////////////////////////////////////////////
-// TunnelSession
-///////////////////////////////////////////////////////////////////////////////
-
-//
-// Signalling thread methods
-//
-
-TunnelSession::TunnelSession(TunnelSessionClientBase* client, Session* session,
-                             talk_base::Thread* stream_thread)
-    : client_(client), session_(session), channel_(NULL) {
-  ASSERT(client_ != NULL);
-  ASSERT(session_ != NULL);
-  session_->SignalState.connect(this, &TunnelSession::OnSessionState);
-  channel_ = new PseudoTcpChannel(stream_thread, session_);
-  channel_->SignalChannelClosed.connect(this, &TunnelSession::OnChannelClosed);
-}
-
-TunnelSession::~TunnelSession() {
-  ASSERT(client_ != NULL);
-  ASSERT(session_ == NULL);
-  ASSERT(channel_ == NULL);
-}
-
-talk_base::StreamInterface* TunnelSession::GetStream() {
-  ASSERT(channel_ != NULL);
-  return channel_->GetStream();
-}
-
-bool TunnelSession::HasSession(Session* session) {
-  ASSERT(NULL != session_);
-  return (session_ == session);
-}
-
-Session* TunnelSession::ReleaseSession(bool channel_exists) {
-  ASSERT(NULL != session_);
-  ASSERT(NULL != channel_);
-  Session* session = session_;
-  session_->SignalState.disconnect(this);
-  session_ = NULL;
-  if (channel_exists)
-    channel_->SignalChannelClosed.disconnect(this);
-  channel_ = NULL;
-  delete this;
-  return session;
-}
-
-void TunnelSession::OnSessionState(BaseSession* session,
-                                   BaseSession::State state) {
-  LOG(LS_INFO) << "TunnelSession::OnSessionState("
-               << talk_base::nonnull(
-                    talk_base::FindLabel(state, SESSION_STATES), "Unknown")
-               << ")";
-  ASSERT(session == session_);
-
-  switch (state) {
-  case Session::STATE_RECEIVEDINITIATE:
-    OnInitiate();
-    break;
-  case Session::STATE_SENTACCEPT:
-  case Session::STATE_RECEIVEDACCEPT:
-    OnAccept();
-    break;
-  case Session::STATE_SENTTERMINATE:
-  case Session::STATE_RECEIVEDTERMINATE:
-    OnTerminate();
-    break;
-  case Session::STATE_DEINIT:
-    // ReleaseSession should have been called before this.
-    ASSERT(false);
-    break;
-  default:
-    break;
-  }
-}
-
-void TunnelSession::OnInitiate() {
-  ASSERT(client_ != NULL);
-  ASSERT(session_ != NULL);
-  client_->OnIncomingTunnel(buzz::Jid(session_->remote_name()), session_);
-}
-
-void TunnelSession::OnAccept() {
-  ASSERT(channel_ != NULL);
-  const ContentInfo* content =
-      session_->remote_description()->FirstContentByType(NS_TUNNEL);
-  ASSERT(content != NULL);
-  VERIFY(channel_->Connect(content->name, "tcp"));
-}
-
-void TunnelSession::OnTerminate() {
-  ASSERT(channel_ != NULL);
-  channel_->OnSessionTerminate(session_);
-}
-
-void TunnelSession::OnChannelClosed(PseudoTcpChannel* channel) {
-  ASSERT(channel_ == channel);
-  ASSERT(session_ != NULL);
-  session_->Terminate();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-} // namespace cricket
diff --git a/third_party/libjingle/source/talk/session/tunnel/tunnelsessionclient.h b/third_party/libjingle/source/talk/session/tunnel/tunnelsessionclient.h
deleted file mode 100644
index 7259fa1..0000000
--- a/third_party/libjingle/source/talk/session/tunnel/tunnelsessionclient.h
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2008, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __TUNNELSESSIONCLIENT_H__
-#define __TUNNELSESSIONCLIENT_H__
-
-#include <vector>
-
-#include "talk/base/criticalsection.h"
-#include "talk/base/stream.h"
-#include "talk/p2p/base/constants.h"
-#include "talk/p2p/base/pseudotcp.h"
-#include "talk/p2p/base/session.h"
-#include "talk/p2p/base/sessiondescription.h"
-#include "talk/p2p/base/sessionmanager.h"
-#include "talk/p2p/base/sessionclient.h"
-#include "talk/xmllite/qname.h"
-#include "talk/xmpp/constants.h"
-
-namespace cricket {
-
-class TunnelSession;
-class TunnelStream;
-
-enum TunnelSessionRole { INITIATOR, RESPONDER };
-
-///////////////////////////////////////////////////////////////////////////////
-// TunnelSessionClient
-///////////////////////////////////////////////////////////////////////////////
-
-// Base class is still abstract
-class TunnelSessionClientBase
-  : public SessionClient, public talk_base::MessageHandler {
-public:
-  TunnelSessionClientBase(const buzz::Jid& jid, SessionManager* manager,
-                          const std::string &ns);
-  virtual ~TunnelSessionClientBase();
-
-  const buzz::Jid& jid() const { return jid_; }
-  SessionManager* session_manager() const { return session_manager_; }
-
-  void OnSessionCreate(Session* session, bool received);
-  void OnSessionDestroy(Session* session);
-
-  // This can be called on any thread.  The stream interface is
-  // thread-safe, but notifications must be registered on the creating
-  // thread.
-  talk_base::StreamInterface* CreateTunnel(const buzz::Jid& to,
-                                           const std::string& description);
-
-  talk_base::StreamInterface* AcceptTunnel(Session* session);
-  void DeclineTunnel(Session* session);
-
-  // Invoked on an incoming tunnel
-  virtual void OnIncomingTunnel(const buzz::Jid &jid, Session *session) = 0;
-
-  // Invoked on an outgoing session request
-  virtual SessionDescription* CreateOffer(
-      const buzz::Jid &jid, const std::string &description) = 0;
-  // Invoked on a session request accept to create
-  // the local-side session description
-  virtual SessionDescription* CreateAnswer(
-      const SessionDescription* offer) = 0;
-
-protected:
-
-  void OnMessage(talk_base::Message* pmsg);
-
-  // helper method to instantiate TunnelSession. By overriding this,
-  // subclasses of TunnelSessionClient are able to instantiate
-  // subclasses of TunnelSession instead.
-  virtual TunnelSession* MakeTunnelSession(Session* session,
-                                           talk_base::Thread* stream_thread,
-                                           TunnelSessionRole role);
-
-  buzz::Jid jid_;
-  SessionManager* session_manager_;
-  std::vector<TunnelSession*> sessions_;
-  std::string namespace_;
-  bool shutdown_;
-};
-
-class TunnelSessionClient
-  : public TunnelSessionClientBase, public sigslot::has_slots<>  {
-public:
-  TunnelSessionClient(const buzz::Jid& jid, SessionManager* manager);
-  TunnelSessionClient(const buzz::Jid& jid, SessionManager* manager,
-                      const std::string &ns);
-  virtual ~TunnelSessionClient();
-
-  virtual bool ParseContent(SignalingProtocol protocol,
-                            const buzz::XmlElement* elem,
-                            const ContentDescription** content,
-                            ParseError* error);
-  virtual bool WriteContent(SignalingProtocol protocol,
-                            const ContentDescription* content,
-                            buzz::XmlElement** elem,
-                            WriteError* error);
-
-  // Signal arguments are this, initiator, description, session
-  sigslot::signal4<TunnelSessionClient*, buzz::Jid, std::string, Session*>
-    SignalIncomingTunnel;
-
-  virtual void OnIncomingTunnel(const buzz::Jid &jid,
-                                Session *session);
-  virtual SessionDescription* CreateOffer(
-      const buzz::Jid &jid, const std::string &description);
-  virtual SessionDescription* CreateAnswer(
-      const SessionDescription* offer);
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// TunnelSession
-// Note: The lifetime of TunnelSession is complicated.  It needs to survive
-// until the following three conditions are true:
-// 1) TunnelStream has called Close (tracked via non-null stream_)
-// 2) PseudoTcp has completed (tracked via non-null tcp_)
-// 3) Session has been destroyed (tracked via non-null session_)
-// This is accomplished by calling CheckDestroy after these indicators change.
-///////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////
-// TunnelStream
-// Note: Because TunnelStream provides a stream interface, its lifetime is
-// controlled by the owner of the stream pointer.  As a result, we must support
-// both the TunnelSession disappearing before TunnelStream, and vice versa.
-///////////////////////////////////////////////////////////////////////////////
-
-class PseudoTcpChannel;
-
-class TunnelSession : public sigslot::has_slots<> {
- public:
-  // Signalling thread methods
-  TunnelSession(TunnelSessionClientBase* client, Session* session,
-                talk_base::Thread* stream_thread);
-
-  virtual talk_base::StreamInterface* GetStream();
-  bool HasSession(Session* session);
-  Session* ReleaseSession(bool channel_exists);
-
- protected:
-  virtual ~TunnelSession();
-
-  virtual void OnSessionState(BaseSession* session, BaseSession::State state);
-  virtual void OnInitiate();
-  virtual void OnAccept();
-  virtual void OnTerminate();
-  virtual void OnChannelClosed(PseudoTcpChannel* channel);
-
-  TunnelSessionClientBase* client_;
-  Session* session_;
-  PseudoTcpChannel* channel_;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-
-} // namespace cricket
-
-#endif // __TUNNELSESSIONCLIENT_H__
diff --git a/third_party/libjingle/source/talk/site_scons/site_tools/talk_libjingle.py b/third_party/libjingle/source/talk/site_scons/site_tools/talk_libjingle.py
deleted file mode 100644
index 33c136c..0000000
--- a/third_party/libjingle/source/talk/site_scons/site_tools/talk_libjingle.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# Copyright 2010 Google Inc.
-# All Rights Reserved.
-# Author: thaloun@google.com (Tim Haloun)
-
-"""Tools that we need to include with libjingle."""
-
-import subprocess
-
-
-# We need this in libjingle because main.scons depends on it and
-# libjingle depends on main.scons.
-def EnableFeatureWherePackagePresent(env, bit, cpp_flag, package):
-  """Enable a feature if a required pkg-config package is present.
-
-  Args:
-    env: The current SCons environment.
-    bit: The name of the Bit to enable when the package is present.
-    cpp_flag: The CPP flag to enable when the package is present.
-    package: The name of the package.
-  """
-  if not env.Bit('host_linux'):
-    return
-  if _HavePackage(package):
-    env.SetBits(bit)
-    env.Append(CPPDEFINES = [cpp_flag])
-  else:
-    print ('Warning: Package \"%s\" not found. Feature \"%s\" will not be '
-           'built. To build with this feature, install the package that '
-           'provides the \"%s.pc\" file.') % (package, bit, package)
-
-
-def _HavePackage(package):
-  """Whether the given pkg-config package name is present on the build system.
-
-  Args:
-    package: The name of the package.
-
-  Returns:
-    True if the package is present, else False
-  """
-  return subprocess.call(['pkg-config', '--exists', package]) == 0
-
-
-def generate(env):  # pylint: disable-msg=C6409
-  env.AddMethod(EnableFeatureWherePackagePresent)
-
-
-def exists(env):  # pylint: disable-msg=C6409,W0613
-  return 1
diff --git a/third_party/libjingle/source/talk/site_scons/site_tools/talk_linux.py b/third_party/libjingle/source/talk/site_scons/site_tools/talk_linux.py
deleted file mode 100644
index 67214c0..0000000
--- a/third_party/libjingle/source/talk/site_scons/site_tools/talk_linux.py
+++ /dev/null
@@ -1,271 +0,0 @@
-# Copyright 2010 Google Inc.
-# All Rights Reserved.
-# Author: tschmelcher@google.com (Tristan Schmelcher)
-
-"""Tool for helpers used in linux building process."""
-
-import os
-import SCons.Defaults
-import subprocess
-
-
-def _OutputFromShellCommand(command):
-  process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
-  return process.communicate()[0].strip()
-
-
-# This is a pure SCons helper function.
-def _InternalBuildDebianPackage(env, debian_files, package_files,
-    output_dir=None, force_version=None):
-  """Creates build rules to build a Debian package from the specified sources.
-
-  Args:
-    env: SCons Environment.
-    debian_files: Array of the Debian control file sources that should be
-        copied into the package source tree, e.g., changelog, control, rules,
-        etc.
-    package_files: An array of 2-tuples listing the files that should be
-        copied into the package source tree.
-        The first element is the path where the file should be placed for the
-            .install control file to find it, relative to the generated debian
-            package source directory.
-        The second element is the file source.
-    output_dir: An optional directory to place the files in. If omitted, the
-        current output directory is used.
-    force_version: Optional. Forces the version of the package to start with
-        this version string if specified. If the last entry in the changelog
-        is not for a version that starts with this then a dummy entry is
-        generated with this version and a ~prerelease suffix (so that the
-        final version will compare as greater).
-
-  Return:
-    A list of the targets (if any).
-  """
-  if 0 != subprocess.call(['which', 'dpkg-buildpackage']):
-    print ('dpkg-buildpackage not installed on this system; '
-           'skipping DEB build stage')
-    return []
-  # Read the control file and changelog file to determine the package name,
-  # version, and arch that the Debian build tools will use to name the
-  # generated files.
-  control_file = None
-  changelog_file = None
-  for file in debian_files:
-    if os.path.basename(file) == 'control':
-      control_file = env.File(file).srcnode().abspath
-    elif os.path.basename(file) == 'changelog':
-      changelog_file = env.File(file).srcnode().abspath
-  if not control_file:
-    raise Exception('Need to have a control file')
-  if not changelog_file:
-    raise Exception('Need to have a changelog file')
-  source = _OutputFromShellCommand(
-      "awk '/^Source:/ { print $2; }' " + control_file)
-  packages = _OutputFromShellCommand(
-      "awk '/^Package:/ { print $2; }' " + control_file).split('\n')
-  version = _OutputFromShellCommand(
-      "sed -nr '1 { s/.*\\((.*)\\).*/\\1/; p }' " + changelog_file)
-  arch = _OutputFromShellCommand('dpkg --print-architecture')
-  add_dummy_changelog_entry = False
-  if force_version and not version.startswith(force_version):
-    print ('Warning: no entry in ' + changelog_file + ' for version ' +
-        force_version + ' (last is ' + version +'). A dummy entry will be ' +
-        'generated. Remember to add the real changelog entry before ' +
-        'releasing.')
-    version = force_version + '~prerelease'
-    add_dummy_changelog_entry = True
-  source_dir_name = source + '_' + version + '_' + arch
-  target_file_names = [ source_dir_name + '.changes' ]
-  for package in packages:
-    package_file_name = package + '_' + version + '_' + arch + '.deb'
-    target_file_names.append(package_file_name)
-  # The targets
-  if output_dir:
-    targets = [os.path.join(output_dir, s) for s in target_file_names]
-  else:
-    targets = target_file_names
-  # Path to where we will construct the debian build tree.
-  deb_build_tree = os.path.join(source_dir_name, 'deb_build_tree')
-  # First copy the files.
-  for file in package_files:
-    env.Command(os.path.join(deb_build_tree, file[0]), file[1],
-        SCons.Defaults.Copy('$TARGET', '$SOURCE'))
-    env.Depends(targets, os.path.join(deb_build_tree, file[0]))
-  # Now copy the Debian metadata sources. We have to do this all at once so
-  # that we can remove the target directory before copying, because there
-  # can't be any other stale files there or else dpkg-buildpackage may use
-  # them and give incorrect build output.
-  copied_debian_files_paths = []
-  for file in debian_files:
-    copied_debian_files_paths.append(os.path.join(deb_build_tree, 'debian',
-        os.path.basename(file)))
-  copy_commands = [
-      """dir=$$(dirname $TARGET) && \
-          rm -Rf $$dir && \
-          mkdir -p $$dir && \
-          cp $SOURCES $$dir && \
-          chmod -R u+w $$dir"""
-  ]
-  if add_dummy_changelog_entry:
-    copy_commands += [
-        """debchange -c $$(dirname $TARGET)/changelog --newversion %s \
-            --distribution UNRELEASED \
-            'Developer preview build. (This entry was auto-generated.)'""" %
-        version
-    ]
-  env.Command(copied_debian_files_paths, debian_files, copy_commands)
-  env.Depends(targets, copied_debian_files_paths)
-  # Must explicitly specify -a because otherwise cross-builds won't work.
-  # Must explicitly specify -D because -a disables it.
-  # Must explicitly specify fakeroot because old dpkg tools don't assume that.
-  env.Command(targets, None,
-      """dir=%(dir)s && \
-          cd $$dir && \
-          dpkg-buildpackage -b -uc -a%(arch)s -D -rfakeroot && \
-          cd $$OLDPWD && \
-          for file in %(targets)s; do \
-            mv $$dir/../$$file $$(dirname $TARGET) || exit 1; \
-          done""" %
-      {'dir':env.Dir(deb_build_tree).path,
-       'arch':arch,
-       'targets':' '.join(target_file_names)})
-  return targets
-
-
-def BuildDebianPackage(env, debian_files, package_files, force_version=None):
-  """Creates build rules to build a Debian package from the specified sources.
-
-  This is a Hammer-ified version of _InternalBuildDebianPackage that knows to
-  put the packages in the Hammer staging dir.
-
-  Args:
-    env: SCons Environment.
-    debian_files: Array of the Debian control file sources that should be
-        copied into the package source tree, e.g., changelog, control, rules,
-        etc.
-    package_files: An array of 2-tuples listing the files that should be
-        copied into the package source tree.
-        The first element is the path where the file should be placed for the
-            .install control file to find it, relative to the generated debian
-            package source directory.
-        The second element is the file source.
-    force_version: Optional. Forces the version of the package to start with
-        this version string if specified. If the last entry in the changelog
-        is not for a version that starts with this then a dummy entry is
-        generated with this version and a ~prerelease suffix (so that the
-        final version will compare as greater).
-
-  Return:
-    A list of the targets (if any).
-  """
-  if not env.Bit('host_linux'):
-    return []
-  return _InternalBuildDebianPackage(env, debian_files, package_files,
-      output_dir='$STAGING_DIR', force_version=force_version)
-
-
-def _HavePackage(package):
-  """Whether the given pkg-config package name is present on the build system.
-
-  Args:
-    package: The name of the package.
-
-  Returns:
-    True if the package is present, else False
-  """
-  return subprocess.call(['pkg-config', '--exists', package]) == 0
-
-
-def _GetPackageFlags(flag_type, packages):
-  """Get the flags needed to compile/link against the given package(s).
-
-  Returns the flags that are needed to compile/link against the given pkg-config
-  package(s).
-
-  Args:
-    flag_type: The option to pkg-config specifying the type of flags to get.
-    packages: The list of package names as strings.
-
-  Returns:
-    The flags of the requested type.
-  """
-  process = subprocess.Popen(['pkg-config', flag_type] + packages,
-                             stdout=subprocess.PIPE)
-  return process.communicate()[0].strip().split(' ')
-
-
-def GetPackageParams(env, packages):
-  """Get the params needed to compile/link against the given package(s).
-
-  Returns the params that are needed to compile/link against the given
-  pkg-config package(s).
-
-  Args:
-    env: The current SCons environment.
-    packages: The name of the package, or a list of names.
-
-  Returns:
-    A dictionary containing the params.
-
-  Raises:
-    Exception: One or more of the packages is not installed.
-  """
-  if not env.Bit('host_linux'):
-    return {}
-  if not SCons.Util.is_List(packages):
-    packages = [packages]
-  for package in packages:
-    if not _HavePackage(package):
-      raise Exception(('Required package \"%s\" was not found. Please install '
-                       'the package that provides the \"%s.pc\" file.') %
-                      (package, package))
-  package_ccflags = _GetPackageFlags('--cflags', packages)
-  package_libs = _GetPackageFlags('--libs', packages)
-  # Split package_libs into libs, libdirs, and misc. linker flags. (In a perfect
-  # world we could just leave libdirs in link_flags, but some linkers are
-  # somehow confused by the different argument order.)
-  libs = [flag[2:] for flag in package_libs if flag[0:2] == '-l']
-  libdirs = [flag[2:] for flag in package_libs if flag[0:2] == '-L']
-  link_flags = [flag for flag in package_libs if flag[0:2] not in ['-l', '-L']]
-  return {
-      'ccflags': package_ccflags,
-      'libs': libs,
-      'libdirs': libdirs,
-      'link_flags': link_flags,
-      'dependent_target_settings' : {
-          'libs': libs[:],
-          'libdirs': libdirs[:],
-          'link_flags': link_flags[:],
-      },
-  }
-
-
-def EnableFeatureWherePackagePresent(env, bit, cpp_flag, package):
-  """Enable a feature if a required pkg-config package is present.
-
-  Args:
-    env: The current SCons environment.
-    bit: The name of the Bit to enable when the package is present.
-    cpp_flag: The CPP flag to enable when the package is present.
-    package: The name of the package.
-  """
-  if not env.Bit('host_linux'):
-    return
-  if _HavePackage(package):
-    env.SetBits(bit)
-    env.Append(CPPDEFINES=[cpp_flag])
-  else:
-    print ('Warning: Package \"%s\" not found. Feature \"%s\" will not be '
-           'built. To build with this feature, install the package that '
-           'provides the \"%s.pc\" file.') % (package, bit, package)
-
-
-def generate(env):
-  if env.Bit('linux'):
-    env.AddMethod(EnableFeatureWherePackagePresent)
-    env.AddMethod(GetPackageParams)
-    env.AddMethod(BuildDebianPackage)
-
-
-def exists(env):
-  return 1  # Required by scons
diff --git a/third_party/libjingle/source/talk/site_scons/site_tools/talk_noops.py b/third_party/libjingle/source/talk/site_scons/site_tools/talk_noops.py
deleted file mode 100644
index bb8f106..0000000
--- a/third_party/libjingle/source/talk/site_scons/site_tools/talk_noops.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright 2010 Google Inc.
-# All Rights Reserved.
-# Author: thaloun@google.com (Tim Haloun)
-
-"""Noop tool that defines builder functions for non-default platforms to
-   avoid errors when scanning sconsscripts."""
-
-import SCons.Builder
-
-
-def generate(env):
-  """SCons method."""
-  if not env.Bit('windows'):
-    builder = SCons.Builder.Builder(
-      action=''
-    )
-    env.Append(BUILDERS={'RES': builder, 'Grit': builder})
-
-def exists(env):
-  return 1
diff --git a/third_party/libjingle/source/talk/site_scons/talk.py b/third_party/libjingle/source/talk/site_scons/talk.py
deleted file mode 100644
index 2989160..0000000
--- a/third_party/libjingle/source/talk/site_scons/talk.py
+++ /dev/null
@@ -1,624 +0,0 @@
-# Copyright 2010 Google Inc.
-# All Rights Reserved.
-#
-# Author: Tim Haloun (thaloun@google.com)
-#         Daniel Petersson (dape@google.com)
-#
-import os
-import SCons.Util
-
-class LibraryInfo:
-  """Records information on the libraries defined in a build configuration.
-
-  Attributes:
-    lib_targets: Dictionary of library target params for lookups in
-        ExtendComponent().
-    prebuilt_libraries: Set of all prebuilt static libraries.
-    system_libraries: Set of libraries not found in the above (used to detect
-        out-of-order build rules).
-  """
-
-  # Dictionary of LibraryInfo objects keyed by BUILD_TYPE value.
-  __library_info = {}
-
-  @staticmethod
-  def get(env):
-    """Gets the LibraryInfo object for the current build type.
-
-    Args:
-      env: The environment object.
-
-    Returns:
-      The LibraryInfo object.
-    """
-    return LibraryInfo.__library_info.setdefault(env['BUILD_TYPE'],
-                                                 LibraryInfo())
-
-  def __init__(self):
-    self.lib_targets = {}
-    self.prebuilt_libraries = set()
-    self.system_libraries = set()
-
-
-def _GetLibParams(env, lib):
-  """Gets the params for the given library if it is a library target.
-
-  Returns the params that were specified when the given lib target name was
-  created, or None if no such lib target has been defined. In the None case, it
-  additionally records the negative result so as to detect out-of-order
-  dependencies for future targets.
-
-  Args:
-    env: The environment object.
-    lib: The library's name as a string.
-
-  Returns:
-    Its dictionary of params, or None.
-  """
-  info = LibraryInfo.get(env)
-  if lib in info.lib_targets:
-    return info.lib_targets[lib]
-  else:
-    if lib not in info.prebuilt_libraries and lib not in info.system_libraries:
-      info.system_libraries.add(lib)
-    return None
-
-
-def _RecordLibParams(env, lib, params):
-  """Record the params used for a library target.
-
-  Record the params used for a library target while checking for several error
-  conditions.
-
-  Args:
-    env: The environment object.
-    lib: The library target's name as a string.
-    params: Its dictionary of params.
-
-  Raises:
-    Exception: The lib target has already been recorded, or the lib was
-        previously declared to be prebuilt, or the lib target is being defined
-        after a reverse library dependency.
-  """
-  info = LibraryInfo.get(env)
-  if lib in info.lib_targets:
-    raise Exception('Multiple definitions of ' + lib)
-  if lib in info.prebuilt_libraries:
-    raise Exception(lib + ' already declared as a prebuilt library')
-  if lib in info.system_libraries:
-    raise Exception(lib + ' cannot be defined after its reverse library '
-                    'dependencies')
-  info.lib_targets[lib] = params
-
-
-def _IsPrebuiltLibrary(env, lib):
-  """Checks whether or not the given library is a prebuilt static library.
-
-  Returns whether or not the given library name has been declared to be a
-  prebuilt static library. In the False case, it additionally records the
-  negative result so as to detect out-of-order dependencies for future targets.
-
-  Args:
-    env: The environment object.
-    lib: The library's name as a string.
-
-  Returns:
-    True or False
-  """
-  info = LibraryInfo.get(env)
-  if lib in info.prebuilt_libraries:
-    return True
-  else:
-    if lib not in info.lib_targets and lib not in info.system_libraries:
-      info.system_libraries.add(lib)
-    return False
-
-
-def _RecordPrebuiltLibrary(env, lib):
-  """Record that a library is a prebuilt static library.
-
-  Record that the given library name refers to a prebuilt static library while
-  checking for several error conditions.
-
-  Args:
-    env: The environment object.
-    lib: The library's name as a string.
-
-  Raises:
-    Exception: The lib has already been recorded to be prebuilt, or the lib was
-        previously declared as a target, or the lib is being declared as
-        prebuilt after a reverse library dependency.
-  """
-  info = LibraryInfo.get(env)
-  if lib in info.prebuilt_libraries:
-    raise Exception('Multiple prebuilt declarations of ' + lib)
-  if lib in info.lib_targets:
-    raise Exception(lib + ' already defined as a target')
-  if lib in info.system_libraries:
-    raise Exception(lib + ' cannot be declared as prebuilt after its reverse '
-                    'library dependencies')
-  info.prebuilt_libraries.add(lib)
-
-
-def _GenericLibrary(env, static, **kwargs):
-  """Extends ComponentLibrary to support multiplatform builds
-     of dynamic or static libraries.
-
-  Args:
-    env: The environment object.
-    kwargs: The keyword arguments.
-
-  Returns:
-    See swtoolkit ComponentLibrary
-  """
-  params = CombineDicts(kwargs, {'COMPONENT_STATIC': static})
-  return ExtendComponent(env, 'ComponentLibrary', **params)
-
-
-def DeclarePrebuiltLibraries(env, libraries):
-  """Informs the build engine about external static libraries.
-
-  Informs the build engine that the given external library name(s) are prebuilt
-  static libraries, as opposed to shared libraries.
-
-  Args:
-    env: The environment object.
-    libraries: The library or libraries that are being declared as prebuilt
-        static libraries.
-  """
-  if not SCons.Util.is_List(libraries):
-    libraries = [libraries]
-  for library in libraries:
-    _RecordPrebuiltLibrary(env, library)
-
-
-def Library(env, **kwargs):
-  """Extends ComponentLibrary to support multiplatform builds of static
-     libraries.
-
-  Args:
-    env: The current environment.
-    kwargs: The keyword arguments.
-
-  Returns:
-    See swtoolkit ComponentLibrary
-  """
-  return _GenericLibrary(env, True, **kwargs)
-
-
-def DynamicLibrary(env, **kwargs):
-  """Extends ComponentLibrary to support multiplatform builds
-     of dynmic libraries.
-
-  Args:
-    env: The environment object.
-    kwargs: The keyword arguments.
-
-  Returns:
-    See swtoolkit ComponentLibrary
-  """
-  return _GenericLibrary(env, False, **kwargs)
-
-
-def Object(env, **kwargs):
-  return ExtendComponent(env, 'ComponentObject', **kwargs)
-
-
-def Unittest(env, **kwargs):
-  """Extends ComponentTestProgram to support unittest built
-     for multiple platforms.
-
-  Args:
-    env: The current environment.
-    kwargs: The keyword arguments.
-
-  Returns:
-    See swtoolkit ComponentProgram.
-  """
-  kwargs['name'] = kwargs['name'] + '_unittest'
-
-  common_test_params = {
-    'posix_cppdefines': ['GUNIT_NO_GOOGLE3', 'GTEST_HAS_RTTI=0'],
-    'libs': ['unittest_main', 'gunit']
-  }
-  if 'explicit_libs' not in kwargs:
-    common_test_params['win_libs'] = [
-      'advapi32',
-      'crypt32',
-      'iphlpapi',
-      'secur32',
-      'shell32',
-      'shlwapi',
-      'user32',
-      'wininet',
-      'ws2_32'
-    ]
-    common_test_params['lin_libs'] = [
-      'crypto',
-      'pthread',
-      'ssl',
-    ]
-
-  params = CombineDicts(kwargs, common_test_params)
-  return ExtendComponent(env, 'ComponentTestProgram', **params)
-
-
-def App(env, **kwargs):
-  """Extends ComponentProgram to support executables with platform specific
-     options.
-
-  Args:
-    env: The current environment.
-    kwargs: The keyword arguments.
-
-  Returns:
-    See swtoolkit ComponentProgram.
-  """
-  if 'explicit_libs' not in kwargs:
-    common_app_params = {
-      'win_libs': [
-        'advapi32',
-        'crypt32',
-        'iphlpapi',
-        'secur32',
-        'shell32',
-        'shlwapi',
-        'user32',
-        'wininet',
-        'ws2_32'
-      ]}
-    params = CombineDicts(kwargs, common_app_params)
-  else:
-    params = kwargs
-  return ExtendComponent(env, 'ComponentProgram', **params)
-
-def WiX(env, **kwargs):
-  """ Extends the WiX builder
-  Args:
-    env: The current environment.
-    kwargs: The keyword arguments.
-
-  Returns:
-    The node produced by the environment's wix builder
-  """
-  return ExtendComponent(env, 'WiX', **kwargs)
-
-def Repository(env, at, path):
-  """Maps a directory external to $MAIN_DIR to the given path so that sources
-     compiled from it end up in the correct place under $OBJ_DIR.  NOT required
-     when only referring to header files.
-
-  Args:
-    env: The current environment object.
-    at: The 'mount point' within the current directory.
-    path: Path to the actual directory.
-  """
-  env.Dir(at).addRepository(env.Dir(path))
-
-
-def Components(*paths):
-  """Completes the directory paths with the correct file
-     names such that the directory/directory.scons name
-     convention can be used.
-
-  Args:
-    paths: The paths to complete. If it refers to an existing
-           file then it is ignored.
-
-  Returns:
-    The completed lif scons files that are needed to build talk.
-  """
-  files = []
-  for path in paths:
-    if os.path.isfile(path):
-      files.append(path)
-    else:
-      files.append(ExpandSconsPath(path))
-  return files
-
-
-def ExpandSconsPath(path):
-  """Expands a directory path into the path to the
-     scons file that our build uses.
-     Ex: magiflute/plugin/common => magicflute/plugin/common/common.scons
-
-  Args:
-    path: The directory path to expand.
-
-  Returns:
-    The expanded path.
-  """
-  return '%s/%s.scons' % (path, os.path.basename(path))
-
-
-def ReadVersion(filename):
-  """Executes the supplied file and pulls out a version definition from it. """
-  defs = {}
-  execfile(str(filename), defs)
-  if 'version' not in defs:
-    return '0.0.0.0'
-  version = defs['version']
-  parts = version.split(',')
-  build = os.environ.get('GOOGLE_VERSION_BUILDNUMBER')
-  if build:
-    parts[-1] = str(build)
-  return '.'.join(parts)
-
-
-#-------------------------------------------------------------------------------
-# Helper methods for translating talk.Foo() declarations in to manipulations of
-# environmuent construction variables, including parameter parsing and merging,
-#
-def PopEntry(dictionary, key):
-  """Get the value from a dictionary by key. If the key
-     isn't in the dictionary then None is returned. If it is in
-     the dictionary the value is fetched and then is it removed
-     from the dictionary.
-
-  Args:
-    dictionary: The dictionary.
-    key: The key to get the value for.
-  Returns:
-    The value or None if the key is missing.
-  """
-  value = None
-  if key in dictionary:
-    value = dictionary[key]
-    dictionary.pop(key)
-  return value
-
-
-def MergeAndFilterByPlatform(env, params):
-  """Take a dictionary of arguments to lists of values, and, depending on
-     which platform we are targetting, merge the lists of associated keys.
-     Merge by combining value lists like so:
-       {win_foo = [a,b], lin_foo = [c,d], foo = [e], mac_bar = [f], bar = [g] }
-       becomes {foo = [a,b,e], bar = [g]} on windows, and
-       {foo = [e], bar = [f,g]} on mac
-
-  Args:
-    env: The hammer environment which knows which platforms are active
-    params: The keyword argument dictionary.
-  Returns:
-    A new dictionary with the filtered and combined entries of params
-  """
-  platforms = {
-    'linux': 'lin_',
-    'mac': 'mac_',
-    'posix': 'posix_',
-    'windows': 'win_',
-  }
-  active_prefixes = [
-    platforms[x] for x in iter(platforms) if env.Bit(x)
-  ]
-  inactive_prefixes = [
-    platforms[x] for x in iter(platforms) if not env.Bit(x)
-  ]
-
-  merged = {}
-  for arg, values in params.iteritems():
-    inactive_platform = False
-
-    key = arg
-
-    for prefix in active_prefixes:
-      if arg.startswith(prefix):
-        key = arg[len(prefix):]
-
-    for prefix in inactive_prefixes:
-      if arg.startswith(prefix):
-        inactive_platform = True
-
-    if inactive_platform:
-      continue
-
-    AddToDict(merged, key, values)
-
-  return merged
-
-
-def MergeSettingsFromLibraryDependencies(env, params):
-  if 'libs' in params:
-    for lib in params['libs']:
-      libparams = _GetLibParams(env, lib)
-      if libparams:
-        if 'dependent_target_settings' in libparams:
-          params = CombineDicts(
-              params,
-              MergeAndFilterByPlatform(
-                  env,
-                  libparams['dependent_target_settings']))
-  return params
-
-
-def ExtendComponent(env, component, **kwargs):
-  """A wrapper around a scons builder function that preprocesses and post-
-     processes its inputs and outputs.  For example, it merges and filters
-     certain keyword arguments before appending them to the environments
-     construction variables.  It can build signed targets and 64bit copies
-     of targets as well.
-
-  Args:
-    env: The hammer environment with which to build the target
-    component: The environment's builder function, e.g. ComponentProgram
-    kwargs: keyword arguments that are either merged, translated, and passed on
-            to the call to component, or which control execution.
-            TODO(): Document the fields, such as cppdefines->CPPDEFINES,
-            prepend_includedirs, include_talk_media_libs, etc.
-  Returns:
-    The output node returned by the call to component, or a subsequent signed
-    dependant node.
-  """
-  env = env.Clone()
-
-  # prune parameters intended for other platforms, then merge
-  params = MergeAndFilterByPlatform(env, kwargs)
-
-  # get the 'target' field
-  name = PopEntry(params, 'name')
-
-  # get the 'packages' field and process it if present (only used for Linux).
-  packages = PopEntry(params, 'packages')
-  if packages and len(packages):
-    params = CombineDicts(params, env.GetPackageParams(packages))
-
-  # save pristine params of lib targets for future reference
-  if 'ComponentLibrary' == component:
-    _RecordLibParams(env, name, dict(params))
-
-  # add any dependent target settings from library dependencies
-  params = MergeSettingsFromLibraryDependencies(env, params)
-
-  # if this is a signed binary we need to make an unsigned version first
-  signed = env.Bit('windows') and PopEntry(params, 'signed')
-  if signed:
-    name = 'unsigned_' + name
-
-  # potentially exit now
-  srcs = PopEntry(params, 'srcs')
-  if not srcs or not hasattr(env, component):
-    return None
-
-  # apply any explicit dependencies
-  dependencies = PopEntry(params, 'depends')
-  if dependencies is not None:
-    env.Depends(name, dependencies)
-
-  # put the contents of params into the environment
-  # some entries are renamed then appended, others renamed then prepended
-  appends = {
-    'cppdefines' : 'CPPDEFINES',
-    'libdirs' : 'LIBPATH',
-    'link_flags' : 'LINKFLAGS',
-    'libs' : 'LIBS',
-    'FRAMEWORKS' : 'FRAMEWORKS',
-  }
-  prepends = {}
-  if env.Bit('windows'):
-    # MSVC compile flags have precedence at the beginning ...
-    prepends['ccflags'] = 'CCFLAGS'
-  else:
-    # ... while GCC compile flags have precedence at the end
-    appends['ccflags'] = 'CCFLAGS'
-  if PopEntry(params, 'prepend_includedirs'):
-    prepends['includedirs'] = 'CPPPATH'
-  else:
-    appends['includedirs'] = 'CPPPATH'
-
-  for field, var in appends.items():
-    values = PopEntry(params, field)
-    if values is not None:
-      env.Append(**{var : values})
-  for field, var in prepends.items():
-    values = PopEntry(params, field)
-    if values is not None:
-      env.Prepend(**{var : values})
-
-  # any other parameters are replaced without renaming
-  for field, value in params.items():
-    env.Replace(**{field : value})
-
-  if env.Bit('linux') and 'LIBS' in env:
-    libs = env['LIBS']
-    # When using --as-needed + --start/end-group, shared libraries need to come
-    # after --end-group on the command-line because the pruning decision only
-    # considers the preceding modules and --start/end-group may cause the
-    # effective position of early static libraries on the command-line to be
-    # deferred to the point of --end-group. To effect this, we move shared libs
-    # into _LIBFLAGS, which has the --end-group as its first entry. SCons does
-    # not track dependencies on system shared libraries anyway so we lose
-    # nothing by removing them from LIBS.
-    static_libs = [lib for lib in libs if
-                   _GetLibParams(env, lib) or _IsPrebuiltLibrary(env, lib)]
-    shared_libs = ['-l' + lib for lib in libs if not
-                   (_GetLibParams(env, lib) or _IsPrebuiltLibrary(env, lib))]
-    env.Replace(LIBS=static_libs)
-    env.Append(_LIBFLAGS=shared_libs)
-
-  # invoke the builder function
-  builder = getattr(env, component)
-
-  node = builder(name, srcs)
-
-  if signed:
-    # Get the name of the built binary, then get the name of the final signed
-    # version from it.  We need the output path since we don't know the file
-    # extension beforehand.
-    target = node[0].path.split('_', 1)[1]
-    # postsignprefix: If defined, postsignprefix is a string that should be
-    # prepended to the target executable.  This is to provide a work around
-    # for EXEs and DLLs with the same name, which thus have PDBs with the
-    # same name.  Setting postsignprefix allows the EXE and its PDB
-    # to be renamed and copied in a previous step; then the desired
-    # name of the EXE (but not PDB) is reconstructed after signing.
-    postsignprefix = PopEntry(params, 'postsignprefix')
-    if postsignprefix is not None:
-        target = postsignprefix + target
-    signed_node = env.SignedBinary(
-      source = node,
-      target = '$STAGING_DIR/' + target,
-    )
-    env.Alias('signed_binaries', signed_node)
-    return signed_node
-
-  return node
-
-
-def AddToDict(dictionary, key, values, append=True):
-  """Merge the given key value(s) pair into a dictionary.  If it contains an
-     entry with that key already, then combine by appending or prepending the
-     values as directed.  Otherwise, assign a new keyvalue pair.
-  """
-  if values is None:
-    return
-
-  if key not in dictionary:
-    dictionary[key] = values
-    return
-
-  cur = dictionary[key]
-  # TODO: Make sure that there are no duplicates
-  # in the list. I can't use python set for this since
-  # the nodes that are returned by the SCONS builders
-  # are not hashable.
-  # dictionary[key] = list(set(cur).union(set(values)))
-  if append:
-    dictionary[key] = cur + values
-  else:
-    dictionary[key] = values + cur
-
-
-def CombineDicts(a, b):
-  """Unions two dictionaries of arrays/dictionaries.
-
-  Unions two dictionaries of arrays/dictionaries by combining the values of keys
-  shared between them. The original dictionaries should not be used again after
-  this call.
-
-  Args:
-    a: First dict.
-    b: Second dict.
-
-  Returns:
-    The union of a and b.
-  """
-  c = {}
-  for key in a:
-    if key in b:
-      aval = a[key]
-      bval = b.pop(key)
-      if isinstance(aval, dict) and isinstance(bval, dict):
-        c[key] = CombineDicts(aval, bval)
-      else:
-        c[key] = aval + bval
-    else:
-      c[key] = a[key]
-
-  for key in b:
-    c[key] = b[key]
-
-  return c
-
-
-def RenameKey(d, old, new, append=True):
-  AddToDict(d, new, PopEntry(d, old), append)
diff --git a/third_party/libjingle/source/talk/sound/alsasoundsystem.cc b/third_party/libjingle/source/talk/sound/alsasoundsystem.cc
deleted file mode 100644
index c6dc73a..0000000
--- a/third_party/libjingle/source/talk/sound/alsasoundsystem.cc
+++ /dev/null
@@ -1,772 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/sound/alsasoundsystem.h"
-
-#include "talk/base/common.h"
-#include "talk/base/logging.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/base/stringutils.h"
-#include "talk/base/timeutils.h"
-#include "talk/base/worker.h"
-#include "talk/sound/sounddevicelocator.h"
-#include "talk/sound/soundinputstreaminterface.h"
-#include "talk/sound/soundoutputstreaminterface.h"
-
-namespace cricket {
-
-// Lookup table from the cricket format enum in soundsysteminterface.h to
-// ALSA's enums.
-static const snd_pcm_format_t kCricketFormatToAlsaFormatTable[] = {
-  // The order here must match the order in soundsysteminterface.h
-  SND_PCM_FORMAT_S16_LE,
-};
-
-// Lookup table for the size of a single sample of a given format.
-static const size_t kCricketFormatToSampleSizeTable[] = {
-  // The order here must match the order in soundsysteminterface.h
-  sizeof(int16_t),  // 2
-};
-
-// Minimum latency we allow, in microseconds. This is more or less arbitrary,
-// but it has to be at least large enough to be able to buffer data during a
-// missed context switch, and the typical Linux scheduling quantum is 10ms.
-static const int kMinimumLatencyUsecs = 20 * 1000;
-
-// The latency we'll use for kNoLatencyRequirements (chosen arbitrarily).
-static const int kDefaultLatencyUsecs = kMinimumLatencyUsecs * 2;
-
-// We translate newlines in ALSA device descriptions to hyphens.
-static const char kAlsaDescriptionSearch[] = "\n";
-static const char kAlsaDescriptionReplace[] = " - ";
-
-class AlsaDeviceLocator : public SoundDeviceLocator {
- public:
-  AlsaDeviceLocator(const std::string &name,
-                    const std::string &device_name)
-      : SoundDeviceLocator(name, device_name) {
-    // The ALSA descriptions have newlines in them, which won't show up in
-    // a drop-down box. Replace them with hyphens.
-    talk_base::replace_substrs(kAlsaDescriptionSearch,
-                               sizeof(kAlsaDescriptionSearch) - 1,
-                               kAlsaDescriptionReplace,
-                               sizeof(kAlsaDescriptionReplace) - 1,
-                               &name_);
-  }
-
-  virtual SoundDeviceLocator *Copy() const {
-    return new AlsaDeviceLocator(*this);
-  }
-};
-
-// Accesses ALSA functions through our late-binding symbol table instead of
-// directly. This way we don't have to link to libasound, which means our binary
-// will load faster and we can run on strange systems that may not have
-// libasound
-#define LATE(sym) \
-  LATESYM_GET(AlsaSymbolTable, &alsa_->symbol_table_, sym)
-
-// Functionality that is common to both AlsaInputStream and AlsaOutputStream.
-class AlsaStream {
- public:
-  AlsaStream(AlsaSoundSystem *alsa,
-             snd_pcm_t *handle,
-             size_t frame_size,
-             int wait_timeout_ms,
-             int flags,
-             int freq)
-      : alsa_(alsa),
-        handle_(handle),
-        frame_size_(frame_size),
-        wait_timeout_ms_(wait_timeout_ms),
-        flags_(flags),
-        freq_(freq) {
-  }
-
-  ~AlsaStream() {
-    Close();
-  }
-
-  // Waits for the stream to be ready to accept/return more data, and returns
-  // how much can be written/read, or 0 if we need to Wait() again.
-  snd_pcm_uframes_t Wait() {
-    snd_pcm_sframes_t frames;
-    // Ideally we would not use snd_pcm_wait() and instead hook snd_pcm_poll_*
-    // into PhysicalSocketServer, but PhysicalSocketServer is nasty enough
-    // already and the current clients of SoundSystemInterface do not run
-    // anything else on their worker threads, so snd_pcm_wait() is good enough.
-    frames = LATE(snd_pcm_avail_update)(handle_);
-    if (frames < 0) {
-      LOG(LS_ERROR) << "snd_pcm_avail_update(): " << GetError(frames);
-      Recover(frames);
-      return 0;
-    } else if (frames > 0) {
-      // Already ready, so no need to wait.
-      return frames;
-    }
-    // Else no space/data available, so must wait.
-    int ready = LATE(snd_pcm_wait)(handle_, wait_timeout_ms_);
-    if (ready < 0) {
-      LOG(LS_ERROR) << "snd_pcm_wait(): " << GetError(ready);
-      Recover(ready);
-      return 0;
-    } else if (ready == 0) {
-      // Timeout, so nothing can be written/read right now.
-      // We set the timeout to twice the requested latency, so continuous
-      // timeouts are indicative of a problem, so log as a warning.
-      LOG(LS_WARNING) << "Timeout while waiting on stream";
-      return 0;
-    }
-    // Else ready > 0 (i.e., 1), so it's ready. Get count.
-    frames = LATE(snd_pcm_avail_update)(handle_);
-    if (frames < 0) {
-      LOG(LS_ERROR) << "snd_pcm_avail_update(): " << GetError(frames);
-      Recover(frames);
-      return 0;
-    } else if (frames == 0) {
-      // wait() said we were ready, so this ought to have been positive. Has
-      // been observed to happen in practice though.
-      LOG(LS_WARNING) << "Spurious wake-up";
-    }
-    return frames;
-  }
-
-  int CurrentDelayUsecs() {
-    if (!(flags_ & SoundSystemInterface::FLAG_REPORT_LATENCY)) {
-      return 0;
-    }
-
-    snd_pcm_sframes_t delay;
-    int err = LATE(snd_pcm_delay)(handle_, &delay);
-    if (err != 0) {
-      LOG(LS_ERROR) << "snd_pcm_delay(): " << GetError(err);
-      Recover(err);
-      // We'd rather continue playout/capture with an incorrect delay than stop
-      // it altogether, so return a valid value.
-      return 0;
-    }
-    // The delay is in frames. Convert to microseconds.
-    return delay * talk_base::kNumMicrosecsPerSec / freq_;
-  }
-
-  // Used to recover from certain recoverable errors, principally buffer overrun
-  // or underrun (identified as EPIPE). Without calling this the stream stays
-  // in the error state forever.
-  bool Recover(int error) {
-    int err;
-    err = LATE(snd_pcm_recover)(handle_,
-                                error,
-                                // Silent; i.e., no logging on stderr.
-                                1);
-    if (err != 0) {
-      // Docs say snd_pcm_recover returns the original error if it is not one
-      // of the recoverable ones, so this log message will probably contain the
-      // same error twice.
-      LOG(LS_ERROR) << "Unable to recover from \"" << GetError(error) << "\": "
-                    << GetError(err);
-      return false;
-    }
-    if (error == -EPIPE &&  // Buffer underrun/overrun.
-        LATE(snd_pcm_stream)(handle_) == SND_PCM_STREAM_CAPTURE) {
-      // For capture streams we also have to repeat the explicit start() to get
-      // data flowing again.
-      err = LATE(snd_pcm_start)(handle_);
-      if (err != 0) {
-        LOG(LS_ERROR) << "snd_pcm_start(): " << GetError(err);
-        return false;
-      }
-    }
-    return true;
-  }
-
-  bool Close() {
-    if (handle_) {
-      int err;
-      err = LATE(snd_pcm_drop)(handle_);
-      if (err != 0) {
-        LOG(LS_ERROR) << "snd_pcm_drop(): " << GetError(err);
-        // Continue anyways.
-      }
-      err = LATE(snd_pcm_close)(handle_);
-      if (err != 0) {
-        LOG(LS_ERROR) << "snd_pcm_close(): " << GetError(err);
-        // Continue anyways.
-      }
-      handle_ = NULL;
-    }
-    return true;
-  }
-
-  AlsaSoundSystem *alsa() {
-    return alsa_;
-  }
-
-  snd_pcm_t *handle() {
-    return handle_;
-  }
-
-  const char *GetError(int err) {
-    return alsa_->GetError(err);
-  }
-
-  size_t frame_size() {
-    return frame_size_;
-  }
-
- private:
-  AlsaSoundSystem *alsa_;
-  snd_pcm_t *handle_;
-  size_t frame_size_;
-  int wait_timeout_ms_;
-  int flags_;
-  int freq_;
-
-  DISALLOW_COPY_AND_ASSIGN(AlsaStream);
-};
-
-// Redefine for the next two classes.
-#undef LATE
-#define LATE(sym) \
-  LATESYM_GET(AlsaSymbolTable, &stream_.alsa()->symbol_table_, sym)
-
-// Implementation of an input stream. See soundinputstreaminterface.h regarding
-// thread-safety.
-class AlsaInputStream :
-    public SoundInputStreamInterface,
-    private talk_base::Worker {
- public:
-  AlsaInputStream(AlsaSoundSystem *alsa,
-                  snd_pcm_t *handle,
-                  size_t frame_size,
-                  int wait_timeout_ms,
-                  int flags,
-                  int freq)
-      : stream_(alsa, handle, frame_size, wait_timeout_ms, flags, freq),
-        buffer_size_(0) {
-  }
-
-  virtual ~AlsaInputStream() {
-    bool success = StopReading();
-    // We need that to live.
-    VERIFY(success);
-  }
-
-  virtual bool StartReading() {
-    return StartWork();
-  }
-
-  virtual bool StopReading() {
-    return StopWork();
-  }
-
-  virtual bool GetVolume(int *volume) {
-    // TODO: Implement this.
-    return false;
-  }
-
-  virtual bool SetVolume(int volume) {
-    // TODO: Implement this.
-    return false;
-  }
-
-  virtual bool Close() {
-    return StopReading() && stream_.Close();
-  }
-
-  virtual int LatencyUsecs() {
-    return stream_.CurrentDelayUsecs();
-  }
-
- private:
-  // Inherited from Worker.
-  virtual void OnStart() {
-    HaveWork();
-  }
-
-  // Inherited from Worker.
-  virtual void OnHaveWork() {
-    // Block waiting for data.
-    snd_pcm_uframes_t avail = stream_.Wait();
-    if (avail > 0) {
-      // Data is available.
-      size_t size = avail * stream_.frame_size();
-      if (size > buffer_size_) {
-        // Must increase buffer size.
-        buffer_.reset(new char[size]);
-        buffer_size_ = size;
-      }
-      // Read all the data.
-      snd_pcm_sframes_t read = LATE(snd_pcm_readi)(stream_.handle(),
-                                                   buffer_.get(),
-                                                   avail);
-      if (read < 0) {
-        LOG(LS_ERROR) << "snd_pcm_readi(): " << GetError(read);
-        stream_.Recover(read);
-      } else if (read == 0) {
-        // Docs say this shouldn't happen.
-        ASSERT(false);
-        LOG(LS_ERROR) << "No data?";
-      } else {
-        // Got data. Pass it off to the app.
-        SignalSamplesRead(buffer_.get(),
-                          read * stream_.frame_size(),
-                          this);
-      }
-    }
-    // Check for more data with no delay, after any pending messages are
-    // dispatched.
-    HaveWork();
-  }
-
-  // Inherited from Worker.
-  virtual void OnStop() {
-    // Nothing to do.
-  }
-
-  const char *GetError(int err) {
-    return stream_.GetError(err);
-  }
-
-  AlsaStream stream_;
-  talk_base::scoped_array<char> buffer_;
-  size_t buffer_size_;
-
-  DISALLOW_COPY_AND_ASSIGN(AlsaInputStream);
-};
-
-// Implementation of an output stream. See soundoutputstreaminterface.h
-// regarding thread-safety.
-class AlsaOutputStream :
-    public SoundOutputStreamInterface,
-    private talk_base::Worker {
- public:
-  AlsaOutputStream(AlsaSoundSystem *alsa,
-                   snd_pcm_t *handle,
-                   size_t frame_size,
-                   int wait_timeout_ms,
-                   int flags,
-                   int freq)
-      : stream_(alsa, handle, frame_size, wait_timeout_ms, flags, freq) {
-  }
-
-  virtual ~AlsaOutputStream() {
-    bool success = DisableBufferMonitoring();
-    // We need that to live.
-    VERIFY(success);
-  }
-
-  virtual bool EnableBufferMonitoring() {
-    return StartWork();
-  }
-
-  virtual bool DisableBufferMonitoring() {
-    return StopWork();
-  }
-
-  virtual bool WriteSamples(const void *sample_data,
-                            size_t size) {
-    if (size % stream_.frame_size() != 0) {
-      // No client of SoundSystemInterface does this, so let's not support it.
-      // (If we wanted to support it, we'd basically just buffer the fractional
-      // frame until we get more data.)
-      ASSERT(false);
-      LOG(LS_ERROR) << "Writes with fractional frames are not supported";
-      return false;
-    }
-    snd_pcm_uframes_t frames = size / stream_.frame_size();
-    snd_pcm_sframes_t written = LATE(snd_pcm_writei)(stream_.handle(),
-                                                     sample_data,
-                                                     frames);
-    if (written < 0) {
-      LOG(LS_ERROR) << "snd_pcm_writei(): " << GetError(written);
-      stream_.Recover(written);
-      return false;
-    } else if (static_cast<snd_pcm_uframes_t>(written) < frames) {
-      // Shouldn't happen. Drop the rest of the data.
-      LOG(LS_ERROR) << "Stream wrote only " << written << " of " << frames
-                    << " frames!";
-      return false;
-    }
-    return true;
-  }
-
-  virtual bool GetVolume(int *volume) {
-    // TODO: Implement this.
-    return false;
-  }
-
-  virtual bool SetVolume(int volume) {
-    // TODO: Implement this.
-    return false;
-  }
-
-  virtual bool Close() {
-    return DisableBufferMonitoring() && stream_.Close();
-  }
-
-  virtual int LatencyUsecs() {
-    return stream_.CurrentDelayUsecs();
-  }
-
- private:
-  // Inherited from Worker.
-  virtual void OnStart() {
-    HaveWork();
-  }
-
-  // Inherited from Worker.
-  virtual void OnHaveWork() {
-    snd_pcm_uframes_t avail = stream_.Wait();
-    if (avail > 0) {
-      size_t space = avail * stream_.frame_size();
-      SignalBufferSpace(space, this);
-    }
-    HaveWork();
-  }
-
-  // Inherited from Worker.
-  virtual void OnStop() {
-    // Nothing to do.
-  }
-
-  const char *GetError(int err) {
-    return stream_.GetError(err);
-  }
-
-  AlsaStream stream_;
-
-  DISALLOW_COPY_AND_ASSIGN(AlsaOutputStream);
-};
-
-// Redefine for the main class.
-#undef LATE
-#define LATE(sym) LATESYM_GET(AlsaSymbolTable, &symbol_table_, sym)
-
-AlsaSoundSystem::AlsaSoundSystem() : initialized_(false) {}
-
-AlsaSoundSystem::~AlsaSoundSystem() {
-  // Not really necessary, because Terminate() doesn't really do anything.
-  Terminate();
-}
-
-bool AlsaSoundSystem::Init() {
-  if (IsInitialized()) {
-    return true;
-  }
-
-  // Load libasound.
-  if (!symbol_table_.Load()) {
-    // Very odd for a Linux machine to not have a working libasound ...
-    LOG(LS_ERROR) << "Failed to load symbol table";
-    return false;
-  }
-
-  initialized_ = true;
-
-  return true;
-}
-
-void AlsaSoundSystem::Terminate() {
-  if (!IsInitialized()) {
-    return;
-  }
-
-  initialized_ = false;
-
-  // We do not unload the symbol table because we may need it again soon if
-  // Init() is called again.
-}
-
-bool AlsaSoundSystem::EnumeratePlaybackDevices(
-    SoundDeviceLocatorList *devices) {
-  return EnumerateDevices(devices, false);
-}
-
-bool AlsaSoundSystem::EnumerateCaptureDevices(
-    SoundDeviceLocatorList *devices) {
-  return EnumerateDevices(devices, true);
-}
-
-bool AlsaSoundSystem::GetDefaultPlaybackDevice(SoundDeviceLocator **device) {
-  return GetDefaultDevice(device);
-}
-
-bool AlsaSoundSystem::GetDefaultCaptureDevice(SoundDeviceLocator **device) {
-  return GetDefaultDevice(device);
-}
-
-SoundOutputStreamInterface *AlsaSoundSystem::OpenPlaybackDevice(
-    const SoundDeviceLocator *device,
-    const OpenParams &params) {
-  return OpenDevice<SoundOutputStreamInterface>(
-      device,
-      params,
-      SND_PCM_STREAM_PLAYBACK,
-      &AlsaSoundSystem::StartOutputStream);
-}
-
-SoundInputStreamInterface *AlsaSoundSystem::OpenCaptureDevice(
-    const SoundDeviceLocator *device,
-    const OpenParams &params) {
-  return OpenDevice<SoundInputStreamInterface>(
-      device,
-      params,
-      SND_PCM_STREAM_CAPTURE,
-      &AlsaSoundSystem::StartInputStream);
-}
-
-const char *AlsaSoundSystem::GetName() const {
-  return "ALSA";
-}
-
-bool AlsaSoundSystem::EnumerateDevices(
-    SoundDeviceLocatorList *devices,
-    bool capture_not_playback) {
-  ClearSoundDeviceLocatorList(devices);
-
-  if (!IsInitialized()) {
-    return false;
-  }
-
-  const char *type = capture_not_playback ? "Input" : "Output";
-  // dmix and dsnoop are only for playback and capture, respectively, but ALSA
-  // stupidly includes them in both lists.
-  const char *ignore_prefix = capture_not_playback ? "dmix:" : "dsnoop:";
-  // (ALSA lists many more "devices" of questionable interest, but we show them
-  // just in case the weird devices may actually be desirable for some
-  // users/systems.)
-  const char *ignore_default = "default";
-  const char *ignore_null = "null";
-  const char *ignore_pulse = "pulse";
-  // The 'pulse' entry has a habit of mysteriously disappearing when you query
-  // a second time. Remove it from our list. (GIPS lib did the same thing.)
-  int err;
-
-  void **hints;
-  err = LATE(snd_device_name_hint)(-1,     // All cards
-                                   "pcm",  // Only PCM devices
-                                   &hints);
-  if (err != 0) {
-    LOG(LS_ERROR) << "snd_device_name_hint(): " << GetError(err);
-    return false;
-  }
-
-  for (void **list = hints; *list != NULL; ++list) {
-    char *actual_type = LATE(snd_device_name_get_hint)(*list, "IOID");
-    if (actual_type) {  // NULL means it's both.
-      bool wrong_type = (strcmp(actual_type, type) != 0);
-      free(actual_type);
-      if (wrong_type) {
-        // Wrong type of device (i.e., input vs. output).
-        continue;
-      }
-    }
-
-    char *name = LATE(snd_device_name_get_hint)(*list, "NAME");
-    if (!name) {
-      LOG(LS_ERROR) << "Device has no name???";
-      // Skip it.
-      continue;
-    }
-
-    // Now check if we actually want to show this device.
-    if (strcmp(name, ignore_default) != 0 &&
-        strcmp(name, ignore_null) != 0 &&
-        strcmp(name, ignore_pulse) != 0 &&
-        !talk_base::starts_with(name, ignore_prefix)) {
-
-      // Yes, we do.
-      char *desc = LATE(snd_device_name_get_hint)(*list, "DESC");
-      if (!desc) {
-        // Virtual devices don't necessarily have descriptions. Use their names
-        // instead (not pretty!).
-        desc = name;
-      }
-
-      AlsaDeviceLocator *device = new AlsaDeviceLocator(desc, name);
-
-      devices->push_back(device);
-
-      if (desc != name) {
-        free(desc);
-      }
-    }
-
-    free(name);
-  }
-
-  err = LATE(snd_device_name_free_hint)(hints);
-  if (err != 0) {
-    LOG(LS_ERROR) << "snd_device_name_free_hint(): " << GetError(err);
-    // Continue and return true anyways, since we did get the whole list.
-  }
-
-  return true;
-}
-
-bool AlsaSoundSystem::GetDefaultDevice(SoundDeviceLocator **device) {
-  if (!IsInitialized()) {
-    return false;
-  }
-  *device = new AlsaDeviceLocator("Default device", "default");
-  return true;
-}
-
-inline size_t AlsaSoundSystem::FrameSize(const OpenParams &params) {
-  ASSERT(params.format < ARRAY_SIZE(kCricketFormatToSampleSizeTable));
-  return kCricketFormatToSampleSizeTable[params.format] * params.channels;
-}
-
-template <typename StreamInterface>
-StreamInterface *AlsaSoundSystem::OpenDevice(
-    const SoundDeviceLocator *device,
-    const OpenParams &params,
-    snd_pcm_stream_t type,
-    StreamInterface *(AlsaSoundSystem::*start_fn)(
-        snd_pcm_t *handle,
-        size_t frame_size,
-        int wait_timeout_ms,
-        int flags,
-        int freq)) {
-
-  if (!IsInitialized()) {
-    return NULL;
-  }
-
-  StreamInterface *stream;
-  int err;
-
-  const char *dev = static_cast<const AlsaDeviceLocator *>(device)->
-      device_name().c_str();
-
-  snd_pcm_t *handle = NULL;
-  err = LATE(snd_pcm_open)(
-      &handle,
-      dev,
-      type,
-      // No flags.
-      0);
-  if (err != 0) {
-    LOG(LS_ERROR) << "snd_pcm_open(" << dev << "): " << GetError(err);
-    return NULL;
-  }
-  LOG(LS_VERBOSE) << "Opening " << dev;
-  ASSERT(handle);  // If open succeeded, handle ought to be valid
-
-  // Compute requested latency in microseconds.
-  int latency;
-  if (params.latency == kNoLatencyRequirements) {
-    latency = kDefaultLatencyUsecs;
-  } else {
-    // kLowLatency is 0, so we treat it the same as a request for zero latency.
-    // Compute what the user asked for.
-    latency = talk_base::kNumMicrosecsPerSec *
-        params.latency /
-        params.freq /
-        FrameSize(params);
-    // And this is what we'll actually use.
-    latency = talk_base::_max(latency, kMinimumLatencyUsecs);
-  }
-
-  ASSERT(params.format < ARRAY_SIZE(kCricketFormatToAlsaFormatTable));
-
-  err = LATE(snd_pcm_set_params)(handle,
-                                 kCricketFormatToAlsaFormatTable[params.format],
-                                 // SoundSystemInterface only supports
-                                 // interleaved audio.
-                                 SND_PCM_ACCESS_RW_INTERLEAVED,
-                                 params.channels,
-                                 params.freq,
-                                 1,  // Allow ALSA to resample.
-                                 latency);
-  if (err != 0) {
-    LOG(LS_ERROR) << "snd_pcm_set_params(): " << GetError(err);
-    goto fail;
-  }
-
-  err = LATE(snd_pcm_prepare)(handle);
-  if (err != 0) {
-    LOG(LS_ERROR) << "snd_pcm_prepare(): " << GetError(err);
-    goto fail;
-  }
-
-  stream = (this->*start_fn)(
-      handle,
-      FrameSize(params),
-      // We set the wait time to twice the requested latency, so that wait
-      // timeouts should be rare.
-      2 * latency / talk_base::kNumMicrosecsPerMillisec,
-      params.flags,
-      params.freq);
-  if (stream) {
-    return stream;
-  }
-  // Else fall through.
-
- fail:
-  err = LATE(snd_pcm_close)(handle);
-  if (err != 0) {
-    LOG(LS_ERROR) << "snd_pcm_close(): " << GetError(err);
-  }
-  return NULL;
-}
-
-SoundOutputStreamInterface *AlsaSoundSystem::StartOutputStream(
-    snd_pcm_t *handle,
-    size_t frame_size,
-    int wait_timeout_ms,
-    int flags,
-    int freq) {
-  // Nothing to do here but instantiate the stream.
-  return new AlsaOutputStream(
-      this, handle, frame_size, wait_timeout_ms, flags, freq);
-}
-
-SoundInputStreamInterface *AlsaSoundSystem::StartInputStream(
-    snd_pcm_t *handle,
-    size_t frame_size,
-    int wait_timeout_ms,
-    int flags,
-    int freq) {
-  // Output streams start automatically once enough data has been written, but
-  // input streams must be started manually or else snd_pcm_wait() will never
-  // return true.
-  int err;
-  err = LATE(snd_pcm_start)(handle);
-  if (err != 0) {
-    LOG(LS_ERROR) << "snd_pcm_start(): " << GetError(err);
-    return NULL;
-  }
-  return new AlsaInputStream(
-      this, handle, frame_size, wait_timeout_ms, flags, freq);
-}
-
-inline const char *AlsaSoundSystem::GetError(int err) {
-  return LATE(snd_strerror)(err);
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/sound/alsasoundsystem.h b/third_party/libjingle/source/talk/sound/alsasoundsystem.h
deleted file mode 100644
index b5402db..0000000
--- a/third_party/libjingle/source/talk/sound/alsasoundsystem.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SOUND_ALSASOUNDSYSTEM_H_
-#define TALK_SOUND_ALSASOUNDSYSTEM_H_
-
-#include <alsa/asoundlib.h>
-
-#include "talk/base/constructormagic.h"
-#include "talk/sound/alsasymboltable.h"
-#include "talk/sound/soundsysteminterface.h"
-
-namespace cricket {
-
-class AlsaStream;
-class AlsaInputStream;
-class AlsaOutputStream;
-
-// Sound system implementation for ALSA, the predominant sound device API on
-// Linux (but typically not used directly by applications anymore).
-class AlsaSoundSystem : public SoundSystemInterface {
-  friend class AlsaStream;
-  friend class AlsaInputStream;
-  friend class AlsaOutputStream;
- public:
-  static SoundSystemInterface *Create() {
-    return new AlsaSoundSystem();
-  }
-
-  AlsaSoundSystem();
-
-  virtual ~AlsaSoundSystem();
-
-  virtual bool Init();
-  virtual void Terminate();
-
-  virtual bool EnumeratePlaybackDevices(SoundDeviceLocatorList *devices);
-  virtual bool EnumerateCaptureDevices(SoundDeviceLocatorList *devices);
-
-  virtual bool GetDefaultPlaybackDevice(SoundDeviceLocator **device);
-  virtual bool GetDefaultCaptureDevice(SoundDeviceLocator **device);
-
-  virtual SoundOutputStreamInterface *OpenPlaybackDevice(
-      const SoundDeviceLocator *device,
-      const OpenParams &params);
-  virtual SoundInputStreamInterface *OpenCaptureDevice(
-      const SoundDeviceLocator *device,
-      const OpenParams &params);
-
-  virtual const char *GetName() const;
-
- private:
-  bool IsInitialized() { return initialized_; }
-
-  bool EnumerateDevices(SoundDeviceLocatorList *devices,
-                        bool capture_not_playback);
-
-  bool GetDefaultDevice(SoundDeviceLocator **device);
-
-  static size_t FrameSize(const OpenParams &params);
-
-  template <typename StreamInterface>
-  StreamInterface *OpenDevice(
-      const SoundDeviceLocator *device,
-      const OpenParams &params,
-      snd_pcm_stream_t type,
-      StreamInterface *(AlsaSoundSystem::*start_fn)(
-          snd_pcm_t *handle,
-          size_t frame_size,
-          int wait_timeout_ms,
-          int flags,
-          int freq));
-
-  SoundOutputStreamInterface *StartOutputStream(
-      snd_pcm_t *handle,
-      size_t frame_size,
-      int wait_timeout_ms,
-      int flags,
-      int freq);
-
-  SoundInputStreamInterface *StartInputStream(
-      snd_pcm_t *handle,
-      size_t frame_size,
-      int wait_timeout_ms,
-      int flags,
-      int freq);
-
-  const char *GetError(int err);
-
-  bool initialized_;
-  AlsaSymbolTable symbol_table_;
-
-  DISALLOW_COPY_AND_ASSIGN(AlsaSoundSystem);
-};
-
-}  // namespace cricket
-
-#endif  // TALK_SOUND_ALSASOUNDSYSTEM_H_
diff --git a/third_party/libjingle/source/talk/sound/alsasymboltable.cc b/third_party/libjingle/source/talk/sound/alsasymboltable.cc
deleted file mode 100644
index 803bb66..0000000
--- a/third_party/libjingle/source/talk/sound/alsasymboltable.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/sound/alsasymboltable.h"
-
-namespace cricket {
-
-LATE_BINDING_SYMBOL_TABLE_DEFINE_BEGIN(AlsaSymbolTable, "libasound.so.2")
-#define X(sym) \
-    LATE_BINDING_SYMBOL_TABLE_DEFINE_ENTRY(AlsaSymbolTable, sym)
-ALSA_SYMBOLS_LIST
-#undef X
-LATE_BINDING_SYMBOL_TABLE_DEFINE_END(AlsaSymbolTable)
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/sound/alsasymboltable.h b/third_party/libjingle/source/talk/sound/alsasymboltable.h
deleted file mode 100644
index faa6991..0000000
--- a/third_party/libjingle/source/talk/sound/alsasymboltable.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SOUND_ALSASYMBOLTABLE_H_
-#define TALK_SOUND_ALSASYMBOLTABLE_H_
-
-#include "talk/base/latebindingsymboltable.h"
-
-namespace cricket {
-
-// The ALSA symbols we need, as an X-Macro list.
-// This list must contain precisely every libasound function that is used in
-// alsasoundsystem.cc.
-#define ALSA_SYMBOLS_LIST \
-  X(snd_device_name_free_hint) \
-  X(snd_device_name_get_hint) \
-  X(snd_device_name_hint) \
-  X(snd_pcm_avail_update) \
-  X(snd_pcm_close) \
-  X(snd_pcm_delay) \
-  X(snd_pcm_drop) \
-  X(snd_pcm_open) \
-  X(snd_pcm_prepare) \
-  X(snd_pcm_readi) \
-  X(snd_pcm_recover) \
-  X(snd_pcm_set_params) \
-  X(snd_pcm_start) \
-  X(snd_pcm_stream) \
-  X(snd_pcm_wait) \
-  X(snd_pcm_writei) \
-  X(snd_strerror)
-
-LATE_BINDING_SYMBOL_TABLE_DECLARE_BEGIN(AlsaSymbolTable)
-#define X(sym) \
-    LATE_BINDING_SYMBOL_TABLE_DECLARE_ENTRY(AlsaSymbolTable, sym)
-ALSA_SYMBOLS_LIST
-#undef X
-LATE_BINDING_SYMBOL_TABLE_DECLARE_END(AlsaSymbolTable)
-
-}  // namespace cricket
-
-#endif  // TALK_SOUND_ALSASYMBOLTABLE_H_
diff --git a/third_party/libjingle/source/talk/sound/automaticallychosensoundsystem.h b/third_party/libjingle/source/talk/sound/automaticallychosensoundsystem.h
deleted file mode 100644
index 026c080..0000000
--- a/third_party/libjingle/source/talk/sound/automaticallychosensoundsystem.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SOUND_AUTOMATICALLYCHOSENSOUNDSYSTEM_H_
-#define TALK_SOUND_AUTOMATICALLYCHOSENSOUNDSYSTEM_H_
-
-#include "talk/base/common.h"
-#include "talk/base/logging.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/sound/soundsysteminterface.h"
-#include "talk/sound/soundsystemproxy.h"
-
-namespace cricket {
-
-// A function type that creates an instance of a sound system implementation.
-typedef SoundSystemInterface *(*SoundSystemCreator)();
-
-// An AutomaticallyChosenSoundSystem is a sound system proxy that defers to
-// an instance of the first sound system implementation in a list that
-// successfully initializes.
-template <const SoundSystemCreator kSoundSystemCreators[], int kNumSoundSystems>
-class AutomaticallyChosenSoundSystem : public SoundSystemProxy {
- public:
-  // Chooses and initializes the underlying sound system.
-  virtual bool Init();
-  // Terminates the underlying sound system implementation, but caches it for
-  // future re-use.
-  virtual void Terminate();
-
-  virtual const char *GetName() const;
-
- private:
-  talk_base::scoped_ptr<SoundSystemInterface> sound_systems_[kNumSoundSystems];
-};
-
-template <const SoundSystemCreator kSoundSystemCreators[], int kNumSoundSystems>
-bool AutomaticallyChosenSoundSystem<kSoundSystemCreators,
-                                    kNumSoundSystems>::Init() {
-  if (wrapped_) {
-    return true;
-  }
-  for (int i = 0; i < kNumSoundSystems; ++i) {
-    if (!sound_systems_[i].get()) {
-      sound_systems_[i].reset((*kSoundSystemCreators[i])());
-    }
-    if (sound_systems_[i]->Init()) {
-      // This is the first sound system in the list to successfully
-      // initialize, so we're done.
-      wrapped_ = sound_systems_[i].get();
-      break;
-    }
-    // Else it failed to initialize, so try the remaining ones.
-  }
-  if (!wrapped_) {
-    LOG(LS_ERROR) << "Failed to find a usable sound system";
-    return false;
-  }
-  LOG(LS_INFO) << "Selected " << wrapped_->GetName() << " sound system";
-  return true;
-}
-
-template <const SoundSystemCreator kSoundSystemCreators[], int kNumSoundSystems>
-void AutomaticallyChosenSoundSystem<kSoundSystemCreators,
-                                    kNumSoundSystems>::Terminate() {
-  if (!wrapped_) {
-    return;
-  }
-  wrapped_->Terminate();
-  wrapped_ = NULL;
-  // We do not free the scoped_ptrs because we may be re-init'ed soon.
-}
-
-template <const SoundSystemCreator kSoundSystemCreators[], int kNumSoundSystems>
-const char *AutomaticallyChosenSoundSystem<kSoundSystemCreators,
-                                           kNumSoundSystems>::GetName() const {
-  return wrapped_ ? wrapped_->GetName() : "automatic";
-}
-
-}  // namespace cricket
-
-#endif  // TALK_SOUND_AUTOMATICALLYCHOSENSOUNDSYSTEM_H_
diff --git a/third_party/libjingle/source/talk/sound/automaticallychosensoundsystem_unittest.cc b/third_party/libjingle/source/talk/sound/automaticallychosensoundsystem_unittest.cc
deleted file mode 100644
index a8afeec..0000000
--- a/third_party/libjingle/source/talk/sound/automaticallychosensoundsystem_unittest.cc
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/gunit.h"
-#include "talk/sound/automaticallychosensoundsystem.h"
-#include "talk/sound/nullsoundsystem.h"
-
-namespace cricket {
-
-class NeverFailsToFailSoundSystem : public NullSoundSystem {
- public:
-  // Overrides superclass.
-  virtual bool Init() {
-    return false;
-  }
-
-  static SoundSystemInterface *Create() {
-    return new NeverFailsToFailSoundSystem();
-  }
-};
-
-class InitCheckingSoundSystem1 : public NullSoundSystem {
- public:
-  // Overrides superclass.
-  virtual bool Init() {
-    created_ = true;
-    return true;
-  }
-
-  static SoundSystemInterface *Create() {
-    return new InitCheckingSoundSystem1();
-  }
-
-  static bool created_;
-};
-
-bool InitCheckingSoundSystem1::created_ = false;
-
-class InitCheckingSoundSystem2 : public NullSoundSystem {
- public:
-  // Overrides superclass.
-  virtual bool Init() {
-    created_ = true;
-    return true;
-  }
-
-  static SoundSystemInterface *Create() {
-    return new InitCheckingSoundSystem2();
-  }
-
-  static bool created_;
-};
-
-bool InitCheckingSoundSystem2::created_ = false;
-
-class DeletionCheckingSoundSystem1 : public NeverFailsToFailSoundSystem {
- public:
-  virtual ~DeletionCheckingSoundSystem1() {
-    deleted_ = true;
-  }
-
-  static SoundSystemInterface *Create() {
-    return new DeletionCheckingSoundSystem1();
-  }
-
-  static bool deleted_;
-};
-
-bool DeletionCheckingSoundSystem1::deleted_ = false;
-
-class DeletionCheckingSoundSystem2 : public NeverFailsToFailSoundSystem {
- public:
-  virtual ~DeletionCheckingSoundSystem2() {
-    deleted_ = true;
-  }
-
-  static SoundSystemInterface *Create() {
-    return new DeletionCheckingSoundSystem2();
-  }
-
-  static bool deleted_;
-};
-
-bool DeletionCheckingSoundSystem2::deleted_ = false;
-
-class DeletionCheckingSoundSystem3 : public NullSoundSystem {
- public:
-  virtual ~DeletionCheckingSoundSystem3() {
-    deleted_ = true;
-  }
-
-  static SoundSystemInterface *Create() {
-    return new DeletionCheckingSoundSystem3();
-  }
-
-  static bool deleted_;
-};
-
-bool DeletionCheckingSoundSystem3::deleted_ = false;
-
-extern const SoundSystemCreator kSingleSystemFailingCreators[] = {
-  &NeverFailsToFailSoundSystem::Create,
-};
-
-TEST(AutomaticallyChosenSoundSystem, SingleSystemFailing) {
-  AutomaticallyChosenSoundSystem<
-      kSingleSystemFailingCreators,
-      ARRAY_SIZE(kSingleSystemFailingCreators)> sound_system;
-  EXPECT_FALSE(sound_system.Init());
-}
-
-extern const SoundSystemCreator kSingleSystemSucceedingCreators[] = {
-  &NullSoundSystem::Create,
-};
-
-TEST(AutomaticallyChosenSoundSystem, SingleSystemSucceeding) {
-  AutomaticallyChosenSoundSystem<
-      kSingleSystemSucceedingCreators,
-      ARRAY_SIZE(kSingleSystemSucceedingCreators)> sound_system;
-  EXPECT_TRUE(sound_system.Init());
-}
-
-extern const SoundSystemCreator
-    kFailedFirstSystemResultsInUsingSecondCreators[] = {
-  &NeverFailsToFailSoundSystem::Create,
-  &NullSoundSystem::Create,
-};
-
-TEST(AutomaticallyChosenSoundSystem, FailedFirstSystemResultsInUsingSecond) {
-  AutomaticallyChosenSoundSystem<
-      kFailedFirstSystemResultsInUsingSecondCreators,
-      ARRAY_SIZE(kFailedFirstSystemResultsInUsingSecondCreators)> sound_system;
-  EXPECT_TRUE(sound_system.Init());
-}
-
-extern const SoundSystemCreator kEarlierEntriesHavePriorityCreators[] = {
-  &InitCheckingSoundSystem1::Create,
-  &InitCheckingSoundSystem2::Create,
-};
-
-TEST(AutomaticallyChosenSoundSystem, EarlierEntriesHavePriority) {
-  AutomaticallyChosenSoundSystem<
-      kEarlierEntriesHavePriorityCreators,
-      ARRAY_SIZE(kEarlierEntriesHavePriorityCreators)> sound_system;
-  InitCheckingSoundSystem1::created_ = false;
-  InitCheckingSoundSystem2::created_ = false;
-  EXPECT_TRUE(sound_system.Init());
-  EXPECT_TRUE(InitCheckingSoundSystem1::created_);
-  EXPECT_FALSE(InitCheckingSoundSystem2::created_);
-}
-
-extern const SoundSystemCreator kManySoundSystemsCreators[] = {
-  &NullSoundSystem::Create,
-  &NullSoundSystem::Create,
-  &NullSoundSystem::Create,
-  &NullSoundSystem::Create,
-  &NullSoundSystem::Create,
-  &NullSoundSystem::Create,
-  &NullSoundSystem::Create,
-};
-
-TEST(AutomaticallyChosenSoundSystem, ManySoundSystems) {
-  AutomaticallyChosenSoundSystem<
-      kManySoundSystemsCreators,
-      ARRAY_SIZE(kManySoundSystemsCreators)> sound_system;
-  EXPECT_TRUE(sound_system.Init());
-}
-
-extern const SoundSystemCreator kDeletesAllCreatedSoundSystemsCreators[] = {
-  &DeletionCheckingSoundSystem1::Create,
-  &DeletionCheckingSoundSystem2::Create,
-  &DeletionCheckingSoundSystem3::Create,
-};
-
-TEST(AutomaticallyChosenSoundSystem, DeletesAllCreatedSoundSystems) {
-  typedef AutomaticallyChosenSoundSystem<
-      kDeletesAllCreatedSoundSystemsCreators,
-      ARRAY_SIZE(kDeletesAllCreatedSoundSystemsCreators)> TestSoundSystem;
-  TestSoundSystem *sound_system = new TestSoundSystem();
-  DeletionCheckingSoundSystem1::deleted_ = false;
-  DeletionCheckingSoundSystem2::deleted_ = false;
-  DeletionCheckingSoundSystem3::deleted_ = false;
-  EXPECT_TRUE(sound_system->Init());
-  delete sound_system;
-  EXPECT_TRUE(DeletionCheckingSoundSystem1::deleted_);
-  EXPECT_TRUE(DeletionCheckingSoundSystem2::deleted_);
-  EXPECT_TRUE(DeletionCheckingSoundSystem3::deleted_);
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/sound/linuxsoundsystem.cc b/third_party/libjingle/source/talk/sound/linuxsoundsystem.cc
deleted file mode 100644
index 7980a15..0000000
--- a/third_party/libjingle/source/talk/sound/linuxsoundsystem.cc
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/sound/linuxsoundsystem.h"
-
-#include "talk/sound/alsasoundsystem.h"
-#include "talk/sound/pulseaudiosoundsystem.h"
-
-namespace cricket {
-
-const SoundSystemCreator kLinuxSoundSystemCreators[] = {
-#ifdef HAVE_LIBPULSE
-  &PulseAudioSoundSystem::Create,
-#endif
-  &AlsaSoundSystem::Create,
-};
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/sound/linuxsoundsystem.h b/third_party/libjingle/source/talk/sound/linuxsoundsystem.h
deleted file mode 100644
index eb48b88..0000000
--- a/third_party/libjingle/source/talk/sound/linuxsoundsystem.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SOUND_LINUXSOUNDSYSTEM_H_
-#define TALK_SOUND_LINUXSOUNDSYSTEM_H_
-
-#include "talk/sound/automaticallychosensoundsystem.h"
-
-namespace cricket {
-
-extern const SoundSystemCreator kLinuxSoundSystemCreators[
-#ifdef HAVE_LIBPULSE
-    2
-#else
-    1
-#endif
-    ];
-
-// The vast majority of Linux systems use ALSA for the device-level sound API,
-// but an increasing number are using PulseAudio for the application API and
-// only using ALSA internally in PulseAudio itself. But like everything on
-// Linux this is user-configurable, so we need to support both and choose the
-// right one at run-time.
-// PulseAudioSoundSystem is designed to only successfully initialize if
-// PulseAudio is installed and running, and if it is running then direct device
-// access using ALSA typically won't work, so if PulseAudioSoundSystem
-// initializes then we choose that. Otherwise we choose ALSA.
-typedef AutomaticallyChosenSoundSystem<
-    kLinuxSoundSystemCreators,
-    ARRAY_SIZE(kLinuxSoundSystemCreators)> LinuxSoundSystem;
-
-}  // namespace cricket
-
-#endif  // TALK_SOUND_LINUXSOUNDSYSTEM_H_
diff --git a/third_party/libjingle/source/talk/sound/nullsoundsystem.cc b/third_party/libjingle/source/talk/sound/nullsoundsystem.cc
deleted file mode 100644
index 2920008..0000000
--- a/third_party/libjingle/source/talk/sound/nullsoundsystem.cc
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/sound/nullsoundsystem.h"
-
-#include "talk/base/logging.h"
-#include "talk/sound/sounddevicelocator.h"
-#include "talk/sound/soundinputstreaminterface.h"
-#include "talk/sound/soundoutputstreaminterface.h"
-
-namespace talk_base {
-
-class Thread;
-
-}
-
-namespace cricket {
-
-// Name used for the single device and the sound system itself.
-static const char kNullName[] = "null";
-
-class NullSoundDeviceLocator : public SoundDeviceLocator {
- public:
-  NullSoundDeviceLocator() : SoundDeviceLocator(kNullName, kNullName) {}
-
-  virtual SoundDeviceLocator *Copy() const {
-    return new NullSoundDeviceLocator();
-  }
-};
-
-class NullSoundInputStream : public SoundInputStreamInterface {
- public:
-  virtual bool StartReading() {
-    return true;
-  }
-
-  virtual bool StopReading() {
-    return true;
-  }
-
-  virtual bool GetVolume(int *volume) {
-    *volume = SoundSystemInterface::kMinVolume;
-    return true;
-  }
-
-  virtual bool SetVolume(int volume) {
-    return false;
-  }
-
-  virtual bool Close() {
-    return true;
-  }
-
-  virtual int LatencyUsecs() {
-    return 0;
-  }
-};
-
-class NullSoundOutputStream : public SoundOutputStreamInterface {
- public:
-  virtual bool EnableBufferMonitoring() {
-    return true;
-  }
-
-  virtual bool DisableBufferMonitoring() {
-    return true;
-  }
-
-  virtual bool WriteSamples(const void *sample_data,
-                            size_t size) {
-    LOG(LS_VERBOSE) << "Got " << size << " bytes of playback samples";
-    return true;
-  }
-
-  virtual bool GetVolume(int *volume) {
-    *volume = SoundSystemInterface::kMinVolume;
-    return true;
-  }
-
-  virtual bool SetVolume(int volume) {
-    return false;
-  }
-
-  virtual bool Close() {
-    return true;
-  }
-
-  virtual int LatencyUsecs() {
-    return 0;
-  }
-};
-
-NullSoundSystem::~NullSoundSystem() {
-}
-
-bool NullSoundSystem::Init() {
-  return true;
-}
-
-void NullSoundSystem::Terminate() {
-  // Nothing to do.
-}
-
-bool NullSoundSystem::EnumeratePlaybackDevices(
-      SoundSystemInterface::SoundDeviceLocatorList *devices) {
-  ClearSoundDeviceLocatorList(devices);
-  SoundDeviceLocator *device;
-  GetDefaultPlaybackDevice(&device);
-  devices->push_back(device);
-  return true;
-}
-
-bool NullSoundSystem::EnumerateCaptureDevices(
-      SoundSystemInterface::SoundDeviceLocatorList *devices) {
-  ClearSoundDeviceLocatorList(devices);
-  SoundDeviceLocator *device;
-  GetDefaultCaptureDevice(&device);
-  devices->push_back(device);
-  return true;
-}
-
-bool NullSoundSystem::GetDefaultPlaybackDevice(
-    SoundDeviceLocator **device) {
-  *device = new NullSoundDeviceLocator();
-  return true;
-}
-
-bool NullSoundSystem::GetDefaultCaptureDevice(
-    SoundDeviceLocator **device) {
-  *device = new NullSoundDeviceLocator();
-  return true;
-}
-
-SoundOutputStreamInterface *NullSoundSystem::OpenPlaybackDevice(
-      const SoundDeviceLocator *device,
-      const OpenParams &params) {
-  return new NullSoundOutputStream();
-}
-
-SoundInputStreamInterface *NullSoundSystem::OpenCaptureDevice(
-      const SoundDeviceLocator *device,
-      const OpenParams &params) {
-  return new NullSoundInputStream();
-}
-
-const char *NullSoundSystem::GetName() const {
-  return kNullName;
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/sound/nullsoundsystem.h b/third_party/libjingle/source/talk/sound/nullsoundsystem.h
deleted file mode 100644
index 3edb4f9..0000000
--- a/third_party/libjingle/source/talk/sound/nullsoundsystem.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SOUND_NULLSOUNDSYSTEM_H_
-#define TALK_SOUND_NULLSOUNDSYSTEM_H_
-
-#include "talk/sound/soundsysteminterface.h"
-
-namespace cricket {
-
-class SoundDeviceLocator;
-class SoundInputStreamInterface;
-class SoundOutputStreamInterface;
-
-// A simple reference sound system that drops output samples and generates
-// no input samples.
-class NullSoundSystem : public SoundSystemInterface {
- public:
-  static SoundSystemInterface *Create() {
-    return new NullSoundSystem();
-  }
-
-  virtual ~NullSoundSystem();
-
-  virtual bool Init();
-  virtual void Terminate();
-
-  virtual bool EnumeratePlaybackDevices(SoundDeviceLocatorList *devices);
-  virtual bool EnumerateCaptureDevices(SoundDeviceLocatorList *devices);
-
-  virtual SoundOutputStreamInterface *OpenPlaybackDevice(
-      const SoundDeviceLocator *device,
-      const OpenParams &params);
-  virtual SoundInputStreamInterface *OpenCaptureDevice(
-      const SoundDeviceLocator *device,
-      const OpenParams &params);
-
-  virtual bool GetDefaultPlaybackDevice(SoundDeviceLocator **device);
-  virtual bool GetDefaultCaptureDevice(SoundDeviceLocator **device);
-
-  virtual const char *GetName() const;
-};
-
-}  // namespace cricket
-
-#endif  // TALK_SOUND_NULLSOUNDSYSTEM_H_
diff --git a/third_party/libjingle/source/talk/sound/nullsoundsystemfactory.cc b/third_party/libjingle/source/talk/sound/nullsoundsystemfactory.cc
deleted file mode 100644
index 089d51f..0000000
--- a/third_party/libjingle/source/talk/sound/nullsoundsystemfactory.cc
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/sound/nullsoundsystemfactory.h"
-
-#include "talk/sound/nullsoundsystem.h"
-
-namespace cricket {
-
-NullSoundSystemFactory::NullSoundSystemFactory() {
-}
-
-NullSoundSystemFactory::~NullSoundSystemFactory() {
-}
-
-bool NullSoundSystemFactory::SetupInstance() {
-  instance_.reset(new NullSoundSystem());
-  return true;
-}
-
-void NullSoundSystemFactory::CleanupInstance() {
-  instance_.reset();
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/sound/nullsoundsystemfactory.h b/third_party/libjingle/source/talk/sound/nullsoundsystemfactory.h
deleted file mode 100644
index 71ae980..0000000
--- a/third_party/libjingle/source/talk/sound/nullsoundsystemfactory.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SOUND_NULLSOUNDSYSTEMFACTORY_H_
-#define TALK_SOUND_NULLSOUNDSYSTEMFACTORY_H_
-
-#include "talk/sound/soundsystemfactory.h"
-
-namespace cricket {
-
-// A SoundSystemFactory that always returns a NullSoundSystem. Intended for
-// testing.
-class NullSoundSystemFactory : public SoundSystemFactory {
- public:
-  NullSoundSystemFactory();
-  virtual ~NullSoundSystemFactory();
-
- protected:
-  // Inherited from SoundSystemFactory.
-  virtual bool SetupInstance();
-  virtual void CleanupInstance();
-};
-
-}  // namespace cricket
-
-#endif  // TALK_SOUND_NULLSOUNDSYSTEMFACTORY_H_
diff --git a/third_party/libjingle/source/talk/sound/platformsoundsystem.cc b/third_party/libjingle/source/talk/sound/platformsoundsystem.cc
deleted file mode 100644
index 9dff9ae..0000000
--- a/third_party/libjingle/source/talk/sound/platformsoundsystem.cc
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/sound/platformsoundsystem.h"
-
-#include "talk/base/common.h"
-#ifdef LINUX
-#include "talk/sound/linuxsoundsystem.h"
-#else
-#include "talk/sound/nullsoundsystem.h"
-#endif
-
-namespace cricket {
-
-SoundSystemInterface *CreatePlatformSoundSystem() {
-#ifdef LINUX
-  return new LinuxSoundSystem();
-#else
-  ASSERT(false && "Not implemented");
-  return new NullSoundSystem();
-#endif
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/sound/platformsoundsystem.h b/third_party/libjingle/source/talk/sound/platformsoundsystem.h
deleted file mode 100644
index 1a8d214..0000000
--- a/third_party/libjingle/source/talk/sound/platformsoundsystem.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SOUND_PLATFORMSOUNDSYSTEM_H_
-#define TALK_SOUND_PLATFORMSOUNDSYSTEM_H_
-
-namespace cricket {
-
-class SoundSystemInterface;
-
-// Creates the sound system implementation for this platform.
-SoundSystemInterface *CreatePlatformSoundSystem();
-
-}  // namespace cricket
-
-#endif  // TALK_SOUND_PLATFORMSOUNDSYSTEM_H_
diff --git a/third_party/libjingle/source/talk/sound/platformsoundsystemfactory.cc b/third_party/libjingle/source/talk/sound/platformsoundsystemfactory.cc
deleted file mode 100644
index 6c69954..0000000
--- a/third_party/libjingle/source/talk/sound/platformsoundsystemfactory.cc
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/sound/platformsoundsystemfactory.h"
-
-#include "talk/sound/platformsoundsystem.h"
-#include "talk/sound/soundsysteminterface.h"
-
-namespace cricket {
-
-PlatformSoundSystemFactory::PlatformSoundSystemFactory() {
-}
-
-PlatformSoundSystemFactory::~PlatformSoundSystemFactory() {
-}
-
-bool PlatformSoundSystemFactory::SetupInstance() {
-  if (!instance_.get()) {
-    instance_.reset(CreatePlatformSoundSystem());
-  }
-  if (!instance_->Init()) {
-    LOG(LS_ERROR) << "Can't initialize platform's sound system";
-    return false;
-  }
-  return true;
-}
-
-void PlatformSoundSystemFactory::CleanupInstance() {
-  instance_->Terminate();
-  // We do not delete the sound system because we might be re-initialized soon.
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/sound/platformsoundsystemfactory.h b/third_party/libjingle/source/talk/sound/platformsoundsystemfactory.h
deleted file mode 100644
index 63ca863..0000000
--- a/third_party/libjingle/source/talk/sound/platformsoundsystemfactory.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SOUND_PLATFORMSOUNDSYSTEMFACTORY_H_
-#define TALK_SOUND_PLATFORMSOUNDSYSTEMFACTORY_H_
-
-#include "talk/sound/soundsystemfactory.h"
-
-namespace cricket {
-
-// A SoundSystemFactory that returns the platform's native sound system
-// implementation.
-class PlatformSoundSystemFactory : public SoundSystemFactory {
- public:
-  PlatformSoundSystemFactory();
-  virtual ~PlatformSoundSystemFactory();
-
- protected:
-  // Inherited from SoundSystemFactory.
-  virtual bool SetupInstance();
-  virtual void CleanupInstance();
-};
-
-}  // namespace cricket
-
-#endif  // TALK_SOUND_PLATFORMSOUNDSYSTEMFACTORY_H_
-
-
diff --git a/third_party/libjingle/source/talk/sound/pulseaudiosoundsystem.cc b/third_party/libjingle/source/talk/sound/pulseaudiosoundsystem.cc
deleted file mode 100644
index 14aa119..0000000
--- a/third_party/libjingle/source/talk/sound/pulseaudiosoundsystem.cc
+++ /dev/null
@@ -1,1564 +0,0 @@
-/*
- * libjingle
- * Copyright 2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/sound/pulseaudiosoundsystem.h"
-
-#ifdef HAVE_LIBPULSE
-
-#include <pulse/context.h>
-#include <pulse/error.h>
-#include <pulse/introspect.h>
-#include <pulse/stream.h>
-#include <pulse/thread-mainloop.h>
-
-#include "talk/base/common.h"
-#include "talk/base/fileutils.h"  // for GetApplicationName()
-#include "talk/base/logging.h"
-#include "talk/base/worker.h"
-#include "talk/base/timeutils.h"
-#include "talk/sound/sounddevicelocator.h"
-#include "talk/sound/soundinputstreaminterface.h"
-#include "talk/sound/soundoutputstreaminterface.h"
-
-namespace cricket {
-
-// First PulseAudio protocol version that supports PA_STREAM_ADJUST_LATENCY.
-static const uint32_t kAdjustLatencyProtocolVersion = 13;
-
-// We define this flag if it's missing from our headers, because we want to be
-// able to compile against old headers but still use PA_STREAM_ADJUST_LATENCY
-// if run against a recent version of the library.
-#ifndef PA_STREAM_ADJUST_LATENCY
-#define PA_STREAM_ADJUST_LATENCY 0x2000U
-#endif
-
-// Lookup table from the cricket format enum in soundsysteminterface.h to
-// Pulse's enums.
-static const pa_sample_format_t kCricketFormatToPulseFormatTable[] = {
-  // The order here must match the order in soundsysteminterface.h
-  PA_SAMPLE_S16LE,
-};
-
-// Some timing constants for optimal operation. See
-// https://tango.0pointer.de/pipermail/pulseaudio-discuss/2008-January/001170.html
-// for a good explanation of some of the factors that go into this.
-
-// Playback.
-
-// For playback, there is a round-trip delay to fill the server-side playback
-// buffer, so setting too low of a latency is a buffer underflow risk. We will
-// automatically increase the latency if a buffer underflow does occur, but we
-// also enforce a sane minimum at start-up time. Anything lower would be
-// virtually guaranteed to underflow at least once, so there's no point in
-// allowing lower latencies.
-static const int kPlaybackLatencyMinimumMsecs = 20;
-// Every time a playback stream underflows, we will reconfigure it with target
-// latency that is greater by this amount.
-static const int kPlaybackLatencyIncrementMsecs = 20;
-// We also need to configure a suitable request size. Too small and we'd burn
-// CPU from the overhead of transfering small amounts of data at once. Too large
-// and the amount of data remaining in the buffer right before refilling it
-// would be a buffer underflow risk. We set it to half of the buffer size.
-static const int kPlaybackRequestFactor = 2;
-
-// Capture.
-
-// For capture, low latency is not a buffer overflow risk, but it makes us burn
-// CPU from the overhead of transfering small amounts of data at once, so we set
-// a recommended value that we use for the kLowLatency constant (but if the user
-// explicitly requests something lower then we will honour it).
-// 1ms takes about 6-7% CPU. 5ms takes about 5%. 10ms takes about 4.x%.
-static const int kLowCaptureLatencyMsecs = 10;
-// There is a round-trip delay to ack the data to the server, so the
-// server-side buffer needs extra space to prevent buffer overflow. 20ms is
-// sufficient, but there is no penalty to making it bigger, so we make it huge.
-// (750ms is libpulse's default value for the _total_ buffer size in the
-// kNoLatencyRequirements case.)
-static const int kCaptureBufferExtraMsecs = 750;
-
-static void FillPlaybackBufferAttr(int latency,
-                                   pa_buffer_attr *attr) {
-  attr->maxlength = latency;
-  attr->tlength = latency;
-  attr->minreq = latency / kPlaybackRequestFactor;
-  attr->prebuf = attr->tlength - attr->minreq;
-  LOG(LS_VERBOSE) << "Configuring latency = " << attr->tlength << ", minreq = "
-                  << attr->minreq << ", minfill = " << attr->prebuf;
-}
-
-static pa_volume_t CricketVolumeToPulseVolume(int volume) {
-  // PA's volume space goes from 0% at PA_VOLUME_MUTED (value 0) to 100% at
-  // PA_VOLUME_NORM (value 0x10000). It can also go beyond 100% up to
-  // PA_VOLUME_MAX (value UINT32_MAX-1), but using that is probably unwise.
-  // We just linearly map the 0-255 scale of SoundSystemInterface onto
-  // PA_VOLUME_MUTED-PA_VOLUME_NORM. If the programmer exceeds kMaxVolume then
-  // they can access the over-100% features of PA.
-  return PA_VOLUME_MUTED + (PA_VOLUME_NORM - PA_VOLUME_MUTED) *
-      volume / SoundSystemInterface::kMaxVolume;
-}
-
-static int PulseVolumeToCricketVolume(pa_volume_t pa_volume) {
-  return SoundSystemInterface::kMinVolume +
-      (SoundSystemInterface::kMaxVolume - SoundSystemInterface::kMinVolume) *
-      pa_volume / PA_VOLUME_NORM;
-}
-
-static pa_volume_t MaxChannelVolume(pa_cvolume *channel_volumes) {
-  pa_volume_t pa_volume = PA_VOLUME_MUTED;  // Minimum possible value.
-  for (int i = 0; i < channel_volumes->channels; ++i) {
-    if (pa_volume < channel_volumes->values[i]) {
-      pa_volume = channel_volumes->values[i];
-    }
-  }
-  return pa_volume;
-}
-
-class PulseAudioDeviceLocator : public SoundDeviceLocator {
- public:
-  PulseAudioDeviceLocator(const std::string &name,
-                          const std::string &device_name)
-      : SoundDeviceLocator(name, device_name) {
-  }
-
-  virtual SoundDeviceLocator *Copy() const {
-    return new PulseAudioDeviceLocator(*this);
-  }
-};
-
-// Accesses Pulse functions through our late-binding symbol table instead of
-// directly. This way we don't have to link to libpulse, which means our binary
-// will work on systems that don't have it.
-#define LATE(sym) \
-  LATESYM_GET(PulseAudioSymbolTable, &pulse_->symbol_table_, sym)
-
-// Functionality that is common to both PulseAudioInputStream and
-// PulseAudioOutputStream.
-class PulseAudioStream {
- public:
-  PulseAudioStream(PulseAudioSoundSystem *pulse, pa_stream *stream, int flags)
-      : pulse_(pulse), stream_(stream), flags_(flags) {
-  }
-
-  ~PulseAudioStream() {
-    // Close() should have been called during the containing class's destructor.
-    ASSERT(stream_ == NULL);
-  }
-
-  // Must be called with the lock held.
-  bool Close() {
-    if (!IsClosed()) {
-      // Unset this here so that we don't get a TERMINATED callback.
-      LATE(pa_stream_set_state_callback)(stream_, NULL, NULL);
-      if (LATE(pa_stream_disconnect)(stream_) != 0) {
-        LOG(LS_ERROR) << "Can't disconnect stream";
-        // Continue and return true anyways.
-      }
-      LATE(pa_stream_unref)(stream_);
-      stream_ = NULL;
-    }
-    return true;
-  }
-
-  // Must be called with the lock held.
-  int LatencyUsecs() {
-    if (!(flags_ & SoundSystemInterface::FLAG_REPORT_LATENCY)) {
-      return 0;
-    }
-
-    pa_usec_t latency;
-    int negative;
-    Lock();
-    int re = LATE(pa_stream_get_latency)(stream_, &latency, &negative);
-    Unlock();
-    if (re != 0) {
-      LOG(LS_ERROR) << "Can't query latency";
-      // We'd rather continue playout/capture with an incorrect delay than stop
-      // it altogether, so return a valid value.
-      return 0;
-    }
-    if (negative) {
-      // The delay can be negative for monitoring streams if the captured
-      // samples haven't been played yet. In such a case, "latency" contains the
-      // magnitude, so we must negate it to get the real value.
-      return -latency;
-    } else {
-      return latency;
-    }
-  }
-
-  PulseAudioSoundSystem *pulse() {
-    return pulse_;
-  }
-
-  pa_stream *stream() {
-    ASSERT(stream_ != NULL);
-    return stream_;
-  }
-
-  bool IsClosed() {
-    return stream_ == NULL;
-  }
-
-  void Lock() {
-    pulse()->Lock();
-  }
-
-  void Unlock() {
-    pulse()->Unlock();
-  }
-
- private:
-  PulseAudioSoundSystem *pulse_;
-  pa_stream *stream_;
-  int flags_;
-
-  DISALLOW_COPY_AND_ASSIGN(PulseAudioStream);
-};
-
-// Redefine for the next two classes.
-#undef LATE
-#define LATE(sym) \
-  LATESYM_GET(PulseAudioSymbolTable, &stream_.pulse()->symbol_table_, sym)
-
-// Implementation of an input stream. See soundinputstreaminterface.h regarding
-// thread-safety.
-class PulseAudioInputStream :
-    public SoundInputStreamInterface,
-    private talk_base::Worker {
-
-  struct GetVolumeCallbackData {
-    PulseAudioInputStream *instance;
-    pa_cvolume *channel_volumes;
-  };
-
-  struct GetSourceChannelCountCallbackData {
-    PulseAudioInputStream *instance;
-    uint8_t *channels;
-  };
-
- public:
-  PulseAudioInputStream(PulseAudioSoundSystem *pulse,
-                        pa_stream *stream,
-                        int flags)
-      : stream_(pulse, stream, flags),
-        temp_sample_data_(NULL),
-        temp_sample_data_size_(0) {
-    // This callback seems to never be issued, but let's set it anyways.
-    LATE(pa_stream_set_overflow_callback)(stream, &OverflowCallback, NULL);
-  }
-
-  virtual ~PulseAudioInputStream() {
-    bool success = Close();
-    // We need that to live.
-    VERIFY(success);
-  }
-
-  virtual bool StartReading() {
-    return StartWork();
-  }
-
-  virtual bool StopReading() {
-    return StopWork();
-  }
-
-  virtual bool GetVolume(int *volume) {
-    bool ret = false;
-
-    Lock();
-
-    // Unlike output streams, input streams have no concept of a stream volume,
-    // only a device volume. So we have to retrieve the volume of the device
-    // itself.
-
-    pa_cvolume channel_volumes;
-
-    GetVolumeCallbackData data;
-    data.instance = this;
-    data.channel_volumes = &channel_volumes;
-
-    pa_operation *op = LATE(pa_context_get_source_info_by_index)(
-        stream_.pulse()->context_,
-        LATE(pa_stream_get_device_index)(stream_.stream()),
-        &GetVolumeCallbackThunk,
-        &data);
-    if (!stream_.pulse()->FinishOperation(op)) {
-      goto done;
-    }
-
-    if (data.channel_volumes) {
-      // This pointer was never unset by the callback, so we must have received
-      // an empty list of infos. This probably never happens, but we code for it
-      // anyway.
-      LOG(LS_ERROR) << "Did not receive GetVolumeCallback";
-      goto done;
-    }
-
-    // We now have the volume for each channel. Each channel could have a
-    // different volume if, e.g., the user went and changed the volumes in the
-    // PA UI. To get a single volume for SoundSystemInterface we just take the
-    // maximum. Ideally we'd do so with pa_cvolume_max, but it doesn't exist in
-    // Hardy, so we do it manually.
-    pa_volume_t pa_volume;
-    pa_volume = MaxChannelVolume(&channel_volumes);
-    // Now map onto the SoundSystemInterface range.
-    *volume = PulseVolumeToCricketVolume(pa_volume);
-
-    ret = true;
-   done:
-    Unlock();
-    return ret;
-  }
-
-  virtual bool SetVolume(int volume) {
-    bool ret = false;
-    pa_volume_t pa_volume = CricketVolumeToPulseVolume(volume);
-
-    Lock();
-
-    // Unlike output streams, input streams have no concept of a stream volume,
-    // only a device volume. So we have to change the volume of the device
-    // itself.
-
-    // The device may have a different number of channels than the stream and
-    // their mapping may be different, so we don't want to use the channel count
-    // from our sample spec. We could use PA_CHANNELS_MAX to cover our bases,
-    // and the server allows that even if the device's channel count is lower,
-    // but some buggy PA clients don't like that (the pavucontrol on Hardy dies
-    // in an assert if the channel count is different). So instead we look up
-    // the actual number of channels that the device has.
-
-    uint8_t channels;
-
-    GetSourceChannelCountCallbackData data;
-    data.instance = this;
-    data.channels = &channels;
-
-    uint32_t device_index = LATE(pa_stream_get_device_index)(stream_.stream());
-
-    pa_operation *op = LATE(pa_context_get_source_info_by_index)(
-        stream_.pulse()->context_,
-        device_index,
-        &GetSourceChannelCountCallbackThunk,
-        &data);
-    if (!stream_.pulse()->FinishOperation(op)) {
-      goto done;
-    }
-
-    if (data.channels) {
-      // This pointer was never unset by the callback, so we must have received
-      // an empty list of infos. This probably never happens, but we code for it
-      // anyway.
-      LOG(LS_ERROR) << "Did not receive GetSourceChannelCountCallback";
-      goto done;
-    }
-
-    pa_cvolume channel_volumes;
-    LATE(pa_cvolume_set)(&channel_volumes, channels, pa_volume);
-
-    op = LATE(pa_context_set_source_volume_by_index)(
-        stream_.pulse()->context_,
-        device_index,
-        &channel_volumes,
-        // This callback merely logs errors.
-        &SetVolumeCallback,
-        NULL);
-    if (!op) {
-      LOG(LS_ERROR) << "pa_context_set_source_volume_by_index()";
-      goto done;
-    }
-    // Don't need to wait for this to complete.
-    LATE(pa_operation_unref)(op);
-
-    ret = true;
-   done:
-    Unlock();
-    return ret;
-  }
-
-  virtual bool Close() {
-    if (!StopReading()) {
-      return false;
-    }
-    bool ret = true;
-    if (!stream_.IsClosed()) {
-      Lock();
-      ret = stream_.Close();
-      Unlock();
-    }
-    return ret;
-  }
-
-  virtual int LatencyUsecs() {
-    return stream_.LatencyUsecs();
-  }
-
- private:
-  void Lock() {
-    stream_.Lock();
-  }
-
-  void Unlock() {
-    stream_.Unlock();
-  }
-
-  void EnableReadCallback() {
-    LATE(pa_stream_set_read_callback)(
-         stream_.stream(),
-         &ReadCallbackThunk,
-         this);
-  }
-
-  void DisableReadCallback() {
-    LATE(pa_stream_set_read_callback)(
-         stream_.stream(),
-         NULL,
-         NULL);
-  }
-
-  static void ReadCallbackThunk(pa_stream *unused1,
-                                size_t unused2,
-                                void *userdata) {
-    PulseAudioInputStream *instance =
-        static_cast<PulseAudioInputStream *>(userdata);
-    instance->OnReadCallback();
-  }
-
-  void OnReadCallback() {
-    // We get the data pointer and size now in order to save one Lock/Unlock
-    // on OnMessage.
-    if (LATE(pa_stream_peek)(stream_.stream(),
-                             &temp_sample_data_,
-                             &temp_sample_data_size_) != 0) {
-      LOG(LS_ERROR) << "Can't read data!";
-      return;
-    }
-    // Since we consume the data asynchronously on a different thread, we have
-    // to temporarily disable the read callback or else Pulse will call it
-    // continuously until we consume the data. We re-enable it below.
-    DisableReadCallback();
-    HaveWork();
-  }
-
-  // Inherited from Worker.
-  virtual void OnStart() {
-    Lock();
-    EnableReadCallback();
-    Unlock();
-  }
-
-  // Inherited from Worker.
-  virtual void OnHaveWork() {
-    ASSERT(temp_sample_data_ && temp_sample_data_size_);
-    SignalSamplesRead(temp_sample_data_,
-                      temp_sample_data_size_,
-                      this);
-    temp_sample_data_ = NULL;
-    temp_sample_data_size_ = 0;
-
-    Lock();
-    for (;;) {
-      // Ack the last thing we read.
-      if (LATE(pa_stream_drop)(stream_.stream()) != 0) {
-        LOG(LS_ERROR) << "Can't ack read data";
-      }
-
-      if (LATE(pa_stream_readable_size)(stream_.stream()) <= 0) {
-        // Then that was all the data.
-        break;
-      }
-
-      // Else more data.
-      const void *sample_data;
-      size_t sample_data_size;
-      if (LATE(pa_stream_peek)(stream_.stream(),
-                               &sample_data,
-                               &sample_data_size) != 0) {
-        LOG(LS_ERROR) << "Can't read data!";
-        break;
-      }
-
-      // Drop lock for sigslot dispatch, which could take a while.
-      Unlock();
-      SignalSamplesRead(sample_data, sample_data_size, this);
-      Lock();
-
-      // Return to top of loop for the ack and the check for more data.
-    }
-    EnableReadCallback();
-    Unlock();
-  }
-
-  // Inherited from Worker.
-  virtual void OnStop() {
-    Lock();
-    DisableReadCallback();
-    Unlock();
-  }
-
-  static void OverflowCallback(pa_stream *stream,
-                               void *userdata) {
-    LOG(LS_WARNING) << "Buffer overflow on capture stream " << stream;
-  }
-
-  static void GetVolumeCallbackThunk(pa_context *unused,
-                                     const pa_source_info *info,
-                                     int eol,
-                                     void *userdata) {
-    GetVolumeCallbackData *data =
-        static_cast<GetVolumeCallbackData *>(userdata);
-    data->instance->OnGetVolumeCallback(info, eol, &data->channel_volumes);
-  }
-
-  void OnGetVolumeCallback(const pa_source_info *info,
-                           int eol,
-                           pa_cvolume **channel_volumes) {
-    if (eol) {
-      // List is over. Wake GetVolume().
-      stream_.pulse()->Signal();
-      return;
-    }
-
-    if (*channel_volumes) {
-      **channel_volumes = info->volume;
-      // Unset the pointer so that we know that we have have already copied the
-      // volume.
-      *channel_volumes = NULL;
-    } else {
-      // We have received an additional callback after the first one, which
-      // doesn't make sense for a single source. This probably never happens,
-      // but we code for it anyway.
-      LOG(LS_WARNING) << "Ignoring extra GetVolumeCallback";
-    }
-  }
-
-  static void GetSourceChannelCountCallbackThunk(pa_context *unused,
-                                                 const pa_source_info *info,
-                                                 int eol,
-                                                 void *userdata) {
-    GetSourceChannelCountCallbackData *data =
-        static_cast<GetSourceChannelCountCallbackData *>(userdata);
-    data->instance->OnGetSourceChannelCountCallback(info, eol, &data->channels);
-  }
-
-  void OnGetSourceChannelCountCallback(const pa_source_info *info,
-                                       int eol,
-                                       uint8_t **channels) {
-    if (eol) {
-      // List is over. Wake SetVolume().
-      stream_.pulse()->Signal();
-      return;
-    }
-
-    if (*channels) {
-      **channels = info->channel_map.channels;
-      // Unset the pointer so that we know that we have have already copied the
-      // channel count.
-      *channels = NULL;
-    } else {
-      // We have received an additional callback after the first one, which
-      // doesn't make sense for a single source. This probably never happens,
-      // but we code for it anyway.
-      LOG(LS_WARNING) << "Ignoring extra GetSourceChannelCountCallback";
-    }
-  }
-
-  static void SetVolumeCallback(pa_context *unused1,
-                                int success,
-                                void *unused2) {
-    if (!success) {
-      LOG(LS_ERROR) << "Failed to change capture volume";
-    }
-  }
-
-  PulseAudioStream stream_;
-  // Temporary storage for passing data between threads.
-  const void *temp_sample_data_;
-  size_t temp_sample_data_size_;
-
-  DISALLOW_COPY_AND_ASSIGN(PulseAudioInputStream);
-};
-
-// Implementation of an output stream. See soundoutputstreaminterface.h
-// regarding thread-safety.
-class PulseAudioOutputStream :
-    public SoundOutputStreamInterface,
-    private talk_base::Worker {
-
-  struct GetVolumeCallbackData {
-    PulseAudioOutputStream *instance;
-    pa_cvolume *channel_volumes;
-  };
-
- public:
-  PulseAudioOutputStream(PulseAudioSoundSystem *pulse,
-                         pa_stream *stream,
-                         int flags,
-                         int latency)
-      : stream_(pulse, stream, flags),
-        configured_latency_(latency),
-        temp_buffer_space_(0) {
-    LATE(pa_stream_set_underflow_callback)(stream,
-                                           &UnderflowCallbackThunk,
-                                           this);
-  }
-
-  virtual ~PulseAudioOutputStream() {
-    bool success = Close();
-    // We need that to live.
-    VERIFY(success);
-  }
-
-  virtual bool EnableBufferMonitoring() {
-    return StartWork();
-  }
-
-  virtual bool DisableBufferMonitoring() {
-    return StopWork();
-  }
-
-  virtual bool WriteSamples(const void *sample_data,
-                            size_t size) {
-    bool ret = true;
-    Lock();
-    if (LATE(pa_stream_write)(stream_.stream(),
-                              sample_data,
-                              size,
-                              NULL,
-                              0,
-                              PA_SEEK_RELATIVE) != 0) {
-      LOG(LS_ERROR) << "Unable to write";
-      ret = false;
-    }
-    Unlock();
-    return ret;
-  }
-
-  virtual bool GetVolume(int *volume) {
-    bool ret = false;
-
-    Lock();
-
-    pa_cvolume channel_volumes;
-
-    GetVolumeCallbackData data;
-    data.instance = this;
-    data.channel_volumes = &channel_volumes;
-
-    pa_operation *op = LATE(pa_context_get_sink_input_info)(
-        stream_.pulse()->context_,
-        LATE(pa_stream_get_index)(stream_.stream()),
-        &GetVolumeCallbackThunk,
-        &data);
-    if (!stream_.pulse()->FinishOperation(op)) {
-      goto done;
-    }
-
-    if (data.channel_volumes) {
-      // This pointer was never unset by the callback, so we must have received
-      // an empty list of infos. This probably never happens, but we code for it
-      // anyway.
-      LOG(LS_ERROR) << "Did not receive GetVolumeCallback";
-      goto done;
-    }
-
-    // We now have the volume for each channel. Each channel could have a
-    // different volume if, e.g., the user went and changed the volumes in the
-    // PA UI. To get a single volume for SoundSystemInterface we just take the
-    // maximum. Ideally we'd do so with pa_cvolume_max, but it doesn't exist in
-    // Hardy, so we do it manually.
-    pa_volume_t pa_volume;
-    pa_volume = MaxChannelVolume(&channel_volumes);
-    // Now map onto the SoundSystemInterface range.
-    *volume = PulseVolumeToCricketVolume(pa_volume);
-
-    ret = true;
-   done:
-    Unlock();
-    return ret;
-  }
-
-  virtual bool SetVolume(int volume) {
-    bool ret = false;
-    pa_volume_t pa_volume = CricketVolumeToPulseVolume(volume);
-
-    Lock();
-
-    const pa_sample_spec *spec = LATE(pa_stream_get_sample_spec)(
-        stream_.stream());
-    if (!spec) {
-      LOG(LS_ERROR) << "pa_stream_get_sample_spec()";
-      goto done;
-    }
-
-    pa_cvolume channel_volumes;
-    LATE(pa_cvolume_set)(&channel_volumes, spec->channels, pa_volume);
-
-    pa_operation *op;
-    op = LATE(pa_context_set_sink_input_volume)(
-        stream_.pulse()->context_,
-        LATE(pa_stream_get_index)(stream_.stream()),
-        &channel_volumes,
-        // This callback merely logs errors.
-        &SetVolumeCallback,
-        NULL);
-    if (!op) {
-      LOG(LS_ERROR) << "pa_context_set_sink_input_volume()";
-      goto done;
-    }
-    // Don't need to wait for this to complete.
-    LATE(pa_operation_unref)(op);
-
-    ret = true;
-   done:
-    Unlock();
-    return ret;
-  }
-
-  virtual bool Close() {
-    if (!DisableBufferMonitoring()) {
-      return false;
-    }
-    bool ret = true;
-    if (!stream_.IsClosed()) {
-      Lock();
-      LATE(pa_stream_set_underflow_callback)(stream_.stream(),
-                                             NULL,
-                                             NULL);
-      ret = stream_.Close();
-      Unlock();
-    }
-    return ret;
-  }
-
-  virtual int LatencyUsecs() {
-    return stream_.LatencyUsecs();
-  }
-
-#if 0
-  // TODO: Versions 0.9.16 and later of Pulse have a new API for
-  // zero-copy writes, but Hardy is not new enough to have that so we can't
-  // rely on it. Perhaps auto-detect if it's present or not and use it if we
-  // can?
-
-  virtual bool GetWriteBuffer(void **buffer, size_t *size) {
-    bool ret = true;
-    Lock();
-    if (LATE(pa_stream_begin_write)(stream_.stream(), buffer, size) != 0) {
-      LOG(LS_ERROR) << "Can't get write buffer";
-      ret = false;
-    }
-    Unlock();
-    return ret;
-  }
-
-  // Releases the caller's hold on the write buffer. "written" must be the
-  // amount of data that was written.
-  virtual bool ReleaseWriteBuffer(void *buffer, size_t written) {
-    bool ret = true;
-    Lock();
-    if (written == 0) {
-      if (LATE(pa_stream_cancel_write)(stream_.stream()) != 0) {
-        LOG(LS_ERROR) << "Can't cancel write";
-        ret = false;
-      }
-    } else {
-      if (LATE(pa_stream_write)(stream_.stream(),
-                                buffer,
-                                written,
-                                NULL,
-                                0,
-                                PA_SEEK_RELATIVE) != 0) {
-        LOG(LS_ERROR) << "Unable to write";
-        ret = false;
-      }
-    }
-    Unlock();
-    return ret;
-  }
-#endif
-
- private:
-  void Lock() {
-    stream_.Lock();
-  }
-
-  void Unlock() {
-    stream_.Unlock();
-  }
-
-  void EnableWriteCallback() {
-    pa_stream_state_t state = LATE(pa_stream_get_state)(stream_.stream());
-    if (state == PA_STREAM_READY) {
-      // May already have available space. Must check.
-      temp_buffer_space_ = LATE(pa_stream_writable_size)(stream_.stream());
-      if (temp_buffer_space_ > 0) {
-        // Yup, there is already space available, so if we register a write
-        // callback then it will not receive any event. So dispatch one ourself
-        // instead.
-        HaveWork();
-        return;
-      }
-    }
-    LATE(pa_stream_set_write_callback)(
-         stream_.stream(),
-         &WriteCallbackThunk,
-         this);
-  }
-
-  void DisableWriteCallback() {
-    LATE(pa_stream_set_write_callback)(
-         stream_.stream(),
-         NULL,
-         NULL);
-  }
-
-  static void WriteCallbackThunk(pa_stream *unused,
-                                 size_t buffer_space,
-                                 void *userdata) {
-    PulseAudioOutputStream *instance =
-        static_cast<PulseAudioOutputStream *>(userdata);
-    instance->OnWriteCallback(buffer_space);
-  }
-
-  void OnWriteCallback(size_t buffer_space) {
-    temp_buffer_space_ = buffer_space;
-    // Since we write the data asynchronously on a different thread, we have
-    // to temporarily disable the write callback or else Pulse will call it
-    // continuously until we write the data. We re-enable it below.
-    DisableWriteCallback();
-    HaveWork();
-  }
-
-  // Inherited from Worker.
-  virtual void OnStart() {
-    Lock();
-    EnableWriteCallback();
-    Unlock();
-  }
-
-  // Inherited from Worker.
-  virtual void OnHaveWork() {
-    ASSERT(temp_buffer_space_ > 0);
-
-    SignalBufferSpace(temp_buffer_space_, this);
-
-    temp_buffer_space_ = 0;
-    Lock();
-    EnableWriteCallback();
-    Unlock();
-  }
-
-  // Inherited from Worker.
-  virtual void OnStop() {
-    Lock();
-    DisableWriteCallback();
-    Unlock();
-  }
-
-  static void UnderflowCallbackThunk(pa_stream *unused,
-                                     void *userdata) {
-    PulseAudioOutputStream *instance =
-        static_cast<PulseAudioOutputStream *>(userdata);
-    instance->OnUnderflowCallback();
-  }
-
-  void OnUnderflowCallback() {
-    LOG(LS_WARNING) << "Buffer underflow on playback stream "
-                    << stream_.stream();
-
-    if (configured_latency_ == SoundSystemInterface::kNoLatencyRequirements) {
-      // We didn't configure a pa_buffer_attr before, so switching to one now
-      // would be questionable.
-      return;
-    }
-
-    // Otherwise reconfigure the stream with a higher target latency.
-
-    const pa_sample_spec *spec = LATE(pa_stream_get_sample_spec)(
-        stream_.stream());
-    if (!spec) {
-      LOG(LS_ERROR) << "pa_stream_get_sample_spec()";
-      return;
-    }
-
-    size_t bytes_per_sec = LATE(pa_bytes_per_second)(spec);
-
-    int new_latency = configured_latency_ +
-        bytes_per_sec * kPlaybackLatencyIncrementMsecs /
-        talk_base::kNumMicrosecsPerSec;
-
-    pa_buffer_attr new_attr = {0};
-    FillPlaybackBufferAttr(new_latency, &new_attr);
-
-    pa_operation *op = LATE(pa_stream_set_buffer_attr)(stream_.stream(),
-                                                       &new_attr,
-                                                       // No callback.
-                                                       NULL,
-                                                       NULL);
-    if (!op) {
-      LOG(LS_ERROR) << "pa_stream_set_buffer_attr()";
-      return;
-    }
-    // Don't need to wait for this to complete.
-    LATE(pa_operation_unref)(op);
-
-    // Save the new latency in case we underflow again.
-    configured_latency_ = new_latency;
-  }
-
-  static void GetVolumeCallbackThunk(pa_context *unused,
-                                     const pa_sink_input_info *info,
-                                     int eol,
-                                     void *userdata) {
-    GetVolumeCallbackData *data =
-        static_cast<GetVolumeCallbackData *>(userdata);
-    data->instance->OnGetVolumeCallback(info, eol, &data->channel_volumes);
-  }
-
-  void OnGetVolumeCallback(const pa_sink_input_info *info,
-                           int eol,
-                           pa_cvolume **channel_volumes) {
-    if (eol) {
-      // List is over. Wake GetVolume().
-      stream_.pulse()->Signal();
-      return;
-    }
-
-    if (*channel_volumes) {
-      **channel_volumes = info->volume;
-      // Unset the pointer so that we know that we have have already copied the
-      // volume.
-      *channel_volumes = NULL;
-    } else {
-      // We have received an additional callback after the first one, which
-      // doesn't make sense for a single sink input. This probably never
-      // happens, but we code for it anyway.
-      LOG(LS_WARNING) << "Ignoring extra GetVolumeCallback";
-    }
-  }
-
-  static void SetVolumeCallback(pa_context *unused1,
-                                int success,
-                                void *unused2) {
-    if (!success) {
-      LOG(LS_ERROR) << "Failed to change playback volume";
-    }
-  }
-
-  PulseAudioStream stream_;
-  int configured_latency_;
-  // Temporary storage for passing data between threads.
-  size_t temp_buffer_space_;
-
-  DISALLOW_COPY_AND_ASSIGN(PulseAudioOutputStream);
-};
-
-// Redefine for the main class.
-#undef LATE
-#define LATE(sym) \
-  LATESYM_GET(PulseAudioSymbolTable, &symbol_table_, sym)
-
-PulseAudioSoundSystem::PulseAudioSoundSystem()
-    : mainloop_(NULL), context_(NULL) {
-}
-
-PulseAudioSoundSystem::~PulseAudioSoundSystem() {
-  Terminate();
-}
-
-bool PulseAudioSoundSystem::Init() {
-  if (IsInitialized()) {
-    return true;
-  }
-
-  // Load libpulse.
-  if (!symbol_table_.Load()) {
-    // Most likely the Pulse library and sound server are not installed on
-    // this system.
-    LOG(LS_WARNING) << "Failed to load symbol table";
-    return false;
-  }
-
-  // Now create and start the Pulse event thread.
-  mainloop_ = LATE(pa_threaded_mainloop_new)();
-  if (!mainloop_) {
-    LOG(LS_ERROR) << "Can't create mainloop";
-    goto fail0;
-  }
-
-  if (LATE(pa_threaded_mainloop_start)(mainloop_) != 0) {
-    LOG(LS_ERROR) << "Can't start mainloop";
-    goto fail1;
-  }
-
-  Lock();
-  context_ = CreateNewConnection();
-  Unlock();
-
-  if (!context_) {
-    goto fail2;
-  }
-
-  // Otherwise we're now ready!
-  return true;
-
- fail2:
-  LATE(pa_threaded_mainloop_stop)(mainloop_);
- fail1:
-  LATE(pa_threaded_mainloop_free)(mainloop_);
-  mainloop_ = NULL;
- fail0:
-  return false;
-}
-
-void PulseAudioSoundSystem::Terminate() {
-  if (!IsInitialized()) {
-    return;
-  }
-
-  Lock();
-  LATE(pa_context_disconnect)(context_);
-  LATE(pa_context_unref)(context_);
-  Unlock();
-  context_ = NULL;
-  LATE(pa_threaded_mainloop_stop)(mainloop_);
-  LATE(pa_threaded_mainloop_free)(mainloop_);
-  mainloop_ = NULL;
-
-  // We do not unload the symbol table because we may need it again soon if
-  // Init() is called again.
-}
-
-bool PulseAudioSoundSystem::EnumeratePlaybackDevices(
-    SoundDeviceLocatorList *devices) {
-  return EnumerateDevices<pa_sink_info>(
-      devices,
-      &LATE(pa_context_get_sink_info_list),
-      &EnumeratePlaybackDevicesCallbackThunk);
-}
-
-bool PulseAudioSoundSystem::EnumerateCaptureDevices(
-    SoundDeviceLocatorList *devices) {
-  return EnumerateDevices<pa_source_info>(
-      devices,
-      &LATE(pa_context_get_source_info_list),
-      &EnumerateCaptureDevicesCallbackThunk);
-}
-
-bool PulseAudioSoundSystem::GetDefaultPlaybackDevice(
-    SoundDeviceLocator **device) {
-  return GetDefaultDevice<&pa_server_info::default_sink_name>(device);
-}
-
-bool PulseAudioSoundSystem::GetDefaultCaptureDevice(
-    SoundDeviceLocator **device) {
-  return GetDefaultDevice<&pa_server_info::default_source_name>(device);
-}
-
-SoundOutputStreamInterface *PulseAudioSoundSystem::OpenPlaybackDevice(
-    const SoundDeviceLocator *device,
-    const OpenParams &params) {
-  return OpenDevice<SoundOutputStreamInterface>(
-      device,
-      params,
-      "Playback",
-      &PulseAudioSoundSystem::ConnectOutputStream);
-}
-
-SoundInputStreamInterface *PulseAudioSoundSystem::OpenCaptureDevice(
-    const SoundDeviceLocator *device,
-    const OpenParams &params) {
-  return OpenDevice<SoundInputStreamInterface>(
-      device,
-      params,
-      "Capture",
-      &PulseAudioSoundSystem::ConnectInputStream);
-}
-
-const char *PulseAudioSoundSystem::GetName() const {
-  return "PulseAudio";
-}
-
-inline bool PulseAudioSoundSystem::IsInitialized() {
-  return mainloop_ != NULL;
-}
-
-struct ConnectToPulseCallbackData {
-  PulseAudioSoundSystem *instance;
-  bool connect_done;
-};
-
-void PulseAudioSoundSystem::ConnectToPulseCallbackThunk(
-    pa_context *context, void *userdata) {
-  ConnectToPulseCallbackData *data =
-      static_cast<ConnectToPulseCallbackData *>(userdata);
-  data->instance->OnConnectToPulseCallback(context, &data->connect_done);
-}
-
-void PulseAudioSoundSystem::OnConnectToPulseCallback(
-    pa_context *context, bool *connect_done) {
-  pa_context_state_t state = LATE(pa_context_get_state)(context);
-  if (state == PA_CONTEXT_READY ||
-      state == PA_CONTEXT_FAILED ||
-      state == PA_CONTEXT_TERMINATED) {
-    // Connection process has reached a terminal state. Wake ConnectToPulse().
-    *connect_done = true;
-    Signal();
-  }
-}
-
-// Must be called with the lock held.
-bool PulseAudioSoundSystem::ConnectToPulse(pa_context *context) {
-  bool ret = true;
-  ConnectToPulseCallbackData data;
-  // Have to put this up here to satisfy the compiler.
-  pa_context_state_t state;
-
-  data.instance = this;
-  data.connect_done = false;
-
-  LATE(pa_context_set_state_callback)(context,
-                                      &ConnectToPulseCallbackThunk,
-                                      &data);
-
-  // Connect to PulseAudio sound server.
-  if (LATE(pa_context_connect)(context,
-                               NULL,          // Default server
-                               PA_CONTEXT_NOAUTOSPAWN,
-                               NULL) != 0) {  // No special fork handling needed
-    LOG(LS_ERROR) << "Can't start connection to PulseAudio sound server";
-    ret = false;
-    goto done;
-  }
-
-  // Wait for the connection state machine to reach a terminal state.
-  do {
-    Wait();
-  } while (!data.connect_done);
-
-  // Now check to see what final state we reached.
-  state = LATE(pa_context_get_state)(context);
-
-  if (state != PA_CONTEXT_READY) {
-    if (state == PA_CONTEXT_FAILED) {
-      LOG(LS_ERROR) << "Failed to connect to PulseAudio sound server";
-    } else if (state == PA_CONTEXT_TERMINATED) {
-      LOG(LS_ERROR) << "PulseAudio connection terminated early";
-    } else {
-      // Shouldn't happen, because we only signal on one of those three states.
-      LOG(LS_ERROR) << "Unknown problem connecting to PulseAudio";
-    }
-    ret = false;
-  }
-
- done:
-  // We unset our callback for safety just in case the state might somehow
-  // change later, because the pointer to "data" will be invalid after return
-  // from this function.
-  LATE(pa_context_set_state_callback)(context, NULL, NULL);
-  return ret;
-}
-
-// Must be called with the lock held.
-pa_context *PulseAudioSoundSystem::CreateNewConnection() {
-  // Create connection context.
-  std::string app_name;
-  // TODO: Pulse etiquette says this name should be localized. Do
-  // we care?
-  talk_base::Filesystem::GetApplicationName(&app_name);
-  pa_context *context = LATE(pa_context_new)(
-      LATE(pa_threaded_mainloop_get_api)(mainloop_),
-      app_name.c_str());
-  if (!context) {
-    LOG(LS_ERROR) << "Can't create context";
-    goto fail0;
-  }
-
-  // Now connect.
-  if (!ConnectToPulse(context)) {
-    goto fail1;
-  }
-
-  // Otherwise the connection succeeded and is ready.
-  return context;
-
- fail1:
-  LATE(pa_context_unref)(context);
- fail0:
-  return NULL;
-}
-
-struct EnumerateDevicesCallbackData {
-  PulseAudioSoundSystem *instance;
-  SoundSystemInterface::SoundDeviceLocatorList *devices;
-};
-
-void PulseAudioSoundSystem::EnumeratePlaybackDevicesCallbackThunk(
-    pa_context *unused,
-    const pa_sink_info *info,
-    int eol,
-    void *userdata) {
-  EnumerateDevicesCallbackData *data =
-      static_cast<EnumerateDevicesCallbackData *>(userdata);
-  data->instance->OnEnumeratePlaybackDevicesCallback(data->devices, info, eol);
-}
-
-void PulseAudioSoundSystem::EnumerateCaptureDevicesCallbackThunk(
-    pa_context *unused,
-    const pa_source_info *info,
-    int eol,
-    void *userdata) {
-  EnumerateDevicesCallbackData *data =
-      static_cast<EnumerateDevicesCallbackData *>(userdata);
-  data->instance->OnEnumerateCaptureDevicesCallback(data->devices, info, eol);
-}
-
-void PulseAudioSoundSystem::OnEnumeratePlaybackDevicesCallback(
-    SoundDeviceLocatorList *devices,
-    const pa_sink_info *info,
-    int eol) {
-  if (eol) {
-    // List is over. Wake EnumerateDevices().
-    Signal();
-    return;
-  }
-
-  // Else this is the next device.
-  devices->push_back(
-      new PulseAudioDeviceLocator(info->description, info->name));
-}
-
-void PulseAudioSoundSystem::OnEnumerateCaptureDevicesCallback(
-    SoundDeviceLocatorList *devices,
-    const pa_source_info *info,
-    int eol) {
-  if (eol) {
-    // List is over. Wake EnumerateDevices().
-    Signal();
-    return;
-  }
-
-  if (info->monitor_of_sink != PA_INVALID_INDEX) {
-    // We don't want to list monitor sources, since they are almost certainly
-    // not what the user wants for voice conferencing.
-    return;
-  }
-
-  // Else this is the next device.
-  devices->push_back(
-      new PulseAudioDeviceLocator(info->description, info->name));
-}
-
-template <typename InfoStruct>
-bool PulseAudioSoundSystem::EnumerateDevices(
-    SoundDeviceLocatorList *devices,
-    pa_operation *(*enumerate_fn)(
-        pa_context *c,
-        void (*callback_fn)(
-            pa_context *c,
-            const InfoStruct *i,
-            int eol,
-            void *userdata),
-        void *userdata),
-    void (*callback_fn)(
-        pa_context *c,
-        const InfoStruct *i,
-        int eol,
-        void *userdata)) {
-  ClearSoundDeviceLocatorList(devices);
-  if (!IsInitialized()) {
-    return false;
-  }
-
-  EnumerateDevicesCallbackData data;
-  data.instance = this;
-  data.devices = devices;
-
-  Lock();
-  pa_operation *op = (*enumerate_fn)(
-      context_,
-      callback_fn,
-      &data);
-  bool ret = FinishOperation(op);
-  Unlock();
-  return ret;
-}
-
-struct GetDefaultDeviceCallbackData {
-  PulseAudioSoundSystem *instance;
-  SoundDeviceLocator **device;
-};
-
-template <const char *(pa_server_info::*field)>
-void PulseAudioSoundSystem::GetDefaultDeviceCallbackThunk(
-    pa_context *unused,
-    const pa_server_info *info,
-    void *userdata) {
-  GetDefaultDeviceCallbackData *data =
-      static_cast<GetDefaultDeviceCallbackData *>(userdata);
-  data->instance->OnGetDefaultDeviceCallback<field>(info, data->device);
-}
-
-template <const char *(pa_server_info::*field)>
-void PulseAudioSoundSystem::OnGetDefaultDeviceCallback(
-    const pa_server_info *info,
-    SoundDeviceLocator **device) {
-  if (info) {
-    const char *dev = info->*field;
-    if (dev) {
-      *device = new PulseAudioDeviceLocator("Default device", dev);
-    }
-  }
-  Signal();
-}
-
-template <const char *(pa_server_info::*field)>
-bool PulseAudioSoundSystem::GetDefaultDevice(SoundDeviceLocator **device) {
-  if (!IsInitialized()) {
-    return false;
-  }
-  bool ret;
-  *device = NULL;
-  GetDefaultDeviceCallbackData data;
-  data.instance = this;
-  data.device = device;
-  Lock();
-  pa_operation *op = LATE(pa_context_get_server_info)(
-      context_,
-      &GetDefaultDeviceCallbackThunk<field>,
-      &data);
-  ret = FinishOperation(op);
-  Unlock();
-  return ret && (*device != NULL);
-}
-
-void PulseAudioSoundSystem::StreamStateChangedCallbackThunk(
-    pa_stream *stream,
-    void *userdata) {
-  PulseAudioSoundSystem *instance =
-      static_cast<PulseAudioSoundSystem *>(userdata);
-  instance->OnStreamStateChangedCallback(stream);
-}
-
-void PulseAudioSoundSystem::OnStreamStateChangedCallback(pa_stream *stream) {
-  pa_stream_state_t state = LATE(pa_stream_get_state)(stream);
-  if (state == PA_STREAM_READY) {
-    LOG(LS_INFO) << "Pulse stream " << stream << " ready";
-  } else if (state == PA_STREAM_FAILED ||
-             state == PA_STREAM_TERMINATED ||
-             state == PA_STREAM_UNCONNECTED) {
-    LOG(LS_ERROR) << "Pulse stream " << stream << " failed to connect: "
-                  << LastError();
-  }
-}
-
-template <typename StreamInterface>
-StreamInterface *PulseAudioSoundSystem::OpenDevice(
-    const SoundDeviceLocator *device,
-    const OpenParams &params,
-    const char *stream_name,
-    StreamInterface *(PulseAudioSoundSystem::*connect_fn)(
-        pa_stream *stream,
-        const char *dev,
-        int flags,
-        pa_stream_flags_t pa_flags,
-        int latency,
-        const pa_sample_spec &spec)) {
-  if (!IsInitialized()) {
-    return NULL;
-  }
-
-  const char *dev = static_cast<const PulseAudioDeviceLocator *>(device)->
-      device_name().c_str();
-
-  StreamInterface *stream_interface = NULL;
-
-  ASSERT(params.format < ARRAY_SIZE(kCricketFormatToPulseFormatTable));
-
-  pa_sample_spec spec;
-  spec.format = kCricketFormatToPulseFormatTable[params.format];
-  spec.rate = params.freq;
-  spec.channels = params.channels;
-
-  int pa_flags = 0;
-  if (params.flags & FLAG_REPORT_LATENCY) {
-    pa_flags |= PA_STREAM_INTERPOLATE_TIMING |
-                PA_STREAM_AUTO_TIMING_UPDATE;
-  }
-
-  if (params.latency != kNoLatencyRequirements) {
-    // If configuring a specific latency then we want to specify
-    // PA_STREAM_ADJUST_LATENCY to make the server adjust parameters
-    // automatically to reach that target latency. However, that flag doesn't
-    // exist in Ubuntu 8.04 and many people still use that, so we have to check
-    // the protocol version of libpulse.
-    if (LATE(pa_context_get_protocol_version)(context_) >=
-        kAdjustLatencyProtocolVersion) {
-      pa_flags |= PA_STREAM_ADJUST_LATENCY;
-    }
-  }
-
-  Lock();
-
-  pa_stream *stream = LATE(pa_stream_new)(context_, stream_name, &spec, NULL);
-  if (!stream) {
-    LOG(LS_ERROR) << "Can't create pa_stream";
-    goto done;
-  }
-
-  // Set a state callback to log errors.
-  LATE(pa_stream_set_state_callback)(stream,
-                                     &StreamStateChangedCallbackThunk,
-                                     this);
-
-  stream_interface = (this->*connect_fn)(
-      stream,
-      dev,
-      params.flags,
-      static_cast<pa_stream_flags_t>(pa_flags),
-      params.latency,
-      spec);
-  if (!stream_interface) {
-    LOG(LS_ERROR) << "Can't connect stream to " << dev;
-    LATE(pa_stream_unref)(stream);
-  }
-
- done:
-  Unlock();
-  return stream_interface;
-}
-
-// Must be called with the lock held.
-SoundOutputStreamInterface *PulseAudioSoundSystem::ConnectOutputStream(
-    pa_stream *stream,
-    const char *dev,
-    int flags,
-    pa_stream_flags_t pa_flags,
-    int latency,
-    const pa_sample_spec &spec) {
-  pa_buffer_attr attr = {0};
-  pa_buffer_attr *pattr = NULL;
-  if (latency != kNoLatencyRequirements) {
-    // kLowLatency is 0, so we treat it the same as a request for zero latency.
-    ssize_t bytes_per_sec = LATE(pa_bytes_per_second)(&spec);
-    latency = talk_base::_max(
-        latency,
-        static_cast<int>(
-            bytes_per_sec * kPlaybackLatencyMinimumMsecs /
-            talk_base::kNumMicrosecsPerSec));
-    FillPlaybackBufferAttr(latency, &attr);
-    pattr = &attr;
-  }
-  if (LATE(pa_stream_connect_playback)(stream,
-                                       dev,
-                                       pattr,
-                                       pa_flags,
-                                       // Let server choose volume
-                                       NULL,
-                                       // Not synchronized to any other playout
-                                       NULL) != 0) {
-    return NULL;
-  }
-  return new PulseAudioOutputStream(this, stream, flags, latency);
-}
-
-// Must be called with the lock held.
-SoundInputStreamInterface *PulseAudioSoundSystem::ConnectInputStream(
-    pa_stream *stream,
-    const char *dev,
-    int flags,
-    pa_stream_flags_t pa_flags,
-    int latency,
-    const pa_sample_spec &spec) {
-  pa_buffer_attr attr = {0};
-  pa_buffer_attr *pattr = NULL;
-  if (latency != kNoLatencyRequirements) {
-    size_t bytes_per_sec = LATE(pa_bytes_per_second)(&spec);
-    if (latency == kLowLatency) {
-      latency = bytes_per_sec * kLowCaptureLatencyMsecs /
-          talk_base::kNumMicrosecsPerSec;
-    }
-    // Note: fragsize specifies a maximum transfer size, not a minimum, so it is
-    // not possible to force a high latency setting, only a low one.
-    attr.fragsize = latency;
-    attr.maxlength = latency + bytes_per_sec * kCaptureBufferExtraMsecs /
-        talk_base::kNumMicrosecsPerSec;
-    LOG(LS_VERBOSE) << "Configuring latency = " << attr.fragsize
-                    << ", maxlength = " << attr.maxlength;
-    pattr = &attr;
-  }
-  if (LATE(pa_stream_connect_record)(stream,
-                                     dev,
-                                     pattr,
-                                     pa_flags) != 0) {
-    return NULL;
-  }
-  return new PulseAudioInputStream(this, stream, flags);
-}
-
-// Must be called with the lock held.
-bool PulseAudioSoundSystem::FinishOperation(pa_operation *op) {
-  if (!op) {
-    LOG(LS_ERROR) << "Failed to start operation";
-    return false;
-  }
-
-  do {
-    Wait();
-  } while (LATE(pa_operation_get_state)(op) == PA_OPERATION_RUNNING);
-
-  LATE(pa_operation_unref)(op);
-
-  return true;
-}
-
-inline void PulseAudioSoundSystem::Lock() {
-  LATE(pa_threaded_mainloop_lock)(mainloop_);
-}
-
-inline void PulseAudioSoundSystem::Unlock() {
-  LATE(pa_threaded_mainloop_unlock)(mainloop_);
-}
-
-// Must be called with the lock held.
-inline void PulseAudioSoundSystem::Wait() {
-  LATE(pa_threaded_mainloop_wait)(mainloop_);
-}
-
-// Must be called with the lock held.
-inline void PulseAudioSoundSystem::Signal() {
-  LATE(pa_threaded_mainloop_signal)(mainloop_, 0);
-}
-
-// Must be called with the lock held.
-const char *PulseAudioSoundSystem::LastError() {
-  return LATE(pa_strerror)(LATE(pa_context_errno)(context_));
-}
-
-}  // namespace cricket
-
-#endif  // HAVE_LIBPULSE
diff --git a/third_party/libjingle/source/talk/sound/pulseaudiosoundsystem.h b/third_party/libjingle/source/talk/sound/pulseaudiosoundsystem.h
deleted file mode 100644
index 4cf3dfc..0000000
--- a/third_party/libjingle/source/talk/sound/pulseaudiosoundsystem.h
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SOUND_PULSEAUDIOSOUNDSYSTEM_H_
-#define TALK_SOUND_PULSEAUDIOSOUNDSYSTEM_H_
-
-#ifdef HAVE_LIBPULSE
-
-// For the flag enums, which can't be forward-declared.
-#include <pulse/def.h>
-
-#include "talk/base/constructormagic.h"
-#include "talk/sound/pulseaudiosymboltable.h"
-#include "talk/sound/soundsysteminterface.h"
-
-struct pa_context;
-struct pa_operation;
-struct pa_sample_spec;
-struct pa_server_info;
-struct pa_sink_info;
-struct pa_source_info;
-struct pa_stream;
-struct pa_threaded_mainloop;
-
-namespace cricket {
-
-class PulseAudioInputStream;
-class PulseAudioOutputStream;
-class PulseAudioStream;
-
-// Sound system implementation for PulseAudio, a cross-platform sound server
-// (but commonly used only on Linux, which is the only platform we support
-// it on).
-// Init(), Terminate(), and the destructor should never be invoked concurrently,
-// but all other methods are thread-safe.
-class PulseAudioSoundSystem : public SoundSystemInterface {
-  friend class PulseAudioInputStream;
-  friend class PulseAudioOutputStream;
-  friend class PulseAudioStream;
- public:
-  static SoundSystemInterface *Create() {
-    return new PulseAudioSoundSystem();
-  }
-
-  PulseAudioSoundSystem();
-
-  virtual ~PulseAudioSoundSystem();
-
-  virtual bool Init();
-  virtual void Terminate();
-
-  virtual bool EnumeratePlaybackDevices(SoundDeviceLocatorList *devices);
-  virtual bool EnumerateCaptureDevices(SoundDeviceLocatorList *devices);
-
-  virtual bool GetDefaultPlaybackDevice(SoundDeviceLocator **device);
-  virtual bool GetDefaultCaptureDevice(SoundDeviceLocator **device);
-
-  virtual SoundOutputStreamInterface *OpenPlaybackDevice(
-      const SoundDeviceLocator *device,
-      const OpenParams &params);
-  virtual SoundInputStreamInterface *OpenCaptureDevice(
-      const SoundDeviceLocator *device,
-      const OpenParams &params);
-
-  virtual const char *GetName() const;
-
- private:
-  bool IsInitialized();
-
-  static void ConnectToPulseCallbackThunk(pa_context *context, void *userdata);
-
-  void OnConnectToPulseCallback(pa_context *context, bool *connect_done);
-
-  bool ConnectToPulse(pa_context *context);
-
-  pa_context *CreateNewConnection();
-
-  template <typename InfoStruct>
-  bool EnumerateDevices(SoundDeviceLocatorList *devices,
-                        pa_operation *(*enumerate_fn)(
-                            pa_context *c,
-                            void (*callback_fn)(
-                                pa_context *c,
-                                const InfoStruct *i,
-                                int eol,
-                                void *userdata),
-                            void *userdata),
-                        void (*callback_fn)(
-                            pa_context *c,
-                            const InfoStruct *i,
-                            int eol,
-                            void *userdata));
-
-  static void EnumeratePlaybackDevicesCallbackThunk(pa_context *unused,
-                                                    const pa_sink_info *info,
-                                                    int eol,
-                                                    void *userdata);
-
-  static void EnumerateCaptureDevicesCallbackThunk(pa_context *unused,
-                                                   const pa_source_info *info,
-                                                   int eol,
-                                                   void *userdata);
-
-  void OnEnumeratePlaybackDevicesCallback(
-      SoundDeviceLocatorList *devices,
-      const pa_sink_info *info,
-      int eol);
-
-  void OnEnumerateCaptureDevicesCallback(
-      SoundDeviceLocatorList *devices,
-      const pa_source_info *info,
-      int eol);
-
-  template <const char *(pa_server_info::*field)>
-  static void GetDefaultDeviceCallbackThunk(
-      pa_context *unused,
-      const pa_server_info *info,
-      void *userdata);
-
-  template <const char *(pa_server_info::*field)>
-  void OnGetDefaultDeviceCallback(
-      const pa_server_info *info,
-      SoundDeviceLocator **device);
-
-  template <const char *(pa_server_info::*field)>
-  bool GetDefaultDevice(SoundDeviceLocator **device);
-
-  static void StreamStateChangedCallbackThunk(pa_stream *stream,
-                                              void *userdata);
-
-  void OnStreamStateChangedCallback(pa_stream *stream);
-
-  template <typename StreamInterface>
-  StreamInterface *OpenDevice(
-      const SoundDeviceLocator *device,
-      const OpenParams &params,
-      const char *stream_name,
-      StreamInterface *(PulseAudioSoundSystem::*connect_fn)(
-          pa_stream *stream,
-          const char *dev,
-          int flags,
-          pa_stream_flags_t pa_flags,
-          int latency,
-          const pa_sample_spec &spec));
-
-  SoundOutputStreamInterface *ConnectOutputStream(
-      pa_stream *stream,
-      const char *dev,
-      int flags,
-      pa_stream_flags_t pa_flags,
-      int latency,
-      const pa_sample_spec &spec);
-
-  SoundInputStreamInterface *ConnectInputStream(
-      pa_stream *stream,
-      const char *dev,
-      int flags,
-      pa_stream_flags_t pa_flags,
-      int latency,
-      const pa_sample_spec &spec);
-
-  bool FinishOperation(pa_operation *op);
-
-  void Lock();
-  void Unlock();
-  void Wait();
-  void Signal();
-
-  const char *LastError();
-
-  pa_threaded_mainloop *mainloop_;
-  pa_context *context_;
-  PulseAudioSymbolTable symbol_table_;
-
-  DISALLOW_COPY_AND_ASSIGN(PulseAudioSoundSystem);
-};
-
-}  // namespace cricket
-
-#endif  // HAVE_LIBPULSE
-
-#endif  // TALK_SOUND_PULSEAUDIOSOUNDSYSTEM_H_
diff --git a/third_party/libjingle/source/talk/sound/pulseaudiosymboltable.cc b/third_party/libjingle/source/talk/sound/pulseaudiosymboltable.cc
deleted file mode 100644
index 008b003..0000000
--- a/third_party/libjingle/source/talk/sound/pulseaudiosymboltable.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/sound/pulseaudiosymboltable.h"
-
-namespace cricket {
-
-LATE_BINDING_SYMBOL_TABLE_DEFINE_BEGIN(PulseAudioSymbolTable, "libpulse.so.0")
-#define X(sym) \
-    LATE_BINDING_SYMBOL_TABLE_DEFINE_ENTRY(PulseAudioSymbolTable, sym)
-PULSE_AUDIO_SYMBOLS_LIST
-#undef X
-LATE_BINDING_SYMBOL_TABLE_DEFINE_END(PulseAudioSymbolTable)
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/sound/pulseaudiosymboltable.h b/third_party/libjingle/source/talk/sound/pulseaudiosymboltable.h
deleted file mode 100644
index 21be35e..0000000
--- a/third_party/libjingle/source/talk/sound/pulseaudiosymboltable.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SOUND_PULSEAUDIOSYMBOLTABLE_H_
-#define TALK_SOUND_PULSEAUDIOSYMBOLTABLE_H_
-
-#include "talk/base/latebindingsymboltable.h"
-
-namespace cricket {
-
-// The PulseAudio symbols we need, as an X-Macro list.
-// This list must contain precisely every libpulse function that is used in
-// pulseaudiosoundsystem.cc.
-#define PULSE_AUDIO_SYMBOLS_LIST \
-  X(pa_bytes_per_second) \
-  X(pa_context_connect) \
-  X(pa_context_disconnect) \
-  X(pa_context_errno) \
-  X(pa_context_get_protocol_version) \
-  X(pa_context_get_server_info) \
-  X(pa_context_get_sink_info_list) \
-  X(pa_context_get_sink_input_info) \
-  X(pa_context_get_source_info_by_index) \
-  X(pa_context_get_source_info_list) \
-  X(pa_context_get_state) \
-  X(pa_context_new) \
-  X(pa_context_set_sink_input_volume) \
-  X(pa_context_set_source_volume_by_index) \
-  X(pa_context_set_state_callback) \
-  X(pa_context_unref) \
-  X(pa_cvolume_set) \
-  X(pa_operation_get_state) \
-  X(pa_operation_unref) \
-  X(pa_stream_connect_playback) \
-  X(pa_stream_connect_record) \
-  X(pa_stream_disconnect) \
-  X(pa_stream_drop) \
-  X(pa_stream_get_device_index) \
-  X(pa_stream_get_index) \
-  X(pa_stream_get_latency) \
-  X(pa_stream_get_sample_spec) \
-  X(pa_stream_get_state) \
-  X(pa_stream_new) \
-  X(pa_stream_peek) \
-  X(pa_stream_readable_size) \
-  X(pa_stream_set_buffer_attr) \
-  X(pa_stream_set_overflow_callback) \
-  X(pa_stream_set_read_callback) \
-  X(pa_stream_set_state_callback) \
-  X(pa_stream_set_underflow_callback) \
-  X(pa_stream_set_write_callback) \
-  X(pa_stream_unref) \
-  X(pa_stream_writable_size) \
-  X(pa_stream_write) \
-  X(pa_strerror) \
-  X(pa_threaded_mainloop_free) \
-  X(pa_threaded_mainloop_get_api) \
-  X(pa_threaded_mainloop_lock) \
-  X(pa_threaded_mainloop_new) \
-  X(pa_threaded_mainloop_signal) \
-  X(pa_threaded_mainloop_start) \
-  X(pa_threaded_mainloop_stop) \
-  X(pa_threaded_mainloop_unlock) \
-  X(pa_threaded_mainloop_wait)
-
-LATE_BINDING_SYMBOL_TABLE_DECLARE_BEGIN(PulseAudioSymbolTable)
-#define X(sym) \
-    LATE_BINDING_SYMBOL_TABLE_DECLARE_ENTRY(PulseAudioSymbolTable, sym)
-PULSE_AUDIO_SYMBOLS_LIST
-#undef X
-LATE_BINDING_SYMBOL_TABLE_DECLARE_END(PulseAudioSymbolTable)
-
-}  // namespace cricket
-
-#endif  // TALK_SOUND_PULSEAUDIOSYMBOLTABLE_H_
diff --git a/third_party/libjingle/source/talk/sound/sounddevicelocator.h b/third_party/libjingle/source/talk/sound/sounddevicelocator.h
deleted file mode 100644
index e0a8970..0000000
--- a/third_party/libjingle/source/talk/sound/sounddevicelocator.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SOUND_SOUNDDEVICELOCATOR_H_
-#define TALK_SOUND_SOUNDDEVICELOCATOR_H_
-
-#include <string>
-
-#include "talk/base/constructormagic.h"
-
-namespace cricket {
-
-// A simple container for holding the name of a device and any additional id
-// information needed to locate and open it. Implementations of
-// SoundSystemInterface must subclass this to add any id information that they
-// need.
-class SoundDeviceLocator {
- public:
-  virtual ~SoundDeviceLocator() {}
-
-  // Human-readable name for the device.
-  const std::string &name() const { return name_; }
-
-  // Name sound system uses to locate this device.
-  const std::string &device_name() const { return device_name_; }
-
-  // Makes a duplicate of this locator.
-  virtual SoundDeviceLocator *Copy() const = 0;
-
- protected:
-  SoundDeviceLocator(const std::string &name,
-                     const std::string &device_name)
-      : name_(name), device_name_(device_name) {}
-
-  explicit SoundDeviceLocator(const SoundDeviceLocator &that)
-      : name_(that.name_), device_name_(that.device_name_) {}
-
-  std::string name_;
-  std::string device_name_;
-
- private:
-  DISALLOW_ASSIGN(SoundDeviceLocator);
-};
-
-}  // namespace cricket
-
-#endif  // TALK_SOUND_SOUNDDEVICELOCATOR_H_
diff --git a/third_party/libjingle/source/talk/sound/soundinputstreaminterface.h b/third_party/libjingle/source/talk/sound/soundinputstreaminterface.h
deleted file mode 100644
index de831a6..0000000
--- a/third_party/libjingle/source/talk/sound/soundinputstreaminterface.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SOUND_SOUNDINPUTSTREAMINTERFACE_H_
-#define TALK_SOUND_SOUNDINPUTSTREAMINTERFACE_H_
-
-#include "talk/base/constructormagic.h"
-#include "talk/base/sigslot.h"
-
-namespace cricket {
-
-// Interface for consuming an input stream from a recording device.
-// Semantics and thread-safety of StartReading()/StopReading() are the same as
-// for talk_base::Worker.
-class SoundInputStreamInterface {
- public:
-  virtual ~SoundInputStreamInterface() {}
-
-  // Starts the reading of samples on the current thread.
-  virtual bool StartReading() = 0;
-  // Stops the reading of samples.
-  virtual bool StopReading() = 0;
-
-  // Retrieves the current input volume for this stream. Nominal range is
-  // defined by SoundSystemInterface::k(Max|Min)Volume, but values exceeding the
-  // max may be possible in some implementations. This call retrieves the actual
-  // volume currently in use by the OS, not a cached value from a previous
-  // (Get|Set)Volume() call.
-  virtual bool GetVolume(int *volume) = 0;
-
-  // Changes the input volume for this stream. Nominal range is defined by
-  // SoundSystemInterface::k(Max|Min)Volume. The effect of exceeding kMaxVolume
-  // is implementation-defined.
-  virtual bool SetVolume(int volume) = 0;
-
-  // Closes this stream object. If currently reading then this may only be
-  // called from the reading thread.
-  virtual bool Close() = 0;
-
-  // Get the latency of the stream.
-  virtual int LatencyUsecs() = 0;
-
-  // Notifies the consumer of new data read from the device.
-  // The first parameter is a pointer to the data read, and is only valid for
-  // the duration of the call.
-  // The second parameter is the amount of data read in bytes (i.e., the valid
-  // length of the memory pointed to).
-  // The 3rd parameter is the stream that is issuing the callback.
-  sigslot::signal3<const void *, size_t,
-      SoundInputStreamInterface *> SignalSamplesRead;
-
- protected:
-  SoundInputStreamInterface() {}
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(SoundInputStreamInterface);
-};
-
-}  // namespace cricket
-
-#endif  // TALK_SOUND_SOUNDOUTPUTSTREAMINTERFACE_H_
diff --git a/third_party/libjingle/source/talk/sound/soundoutputstreaminterface.h b/third_party/libjingle/source/talk/sound/soundoutputstreaminterface.h
deleted file mode 100644
index d096ba3..0000000
--- a/third_party/libjingle/source/talk/sound/soundoutputstreaminterface.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SOUND_SOUNDOUTPUTSTREAMINTERFACE_H_
-#define TALK_SOUND_SOUNDOUTPUTSTREAMINTERFACE_H_
-
-#include "talk/base/constructormagic.h"
-#include "talk/base/sigslot.h"
-
-namespace cricket {
-
-// Interface for outputting a stream to a playback device.
-// Semantics and thread-safety of EnableBufferMonitoring()/
-// DisableBufferMonitoring() are the same as for talk_base::Worker.
-class SoundOutputStreamInterface {
- public:
-  virtual ~SoundOutputStreamInterface() {}
-
-  // Enables monitoring the available buffer space on the current thread.
-  virtual bool EnableBufferMonitoring() = 0;
-  // Disables the monitoring.
-  virtual bool DisableBufferMonitoring() = 0;
-
-  // Write the given samples to the devices. If currently monitoring then this
-  // may only be called from the monitoring thread.
-  virtual bool WriteSamples(const void *sample_data,
-                            size_t size) = 0;
-
-  // Retrieves the current output volume for this stream. Nominal range is
-  // defined by SoundSystemInterface::k(Max|Min)Volume, but values exceeding the
-  // max may be possible in some implementations. This call retrieves the actual
-  // volume currently in use by the OS, not a cached value from a previous
-  // (Get|Set)Volume() call.
-  virtual bool GetVolume(int *volume) = 0;
-
-  // Changes the output volume for this stream. Nominal range is defined by
-  // SoundSystemInterface::k(Max|Min)Volume. The effect of exceeding kMaxVolume
-  // is implementation-defined.
-  virtual bool SetVolume(int volume) = 0;
-
-  // Closes this stream object. If currently monitoring then this may only be
-  // called from the monitoring thread.
-  virtual bool Close() = 0;
-
-  // Get the latency of the stream.
-  virtual int LatencyUsecs() = 0;
-
-  // Notifies the producer of the available buffer space for writes.
-  // It fires continuously as long as the space is greater than zero.
-  // The first parameter is the amount of buffer space available for data to
-  // be written (i.e., the maximum amount of data that can be written right now
-  // with WriteSamples() without blocking).
-  // The 2nd parameter is the stream that is issuing the callback.
-  sigslot::signal2<size_t, SoundOutputStreamInterface *> SignalBufferSpace;
-
- protected:
-  SoundOutputStreamInterface() {}
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(SoundOutputStreamInterface);
-};
-
-}  // namespace cricket
-
-#endif  // TALK_SOUND_SOUNDOUTPUTSTREAMINTERFACE_H_
diff --git a/third_party/libjingle/source/talk/sound/soundsystemfactory.h b/third_party/libjingle/source/talk/sound/soundsystemfactory.h
deleted file mode 100644
index 517220b..0000000
--- a/third_party/libjingle/source/talk/sound/soundsystemfactory.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SOUND_SOUNDSYSTEMFACTORY_H_
-#define TALK_SOUND_SOUNDSYSTEMFACTORY_H_
-
-#include "talk/base/referencecountedsingletonfactory.h"
-
-namespace cricket {
-
-class SoundSystemInterface;
-
-typedef talk_base::ReferenceCountedSingletonFactory<SoundSystemInterface>
-    SoundSystemFactory;
-
-typedef talk_base::rcsf_ptr<SoundSystemInterface> SoundSystemHandle;
-
-}  // namespace cricket
-
-#endif  // TALK_SOUND_SOUNDSYSTEMFACTORY_H_
diff --git a/third_party/libjingle/source/talk/sound/soundsysteminterface.cc b/third_party/libjingle/source/talk/sound/soundsysteminterface.cc
deleted file mode 100644
index b432262..0000000
--- a/third_party/libjingle/source/talk/sound/soundsysteminterface.cc
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/sound/soundsysteminterface.h"
-
-#include "talk/sound/sounddevicelocator.h"
-
-namespace cricket {
-
-void SoundSystemInterface::ClearSoundDeviceLocatorList(
-    SoundSystemInterface::SoundDeviceLocatorList *devices) {
-  for (SoundDeviceLocatorList::iterator i = devices->begin();
-       i != devices->end();
-       ++i) {
-    if (*i) {
-      delete *i;
-    }
-  }
-  devices->clear();
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/sound/soundsysteminterface.h b/third_party/libjingle/source/talk/sound/soundsysteminterface.h
deleted file mode 100644
index 7a059b0..0000000
--- a/third_party/libjingle/source/talk/sound/soundsysteminterface.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SOUND_SOUNDSYSTEMINTERFACE_H_
-#define TALK_SOUND_SOUNDSYSTEMINTERFACE_H_
-
-#include <vector>
-
-#include "talk/base/constructormagic.h"
-
-namespace cricket {
-
-class SoundDeviceLocator;
-class SoundInputStreamInterface;
-class SoundOutputStreamInterface;
-
-// Interface for a platform's sound system.
-// Implementations must guarantee thread-safety for at least the following use
-// cases:
-// 1) Concurrent enumeration and opening of devices from different threads.
-// 2) Concurrent use of different Sound(Input|Output)StreamInterface
-// instances from different threads (but concurrent use of the _same_ one from
-// different threads need not be supported).
-class SoundSystemInterface {
- public:
-  typedef std::vector<SoundDeviceLocator *> SoundDeviceLocatorList;
-
-  enum SampleFormat {
-    // Only one supported sample format at this time.
-    // The values here may be used in lookup tables, so they shouldn't change.
-    FORMAT_S16LE = 0,
-  };
-
-  enum Flags {
-    // Enable reporting the current stream latency in
-    // Sound(Input|Output)StreamInterface. See those classes for more details.
-    FLAG_REPORT_LATENCY = (1 << 0),
-  };
-
-  struct OpenParams {
-    // Format for the sound stream.
-    SampleFormat format;
-    // Sampling frequency in hertz.
-    unsigned int freq;
-    // Number of channels in the PCM stream.
-    unsigned int channels;
-    // Misc flags. Should be taken from the Flags enum above.
-    int flags;
-    // Desired latency, measured as number of bytes of sample data
-    int latency;
-  };
-
-  // Special values for the "latency" field of OpenParams.
-  // Use this one to say you don't care what the latency is. The sound system
-  // will optimize for other things instead.
-  static const int kNoLatencyRequirements = -1;
-  // Use this one to say that you want the sound system to pick an appropriate
-  // small latency value. The sound system may pick the minimum allowed one, or
-  // a slightly higher one in the event that the true minimum requires an
-  // undesirable trade-off.
-  static const int kLowLatency = 0;
- 
-  // Max value for the volume parameters for Sound(Input|Output)StreamInterface.
-  static const int kMaxVolume = 255;
-  // Min value for the volume parameters for Sound(Input|Output)StreamInterface.
-  static const int kMinVolume = 0;
-
-  // Helper for clearing a locator list and deleting the entries.
-  static void ClearSoundDeviceLocatorList(SoundDeviceLocatorList *devices);
-
-  virtual ~SoundSystemInterface() {}
-
-  virtual bool Init() = 0;
-  virtual void Terminate() = 0;
-
-  // Enumerates the available devices. (Any pre-existing locators in the lists
-  // are deleted.)
-  virtual bool EnumeratePlaybackDevices(SoundDeviceLocatorList *devices) = 0;
-  virtual bool EnumerateCaptureDevices(SoundDeviceLocatorList *devices) = 0;
-
-  // Gets a special locator for the default device.
-  virtual bool GetDefaultPlaybackDevice(SoundDeviceLocator **device) = 0;
-  virtual bool GetDefaultCaptureDevice(SoundDeviceLocator **device) = 0;
-
-  // Opens the given device, or returns NULL on error.
-  virtual SoundOutputStreamInterface *OpenPlaybackDevice(
-      const SoundDeviceLocator *device,
-      const OpenParams &params) = 0;
-  virtual SoundInputStreamInterface *OpenCaptureDevice(
-      const SoundDeviceLocator *device,
-      const OpenParams &params) = 0;
-
-  // A human-readable name for this sound system.
-  virtual const char *GetName() const = 0;
-
- protected:
-  SoundSystemInterface() {}
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(SoundSystemInterface);
-};
-
-}  // namespace cricket
-
-#endif  // TALK_SOUND_SOUNDSYSTEMINTERFACE_H_
diff --git a/third_party/libjingle/source/talk/sound/soundsystemproxy.cc b/third_party/libjingle/source/talk/sound/soundsystemproxy.cc
deleted file mode 100644
index 737a6bb..0000000
--- a/third_party/libjingle/source/talk/sound/soundsystemproxy.cc
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/sound/soundsystemproxy.h"
-
-namespace cricket {
-
-bool SoundSystemProxy::EnumeratePlaybackDevices(
-    SoundDeviceLocatorList *devices) {
-  return wrapped_ ? wrapped_->EnumeratePlaybackDevices(devices) : false;
-}
-
-bool SoundSystemProxy::EnumerateCaptureDevices(
-    SoundDeviceLocatorList *devices) {
-  return wrapped_ ? wrapped_->EnumerateCaptureDevices(devices) : false;
-}
-
-bool SoundSystemProxy::GetDefaultPlaybackDevice(
-    SoundDeviceLocator **device) {
-  return wrapped_ ? wrapped_->GetDefaultPlaybackDevice(device) : false;
-}
-
-bool SoundSystemProxy::GetDefaultCaptureDevice(
-    SoundDeviceLocator **device) {
-  return wrapped_ ? wrapped_->GetDefaultCaptureDevice(device) : false;
-}
-
-SoundOutputStreamInterface *SoundSystemProxy::OpenPlaybackDevice(
-    const SoundDeviceLocator *device,
-    const OpenParams &params) {
-  return wrapped_ ? wrapped_->OpenPlaybackDevice(device, params) : NULL;
-}
-
-SoundInputStreamInterface *SoundSystemProxy::OpenCaptureDevice(
-    const SoundDeviceLocator *device,
-    const OpenParams &params) {
-  return wrapped_ ? wrapped_->OpenCaptureDevice(device, params) : NULL;
-}
-
-}  // namespace cricket
diff --git a/third_party/libjingle/source/talk/sound/soundsystemproxy.h b/third_party/libjingle/source/talk/sound/soundsystemproxy.h
deleted file mode 100644
index 9ccace8..0000000
--- a/third_party/libjingle/source/talk/sound/soundsystemproxy.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2010, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_SOUND_SOUNDSYSTEMPROXY_H_
-#define TALK_SOUND_SOUNDSYSTEMPROXY_H_
-
-#include "talk/base/basictypes.h"  // for NULL
-#include "talk/sound/soundsysteminterface.h"
-
-namespace cricket {
-
-// A SoundSystemProxy is a sound system that defers to another one.
-// Init(), Terminate(), and GetName() are left as pure virtual, so a sub-class
-// must define them.
-class SoundSystemProxy : public SoundSystemInterface {
- public:
-  SoundSystemProxy() : wrapped_(NULL) {}
-
-  // Each of these methods simply defers to wrapped_ if non-NULL, else fails.
-
-  virtual bool EnumeratePlaybackDevices(SoundDeviceLocatorList *devices);
-  virtual bool EnumerateCaptureDevices(SoundDeviceLocatorList *devices);
-
-  virtual bool GetDefaultPlaybackDevice(SoundDeviceLocator **device);
-  virtual bool GetDefaultCaptureDevice(SoundDeviceLocator **device);
-
-  virtual SoundOutputStreamInterface *OpenPlaybackDevice(
-      const SoundDeviceLocator *device,
-      const OpenParams &params);
-  virtual SoundInputStreamInterface *OpenCaptureDevice(
-      const SoundDeviceLocator *device,
-      const OpenParams &params);
-
- protected:
-  SoundSystemInterface *wrapped_;
-};
-
-}  // namespace cricket
-
-#endif  // TALK_SOUND_SOUNDSYSTEMPROXY_H_
diff --git a/third_party/libjingle/source/talk/third_party/libudev/libudev.h b/third_party/libjingle/source/talk/third_party/libudev/libudev.h
deleted file mode 100644
index 5bc42df..0000000
--- a/third_party/libjingle/source/talk/third_party/libudev/libudev.h
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * libudev - interface to udev device information
- *
- * Copyright (C) 2008-2010 Kay Sievers <kay.sievers@vrfy.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- */
-
-#ifndef _LIBUDEV_H_
-#define _LIBUDEV_H_
-
-#include <stdarg.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * udev - library context
- * 
- * reads the udev config and system environment
- * allows custom logging
- */
-struct udev;
-struct udev *udev_ref(struct udev *udev);
-void udev_unref(struct udev *udev);
-struct udev *udev_new(void);
-void udev_set_log_fn(struct udev *udev,
-			    void (*log_fn)(struct udev *udev,
-					   int priority, const char *file, int line, const char *fn,
-					   const char *format, va_list args));
-int udev_get_log_priority(struct udev *udev);
-void udev_set_log_priority(struct udev *udev, int priority);
-const char *udev_get_sys_path(struct udev *udev);
-const char *udev_get_dev_path(struct udev *udev);
-void *udev_get_userdata(struct udev *udev);
-void udev_set_userdata(struct udev *udev, void *userdata);
-
-/*
- * udev_list
- *
- * access to libudev generated lists
- */
-struct udev_list_entry;
-struct udev_list_entry *udev_list_entry_get_next(struct udev_list_entry *list_entry);
-struct udev_list_entry *udev_list_entry_get_by_name(struct udev_list_entry *list_entry, const char *name);
-const char *udev_list_entry_get_name(struct udev_list_entry *list_entry);
-const char *udev_list_entry_get_value(struct udev_list_entry *list_entry);
-/**
- * udev_list_entry_foreach:
- * @list_entry: entry to store the current position
- * @first_entry: first entry to start with
- *
- * Helper to iterate over all entries of a list.
- */
-#define udev_list_entry_foreach(list_entry, first_entry) \
-	for (list_entry = first_entry; \
-	     list_entry != NULL; \
-	     list_entry = udev_list_entry_get_next(list_entry))
-
-/*
- * udev_device
- *
- * access to sysfs/kernel devices
- */
-struct udev_device;
-struct udev_device *udev_device_ref(struct udev_device *udev_device);
-void udev_device_unref(struct udev_device *udev_device);
-struct udev *udev_device_get_udev(struct udev_device *udev_device);
-struct udev_device *udev_device_new_from_syspath(struct udev *udev, const char *syspath);
-struct udev_device *udev_device_new_from_devnum(struct udev *udev, char type, dev_t devnum);
-struct udev_device *udev_device_new_from_subsystem_sysname(struct udev *udev, const char *subsystem, const char *sysname);
-struct udev_device *udev_device_new_from_environment(struct udev *udev);
-/* udev_device_get_parent_*() does not take a reference on the returned device, it is automatically unref'd with the parent */
-struct udev_device *udev_device_get_parent(struct udev_device *udev_device);
-struct udev_device *udev_device_get_parent_with_subsystem_devtype(struct udev_device *udev_device,
-								  const char *subsystem, const char *devtype);
-/* retrieve device properties */
-const char *udev_device_get_devpath(struct udev_device *udev_device);
-const char *udev_device_get_subsystem(struct udev_device *udev_device);
-const char *udev_device_get_devtype(struct udev_device *udev_device);
-const char *udev_device_get_syspath(struct udev_device *udev_device);
-const char *udev_device_get_sysname(struct udev_device *udev_device);
-const char *udev_device_get_sysnum(struct udev_device *udev_device);
-const char *udev_device_get_devnode(struct udev_device *udev_device);
-struct udev_list_entry *udev_device_get_devlinks_list_entry(struct udev_device *udev_device);
-struct udev_list_entry *udev_device_get_properties_list_entry(struct udev_device *udev_device);
-struct udev_list_entry *udev_device_get_tags_list_entry(struct udev_device *udev_device);
-const char *udev_device_get_property_value(struct udev_device *udev_device, const char *key);
-const char *udev_device_get_driver(struct udev_device *udev_device);
-dev_t udev_device_get_devnum(struct udev_device *udev_device);
-const char *udev_device_get_action(struct udev_device *udev_device);
-unsigned long long int udev_device_get_seqnum(struct udev_device *udev_device);
-const char *udev_device_get_sysattr_value(struct udev_device *udev_device, const char *sysattr);
-
-/*
- * udev_monitor
- *
- * access to kernel uevents and udev events
- */
-struct udev_monitor;
-struct udev_monitor *udev_monitor_ref(struct udev_monitor *udev_monitor);
-void udev_monitor_unref(struct udev_monitor *udev_monitor);
-struct udev *udev_monitor_get_udev(struct udev_monitor *udev_monitor);
-/* kernel and udev generated events over netlink */
-struct udev_monitor *udev_monitor_new_from_netlink(struct udev *udev, const char *name);
-/* custom socket (use netlink and filters instead) */
-struct udev_monitor *udev_monitor_new_from_socket(struct udev *udev, const char *socket_path);
-/* bind socket */
-int udev_monitor_enable_receiving(struct udev_monitor *udev_monitor);
-int udev_monitor_set_receive_buffer_size(struct udev_monitor *udev_monitor, int size);
-int udev_monitor_get_fd(struct udev_monitor *udev_monitor);
-struct udev_device *udev_monitor_receive_device(struct udev_monitor *udev_monitor);
-/* in-kernel socket filters to select messages that get delivered to a listener */
-int udev_monitor_filter_add_match_subsystem_devtype(struct udev_monitor *udev_monitor,
-						    const char *subsystem, const char *devtype);
-int udev_monitor_filter_add_match_tag(struct udev_monitor *udev_monitor, const char *tag);
-int udev_monitor_filter_update(struct udev_monitor *udev_monitor);
-int udev_monitor_filter_remove(struct udev_monitor *udev_monitor);
-
-/*
- * udev_enumerate
- *
- * search sysfs for specific devices and provide a sorted list
- */
-struct udev_enumerate;
-struct udev_enumerate *udev_enumerate_ref(struct udev_enumerate *udev_enumerate);
-void udev_enumerate_unref(struct udev_enumerate *udev_enumerate);
-struct udev *udev_enumerate_get_udev(struct udev_enumerate *udev_enumerate);
-struct udev_enumerate *udev_enumerate_new(struct udev *udev);
-/* device properties filter */
-int udev_enumerate_add_match_subsystem(struct udev_enumerate *udev_enumerate, const char *subsystem);
-int udev_enumerate_add_nomatch_subsystem(struct udev_enumerate *udev_enumerate, const char *subsystem);
-int udev_enumerate_add_match_sysattr(struct udev_enumerate *udev_enumerate, const char *sysattr, const char *value);
-int udev_enumerate_add_nomatch_sysattr(struct udev_enumerate *udev_enumerate, const char *sysattr, const char *value);
-int udev_enumerate_add_match_property(struct udev_enumerate *udev_enumerate, const char *property, const char *value);
-int udev_enumerate_add_match_sysname(struct udev_enumerate *udev_enumerate, const char *sysname);
-int udev_enumerate_add_match_tag(struct udev_enumerate *udev_enumerate, const char *tag);
-int udev_enumerate_add_syspath(struct udev_enumerate *udev_enumerate, const char *syspath);
-/* run enumeration with active filters */
-int udev_enumerate_scan_devices(struct udev_enumerate *udev_enumerate);
-int udev_enumerate_scan_subsystems(struct udev_enumerate *udev_enumerate);
-/* return device list */
-struct udev_list_entry *udev_enumerate_get_list_entry(struct udev_enumerate *udev_enumerate);
-
-/*
- * udev_queue
- *
- * access to the currently running udev events
- */
-struct udev_queue;
-struct udev_queue *udev_queue_ref(struct udev_queue *udev_queue);
-void udev_queue_unref(struct udev_queue *udev_queue);
-struct udev *udev_queue_get_udev(struct udev_queue *udev_queue);
-struct udev_queue *udev_queue_new(struct udev *udev);
-unsigned long long int udev_queue_get_kernel_seqnum(struct udev_queue *udev_queue);
-unsigned long long int udev_queue_get_udev_seqnum(struct udev_queue *udev_queue);
-int udev_queue_get_udev_is_active(struct udev_queue *udev_queue);
-int udev_queue_get_queue_is_empty(struct udev_queue *udev_queue);
-int udev_queue_get_seqnum_is_finished(struct udev_queue *udev_queue, unsigned long long int seqnum);
-int udev_queue_get_seqnum_sequence_is_finished(struct udev_queue *udev_queue,
-					       unsigned long long int start, unsigned long long int end);
-struct udev_list_entry *udev_queue_get_queued_list_entry(struct udev_queue *udev_queue);
-struct udev_list_entry *udev_queue_get_failed_list_entry(struct udev_queue *udev_queue);
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif
diff --git a/third_party/libjingle/source/talk/xmllite/qname.cc b/third_party/libjingle/source/talk/xmllite/qname.cc
deleted file mode 100644
index 81a2871..0000000
--- a/third_party/libjingle/source/talk/xmllite/qname.cc
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/xmllite/qname.h"
-
-namespace buzz {
-
-QName::QName(const QName& qname)
-    : namespace_(qname.namespace_),
-      local_part_(qname.local_part_) {
-}
-
-QName::QName(const StaticQName& const_value)
-    : namespace_(const_value.ns),
-      local_part_(const_value.local) {
-}
-
-QName::QName(const std::string& ns, const std::string& local)
-    : namespace_(ns),
-      local_part_(local) {
-}
-
-QName::QName(const std::string& merged_or_local) {
-  size_t i = merged_or_local.rfind(':');
-  if (i == std::string::npos) {
-    local_part_ = merged_or_local;
-  } else {
-    namespace_ = merged_or_local.substr(0, i);
-    local_part_ = merged_or_local.substr(i + 1);
-  }
-}
-
-QName::~QName() {
-}
-
-std::string QName::Merged() const {
-  if (namespace_[0] == '\0')
-    return local_part_;
-
-  std::string result;
-  result.reserve(namespace_.length() + 1 + local_part_.length());
-  result += namespace_;
-  result += ':';
-  result += local_part_;
-  return result;
-}
-
-int QName::Compare(const StaticQName& other) const {
-  int result = local_part_.compare(other.local);
-  if (result != 0)
-    return result;
-
-  return namespace_.compare(other.ns);
-}
-
-int QName::Compare(const QName& other) const {
-  int result = local_part_.compare(other.local_part_);
-  if (result != 0)
-    return result;
-
-  return namespace_.compare(other.namespace_);
-}
-
-}
diff --git a/third_party/libjingle/source/talk/xmllite/qname.h b/third_party/libjingle/source/talk/xmllite/qname.h
deleted file mode 100644
index 9c2ff13..0000000
--- a/third_party/libjingle/source/talk/xmllite/qname.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_XMLLITE_QNAME_H_
-#define TALK_XMLLITE_QNAME_H_
-
-#include <string>
-
-namespace buzz {
-
-class QName;
-
-// StaticQName is used to represend constant quailified names. They
-// can be initialized statically and don't need intializers code, e.g.
-//   const StaticQName QN_FOO = { "foo_namespace", "foo" };
-//
-// Beside this use case, QName should be used everywhere
-// else. StaticQName instances are implicitly converted to QName
-// objects.
-struct StaticQName {
-  const char* const ns;
-  const char* const local;
-
-  bool operator==(const QName& other) const;
-  bool operator!=(const QName& other) const;
-};
-
-class QName {
- public:
-  QName(const QName& qname);
-  QName(const StaticQName& const_value);
-  QName(const std::string& ns, const std::string& local);
-  explicit QName(const std::string& merged_or_local);
-  ~QName();
-
-  const std::string& Namespace() const { return namespace_; }
-  const std::string& LocalPart() const { return local_part_; }
-  std::string Merged() const;
-
-  int Compare(const StaticQName& other) const;
-  int Compare(const QName& other) const;
-
-  bool operator==(const StaticQName& other) const {
-    return Compare(other) == 0;
-  }
-  bool operator==(const QName& other) const {
-    return Compare(other) == 0;
-  }
-  bool operator!=(const StaticQName& other) const {
-    return Compare(other) != 0;
-  }
-  bool operator!=(const QName& other) const {
-    return Compare(other) != 0;
-  }
-  bool operator<(const QName& other) const {
-    return Compare(other) < 0;
-  }
-
- private:
-  std::string namespace_;
-  std::string local_part_;
-};
-
-inline bool StaticQName::operator==(const QName& other) const {
-  return other.Compare(*this) == 0;
-}
-
-inline bool StaticQName::operator!=(const QName& other) const {
-  return other.Compare(*this) != 0;
-}
-
-}
-
-#endif  // TALK_XMLLITE_QNAME_H_
diff --git a/third_party/libjingle/source/talk/xmllite/qname_unittest.cc b/third_party/libjingle/source/talk/xmllite/qname_unittest.cc
deleted file mode 100644
index 976d822..0000000
--- a/third_party/libjingle/source/talk/xmllite/qname_unittest.cc
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * libjingle
- * Copyright 2004, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string>
-#include "talk/base/gunit.h"
-#include "talk/xmllite/qname.h"
-
-using buzz::StaticQName;
-using buzz::QName;
-
-TEST(QNameTest, TestTrivial) {
-  QName name("test");
-  EXPECT_EQ(name.LocalPart(), "test");
-  EXPECT_EQ(name.Namespace(), "");
-}
-
-TEST(QNameTest, TestSplit) {
-  QName name("a:test");
-  EXPECT_EQ(name.LocalPart(), "test");
-  EXPECT_EQ(name.Namespace(), "a");
-  QName name2("a-very:long:namespace:test-this");
-  EXPECT_EQ(name2.LocalPart(), "test-this");
-  EXPECT_EQ(name2.Namespace(), "a-very:long:namespace");
-}
-
-TEST(QNameTest, TestMerge) {
-  QName name("a", "test");
-  EXPECT_EQ(name.LocalPart(), "test");
-  EXPECT_EQ(name.Namespace(), "a");
-  EXPECT_EQ(name.Merged(), "a:test");
-  QName name2("a-very:long:namespace", "test-this");
-  EXPECT_EQ(name2.LocalPart(), "test-this");
-  EXPECT_EQ(name2.Namespace(), "a-very:long:namespace");
-  EXPECT_EQ(name2.Merged(), "a-very:long:namespace:test-this");
-}
-
-TEST(QNameTest, TestAssignment) {
-  QName name("a", "test");
-  // copy constructor
-  QName namecopy(name);
-  EXPECT_EQ(namecopy.LocalPart(), "test");
-  EXPECT_EQ(namecopy.Namespace(), "a");
-  QName nameassigned("");
-  nameassigned = name;
-  EXPECT_EQ(nameassigned.LocalPart(), "test");
-  EXPECT_EQ(nameassigned.Namespace(), "a");
-}
-
-TEST(QNameTest, TestConstAssignment) {
-  StaticQName name = { "a", "test" };
-  QName namecopy(name);
-  EXPECT_EQ(namecopy.LocalPart(), "test");
-  EXPECT_EQ(namecopy.Namespace(), "a");
-  QName nameassigned("");
-  nameassigned = name;
-  EXPECT_EQ(nameassigned.LocalPart(), "test");
-  EXPECT_EQ(nameassigned.Namespace(), "a");
-}
-
-TEST(QNameTest, TestEquality) {
-  QName name("a-very:long:namespace:test-this");
-  QName name2("a-very:long:namespace", "test-this");
-  QName name3("a-very:long:namespaxe", "test-this");
-  EXPECT_TRUE(name == name2);
-  EXPECT_FALSE(name == name3);
-}
-
-TEST(QNameTest, TestCompare) {
-  QName name("a");
-  QName name2("nsa", "a");
-  QName name3("nsa", "b");
-  QName name4("nsb", "b");
-
-  EXPECT_TRUE(name < name2);
-  EXPECT_FALSE(name2 < name);
-
-  EXPECT_FALSE(name2 < name2);
-
-  EXPECT_TRUE(name2 < name3);
-  EXPECT_FALSE(name3 < name2);
-
-  EXPECT_TRUE(name3 < name4);
-  EXPECT_FALSE(name4 < name3);
-}
-
-TEST(QNameTest, TestStaticQName) {
-  const StaticQName const_name1 = { "namespace", "local-name1" };
-  const StaticQName const_name2 = { "namespace", "local-name2" };
-  const QName name("namespace", "local-name1");
-  const QName name1 = const_name1;
-  const QName name2 = const_name2;
-
-  EXPECT_TRUE(name == const_name1);
-  EXPECT_TRUE(const_name1 == name);
-  EXPECT_FALSE(name != const_name1);
-  EXPECT_FALSE(const_name1 != name);
-
-  EXPECT_TRUE(name == name1);
-  EXPECT_TRUE(name1 == name);
-  EXPECT_FALSE(name != name1);
-  EXPECT_FALSE(name1 != name);
-
-  EXPECT_FALSE(name == name2);
-  EXPECT_FALSE(name2 == name);
-  EXPECT_TRUE(name != name2);
-  EXPECT_TRUE(name2 != name);
-}
diff --git a/third_party/libjingle/source/talk/xmllite/xmlbuilder.cc b/third_party/libjingle/source/talk/xmllite/xmlbuilder.cc
deleted file mode 100644
index 4d08a80..0000000
--- a/third_party/libjingle/source/talk/xmllite/xmlbuilder.cc
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/xmllite/xmlbuilder.h"
-
-#include <vector>
-#include <set>
-#include "talk/base/common.h"
-#include "talk/xmllite/xmlconstants.h"
-#include "talk/xmllite/xmlelement.h"
-
-namespace buzz {
-
-XmlBuilder::XmlBuilder() :
-  pelCurrent_(NULL),
-  pelRoot_(NULL),
-  pvParents_(new std::vector<XmlElement *>()) {
-}
-
-void
-XmlBuilder::Reset() {
-  pelRoot_.reset();
-  pelCurrent_ = NULL;
-  pvParents_->clear();
-}
-
-XmlElement *
-XmlBuilder::BuildElement(XmlParseContext * pctx,
-                              const char * name, const char ** atts) {
-  QName tagName(pctx->ResolveQName(name, false));
-  if (tagName == QN_EMPTY)
-    return NULL;
-
-  XmlElement * pelNew = new XmlElement(tagName);
-
-  if (!*atts)
-    return pelNew;
-
-  std::set<QName> seenNonlocalAtts;
-
-  while (*atts) {
-    QName attName(pctx->ResolveQName(*atts, true));
-    if (attName == QN_EMPTY) {
-      delete pelNew;
-      return NULL;
-    }
-
-    // verify that namespaced names are unique
-    if (!attName.Namespace().empty()) {
-      if (seenNonlocalAtts.count(attName)) {
-        delete pelNew;
-        return NULL;
-      }
-      seenNonlocalAtts.insert(attName);
-    }
-
-    pelNew->AddAttr(attName, std::string(*(atts + 1)));
-    atts += 2;
-  }
-
-  return pelNew;
-}
-
-void
-XmlBuilder::StartElement(XmlParseContext * pctx,
-                              const char * name, const char ** atts) {
-  XmlElement * pelNew = BuildElement(pctx, name, atts);
-  if (pelNew == NULL) {
-    pctx->RaiseError(XML_ERROR_SYNTAX);
-    return;
-  }
-
-  if (!pelCurrent_) {
-    pelCurrent_ = pelNew;
-    pelRoot_.reset(pelNew);
-    pvParents_->push_back(NULL);
-  } else {
-    pelCurrent_->AddElement(pelNew);
-    pvParents_->push_back(pelCurrent_);
-    pelCurrent_ = pelNew;
-  }
-}
-
-void
-XmlBuilder::EndElement(XmlParseContext * pctx, const char * name) {
-  UNUSED(pctx);
-  UNUSED(name);
-  pelCurrent_ = pvParents_->back();
-  pvParents_->pop_back();
-}
-
-void
-XmlBuilder::CharacterData(XmlParseContext * pctx,
-                               const char * text, int len) {
-  UNUSED(pctx);
-  if (pelCurrent_) {
-    pelCurrent_->AddParsedText(text, len);
-  }
-}
-
-void
-XmlBuilder::Error(XmlParseContext * pctx, XML_Error err) {
-  UNUSED(pctx);
-  UNUSED(err);
-  pelRoot_.reset(NULL);
-  pelCurrent_ = NULL;
-  pvParents_->clear();
-}
-
-XmlElement *
-XmlBuilder::CreateElement() {
-  return pelRoot_.release();
-}
-
-XmlElement *
-XmlBuilder::BuiltElement() {
-  return pelRoot_.get();
-}
-
-XmlBuilder::~XmlBuilder() {
-}
-
-
-
-}
diff --git a/third_party/libjingle/source/talk/xmllite/xmlbuilder.h b/third_party/libjingle/source/talk/xmllite/xmlbuilder.h
deleted file mode 100644
index 984eee2..0000000
--- a/third_party/libjingle/source/talk/xmllite/xmlbuilder.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _xmlbuilder_h_
-#define _xmlbuilder_h_
-
-#include <string>
-#include <vector>
-#include "talk/base/scoped_ptr.h"
-#include "talk/xmllite/xmlparser.h"
-
-#ifdef EXPAT_RELATIVE_PATH
-#include "expat.h"
-#else
-#include "third_party/expat/v2_0_1/Source/lib/expat.h"
-#endif  // EXPAT_RELATIVE_PATH
-
-namespace buzz {
-
-class XmlElement;
-class XmlParseContext;
-
-
-class XmlBuilder : public XmlParseHandler {
-public:
-  XmlBuilder();
-
-  static XmlElement * BuildElement(XmlParseContext * pctx,
-                                  const char * name, const char ** atts);
-  virtual void StartElement(XmlParseContext * pctx,
-                            const char * name, const char ** atts);
-  virtual void EndElement(XmlParseContext * pctx, const char * name);
-  virtual void CharacterData(XmlParseContext * pctx,
-                             const char * text, int len);
-  virtual void Error(XmlParseContext * pctx, XML_Error);
-  virtual ~XmlBuilder();
-
-  void Reset();
-
-  // Take ownership of the built element; second call returns NULL
-  XmlElement * CreateElement();
-
-  // Peek at the built element without taking ownership
-  XmlElement * BuiltElement();
-
-private:
-  XmlElement * pelCurrent_;
-  talk_base::scoped_ptr<XmlElement> pelRoot_;
-  talk_base::scoped_ptr<std::vector<XmlElement*> > pvParents_;
-};
-
-}
-
-#endif
diff --git a/third_party/libjingle/source/talk/xmllite/xmlbuilder_unittest.cc b/third_party/libjingle/source/talk/xmllite/xmlbuilder_unittest.cc
deleted file mode 100644
index 9302276..0000000
--- a/third_party/libjingle/source/talk/xmllite/xmlbuilder_unittest.cc
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * libjingle
- * Copyright 2004, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string>
-#include <sstream>
-#include <iostream>
-#include "talk/base/common.h"
-#include "talk/base/gunit.h"
-#include "talk/xmllite/xmlbuilder.h"
-#include "talk/xmllite/xmlelement.h"
-#include "talk/xmllite/xmlparser.h"
-
-using buzz::XmlBuilder;
-using buzz::XmlElement;
-using buzz::XmlParser;
-
-TEST(XmlBuilderTest, TestTrivial) {
-  XmlBuilder builder;
-  XmlParser::ParseXml(&builder, "<testing/>");
-  EXPECT_EQ("<testing/>", builder.BuiltElement()->Str());
-}
-
-TEST(XmlBuilderTest, TestAttributes1) {
-  XmlBuilder builder;
-  XmlParser::ParseXml(&builder, "<testing a='b'/>");
-  EXPECT_EQ("<testing a=\"b\"/>", builder.BuiltElement()->Str());
-}
-
-TEST(XmlBuilderTest, TestAttributes2) {
-  XmlBuilder builder;
-  XmlParser::ParseXml(&builder, "<testing e='' long='some text'/>");
-  EXPECT_EQ("<testing e=\"\" long=\"some text\"/>",
-      builder.BuiltElement()->Str());
-}
-
-TEST(XmlBuilderTest, TestNesting1) {
-  XmlBuilder builder;
-  XmlParser::ParseXml(&builder,
-      "<top><first/><second><third></third></second></top>");
-  EXPECT_EQ("<top><first/><second><third/></second></top>",
-      builder.BuiltElement()->Str());
-}
-
-TEST(XmlBuilderTest, TestNesting2) {
-  XmlBuilder builder;
-  XmlParser::ParseXml(&builder,
-    "<top><fifth><deeper><and><deeper/></and><sibling><leaf/>"
-    "</sibling></deeper></fifth><first/><second><third></third>"
-    "</second></top>");
-  EXPECT_EQ("<top><fifth><deeper><and><deeper/></and><sibling><leaf/>"
-    "</sibling></deeper></fifth><first/><second><third/>"
-    "</second></top>", builder.BuiltElement()->Str());
-}
-
-TEST(XmlBuilderTest, TestQuoting1) {
-  XmlBuilder builder;
-  XmlParser::ParseXml(&builder, "<testing a='>'/>");
-  EXPECT_EQ("<testing a=\"&gt;\"/>", builder.BuiltElement()->Str());
-}
-
-TEST(XmlBuilderTest, TestQuoting2) {
-  XmlBuilder builder;
-  XmlParser::ParseXml(&builder, "<testing a='&lt;>&amp;&quot;'/>");
-  EXPECT_EQ("<testing a=\"&lt;&gt;&amp;&quot;\"/>",
-      builder.BuiltElement()->Str());
-}
-
-TEST(XmlBuilderTest, TestQuoting3) {
-  XmlBuilder builder;
-  XmlParser::ParseXml(&builder, "<testing a='so &quot;important&quot;'/>");
-  EXPECT_EQ("<testing a=\"so &quot;important&quot;\"/>",
-      builder.BuiltElement()->Str());
-}
-
-TEST(XmlBuilderTest, TestQuoting4) {
-  XmlBuilder builder;
-  XmlParser::ParseXml(&builder, "<testing a='&quot;important&quot;, yes'/>");
-  EXPECT_EQ("<testing a=\"&quot;important&quot;, yes\"/>",
-      builder.BuiltElement()->Str());
-}
-
-TEST(XmlBuilderTest, TestQuoting5) {
-  XmlBuilder builder;
-  XmlParser::ParseXml(&builder,
-      "<testing a='&lt;what is &quot;important&quot;&gt;'/>");
-  EXPECT_EQ("<testing a=\"&lt;what is &quot;important&quot;&gt;\"/>",
-      builder.BuiltElement()->Str());
-}
-
-TEST(XmlBuilderTest, TestText1) {
-  XmlBuilder builder;
-  XmlParser::ParseXml(&builder, "<testing>></testing>");
-  EXPECT_EQ("<testing>&gt;</testing>", builder.BuiltElement()->Str());
-}
-
-TEST(XmlBuilderTest, TestText2) {
-  XmlBuilder builder;
-  XmlParser::ParseXml(&builder, "<testing>&lt;>&amp;&quot;</testing>");
-  EXPECT_EQ("<testing>&lt;&gt;&amp;\"</testing>",
-      builder.BuiltElement()->Str());
-}
-
-TEST(XmlBuilderTest, TestText3) {
-  XmlBuilder builder;
-  XmlParser::ParseXml(&builder, "<testing>so &lt;important&gt;</testing>");
-  EXPECT_EQ("<testing>so &lt;important&gt;</testing>",
-      builder.BuiltElement()->Str());
-}
-
-TEST(XmlBuilderTest, TestText4) {
-  XmlBuilder builder;
-  XmlParser::ParseXml(&builder, "<testing>&lt;important&gt;, yes</testing>");
-  EXPECT_EQ("<testing>&lt;important&gt;, yes</testing>",
-      builder.BuiltElement()->Str());
-}
-
-TEST(XmlBuilderTest, TestText5) {
-  XmlBuilder builder;
-  XmlParser::ParseXml(&builder,
-      "<testing>importance &amp;&lt;important&gt;&amp;</testing>");
-  EXPECT_EQ("<testing>importance &amp;&lt;important&gt;&amp;</testing>",
-      builder.BuiltElement()->Str());
-}
-
-TEST(XmlBuilderTest, TestNamespace1) {
-  XmlBuilder builder;
-  XmlParser::ParseXml(&builder, "<testing xmlns='foo'/>");
-  EXPECT_EQ("<testing xmlns=\"foo\"/>", builder.BuiltElement()->Str());
-}
-
-TEST(XmlBuilderTest, TestNamespace2) {
-  XmlBuilder builder;
-  XmlParser::ParseXml(&builder, "<testing xmlns:a='foo' a:b='c'/>");
-  EXPECT_EQ("<testing xmlns:a=\"foo\" a:b=\"c\"/>",
-      builder.BuiltElement()->Str());
-}
-
-TEST(XmlBuilderTest, TestNamespace3) {
-  XmlBuilder builder;
-  XmlParser::ParseXml(&builder, "<testing xmlns:a=''/>");
-  EXPECT_TRUE(NULL == builder.BuiltElement());
-}
-
-TEST(XmlBuilderTest, TestNamespace4) {
-  XmlBuilder builder;
-  XmlParser::ParseXml(&builder, "<testing a:b='c'/>");
-  EXPECT_TRUE(NULL == builder.BuiltElement());
-}
-
-TEST(XmlBuilderTest, TestAttrCollision1) {
-  XmlBuilder builder;
-  XmlParser::ParseXml(&builder, "<testing a='first' a='second'/>");
-  EXPECT_TRUE(NULL == builder.BuiltElement());
-}
-
-TEST(XmlBuilderTest, TestAttrCollision2) {
-  XmlBuilder builder;
-  XmlParser::ParseXml(&builder,
-      "<testing xmlns:a='foo' xmlns:b='foo' a:x='c' b:x='d'/>");
-  EXPECT_TRUE(NULL == builder.BuiltElement());
-}
-
-TEST(XmlBuilderTest, TestAttrCollision3) {
-  XmlBuilder builder;
-  XmlParser::ParseXml(&builder,
-      "<testing xmlns:a='foo'><nested xmlns:b='foo' a:x='c' b:x='d'/>"
-      "</testing>");
-  EXPECT_TRUE(NULL == builder.BuiltElement());
-}
-
diff --git a/third_party/libjingle/source/talk/xmllite/xmlconstants.cc b/third_party/libjingle/source/talk/xmllite/xmlconstants.cc
deleted file mode 100644
index 87eb544..0000000
--- a/third_party/libjingle/source/talk/xmllite/xmlconstants.cc
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/xmllite/xmlconstants.h"
-
-namespace buzz {
-
-const char STR_EMPTY[] = "";
-const char NS_XML[] = "http://www.w3.org/XML/1998/namespace";
-const char NS_XMLNS[] = "http://www.w3.org/2000/xmlns/";
-const char STR_XMLNS[] = "xmlns";
-const char STR_XML[] = "xml";
-const char STR_VERSION[] = "version";
-const char STR_ENCODING[] = "encoding";
-
-const StaticQName QN_EMPTY = { STR_EMPTY, STR_EMPTY };
-const StaticQName QN_XMLNS = { STR_EMPTY, STR_XMLNS };
-
-// TODO: Local statics are not thread-safe. Remove the
-// following two functions if possible.
-const std::string& EmptyStringRef() {
-  static std::string result;
-  return result;
-}
-
-const QName& EmptyQNameRef() {
-  static QName result(QN_EMPTY);
-  return result;
-}
-
-
-}
diff --git a/third_party/libjingle/source/talk/xmllite/xmlconstants.h b/third_party/libjingle/source/talk/xmllite/xmlconstants.h
deleted file mode 100644
index a08e5a9..0000000
--- a/third_party/libjingle/source/talk/xmllite/xmlconstants.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_XMLLITE_XMLCONSTANTS_H_
-#define TALK_XMLLITE_XMLCONSTANTS_H_
-
-#include <string>
-
-#include "talk/xmllite/qname.h"
-
-namespace buzz {
-
-extern const char STR_EMPTY[];
-extern const char NS_XML[];
-extern const char NS_XMLNS[];
-extern const char STR_XMLNS[];
-extern const char STR_XML[];
-extern const char STR_VERSION[];
-extern const char STR_ENCODING[];
-
-extern const StaticQName QN_EMPTY;
-extern const StaticQName QN_XMLNS;
-
-// Returns reference to an empty string.
-const std::string& EmptyStringRef();
-const QName& EmptyQNameRef();
-
-}
-
-#endif  // TALK_XMLLITE_XMLCONSTANTS_H_
diff --git a/third_party/libjingle/source/talk/xmllite/xmlelement.cc b/third_party/libjingle/source/talk/xmllite/xmlelement.cc
deleted file mode 100644
index 7b208e6..0000000
--- a/third_party/libjingle/source/talk/xmllite/xmlelement.cc
+++ /dev/null
@@ -1,551 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/xmllite/xmlelement.h"
-
-#include <ostream>
-#include <sstream>
-#include <string>
-#include <vector>
-
-#include "talk/base/common.h"
-#include "talk/xmllite/qname.h"
-#include "talk/xmllite/xmlparser.h"
-#include "talk/xmllite/xmlbuilder.h"
-#include "talk/xmllite/xmlprinter.h"
-#include "talk/xmllite/xmlconstants.h"
-
-namespace buzz {
-
-XmlChild::~XmlChild() {
-}
-
-bool
-XmlText::IsTextImpl() const {
-  return true;
-}
-
-XmlElement *
-XmlText::AsElementImpl() const {
-  return NULL;
-}
-
-XmlText *
-XmlText::AsTextImpl() const {
-  return const_cast<XmlText *>(this);
-}
-
-void
-XmlText::SetText(const std::string & text) {
-  text_ = text;
-}
-
-void
-XmlText::AddParsedText(const char * buf, int len) {
-  text_.append(buf, len);
-}
-
-void
-XmlText::AddText(const std::string & text) {
-  text_ += text;
-}
-
-XmlText::~XmlText() {
-}
-
-XmlElement::XmlElement(const QName & name) :
-    name_(name),
-    pFirstAttr_(NULL),
-    pLastAttr_(NULL),
-    pFirstChild_(NULL),
-    pLastChild_(NULL),
-    cdata_(false) {
-}
-
-XmlElement::XmlElement(const XmlElement & elt) :
-    XmlChild(),
-    name_(elt.name_),
-    pFirstAttr_(NULL),
-    pLastAttr_(NULL),
-    pFirstChild_(NULL),
-    pLastChild_(NULL),
-    cdata_(false) {
-
-  // copy attributes
-  XmlAttr * pAttr;
-  XmlAttr ** ppLastAttr = &pFirstAttr_;
-  XmlAttr * newAttr = NULL;
-  for (pAttr = elt.pFirstAttr_; pAttr; pAttr = pAttr->NextAttr()) {
-    newAttr = new XmlAttr(*pAttr);
-    *ppLastAttr = newAttr;
-    ppLastAttr = &(newAttr->pNextAttr_);
-  }
-  pLastAttr_ = newAttr;
-
-  // copy children
-  XmlChild * pChild;
-  XmlChild ** ppLast = &pFirstChild_;
-  XmlChild * newChild = NULL;
-
-  for (pChild = elt.pFirstChild_; pChild; pChild = pChild->NextChild()) {
-    if (pChild->IsText()) {
-      newChild = new XmlText(*(pChild->AsText()));
-    } else {
-      newChild = new XmlElement(*(pChild->AsElement()));
-    }
-    *ppLast = newChild;
-    ppLast = &(newChild->pNextChild_);
-  }
-  pLastChild_ = newChild;
-
-  cdata_ = elt.cdata_;
-}
-
-XmlElement::XmlElement(const QName & name, bool useDefaultNs) :
-  name_(name),
-  pFirstAttr_(useDefaultNs ? new XmlAttr(QN_XMLNS, name.Namespace()) : NULL),
-  pLastAttr_(pFirstAttr_),
-  pFirstChild_(NULL),
-  pLastChild_(NULL),
-  cdata_(false) {
-}
-
-bool
-XmlElement::IsTextImpl() const {
-  return false;
-}
-
-XmlElement *
-XmlElement::AsElementImpl() const {
-  return const_cast<XmlElement *>(this);
-}
-
-XmlText *
-XmlElement::AsTextImpl() const {
-  return NULL;
-}
-
-const std::string &
-XmlElement::BodyText() const {
-  if (pFirstChild_ && pFirstChild_->IsText() && pLastChild_ == pFirstChild_) {
-    return pFirstChild_->AsText()->Text();
-  }
-
-  return EmptyStringRef();
-}
-
-void
-XmlElement::SetBodyText(const std::string & text) {
-  if (text == STR_EMPTY) {
-    ClearChildren();
-  } else if (pFirstChild_ == NULL) {
-    AddText(text);
-  } else if (pFirstChild_->IsText() && pLastChild_ == pFirstChild_) {
-    pFirstChild_->AsText()->SetText(text);
-  } else {
-    ClearChildren();
-    AddText(text);
-  }
-}
-
-const QName &
-XmlElement::FirstElementName() const {
-  const XmlElement * element = FirstElement();
-  if (element == NULL)
-    return EmptyQNameRef();
-  return element->Name();
-}
-
-XmlAttr *
-XmlElement::FirstAttr() {
-  return pFirstAttr_;
-}
-
-const std::string &
-XmlElement::Attr(const StaticQName & name) const {
-  XmlAttr * pattr;
-  for (pattr = pFirstAttr_; pattr; pattr = pattr->pNextAttr_) {
-    if (pattr->name_ == name)
-      return pattr->value_;
-  }
-  return EmptyStringRef();
-}
-
-const std::string &
-XmlElement::Attr(const QName & name) const {
-  XmlAttr * pattr;
-  for (pattr = pFirstAttr_; pattr; pattr = pattr->pNextAttr_) {
-    if (pattr->name_ == name)
-      return pattr->value_;
-  }
-  return EmptyStringRef();
-}
-
-bool
-XmlElement::HasAttr(const StaticQName & name) const {
-  XmlAttr * pattr;
-  for (pattr = pFirstAttr_; pattr; pattr = pattr->pNextAttr_) {
-    if (pattr->name_ == name)
-      return true;
-  }
-  return false;
-}
-
-bool
-XmlElement::HasAttr(const QName & name) const {
-  XmlAttr * pattr;
-  for (pattr = pFirstAttr_; pattr; pattr = pattr->pNextAttr_) {
-    if (pattr->name_ == name)
-      return true;
-  }
-  return false;
-}
-
-void
-XmlElement::SetAttr(const QName & name, const std::string & value) {
-  XmlAttr * pattr;
-  for (pattr = pFirstAttr_; pattr; pattr = pattr->pNextAttr_) {
-    if (pattr->name_ == name)
-      break;
-  }
-  if (!pattr) {
-    pattr = new XmlAttr(name, value);
-    if (pLastAttr_)
-      pLastAttr_->pNextAttr_ = pattr;
-    else
-      pFirstAttr_ = pattr;
-    pLastAttr_ = pattr;
-    return;
-  }
-  pattr->value_ = value;
-}
-
-void
-XmlElement::ClearAttr(const QName & name) {
-  XmlAttr * pattr;
-  XmlAttr *pLastAttr = NULL;
-  for (pattr = pFirstAttr_; pattr; pattr = pattr->pNextAttr_) {
-    if (pattr->name_ == name)
-      break;
-    pLastAttr = pattr;
-  }
-  if (!pattr)
-    return;
-  if (!pLastAttr)
-    pFirstAttr_ = pattr->pNextAttr_;
-  else
-    pLastAttr->pNextAttr_ = pattr->pNextAttr_;
-  if (pLastAttr_ == pattr)
-    pLastAttr_ = pLastAttr;
-  delete pattr;
-}
-
-XmlChild *
-XmlElement::FirstChild() {
-  return pFirstChild_;
-}
-
-XmlElement *
-XmlElement::FirstElement() {
-  XmlChild * pChild;
-  for (pChild = pFirstChild_; pChild; pChild = pChild->pNextChild_) {
-    if (!pChild->IsText())
-      return pChild->AsElement();
-  }
-  return NULL;
-}
-
-XmlElement *
-XmlElement::NextElement() {
-  XmlChild * pChild;
-  for (pChild = pNextChild_; pChild; pChild = pChild->pNextChild_) {
-    if (!pChild->IsText())
-      return pChild->AsElement();
-  }
-  return NULL;
-}
-
-XmlElement *
-XmlElement::FirstWithNamespace(const std::string & ns) {
-  XmlChild * pChild;
-  for (pChild = pFirstChild_; pChild; pChild = pChild->pNextChild_) {
-    if (!pChild->IsText() && pChild->AsElement()->Name().Namespace() == ns)
-      return pChild->AsElement();
-  }
-  return NULL;
-}
-
-XmlElement *
-XmlElement::NextWithNamespace(const std::string & ns) {
-  XmlChild * pChild;
-  for (pChild = pNextChild_; pChild; pChild = pChild->pNextChild_) {
-    if (!pChild->IsText() && pChild->AsElement()->Name().Namespace() == ns)
-      return pChild->AsElement();
-  }
-  return NULL;
-}
-
-XmlElement *
-XmlElement::FirstNamed(const QName & name) {
-  XmlChild * pChild;
-  for (pChild = pFirstChild_; pChild; pChild = pChild->pNextChild_) {
-    if (!pChild->IsText() && pChild->AsElement()->Name() == name)
-      return pChild->AsElement();
-  }
-  return NULL;
-}
-
-XmlElement *
-XmlElement::FirstNamed(const StaticQName & name) {
-  XmlChild * pChild;
-  for (pChild = pFirstChild_; pChild; pChild = pChild->pNextChild_) {
-    if (!pChild->IsText() && pChild->AsElement()->Name() == name)
-      return pChild->AsElement();
-  }
-  return NULL;
-}
-
-XmlElement *
-XmlElement::NextNamed(const QName & name) {
-  XmlChild * pChild;
-  for (pChild = pNextChild_; pChild; pChild = pChild->pNextChild_) {
-    if (!pChild->IsText() && pChild->AsElement()->Name() == name)
-      return pChild->AsElement();
-  }
-  return NULL;
-}
-
-XmlElement *
-XmlElement::NextNamed(const StaticQName & name) {
-  XmlChild * pChild;
-  for (pChild = pNextChild_; pChild; pChild = pChild->pNextChild_) {
-    if (!pChild->IsText() && pChild->AsElement()->Name() == name)
-      return pChild->AsElement();
-  }
-  return NULL;
-}
-
-XmlElement* XmlElement::FindOrAddNamedChild(const QName& name) {
-  XmlElement* child = FirstNamed(name);
-  if (!child) {
-    child = new XmlElement(name);
-    AddElement(child);
-  }
-
-  return child;
-}
-
-const std::string &
-XmlElement::TextNamed(const QName & name) const {
-  XmlChild * pChild;
-  for (pChild = pFirstChild_; pChild; pChild = pChild->pNextChild_) {
-    if (!pChild->IsText() && pChild->AsElement()->Name() == name)
-      return pChild->AsElement()->BodyText();
-  }
-  return EmptyStringRef();
-}
-
-void
-XmlElement::InsertChildAfter(XmlChild * pPredecessor, XmlChild * pNext) {
-  if (pPredecessor == NULL) {
-    pNext->pNextChild_ = pFirstChild_;
-    pFirstChild_ = pNext;
-  }
-  else {
-    pNext->pNextChild_ = pPredecessor->pNextChild_;
-    pPredecessor->pNextChild_ = pNext;
-  }
-}
-
-void
-XmlElement::RemoveChildAfter(XmlChild * pPredecessor) {
-  XmlChild * pNext;
-
-  if (pPredecessor == NULL) {
-    pNext = pFirstChild_;
-    pFirstChild_ = pNext->pNextChild_;
-  }
-  else {
-    pNext = pPredecessor->pNextChild_;
-    pPredecessor->pNextChild_ = pNext->pNextChild_;
-  }
-
-  if (pLastChild_ == pNext)
-    pLastChild_ = pPredecessor;
-
-  delete pNext;
-}
-
-void
-XmlElement::AddAttr(const QName & name, const std::string & value) {
-  ASSERT(!HasAttr(name));
-
-  XmlAttr ** pprev = pLastAttr_ ? &(pLastAttr_->pNextAttr_) : &pFirstAttr_;
-  pLastAttr_ = (*pprev = new XmlAttr(name, value));
-}
-
-void
-XmlElement::AddAttr(const QName & name, const std::string & value,
-                         int depth) {
-  XmlElement * element = this;
-  while (depth--) {
-    element = element->pLastChild_->AsElement();
-  }
-  element->AddAttr(name, value);
-}
-
-void
-XmlElement::AddParsedText(const char * cstr, int len) {
-  if (len == 0)
-    return;
-
-  if (pLastChild_ && pLastChild_->IsText()) {
-    pLastChild_->AsText()->AddParsedText(cstr, len);
-    return;
-  }
-  XmlChild ** pprev = pLastChild_ ? &(pLastChild_->pNextChild_) : &pFirstChild_;
-  pLastChild_ = *pprev = new XmlText(cstr, len);
-}
-
-void
-XmlElement::AddCDATAText(const char * buf, int len) {
-  cdata_ = true;
-  AddParsedText(buf, len);
-}
-
-void
-XmlElement::AddText(const std::string & text) {
-  if (text == STR_EMPTY)
-    return;
-
-  if (pLastChild_ && pLastChild_->IsText()) {
-    pLastChild_->AsText()->AddText(text);
-    return;
-  }
-  XmlChild ** pprev = pLastChild_ ? &(pLastChild_->pNextChild_) : &pFirstChild_;
-  pLastChild_ = *pprev = new XmlText(text);
-}
-
-void
-XmlElement::AddText(const std::string & text, int depth) {
-  // note: the first syntax is ambigious for msvc 6
-  // XmlElement * pel(this);
-  XmlElement * element = this;
-  while (depth--) {
-    element = element->pLastChild_->AsElement();
-  }
-  element->AddText(text);
-}
-
-void
-XmlElement::AddElement(XmlElement *pelChild) {
-  if (pelChild == NULL)
-    return;
-
-  XmlChild ** pprev = pLastChild_ ? &(pLastChild_->pNextChild_) : &pFirstChild_;
-  pLastChild_ = *pprev = pelChild;
-  pelChild->pNextChild_ = NULL;
-}
-
-void
-XmlElement::AddElement(XmlElement *pelChild, int depth) {
-  XmlElement * element = this;
-  while (depth--) {
-    element = element->pLastChild_->AsElement();
-  }
-  element->AddElement(pelChild);
-}
-
-void
-XmlElement::ClearNamedChildren(const QName & name) {
-  XmlChild * prev_child = NULL;
-  XmlChild * next_child;
-  XmlChild * child;
-  for (child = FirstChild(); child; child = next_child) {
-    next_child = child->NextChild();
-    if (!child->IsText() && child->AsElement()->Name() == name)
-    {
-      RemoveChildAfter(prev_child);
-      continue;
-    }
-    prev_child = child;
-  }
-}
-
-void
-XmlElement::ClearAttributes() {
-  XmlAttr * pattr;
-  for (pattr = pFirstAttr_; pattr; ) {
-    XmlAttr * pToDelete = pattr;
-    pattr = pattr->pNextAttr_;
-    delete pToDelete;
-  }
-  pFirstAttr_ = pLastAttr_ = NULL;
-}
-
-void
-XmlElement::ClearChildren() {
-  XmlChild * pchild;
-  for (pchild = pFirstChild_; pchild; ) {
-    XmlChild * pToDelete = pchild;
-    pchild = pchild->pNextChild_;
-    delete pToDelete;
-  }
-  pFirstChild_ = pLastChild_ = NULL;
-}
-
-std::string
-XmlElement::Str() const {
-  std::stringstream ss;
-  XmlPrinter::PrintXml(&ss, this);
-  return ss.str();
-}
-
-XmlElement *
-XmlElement::ForStr(const std::string & str) {
-  XmlBuilder builder;
-  XmlParser::ParseXml(&builder, str);
-  return builder.CreateElement();
-}
-
-XmlElement::~XmlElement() {
-  XmlAttr * pattr;
-  for (pattr = pFirstAttr_; pattr; ) {
-    XmlAttr * pToDelete = pattr;
-    pattr = pattr->pNextAttr_;
-    delete pToDelete;
-  }
-
-  XmlChild * pchild;
-  for (pchild = pFirstChild_; pchild; ) {
-    XmlChild * pToDelete = pchild;
-    pchild = pchild->pNextChild_;
-    delete pToDelete;
-  }
-}
-
-}
diff --git a/third_party/libjingle/source/talk/xmllite/xmlelement.h b/third_party/libjingle/source/talk/xmllite/xmlelement.h
deleted file mode 100644
index 7cb30f3..0000000
--- a/third_party/libjingle/source/talk/xmllite/xmlelement.h
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_XMLLITE_XMLELEMENT_H_
-#define TALK_XMLLITE_XMLELEMENT_H_
-
-#include <iosfwd>
-#include <string>
-
-#include "talk/base/scoped_ptr.h"
-#include "talk/xmllite/qname.h"
-
-namespace buzz {
-
-class XmlChild;
-class XmlText;
-class XmlElement;
-class XmlAttr;
-
-class XmlChild {
-friend class XmlElement;
-
-public:
-  XmlChild * NextChild() { return pNextChild_; }
-  const XmlChild * NextChild() const { return pNextChild_; }
-
-  bool IsText() const { return IsTextImpl(); }
-
-  XmlElement * AsElement() { return AsElementImpl(); }
-  const XmlElement * AsElement() const { return AsElementImpl(); }
-
-  XmlText * AsText() { return AsTextImpl(); }
-  const XmlText * AsText() const { return AsTextImpl(); }
-
-
-protected:
-
-  XmlChild() :
-    pNextChild_(NULL) {
-  }
-
-  virtual bool IsTextImpl() const = 0;
-  virtual XmlElement * AsElementImpl() const = 0;
-  virtual XmlText * AsTextImpl() const = 0;
-
-
-  virtual ~XmlChild();
-
-private:
-  XmlChild(const XmlChild & noimpl);
-
-  XmlChild * pNextChild_;
-
-};
-
-class XmlText : public XmlChild {
-public:
-  explicit XmlText(const std::string & text) :
-    XmlChild(),
-    text_(text) {
-  }
-  explicit XmlText(const XmlText & t) :
-    XmlChild(),
-    text_(t.text_) {
-  }
-  explicit XmlText(const char * cstr, size_t len) :
-    XmlChild(),
-    text_(cstr, len) {
-  }
-  virtual ~XmlText();
-
-  const std::string & Text() const { return text_; }
-  void SetText(const std::string & text);
-  void AddParsedText(const char * buf, int len);
-  void AddText(const std::string & text);
-
-protected:
-  virtual bool IsTextImpl() const;
-  virtual XmlElement * AsElementImpl() const;
-  virtual XmlText * AsTextImpl() const;
-
-private:
-  std::string text_;
-};
-
-class XmlAttr {
-friend class XmlElement;
-
-public:
-  XmlAttr * NextAttr() const { return pNextAttr_; }
-  const QName & Name() const { return name_; }
-  const std::string & Value() const { return value_; }
-
-private:
-  explicit XmlAttr(const QName & name, const std::string & value) :
-    pNextAttr_(NULL),
-    name_(name),
-    value_(value) {
-  }
-  explicit XmlAttr(const XmlAttr & att) :
-    pNextAttr_(NULL),
-    name_(att.name_),
-    value_(att.value_) {
-  }
-
-  XmlAttr * pNextAttr_;
-  QName name_;
-  std::string value_;
-};
-
-class XmlElement : public XmlChild {
-public:
-  explicit XmlElement(const QName & name);
-  explicit XmlElement(const QName & name, bool useDefaultNs);
-  explicit XmlElement(const XmlElement & elt);
-
-  virtual ~XmlElement();
-
-  const QName& Name() const { return name_; }
-  void SetName(const QName& name) { name_ = name; }
-
-  const std::string & BodyText() const;
-  void SetBodyText(const std::string & text);
-
-  const QName & FirstElementName() const;
-
-  XmlAttr * FirstAttr();
-  const XmlAttr * FirstAttr() const
-    { return const_cast<XmlElement *>(this)->FirstAttr(); }
-
-  // Attr will return STR_EMPTY if the attribute isn't there:
-  // use HasAttr to test presence of an attribute.
-  const std::string & Attr(const StaticQName& name) const;
-  const std::string & Attr(const QName& name) const;
-  bool HasAttr(const StaticQName & name) const;
-  bool HasAttr(const QName & name) const;
-  void SetAttr(const QName & name, const std::string & value);
-  void ClearAttr(const QName & name);
-
-  XmlChild * FirstChild();
-  const XmlChild * FirstChild() const
-    { return const_cast<XmlElement *>(this)->FirstChild(); }
-
-  XmlElement * FirstElement();
-  const XmlElement * FirstElement() const
-    { return const_cast<XmlElement *>(this)->FirstElement(); }
-
-  XmlElement * NextElement();
-  const XmlElement * NextElement() const
-    { return const_cast<XmlElement *>(this)->NextElement(); }
-
-  XmlElement * FirstWithNamespace(const std::string & ns);
-  const XmlElement * FirstWithNamespace(const std::string & ns) const
-    { return const_cast<XmlElement *>(this)->FirstWithNamespace(ns); }
-
-  XmlElement * NextWithNamespace(const std::string & ns);
-  const XmlElement * NextWithNamespace(const std::string & ns) const
-    { return const_cast<XmlElement *>(this)->NextWithNamespace(ns); }
-
-  XmlElement * FirstNamed(const StaticQName & name);
-  const XmlElement * FirstNamed(const StaticQName & name) const
-    { return const_cast<XmlElement *>(this)->FirstNamed(name); }
-
-  XmlElement * FirstNamed(const QName & name);
-  const XmlElement * FirstNamed(const QName & name) const
-    { return const_cast<XmlElement *>(this)->FirstNamed(name); }
-
-  XmlElement * NextNamed(const StaticQName & name);
-  const XmlElement * NextNamed(const StaticQName & name) const
-    { return const_cast<XmlElement *>(this)->NextNamed(name); }
-
-  XmlElement * NextNamed(const QName & name);
-  const XmlElement * NextNamed(const QName & name) const
-    { return const_cast<XmlElement *>(this)->NextNamed(name); }
-
-  // Finds the first element named 'name'.  If that element can't be found then
-  // adds one and returns it.
-  XmlElement* FindOrAddNamedChild(const QName& name);
-
-  const std::string & TextNamed(const QName & name) const;
-
-  void InsertChildAfter(XmlChild * pPredecessor, XmlChild * pNewChild);
-  void RemoveChildAfter(XmlChild * pPredecessor);
-
-  void AddParsedText(const char * buf, int len);
-  // Note: CDATA is not supported by XMPP, therefore using this function will
-  // generate non-XMPP compatible XML.
-  void AddCDATAText(const char * buf, int len);
-  void AddText(const std::string & text);
-  void AddText(const std::string & text, int depth);
-  void AddElement(XmlElement * pelChild);
-  void AddElement(XmlElement * pelChild, int depth);
-  void AddAttr(const QName & name, const std::string & value);
-  void AddAttr(const QName & name, const std::string & value, int depth);
-  void ClearNamedChildren(const QName & name);
-  void ClearAttributes();
-  void ClearChildren();
-
-  static XmlElement * ForStr(const std::string & str);
-  std::string Str() const;
-
-  bool IsCDATA() const { return cdata_; }
-
-protected:
-  virtual bool IsTextImpl() const;
-  virtual XmlElement * AsElementImpl() const;
-  virtual XmlText * AsTextImpl() const;
-
-private:
-  QName name_;
-  XmlAttr * pFirstAttr_;
-  XmlAttr * pLastAttr_;
-  XmlChild * pFirstChild_;
-  XmlChild * pLastChild_;
-  bool cdata_;
-};
-
-}
-
-#endif  // TALK_XMLLITE_XMLELEMENT_H_
diff --git a/third_party/libjingle/source/talk/xmllite/xmlelement_unittest.cc b/third_party/libjingle/source/talk/xmllite/xmlelement_unittest.cc
deleted file mode 100644
index 6d488fa..0000000
--- a/third_party/libjingle/source/talk/xmllite/xmlelement_unittest.cc
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- * libjingle
- * Copyright 2004, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string>
-#include <sstream>
-#include <iostream>
-#include "talk/base/common.h"
-#include "talk/base/gunit.h"
-#include "talk/base/thread.h"
-#include "talk/xmllite/xmlelement.h"
-
-using buzz::QName;
-using buzz::XmlAttr;
-using buzz::XmlChild;
-using buzz::XmlElement;
-
-std::ostream& operator<<(std::ostream& os, const QName& name) {
-  os << name.Namespace() << ":" << name.LocalPart();
-  return os;
-}
-
-TEST(XmlElementTest, TestConstructors) {
-  XmlElement elt(QName("google:test", "first"));
-  EXPECT_EQ("<test:first xmlns:test=\"google:test\"/>", elt.Str());
-
-  XmlElement elt2(QName("google:test", "first"), true);
-  EXPECT_EQ("<first xmlns=\"google:test\"/>", elt2.Str());
-}
-
-TEST(XmlElementTest, TestAdd) {
-  XmlElement elt(QName("google:test", "root"), true);
-  elt.AddElement(new XmlElement(QName("google:test", "first")));
-  elt.AddElement(new XmlElement(QName("google:test", "nested")), 1);
-  elt.AddText("nested-value", 2);
-  elt.AddText("between-", 1);
-  elt.AddText("value", 1);
-  elt.AddElement(new XmlElement(QName("google:test", "nested2")), 1);
-  elt.AddElement(new XmlElement(QName("google:test", "second")));
-  elt.AddText("init-value", 1);
-  elt.AddElement(new XmlElement(QName("google:test", "nested3")), 1);
-  elt.AddText("trailing-value", 1);
-
-  // make sure it looks ok overall
-  EXPECT_EQ("<root xmlns=\"google:test\">"
-        "<first><nested>nested-value</nested>between-value<nested2/></first>"
-        "<second>init-value<nested3/>trailing-value</second></root>",
-        elt.Str());
-
-  // make sure text was concatenated
-  XmlChild * pchild =
-    elt.FirstChild()->AsElement()->FirstChild()->NextChild();
-  EXPECT_TRUE(pchild->IsText());
-  EXPECT_EQ("between-value", pchild->AsText()->Text());
-}
-
-TEST(XmlElementTest, TestAttrs) {
-  XmlElement elt(QName("", "root"));
-  elt.SetAttr(QName("", "a"), "avalue");
-  EXPECT_EQ("<root a=\"avalue\"/>", elt.Str());
-
-  elt.SetAttr(QName("", "b"), "bvalue");
-  EXPECT_EQ("<root a=\"avalue\" b=\"bvalue\"/>", elt.Str());
-
-  elt.SetAttr(QName("", "a"), "avalue2");
-  EXPECT_EQ("<root a=\"avalue2\" b=\"bvalue\"/>", elt.Str());
-
-  elt.SetAttr(QName("", "b"), "bvalue2");
-  EXPECT_EQ("<root a=\"avalue2\" b=\"bvalue2\"/>", elt.Str());
-
-  elt.SetAttr(QName("", "c"), "cvalue");
-  EXPECT_EQ("<root a=\"avalue2\" b=\"bvalue2\" c=\"cvalue\"/>", elt.Str());
-
-  XmlAttr * patt = elt.FirstAttr();
-  EXPECT_EQ(QName("", "a"), patt->Name());
-  EXPECT_EQ("avalue2", patt->Value());
-
-  patt = patt->NextAttr();
-  EXPECT_EQ(QName("", "b"), patt->Name());
-  EXPECT_EQ("bvalue2", patt->Value());
-
-  patt = patt->NextAttr();
-  EXPECT_EQ(QName("", "c"), patt->Name());
-  EXPECT_EQ("cvalue", patt->Value());
-
-  patt = patt->NextAttr();
-  EXPECT_TRUE(NULL == patt);
-
-  EXPECT_TRUE(elt.HasAttr(QName("", "a")));
-  EXPECT_TRUE(elt.HasAttr(QName("", "b")));
-  EXPECT_TRUE(elt.HasAttr(QName("", "c")));
-  EXPECT_FALSE(elt.HasAttr(QName("", "d")));
-
-  elt.SetAttr(QName("", "d"), "dvalue");
-  EXPECT_EQ("<root a=\"avalue2\" b=\"bvalue2\" c=\"cvalue\" d=\"dvalue\"/>",
-      elt.Str());
-  EXPECT_TRUE(elt.HasAttr(QName("", "d")));
-
-  elt.ClearAttr(QName("", "z"));  // not found, no effect
-  EXPECT_EQ("<root a=\"avalue2\" b=\"bvalue2\" c=\"cvalue\" d=\"dvalue\"/>",
-      elt.Str());
-
-  elt.ClearAttr(QName("", "b"));
-  EXPECT_EQ("<root a=\"avalue2\" c=\"cvalue\" d=\"dvalue\"/>", elt.Str());
-
-  elt.ClearAttr(QName("", "a"));
-  EXPECT_EQ("<root c=\"cvalue\" d=\"dvalue\"/>", elt.Str());
-
-  elt.ClearAttr(QName("", "d"));
-  EXPECT_EQ("<root c=\"cvalue\"/>", elt.Str());
-
-  elt.ClearAttr(QName("", "c"));
-  EXPECT_EQ("<root/>", elt.Str());
-}
-
-TEST(XmlElementTest, TestBodyText) {
-  XmlElement elt(QName("", "root"));
-  EXPECT_EQ("", elt.BodyText());
-
-  elt.AddText("body value text");
-
-  EXPECT_EQ("body value text", elt.BodyText());
-
-  elt.ClearChildren();
-  elt.AddText("more value ");
-  elt.AddText("text");
-
-  EXPECT_EQ("more value text", elt.BodyText());
-
-  elt.ClearChildren();
-  elt.AddText("decoy");
-  elt.AddElement(new XmlElement(QName("", "dummy")));
-  EXPECT_EQ("", elt.BodyText());
-
-  elt.SetBodyText("replacement");
-  EXPECT_EQ("replacement", elt.BodyText());
-
-  elt.SetBodyText("");
-  EXPECT_TRUE(NULL == elt.FirstChild());
-
-  elt.SetBodyText("goodbye");
-  EXPECT_EQ("goodbye", elt.FirstChild()->AsText()->Text());
-  EXPECT_EQ("goodbye", elt.BodyText());
-}
-
-TEST(XmlElementTest, TestCopyConstructor) {
-  XmlElement * element = XmlElement::ForStr(
-      "<root xmlns='test-foo'>This is a <em a='avalue' b='bvalue'>"
-      "little <b>little</b></em> test</root>");
-
-  XmlElement * pelCopy = new XmlElement(*element);
-  EXPECT_EQ("<root xmlns=\"test-foo\">This is a <em a=\"avalue\" b=\"bvalue\">"
-      "little <b>little</b></em> test</root>", pelCopy->Str());
-  delete pelCopy;
-
-  pelCopy = new XmlElement(*(element->FirstChild()->NextChild()->AsElement()));
-  EXPECT_EQ("<foo:em a=\"avalue\" b=\"bvalue\" xmlns:foo=\"test-foo\">"
-      "little <foo:b>little</foo:b></foo:em>", pelCopy->Str());
-
-  XmlAttr * patt = pelCopy->FirstAttr();
-  EXPECT_EQ(QName("", "a"), patt->Name());
-  EXPECT_EQ("avalue", patt->Value());
-
-  patt = patt->NextAttr();
-  EXPECT_EQ(QName("", "b"), patt->Name());
-  EXPECT_EQ("bvalue", patt->Value());
-
-  patt = patt->NextAttr();
-  EXPECT_TRUE(NULL == patt);
-  delete pelCopy;
-  delete element;
-}
-
-TEST(XmlElementTest, TestNameSearch) {
-  XmlElement * element = XmlElement::ForStr(
-    "<root xmlns='test-foo'>"
-      "<firstname>George</firstname>"
-      "<middlename>X.</middlename>"
-      "some text"
-      "<lastname>Harrison</lastname>"
-      "<firstname>John</firstname>"
-      "<middlename>Y.</middlename>"
-      "<lastname>Lennon</lastname>"
-    "</root>");
-  EXPECT_TRUE(NULL ==
-      element->FirstNamed(QName("", "firstname")));
-  EXPECT_EQ(element->FirstChild(),
-      element->FirstNamed(QName("test-foo", "firstname")));
-  EXPECT_EQ(element->FirstChild()->NextChild(),
-      element->FirstNamed(QName("test-foo", "middlename")));
-  EXPECT_EQ(element->FirstElement()->NextElement(),
-      element->FirstNamed(QName("test-foo", "middlename")));
-  EXPECT_EQ("Harrison",
-      element->TextNamed(QName("test-foo", "lastname")));
-  EXPECT_EQ(element->FirstElement()->NextElement()->NextElement(),
-      element->FirstNamed(QName("test-foo", "lastname")));
-  EXPECT_EQ("John", element->FirstNamed(QName("test-foo", "firstname"))->
-      NextNamed(QName("test-foo", "firstname"))->BodyText());
-  EXPECT_EQ("Y.", element->FirstNamed(QName("test-foo", "middlename"))->
-      NextNamed(QName("test-foo", "middlename"))->BodyText());
-  EXPECT_EQ("Lennon", element->FirstNamed(QName("test-foo", "lastname"))->
-      NextNamed(QName("test-foo", "lastname"))->BodyText());
-  EXPECT_TRUE(NULL == element->FirstNamed(QName("test-foo", "firstname"))->
-      NextNamed(QName("test-foo", "firstname"))->
-      NextNamed(QName("test-foo", "firstname")));
-
-  delete element;
-}
-
-class XmlElementCreatorThread : public talk_base::Thread {
- public:
-  XmlElementCreatorThread(int count, buzz::QName qname) :
-      count_(count), qname_(qname) {}
-
-  virtual void Run() {
-    std::vector<buzz::XmlElement*> elems;
-    for (int i = 0; i < count_; i++) {
-      elems.push_back(new XmlElement(qname_));
-    }
-    for (int i = 0; i < count_; i++) {
-      delete elems[i];
-    }
-  }
-
- private:
-  int count_;
-  buzz::QName qname_;
-};
-
-// If XmlElement creation and destruction isn't thread safe,
-// this test should crash.
-TEST(XmlElementTest, TestMultithread) {
-  int thread_count = 2;  // Was 100, but that's too slow.
-  int elem_count = 100;  // Was 100000, but that's too slow.
-  buzz::QName qname("foo", "bar");
-
-  std::vector<talk_base::Thread*> threads;
-  for (int i = 0; i < thread_count; i++) {
-    threads.push_back(
-        new XmlElementCreatorThread(elem_count, qname));
-    threads[i]->Start();
-  }
-
-  for (int i = 0; i < thread_count; i++) {
-    threads[i]->Stop();
-    delete threads[i];
-  }
-}
diff --git a/third_party/libjingle/source/talk/xmllite/xmlnsstack.cc b/third_party/libjingle/source/talk/xmllite/xmlnsstack.cc
deleted file mode 100644
index 26e27f8..0000000
--- a/third_party/libjingle/source/talk/xmllite/xmlnsstack.cc
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/xmllite/xmlnsstack.h"
-
-#include <sstream>
-#include <string>
-#include <vector>
-
-#include "talk/xmllite/xmlelement.h"
-#include "talk/xmllite/xmlconstants.h"
-
-namespace buzz {
-
-XmlnsStack::XmlnsStack() :
-  pxmlnsStack_(new std::vector<std::string>),
-  pxmlnsDepthStack_(new std::vector<size_t>) {
-}
-
-XmlnsStack::~XmlnsStack() {}
-
-void XmlnsStack::PushFrame() {
-  pxmlnsDepthStack_->push_back(pxmlnsStack_->size());
-}
-
-void XmlnsStack::PopFrame() {
-  size_t prev_size = pxmlnsDepthStack_->back();
-  pxmlnsDepthStack_->pop_back();
-  if (prev_size < pxmlnsStack_->size()) {
-    pxmlnsStack_->erase(pxmlnsStack_->begin() + prev_size,
-                        pxmlnsStack_->end());
-  }
-}
-
-std::pair<std::string, bool> XmlnsStack::NsForPrefix(
-    const std::string& prefix) {
-  if (prefix.length() >= 3 &&
-      (prefix[0] == 'x' || prefix[0] == 'X') &&
-      (prefix[1] == 'm' || prefix[1] == 'M') &&
-      (prefix[2] == 'l' || prefix[2] == 'L')) {
-    if (prefix == "xml")
-      return std::make_pair(NS_XML, true);
-    if (prefix == "xmlns")
-      return std::make_pair(NS_XMLNS, true);
-    // Other names with xml prefix are illegal.
-    return std::make_pair(STR_EMPTY, false);
-  }
-
-  std::vector<std::string>::iterator pos;
-  for (pos = pxmlnsStack_->end(); pos > pxmlnsStack_->begin(); ) {
-    pos -= 2;
-    if (*pos == prefix)
-      return std::make_pair(*(pos + 1), true);
-  }
-
-  if (prefix == STR_EMPTY)
-    return std::make_pair(STR_EMPTY, true);  // default namespace
-
-  return std::make_pair(STR_EMPTY, false);  // none found
-}
-
-bool XmlnsStack::PrefixMatchesNs(const std::string& prefix,
-                                 const std::string& ns) {
-  const std::pair<std::string, bool> match = NsForPrefix(prefix);
-  return match.second && (match.first == ns);
-}
-
-std::pair<std::string, bool> XmlnsStack::PrefixForNs(const std::string& ns,
-                                                     bool isattr) {
-  if (ns == NS_XML)
-    return std::make_pair(std::string("xml"), true);
-  if (ns == NS_XMLNS)
-    return std::make_pair(std::string("xmlns"), true);
-  if (isattr ? ns == STR_EMPTY : PrefixMatchesNs(STR_EMPTY, ns))
-    return std::make_pair(STR_EMPTY, true);
-
-  std::vector<std::string>::iterator pos;
-  for (pos = pxmlnsStack_->end(); pos > pxmlnsStack_->begin(); ) {
-    pos -= 2;
-    if (*(pos + 1) == ns &&
-        (!isattr || !pos->empty()) && PrefixMatchesNs(*pos, ns))
-      return std::make_pair(*pos, true);
-  }
-
-  return std::make_pair(STR_EMPTY, false); // none found
-}
-
-std::string XmlnsStack::FormatQName(const QName& name, bool isAttr) {
-  std::string prefix(PrefixForNs(name.Namespace(), isAttr).first);
-  if (prefix == STR_EMPTY)
-    return name.LocalPart();
-  else
-    return prefix + ':' + name.LocalPart();
-}
-
-void XmlnsStack::AddXmlns(const std::string & prefix, const std::string & ns) {
-  pxmlnsStack_->push_back(prefix);
-  pxmlnsStack_->push_back(ns);
-}
-
-void XmlnsStack::RemoveXmlns() {
-  pxmlnsStack_->pop_back();
-  pxmlnsStack_->pop_back();
-}
-
-static bool IsAsciiLetter(char ch) {
-  return ((ch >= 'a' && ch <= 'z') ||
-          (ch >= 'A' && ch <= 'Z'));
-}
-
-static std::string AsciiLower(const std::string & s) {
-  std::string result(s);
-  size_t i;
-  for (i = 0; i < result.length(); i++) {
-    if (result[i] >= 'A' && result[i] <= 'Z')
-      result[i] += 'a' - 'A';
-  }
-  return result;
-}
-
-static std::string SuggestPrefix(const std::string & ns) {
-  size_t len = ns.length();
-  size_t i = ns.find_last_of('.');
-  if (i != std::string::npos && len - i <= 4 + 1)
-    len = i; // chop off ".html" or ".xsd" or ".?{0,4}"
-  size_t last = len;
-  while (last > 0) {
-    last -= 1;
-    if (IsAsciiLetter(ns[last])) {
-      size_t first = last;
-      last += 1;
-      while (first > 0) {
-        if (!IsAsciiLetter(ns[first - 1]))
-          break;
-        first -= 1;
-      }
-      if (last - first > 4)
-        last = first + 3;
-      std::string candidate(AsciiLower(ns.substr(first, last - first)));
-      if (candidate.find("xml") != 0)
-        return candidate;
-      break;
-    }
-  }
-  return "ns";
-}
-
-std::pair<std::string, bool> XmlnsStack::AddNewPrefix(const std::string& ns,
-                                                      bool isAttr) {
-  if (PrefixForNs(ns, isAttr).second)
-    return std::make_pair(STR_EMPTY, false);
-
-  std::string base(SuggestPrefix(ns));
-  std::string result(base);
-  int i = 2;
-  while (NsForPrefix(result).second) {
-    std::stringstream ss;
-    ss << base;
-    ss << (i++);
-    ss >> result;
-  }
-  AddXmlns(result, ns);
-  return std::make_pair(result, true);
-}
-
-void XmlnsStack::Reset() {
-  pxmlnsStack_->clear();
-  pxmlnsDepthStack_->clear();
-}
-
-}
diff --git a/third_party/libjingle/source/talk/xmllite/xmlnsstack.h b/third_party/libjingle/source/talk/xmllite/xmlnsstack.h
deleted file mode 100644
index f6b4b81..0000000
--- a/third_party/libjingle/source/talk/xmllite/xmlnsstack.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_XMLLITE_XMLNSSTACK_H_
-#define TALK_XMLLITE_XMLNSSTACK_H_
-
-#include <string>
-#include <vector>
-#include "talk/base/scoped_ptr.h"
-#include "talk/xmllite/qname.h"
-
-namespace buzz {
-
-class XmlnsStack {
-public:
-  XmlnsStack();
-  ~XmlnsStack();
-
-  void AddXmlns(const std::string& prefix, const std::string& ns);
-  void RemoveXmlns();
-  void PushFrame();
-  void PopFrame();
-  void Reset();
-
-  std::pair<std::string, bool> NsForPrefix(const std::string& prefix);
-  bool PrefixMatchesNs(const std::string & prefix, const std::string & ns);
-  std::pair<std::string, bool> PrefixForNs(const std::string& ns, bool isAttr);
-  std::pair<std::string, bool> AddNewPrefix(const std::string& ns, bool isAttr);
-  std::string FormatQName(const QName & name, bool isAttr);
-
-private:
-
-  talk_base::scoped_ptr<std::vector<std::string> > pxmlnsStack_;
-  talk_base::scoped_ptr<std::vector<size_t> > pxmlnsDepthStack_;
-};
-}
-
-#endif  // TALK_XMLLITE_XMLNSSTACK_H_
diff --git a/third_party/libjingle/source/talk/xmllite/xmlnsstack_unittest.cc b/third_party/libjingle/source/talk/xmllite/xmlnsstack_unittest.cc
deleted file mode 100644
index 21e157b..0000000
--- a/third_party/libjingle/source/talk/xmllite/xmlnsstack_unittest.cc
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * libjingle
- * Copyright 2004, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/xmllite/xmlnsstack.h"
-
-#include <string>
-#include <sstream>
-#include <iostream>
-
-#include "talk/base/common.h"
-#include "talk/base/gunit.h"
-#include "talk/xmllite/xmlconstants.h"
-
-using buzz::NS_XML;
-using buzz::NS_XMLNS;
-using buzz::QName;
-using buzz::XmlnsStack;
-
-TEST(XmlnsStackTest, TestBuiltin) {
-  XmlnsStack stack;
-
-  EXPECT_EQ(std::string(NS_XML), stack.NsForPrefix("xml").first);
-  EXPECT_EQ(std::string(NS_XMLNS), stack.NsForPrefix("xmlns").first);
-  EXPECT_EQ("", stack.NsForPrefix("").first);
-
-  EXPECT_EQ("xml", stack.PrefixForNs(NS_XML, false).first);
-  EXPECT_EQ("xmlns", stack.PrefixForNs(NS_XMLNS, false).first);
-  EXPECT_EQ("", stack.PrefixForNs("", false).first);
-  EXPECT_EQ("", stack.PrefixForNs("", true).first);
-}
-
-TEST(XmlnsStackTest, TestNsForPrefix) {
- XmlnsStack stack;
-  stack.AddXmlns("pre1", "ns1");
-  stack.AddXmlns("pre2", "ns2");
-  stack.AddXmlns("pre1", "ns3");
-  stack.AddXmlns("", "ns4");
-
-  EXPECT_EQ("ns3", stack.NsForPrefix("pre1").first);
-  EXPECT_TRUE(stack.NsForPrefix("pre1").second);
-  EXPECT_EQ("ns2", stack.NsForPrefix("pre2").first);
-  EXPECT_EQ("ns4", stack.NsForPrefix("").first);
-  EXPECT_EQ("", stack.NsForPrefix("pre3").first);
-  EXPECT_EQ(false, stack.NsForPrefix("pre3").second);
-}
-
-TEST(XmlnsStackTest, TestPrefixForNs) {
-  XmlnsStack stack;
-  stack.AddXmlns("pre1", "ns1");
-  stack.AddXmlns("pre2", "ns2");
-  stack.AddXmlns("pre1", "ns3");
-  stack.AddXmlns("pre3", "ns2");
-  stack.AddXmlns("pre4", "ns4");
-  stack.AddXmlns("", "ns4");
-
-  EXPECT_EQ("", stack.PrefixForNs("ns1", false).first);
-  EXPECT_FALSE(stack.PrefixForNs("ns1", false).second);
-  EXPECT_EQ("", stack.PrefixForNs("ns1", true).first);
-  EXPECT_FALSE(stack.PrefixForNs("ns1", true).second);
-  EXPECT_EQ("pre3", stack.PrefixForNs("ns2", false).first);
-  EXPECT_TRUE(stack.PrefixForNs("ns2", false).second);
-  EXPECT_EQ("pre3", stack.PrefixForNs("ns2", true).first);
-  EXPECT_TRUE(stack.PrefixForNs("ns2", true).second);
-  EXPECT_EQ("pre1", stack.PrefixForNs("ns3", false).first);
-  EXPECT_EQ("pre1", stack.PrefixForNs("ns3", true).first);
-  EXPECT_EQ("", stack.PrefixForNs("ns4", false).first);
-  EXPECT_TRUE(stack.PrefixForNs("ns4", false).second);
-  EXPECT_EQ("pre4", stack.PrefixForNs("ns4", true).first);
-  EXPECT_EQ("", stack.PrefixForNs("ns5", false).first);
-  EXPECT_FALSE(stack.PrefixForNs("ns5", false).second);
-  EXPECT_EQ("", stack.PrefixForNs("ns5", true).first);
-  EXPECT_EQ("", stack.PrefixForNs("", false).first);
-  EXPECT_EQ("", stack.PrefixForNs("", true).first);
-
-  stack.AddXmlns("", "ns6");
-  EXPECT_EQ("", stack.PrefixForNs("ns6", false).first);
-  EXPECT_TRUE(stack.PrefixForNs("ns6", false).second);
-  EXPECT_EQ("", stack.PrefixForNs("ns6", true).first);
-  EXPECT_FALSE(stack.PrefixForNs("ns6", true).second);
-}
-
-TEST(XmlnsStackTest, TestFrames) {
-  XmlnsStack stack;
-  stack.PushFrame();
-  stack.AddXmlns("pre1", "ns1");
-  stack.AddXmlns("pre2", "ns2");
-
-  stack.PushFrame();
-  stack.AddXmlns("pre1", "ns3");
-  stack.AddXmlns("pre3", "ns2");
-  stack.AddXmlns("pre4", "ns4");
-
-  stack.PushFrame();
-  stack.PushFrame();
-  stack.AddXmlns("", "ns4");
-
-  // basic test
-  EXPECT_EQ("ns3", stack.NsForPrefix("pre1").first);
-  EXPECT_EQ("ns2", stack.NsForPrefix("pre2").first);
-  EXPECT_EQ("ns2", stack.NsForPrefix("pre3").first);
-  EXPECT_EQ("ns4", stack.NsForPrefix("pre4").first);
-  EXPECT_EQ("", stack.NsForPrefix("pre5").first);
-  EXPECT_FALSE(stack.NsForPrefix("pre5").second);
-  EXPECT_EQ("ns4", stack.NsForPrefix("").first);
-  EXPECT_TRUE(stack.NsForPrefix("").second);
-
-  // pop the default xmlns definition
-  stack.PopFrame();
-  EXPECT_EQ("ns3", stack.NsForPrefix("pre1").first);
-  EXPECT_EQ("ns2", stack.NsForPrefix("pre2").first);
-  EXPECT_EQ("ns2", stack.NsForPrefix("pre3").first);
-  EXPECT_EQ("ns4", stack.NsForPrefix("pre4").first);
-  EXPECT_EQ("", stack.NsForPrefix("pre5").first);
-  EXPECT_FALSE(stack.NsForPrefix("pre5").second);
-  EXPECT_EQ("", stack.NsForPrefix("").first);
-  EXPECT_TRUE(stack.NsForPrefix("").second);
-
-  // pop empty frame (nop)
-  stack.PopFrame();
-  EXPECT_EQ("ns3", stack.NsForPrefix("pre1").first);
-  EXPECT_EQ("ns2", stack.NsForPrefix("pre2").first);
-  EXPECT_EQ("ns2", stack.NsForPrefix("pre3").first);
-  EXPECT_EQ("ns4", stack.NsForPrefix("pre4").first);
-  EXPECT_EQ("", stack.NsForPrefix("pre5").first);
-  EXPECT_FALSE(stack.NsForPrefix("pre5").second);
-  EXPECT_EQ("", stack.NsForPrefix("").first);
-  EXPECT_TRUE(stack.NsForPrefix("").second);
-
-  // pop frame with three defs
-  stack.PopFrame();
-  EXPECT_EQ("ns1", stack.NsForPrefix("pre1").first);
-  EXPECT_EQ("ns2", stack.NsForPrefix("pre2").first);
-  EXPECT_EQ("", stack.NsForPrefix("pre3").first);
-  EXPECT_FALSE(stack.NsForPrefix("pre3").second);
-  EXPECT_EQ("", stack.NsForPrefix("pre4").first);
-  EXPECT_FALSE(stack.NsForPrefix("pre4").second);
-  EXPECT_EQ("", stack.NsForPrefix("pre5").first);
-  EXPECT_FALSE(stack.NsForPrefix("pre5").second);
-  EXPECT_EQ("", stack.NsForPrefix("").first);
-  EXPECT_TRUE(stack.NsForPrefix("").second);
-
-  // pop frame with last two defs
-  stack.PopFrame();
-  EXPECT_FALSE(stack.NsForPrefix("pre1").second);
-  EXPECT_FALSE(stack.NsForPrefix("pre2").second);
-  EXPECT_FALSE(stack.NsForPrefix("pre3").second);
-  EXPECT_FALSE(stack.NsForPrefix("pre4").second);
-  EXPECT_FALSE(stack.NsForPrefix("pre5").second);
-  EXPECT_TRUE(stack.NsForPrefix("").second);
-  EXPECT_EQ("", stack.NsForPrefix("pre1").first);
-  EXPECT_EQ("", stack.NsForPrefix("pre2").first);
-  EXPECT_EQ("", stack.NsForPrefix("pre3").first);
-  EXPECT_EQ("", stack.NsForPrefix("pre4").first);
-  EXPECT_EQ("", stack.NsForPrefix("pre5").first);
-  EXPECT_EQ("", stack.NsForPrefix("").first);
-}
-
-TEST(XmlnsStackTest, TestAddNewPrefix) {
-  XmlnsStack stack;
-
-  // builtin namespaces cannot be added
-  EXPECT_FALSE(stack.AddNewPrefix("", true).second);
-  EXPECT_FALSE(stack.AddNewPrefix("", false).second);
-  EXPECT_FALSE(stack.AddNewPrefix(NS_XML, true).second);
-  EXPECT_FALSE(stack.AddNewPrefix(NS_XML, false).second);
-  EXPECT_FALSE(stack.AddNewPrefix(NS_XMLNS, true).second);
-  EXPECT_FALSE(stack.AddNewPrefix(NS_XMLNS, false).second);
-
-  // namespaces already added cannot be added again.
-  EXPECT_EQ("foo", stack.AddNewPrefix("http://a.b.com/foo.htm", true).first);
-  EXPECT_EQ("bare", stack.AddNewPrefix("http://a.b.com/bare", false).first);
-  EXPECT_EQ("z", stack.AddNewPrefix("z", false).first);
-  EXPECT_FALSE(stack.AddNewPrefix("http://a.b.com/foo.htm", true).second);
-  EXPECT_FALSE(stack.AddNewPrefix("http://a.b.com/bare", true).second);
-  EXPECT_FALSE(stack.AddNewPrefix("z", true).second);
-  EXPECT_FALSE(stack.AddNewPrefix("http://a.b.com/foo.htm", false).second);
-  EXPECT_FALSE(stack.AddNewPrefix("http://a.b.com/bare", false).second);
-  EXPECT_FALSE(stack.AddNewPrefix("z", false).second);
-
-  // default namespace usable by non-attributes only
-  stack.AddXmlns("", "http://my/default");
-  EXPECT_FALSE(stack.AddNewPrefix("http://my/default", false).second);
-  EXPECT_EQ("def", stack.AddNewPrefix("http://my/default", true).first);
-
-  // namespace cannot start with 'xml'
-  EXPECT_EQ("ns", stack.AddNewPrefix("http://a.b.com/xmltest", true).first);
-  EXPECT_EQ("ns2", stack.AddNewPrefix("xmlagain", false).first);
-
-  // verify added namespaces are still defined
-  EXPECT_EQ("http://a.b.com/foo.htm", stack.NsForPrefix("foo").first);
-  EXPECT_TRUE(stack.NsForPrefix("foo").second);
-  EXPECT_EQ("http://a.b.com/bare", stack.NsForPrefix("bare").first);
-  EXPECT_TRUE(stack.NsForPrefix("bare").second);
-  EXPECT_EQ("z", stack.NsForPrefix("z").first);
-  EXPECT_TRUE(stack.NsForPrefix("z").second);
-  EXPECT_EQ("http://my/default", stack.NsForPrefix("").first);
-  EXPECT_TRUE(stack.NsForPrefix("").second);
-  EXPECT_EQ("http://my/default", stack.NsForPrefix("def").first);
-  EXPECT_TRUE(stack.NsForPrefix("def").second);
-  EXPECT_EQ("http://a.b.com/xmltest", stack.NsForPrefix("ns").first);
-  EXPECT_TRUE(stack.NsForPrefix("ns").second);
-  EXPECT_EQ("xmlagain", stack.NsForPrefix("ns2").first);
-  EXPECT_TRUE(stack.NsForPrefix("ns2").second);
-}
-
-TEST(XmlnsStackTest, TestFormatQName) {
-  XmlnsStack stack;
-  stack.AddXmlns("pre1", "ns1");
-  stack.AddXmlns("pre2", "ns2");
-  stack.AddXmlns("pre1", "ns3");
-  stack.AddXmlns("", "ns4");
-
-  EXPECT_EQ("zip",
-      stack.FormatQName(QName("ns1", "zip"), false));  // no match
-  EXPECT_EQ("pre2:abracadabra",
-      stack.FormatQName(QName("ns2", "abracadabra"), false));
-  EXPECT_EQ("pre1:a",
-      stack.FormatQName(QName("ns3", "a"), false));
-  EXPECT_EQ("simple",
-      stack.FormatQName(QName("ns4", "simple"), false));
-  EXPECT_EQ("root",
-      stack.FormatQName(QName("", "root"), false));  // no match
-
-  EXPECT_EQ("zip",
-      stack.FormatQName(QName("ns1", "zip"), true));  // no match
-  EXPECT_EQ("pre2:abracadabra",
-      stack.FormatQName(QName("ns2", "abracadabra"), true));
-  EXPECT_EQ("pre1:a",
-      stack.FormatQName(QName("ns3", "a"), true));
-  EXPECT_EQ("simple",
-      stack.FormatQName(QName("ns4", "simple"), true));  // no match
-  EXPECT_EQ("root",
-      stack.FormatQName(QName("", "root"), true));
-}
diff --git a/third_party/libjingle/source/talk/xmllite/xmlparser.cc b/third_party/libjingle/source/talk/xmllite/xmlparser.cc
deleted file mode 100644
index 4a9d62e..0000000
--- a/third_party/libjingle/source/talk/xmllite/xmlparser.cc
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/xmllite/xmlparser.h"
-
-#include <string>
-#include <vector>
-
-#include "talk/base/common.h"
-#include "talk/xmllite/xmlconstants.h"
-#include "talk/xmllite/xmlelement.h"
-#include "talk/xmllite/xmlnsstack.h"
-#include "talk/xmllite/xmlnsstack.h"
-
-namespace buzz {
-
-
-static void
-StartElementCallback(void * userData, const char *name, const char **atts) {
-  (static_cast<XmlParser *>(userData))->ExpatStartElement(name, atts);
-}
-
-static void
-EndElementCallback(void * userData, const char *name) {
-  (static_cast<XmlParser *>(userData))->ExpatEndElement(name);
-}
-
-static void
-CharacterDataCallback(void * userData, const char *text, int len) {
-  (static_cast<XmlParser *>(userData))->ExpatCharacterData(text, len);
-}
-
-static void
-XmlDeclCallback(void * userData, const char * ver, const char * enc, int st) {
-  (static_cast<XmlParser *>(userData))->ExpatXmlDecl(ver, enc, st);
-}
-
-XmlParser::XmlParser(XmlParseHandler *pxph) :
-    context_(this), pxph_(pxph), sentError_(false) {
-  expat_ = XML_ParserCreate(NULL);
-  XML_SetUserData(expat_, this);
-  XML_SetElementHandler(expat_, StartElementCallback, EndElementCallback);
-  XML_SetCharacterDataHandler(expat_, CharacterDataCallback);
-  XML_SetXmlDeclHandler(expat_, XmlDeclCallback);
-}
-
-void
-XmlParser::Reset() {
-  if (!XML_ParserReset(expat_, NULL)) {
-    XML_ParserFree(expat_);
-    expat_ = XML_ParserCreate(NULL);
-  }
-  XML_SetUserData(expat_, this);
-  XML_SetElementHandler(expat_, StartElementCallback, EndElementCallback);
-  XML_SetCharacterDataHandler(expat_, CharacterDataCallback);
-  XML_SetXmlDeclHandler(expat_, XmlDeclCallback);
-  context_.Reset();
-  sentError_ = false;
-}
-
-static bool
-XmlParser_StartsWithXmlns(const char *name) {
-  return name[0] == 'x' &&
-         name[1] == 'm' &&
-         name[2] == 'l' &&
-         name[3] == 'n' &&
-         name[4] == 's';
-}
-
-void
-XmlParser::ExpatStartElement(const char *name, const char **atts) {
-  if (context_.RaisedError() != XML_ERROR_NONE)
-    return;
-  const char **att;
-  context_.StartElement();
-  for (att = atts; *att; att += 2) {
-    if (XmlParser_StartsWithXmlns(*att)) {
-      if ((*att)[5] == '\0') {
-        context_.StartNamespace("", *(att + 1));
-      }
-      else if ((*att)[5] == ':') {
-        if (**(att + 1) == '\0') {
-          // In XML 1.0 empty namespace illegal with prefix (not in 1.1)
-          context_.RaiseError(XML_ERROR_SYNTAX);
-          return;
-        }
-        context_.StartNamespace((*att) + 6, *(att + 1));
-      }
-    }
-  }
-  context_.SetPosition(XML_GetCurrentLineNumber(expat_),
-                       XML_GetCurrentColumnNumber(expat_),
-                       XML_GetCurrentByteIndex(expat_));
-  pxph_->StartElement(&context_, name, atts);
-}
-
-void
-XmlParser::ExpatEndElement(const char *name) {
-  if (context_.RaisedError() != XML_ERROR_NONE)
-    return;
-  context_.EndElement();
-  context_.SetPosition(XML_GetCurrentLineNumber(expat_),
-                       XML_GetCurrentColumnNumber(expat_),
-                       XML_GetCurrentByteIndex(expat_));
-  pxph_->EndElement(&context_, name);
-}
-
-void
-XmlParser::ExpatCharacterData(const char *text, int len) {
-  if (context_.RaisedError() != XML_ERROR_NONE)
-    return;
-  context_.SetPosition(XML_GetCurrentLineNumber(expat_),
-                       XML_GetCurrentColumnNumber(expat_),
-                       XML_GetCurrentByteIndex(expat_));
-  pxph_->CharacterData(&context_, text, len);
-}
-
-void
-XmlParser::ExpatXmlDecl(const char * ver, const char * enc, int standalone) {
-  if (context_.RaisedError() != XML_ERROR_NONE)
-    return;
-
-  if (ver && std::string("1.0") != ver) {
-    context_.RaiseError(XML_ERROR_SYNTAX);
-    return;
-  }
-
-  if (standalone == 0) {
-    context_.RaiseError(XML_ERROR_SYNTAX);
-    return;
-  }
-
-  if (enc && !((enc[0] == 'U' || enc[0] == 'u') &&
-               (enc[1] == 'T' || enc[1] == 't') &&
-               (enc[2] == 'F' || enc[2] == 'f') &&
-                enc[3] == '-' && enc[4] =='8')) {
-    context_.RaiseError(XML_ERROR_INCORRECT_ENCODING);
-    return;
-  }
-
-}
-
-bool
-XmlParser::Parse(const char *data, size_t len, bool isFinal) {
-  if (sentError_)
-    return false;
-
-  if (XML_Parse(expat_, data, static_cast<int>(len), isFinal) !=
-      XML_STATUS_OK) {
-    context_.SetPosition(XML_GetCurrentLineNumber(expat_),
-                         XML_GetCurrentColumnNumber(expat_),
-                         XML_GetCurrentByteIndex(expat_));
-    context_.RaiseError(XML_GetErrorCode(expat_));
-  }
-
-  if (context_.RaisedError() != XML_ERROR_NONE) {
-    sentError_ = true;
-    pxph_->Error(&context_, context_.RaisedError());
-    return false;
-  }
-
-  return true;
-}
-
-XmlParser::~XmlParser() {
-  XML_ParserFree(expat_);
-}
-
-void
-XmlParser::ParseXml(XmlParseHandler *pxph, std::string text) {
-  XmlParser parser(pxph);
-  parser.Parse(text.c_str(), text.length(), true);
-}
-
-XmlParser::ParseContext::ParseContext(XmlParser *parser) :
-    parser_(parser),
-    xmlnsstack_(),
-    raised_(XML_ERROR_NONE),
-    line_number_(0),
-    column_number_(0),
-    byte_index_(0) {
-}
-
-void
-XmlParser::ParseContext::StartNamespace(const char *prefix, const char *ns) {
-  xmlnsstack_.AddXmlns(*prefix ? prefix : STR_EMPTY, ns);
-}
-
-void
-XmlParser::ParseContext::StartElement() {
-  xmlnsstack_.PushFrame();
-}
-
-void
-XmlParser::ParseContext::EndElement() {
-  xmlnsstack_.PopFrame();
-}
-
-QName
-XmlParser::ParseContext::ResolveQName(const char* qname, bool isAttr) {
-  const char *c;
-  for (c = qname; *c; ++c) {
-    if (*c == ':') {
-      const std::pair<std::string, bool> result =
-          xmlnsstack_.NsForPrefix(std::string(qname, c - qname));
-      if (!result.second)
-        return QN_EMPTY;
-      return QName(result.first, c + 1);
-    }
-  }
-  if (isAttr)
-    return QName(STR_EMPTY, qname);
-
-  std::pair<std::string, bool> result = xmlnsstack_.NsForPrefix(STR_EMPTY);
-  if (!result.second)
-    return QN_EMPTY;
-
-  return QName(result.first, qname);
-}
-
-void
-XmlParser::ParseContext::Reset() {
-  xmlnsstack_.Reset();
-  raised_ = XML_ERROR_NONE;
-}
-
-void
-XmlParser::ParseContext::SetPosition(int line, int column,
-                                          long byte_index) {
-  line_number_ = line;
-  column_number_ = column;
-  byte_index_ = byte_index;
-}
-
-void
-XmlParser::ParseContext::GetPosition(unsigned long * line,
-                                     unsigned long * column,
-                                     unsigned long * byte_index) {
-  if (line != NULL) {
-    *line = static_cast<unsigned long>(line_number_);
-  }
-
-  if (column != NULL) {
-    *column = static_cast<unsigned long>(column_number_);
-  }
-
-  if (byte_index != NULL) {
-    *byte_index = static_cast<unsigned long>(byte_index_);
-  }
-}
-
-XmlParser::ParseContext::~ParseContext() {
-}
-
-}
diff --git a/third_party/libjingle/source/talk/xmllite/xmlparser.h b/third_party/libjingle/source/talk/xmllite/xmlparser.h
deleted file mode 100644
index ce55c23..0000000
--- a/third_party/libjingle/source/talk/xmllite/xmlparser.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_XMLLITE_XMLPARSER_H_
-#define TALK_XMLLITE_XMLPARSER_H_
-
-#include <string>
-
-#include "talk/xmllite/xmlnsstack.h"
-#ifdef EXPAT_RELATIVE_PATH
-#include "expat.h"
-#else
-#include "third_party/expat/v2_0_1/Source/lib/expat.h"
-#endif  // EXPAT_RELATIVE_PATH
-
-struct XML_ParserStruct;
-typedef struct XML_ParserStruct* XML_Parser;
-
-namespace buzz {
-
-class XmlParseHandler;
-class XmlParseContext;
-class XmlParser;
-
-class XmlParseContext {
-public:
-  virtual ~XmlParseContext() {}
-  virtual QName ResolveQName(const char * qname, bool isAttr) = 0;
-  virtual void RaiseError(XML_Error err) = 0;
-  virtual void GetPosition(unsigned long * line, unsigned long * column,
-                           unsigned long * byte_index) = 0;
-};
-
-class XmlParseHandler {
-public:
-  virtual ~XmlParseHandler() {}
-  virtual void StartElement(XmlParseContext * pctx,
-               const char * name, const char ** atts) = 0;
-  virtual void EndElement(XmlParseContext * pctx,
-               const char * name) = 0;
-  virtual void CharacterData(XmlParseContext * pctx,
-               const char * text, int len) = 0;
-  virtual void Error(XmlParseContext * pctx,
-               XML_Error errorCode) = 0;
-};
-
-class XmlParser {
-public:
-  static void ParseXml(XmlParseHandler * pxph, std::string text);
-
-  explicit XmlParser(XmlParseHandler * pxph);
-  bool Parse(const char * data, size_t len, bool isFinal);
-  void Reset();
-  virtual ~XmlParser();
-
-  // expat callbacks
-  void ExpatStartElement(const char * name, const char ** atts);
-  void ExpatEndElement(const char * name);
-  void ExpatCharacterData(const char * text, int len);
-  void ExpatXmlDecl(const char * ver, const char * enc, int standalone);
-
-private:
-
-  class ParseContext : public XmlParseContext {
-  public:
-    ParseContext(XmlParser * parser);
-    virtual ~ParseContext();
-    virtual QName ResolveQName(const char * qname, bool isAttr);
-    virtual void RaiseError(XML_Error err) { if (!raised_) raised_ = err; }
-    virtual void GetPosition(unsigned long * line, unsigned long * column,
-                             unsigned long * byte_index);
-    XML_Error RaisedError() { return raised_; }
-    void Reset();
-
-    void StartElement();
-    void EndElement();
-    void StartNamespace(const char * prefix, const char * ns);
-    void SetPosition(int line, int column, long byte_index);
-
-  private:
-    const XmlParser * parser_;
-    XmlnsStack xmlnsstack_;
-    XML_Error raised_;
-    XML_Size line_number_;
-    XML_Size column_number_;
-    XML_Index byte_index_;
-  };
-
-  ParseContext context_;
-  XML_Parser expat_;
-  XmlParseHandler * pxph_;
-  bool sentError_;
-};
-
-}
-
-#endif  // TALK_XMLLITE_XMLPARSER_H_
diff --git a/third_party/libjingle/source/talk/xmllite/xmlparser_unittest.cc b/third_party/libjingle/source/talk/xmllite/xmlparser_unittest.cc
deleted file mode 100644
index 24947fb..0000000
--- a/third_party/libjingle/source/talk/xmllite/xmlparser_unittest.cc
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * libjingle
- * Copyright 2004, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string>
-#include <sstream>
-#include <iostream>
-#include "talk/base/common.h"
-#include "talk/base/gunit.h"
-#include "talk/xmllite/qname.h"
-#include "talk/xmllite/xmlparser.h"
-
-using buzz::QName;
-using buzz::XmlParser;
-using buzz::XmlParseContext;
-using buzz::XmlParseHandler;
-
-class XmlParserTestHandler : public XmlParseHandler {
- public:
-  virtual void StartElement(XmlParseContext * pctx,
-                            const char * name, const char ** atts) {
-    ss_ << "START (" << pctx->ResolveQName(name, false).Merged();
-    while (*atts) {
-      ss_ << ", " << pctx->ResolveQName(*atts, true).Merged()
-          << "='" << *(atts+1) << "'";
-      atts += 2;
-    }
-    ss_ << ") ";
-  }
-  virtual void EndElement(XmlParseContext * pctx, const char * name) {
-    UNUSED(pctx);
-    UNUSED(name);
-    ss_ << "END ";
-  }
-  virtual void CharacterData(XmlParseContext * pctx,
-                             const char * text, int len) {
-    UNUSED(pctx);
-    ss_ << "TEXT (" << std::string(text, len) << ") ";
-  }
-  virtual void Error(XmlParseContext * pctx, XML_Error code) {
-    UNUSED(pctx);
-    ss_ << "ERROR (" << static_cast<int>(code) << ") ";
-  }
-  virtual ~XmlParserTestHandler() {
-  }
-
-  std::string Str() {
-    return ss_.str();
-  }
-
-  std::string StrClear() {
-    std::string result = ss_.str();
-    ss_.str("");
-    return result;
-  }
-
- private:
-  std::stringstream ss_;
-};
-
-
-TEST(XmlParserTest, TestTrivial) {
-  XmlParserTestHandler handler;
-  XmlParser::ParseXml(&handler, "<testing/>");
-  EXPECT_EQ("START (testing) END ", handler.Str());
-}
-
-TEST(XmlParserTest, TestAttributes) {
-  {
-    XmlParserTestHandler handler;
-    XmlParser::ParseXml(&handler, "<testing a='b'/>");
-    EXPECT_EQ("START (testing, a='b') END ", handler.Str());
-  }
-  {
-    XmlParserTestHandler handler;
-    XmlParser::ParseXml(&handler, "<testing e='' long='some text'/>");
-    EXPECT_EQ("START (testing, e='', long='some text') END ", handler.Str());
-  }
-}
-
-TEST(XmlParserTest, TestNesting) {
-  {
-    XmlParserTestHandler handler;
-    XmlParser::ParseXml(&handler,
-        "<top><first/><second><third></third></second></top>");
-    EXPECT_EQ("START (top) START (first) END START (second) START (third) "
-        "END END END ", handler.Str());
-  }
-  {
-    XmlParserTestHandler handler;
-    XmlParser::ParseXml(&handler, "<top><fifth><deeper><and><deeper/></and>"
-        "<sibling><leaf/></sibling></deeper></fifth><first/><second>"
-        "<third></third></second></top>");
-    EXPECT_EQ("START (top) START (fifth) START (deeper) START (and) START "
-            "(deeper) END END START (sibling) START (leaf) END END END "
-            "END START (first) END START (second) START (third) END END END ",
-            handler.Str());
-  }
-}
-
-TEST(XmlParserTest, TestXmlDecl) {
-  {
-    XmlParserTestHandler handler;
-    XmlParser::ParseXml(&handler, "<?xml version=\"1.0\"?><testing/>");
-    EXPECT_EQ("START (testing) END ", handler.Str());
-  }
-  {
-    XmlParserTestHandler handler;
-    XmlParser::ParseXml(&handler,
-        "<?xml version=\"1.0\" encoding=\"utf-8\"?><testing/>");
-    EXPECT_EQ("START (testing) END ", handler.Str());
-  }
-  {
-    XmlParserTestHandler handler;
-    XmlParser::ParseXml(&handler,
-        "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
-        "<testing/>");
-    EXPECT_EQ("START (testing) END ", handler.Str());
-  }
-}
-
-TEST(XmlParserTest, TestNamespace) {
-  {
-    XmlParserTestHandler handler;
-    XmlParser::ParseXml(&handler, "<top xmlns='my-namespace' a='b'/>");
-    EXPECT_EQ("START (my-namespace:top, xmlns='my-namespace', a='b') END ",
-        handler.Str());
-  }
-  {
-    XmlParserTestHandler handler;
-    XmlParser::ParseXml(&handler, "<foo:top xmlns:foo='my-namespace' "
-          "a='b' foo:c='d'/>");
-    EXPECT_EQ("START (my-namespace:top, "
-        "http://www.w3.org/2000/xmlns/:foo='my-namespace', "
-        "a='b', my-namespace:c='d') END ", handler.Str());
-  }
-  {
-    XmlParserTestHandler handler;
-    XmlParser::ParseXml(&handler, "<top><nested xmlns='my-namespace'><leaf/>"
-        "</nested><sibling/></top>");
-    EXPECT_EQ("START (top) START (my-namespace:nested, xmlns='my-namespace') "
-        "START (my-namespace:leaf) END END START (sibling) END END ",
-        handler.Str());
-  }
-}
-
-TEST(XmlParserTest, TestIncremental) {
-  XmlParserTestHandler handler;
-  XmlParser parser(&handler);
-  std::string fragment;
-
-  fragment = "<stream:stream";
-  parser.Parse(fragment.c_str(), fragment.length(), false);
-  EXPECT_EQ("", handler.StrClear());
-
-  fragment = " id=\"abcdefg\" xmlns=\"";
-  parser.Parse(fragment.c_str(), fragment.length(), false);
-  EXPECT_EQ("", handler.StrClear());
-
-  fragment = "j:c\" xmlns:stream='hm";
-  parser.Parse(fragment.c_str(), fragment.length(), false);
-  EXPECT_EQ("", handler.StrClear());
-
-  fragment = "ph'><test";
-  parser.Parse(fragment.c_str(), fragment.length(), false);
-  EXPECT_EQ("START (hmph:stream, id='abcdefg', xmlns='j:c', "
-      "http://www.w3.org/2000/xmlns/:stream='hmph') ", handler.StrClear());
-
-  fragment = "ing/><again/>abracad";
-  parser.Parse(fragment.c_str(), fragment.length(), false);
-  EXPECT_EQ("START (j:c:testing) END START (j:c:again) END TEXT (abracad) ",
-      handler.StrClear());
-
-  fragment = "abra</stream:";
-  parser.Parse(fragment.c_str(), fragment.length(), false);
-  EXPECT_EQ("TEXT (abra) ", handler.StrClear());
-
-  fragment = "stream>";
-  parser.Parse(fragment.c_str(), fragment.length(), false);
-  EXPECT_EQ("END ", handler.StrClear());
-}
-
-TEST(XmlParserTest, TestReset) {
-  {
-    XmlParserTestHandler handler;
-    XmlParser parser(&handler);
-    std::string fragment;
-
-    fragment = "<top><first/><second><third></third>";
-    parser.Parse(fragment.c_str(), fragment.length(), false);
-    EXPECT_EQ("START (top) START (first) END START (second) START (third) END ",
-        handler.StrClear());
-
-    parser.Reset();
-    fragment = "<tip><first/><second><third></third>";
-    parser.Parse(fragment.c_str(), fragment.length(), false);
-    EXPECT_EQ("START (tip) START (first) END START (second) START (third) END ",
-        handler.StrClear());
-  }
-  {
-    XmlParserTestHandler handler;
-    XmlParser parser(&handler);
-    std::string fragment;
-
-    fragment = "<top xmlns='m'>";
-    parser.Parse(fragment.c_str(), fragment.length(), false);
-    EXPECT_EQ("START (m:top, xmlns='m') ", handler.StrClear());
-
-    fragment = "<testing/><frag";
-    parser.Parse(fragment.c_str(), fragment.length(), false);
-    EXPECT_EQ("START (m:testing) END ", handler.StrClear());
-
-    parser.Reset();
-    fragment = "<testing><fragment/";
-    parser.Parse(fragment.c_str(), fragment.length(), false);
-    EXPECT_EQ("START (testing) ", handler.StrClear());
-
-    fragment = ">";
-    parser.Parse(fragment.c_str(), fragment.length(), false);
-    EXPECT_EQ("START (fragment) END ", handler.StrClear());
-  }
-}
-
-TEST(XmlParserTest, TestError) {
-  {
-    XmlParserTestHandler handler;
-    XmlParser::ParseXml(&handler, "junk");
-    EXPECT_EQ("ERROR (2) ", handler.Str());
-  }
-  {
-    XmlParserTestHandler handler;
-    XmlParser::ParseXml(&handler, "<top/> garbage ");
-    EXPECT_EQ("START (top) END ERROR (9) ", handler.Str());
-  }
-  {
-    XmlParserTestHandler handler;
-    XmlParser::ParseXml(&handler, "<-hm->");
-    EXPECT_EQ("ERROR (4) ", handler.Str());
-  }
-  {
-    XmlParserTestHandler handler;
-    XmlParser::ParseXml(&handler, "<hello>&foobar;</hello>");
-    EXPECT_EQ("START (hello) ERROR (11) ", handler.Str());
-  }
-  {
-    XmlParserTestHandler handler;
-    XmlParser::ParseXml(&handler,
-        "<!DOCTYPE HTML PUBLIC \"foobar\" \"barfoo\">");
-    EXPECT_EQ("ERROR (3) ", handler.Str());
-  }
-  {
-    // XmlParser requires utf-8
-    XmlParserTestHandler handler;
-    XmlParser::ParseXml(&handler,
-        "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?><test/>");
-    EXPECT_EQ("ERROR (19) ", handler.Str());
-  }
-  {
-    // XmlParser requires version 1.0
-    XmlParserTestHandler handler;
-    XmlParser::ParseXml(&handler,
-        "<?xml version=\"2.0\"?><test/>");
-    EXPECT_EQ("ERROR (2) ", handler.Str());
-  }
-  {
-    // XmlParser requires standalone documents
-    XmlParserTestHandler handler;
-    XmlParser::ParseXml(&handler,
-        "<?xml version=\"1.0\" standalone=\"no\"?><test/>");
-    EXPECT_EQ("ERROR (2) ", handler.Str());
-  }
-  {
-    // XmlParser doesn't like empty namespace URIs
-    XmlParserTestHandler handler;
-    XmlParser::ParseXml(&handler,
-        "<test xmlns:foo='' foo:bar='huh?'>");
-    EXPECT_EQ("ERROR (2) ", handler.Str());
-  }
-}
diff --git a/third_party/libjingle/source/talk/xmllite/xmlprinter.cc b/third_party/libjingle/source/talk/xmllite/xmlprinter.cc
deleted file mode 100644
index 1350454..0000000
--- a/third_party/libjingle/source/talk/xmllite/xmlprinter.cc
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/xmllite/xmlprinter.h"
-
-#include <sstream>
-#include <string>
-#include <vector>
-
-#include "talk/xmllite/xmlconstants.h"
-#include "talk/xmllite/xmlelement.h"
-#include "talk/xmllite/xmlnsstack.h"
-
-namespace buzz {
-
-class XmlPrinterImpl {
-public:
-  XmlPrinterImpl(std::ostream* pout, XmlnsStack* ns_stack);
-  void PrintElement(const XmlElement* element);
-  void PrintQuotedValue(const std::string& text);
-  void PrintBodyText(const std::string& text);
-  void PrintCDATAText(const std::string& text);
-
-private:
-  std::ostream *pout_;
-  XmlnsStack* ns_stack_;
-};
-
-void XmlPrinter::PrintXml(std::ostream* pout, const XmlElement* element) {
-  XmlnsStack ns_stack;
-  PrintXml(pout, element, &ns_stack);
-}
-
-void XmlPrinter::PrintXml(std::ostream* pout, const XmlElement* element,
-                          XmlnsStack* ns_stack) {
-  XmlPrinterImpl printer(pout, ns_stack);
-  printer.PrintElement(element);
-}
-
-XmlPrinterImpl::XmlPrinterImpl(std::ostream* pout, XmlnsStack* ns_stack)
-    : pout_(pout),
-      ns_stack_(ns_stack) {
-}
-
-void XmlPrinterImpl::PrintElement(const XmlElement* element) {
-  ns_stack_->PushFrame();
-
-  // first go through attrs of pel to add xmlns definitions
-  const XmlAttr* attr;
-  for (attr = element->FirstAttr(); attr; attr = attr->NextAttr()) {
-    if (attr->Name() == QN_XMLNS) {
-      ns_stack_->AddXmlns(STR_EMPTY, attr->Value());
-    } else if (attr->Name().Namespace() == NS_XMLNS) {
-      ns_stack_->AddXmlns(attr->Name().LocalPart(),
-                          attr->Value());
-    }
-  }
-
-  // then go through qnames to make sure needed xmlns definitons are added
-  std::vector<std::string> new_ns;
-  std::pair<std::string, bool> prefix;
-  prefix = ns_stack_->AddNewPrefix(element->Name().Namespace(), false);
-  if (prefix.second) {
-    new_ns.push_back(prefix.first);
-    new_ns.push_back(element->Name().Namespace());
-  }
-
-  for (attr = element->FirstAttr(); attr; attr = attr->NextAttr()) {
-    prefix = ns_stack_->AddNewPrefix(attr->Name().Namespace(), true);
-    if (prefix.second) {
-      new_ns.push_back(prefix.first);
-      new_ns.push_back(attr->Name().Namespace());
-    }
-  }
-
-  // print the element name
-  *pout_ << '<' << ns_stack_->FormatQName(element->Name(), false);
-
-  // and the attributes
-  for (attr = element->FirstAttr(); attr; attr = attr->NextAttr()) {
-    *pout_ << ' ' << ns_stack_->FormatQName(attr->Name(), true) << "=\"";
-    PrintQuotedValue(attr->Value());
-    *pout_ << '"';
-  }
-
-  // and the extra xmlns declarations
-  std::vector<std::string>::iterator i(new_ns.begin());
-  while (i < new_ns.end()) {
-    if (*i == STR_EMPTY) {
-      *pout_ << " xmlns=\"" << *(i + 1) << '"';
-    } else {
-      *pout_ << " xmlns:" << *i << "=\"" << *(i + 1) << '"';
-    }
-    i += 2;
-  }
-
-  // now the children
-  const XmlChild* child = element->FirstChild();
-
-  if (child == NULL)
-    *pout_ << "/>";
-  else {
-    *pout_ << '>';
-    while (child) {
-      if (child->IsText()) {
-        if (element->IsCDATA()) {
-          PrintCDATAText(child->AsText()->Text());
-        } else {
-          PrintBodyText(child->AsText()->Text());
-        }
-      } else {
-        PrintElement(child->AsElement());
-      }
-      child = child->NextChild();
-    }
-    *pout_ << "</" << ns_stack_->FormatQName(element->Name(), false) << '>';
-  }
-
-  ns_stack_->PopFrame();
-}
-
-void XmlPrinterImpl::PrintQuotedValue(const std::string& text) {
-  size_t safe = 0;
-  for (;;) {
-    size_t unsafe = text.find_first_of("<>&\"", safe);
-    if (unsafe == std::string::npos)
-      unsafe = text.length();
-    *pout_ << text.substr(safe, unsafe - safe);
-    if (unsafe == text.length())
-      return;
-    switch (text[unsafe]) {
-      case '<': *pout_ << "&lt;"; break;
-      case '>': *pout_ << "&gt;"; break;
-      case '&': *pout_ << "&amp;"; break;
-      case '"': *pout_ << "&quot;"; break;
-    }
-    safe = unsafe + 1;
-    if (safe == text.length())
-      return;
-  }
-}
-
-void XmlPrinterImpl::PrintBodyText(const std::string& text) {
-  size_t safe = 0;
-  for (;;) {
-    size_t unsafe = text.find_first_of("<>&", safe);
-    if (unsafe == std::string::npos)
-      unsafe = text.length();
-    *pout_ << text.substr(safe, unsafe - safe);
-    if (unsafe == text.length())
-      return;
-    switch (text[unsafe]) {
-      case '<': *pout_ << "&lt;"; break;
-      case '>': *pout_ << "&gt;"; break;
-      case '&': *pout_ << "&amp;"; break;
-    }
-    safe = unsafe + 1;
-    if (safe == text.length())
-      return;
-  }
-}
-
-void XmlPrinterImpl::PrintCDATAText(const std::string& text) {
-  *pout_ << "<![CDATA[" << text << "]]>";
-}
-
-}  // namespace buzz
diff --git a/third_party/libjingle/source/talk/xmllite/xmlprinter.h b/third_party/libjingle/source/talk/xmllite/xmlprinter.h
deleted file mode 100644
index 90cc255..0000000
--- a/third_party/libjingle/source/talk/xmllite/xmlprinter.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_XMLLITE_XMLPRINTER_H_
-#define TALK_XMLLITE_XMLPRINTER_H_
-
-#include <iosfwd>
-#include <string>
-
-namespace buzz {
-
-class XmlElement;
-class XmlnsStack;
-
-class XmlPrinter {
- public:
-  static void PrintXml(std::ostream* pout, const XmlElement* pelt);
-
-  static void PrintXml(std::ostream* pout, const XmlElement* pelt,
-                       XmlnsStack* ns_stack);
-};
-
-}  // namespace buzz
-
-#endif  // TALK_XMLLITE_XMLPRINTER_H_
diff --git a/third_party/libjingle/source/talk/xmllite/xmlprinter_unittest.cc b/third_party/libjingle/source/talk/xmllite/xmlprinter_unittest.cc
deleted file mode 100644
index 60b0e42..0000000
--- a/third_party/libjingle/source/talk/xmllite/xmlprinter_unittest.cc
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * libjingle
- * Copyright 2004, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/xmllite/xmlprinter.h"
-
-#include <sstream>
-#include <string>
-
-#include "talk/base/common.h"
-#include "talk/base/gunit.h"
-#include "talk/xmllite/qname.h"
-#include "talk/xmllite/xmlelement.h"
-#include "talk/xmllite/xmlnsstack.h"
-
-using buzz::QName;
-using buzz::XmlElement;
-using buzz::XmlnsStack;
-using buzz::XmlPrinter;
-
-TEST(XmlPrinterTest, TestBasicPrinting) {
-  XmlElement elt(QName("google:test", "first"));
-  std::stringstream ss;
-  XmlPrinter::PrintXml(&ss, &elt);
-  EXPECT_EQ("<test:first xmlns:test=\"google:test\"/>", ss.str());
-}
-
-TEST(XmlPrinterTest, TestNamespacedPrinting) {
-  XmlElement elt(QName("google:test", "first"));
-  elt.AddElement(new XmlElement(QName("nested:test", "second")));
-  std::stringstream ss;
-
-  XmlnsStack ns_stack;
-  ns_stack.AddXmlns("gg", "google:test");
-  ns_stack.AddXmlns("", "nested:test");
-
-  XmlPrinter::PrintXml(&ss, &elt, &ns_stack);
-  EXPECT_EQ("<gg:first><second/></gg:first>", ss.str());
-}
diff --git a/third_party/libjingle/source/talk/xmpp/asyncsocket.h b/third_party/libjingle/source/talk/xmpp/asyncsocket.h
deleted file mode 100644
index fb4ef02..0000000
--- a/third_party/libjingle/source/talk/xmpp/asyncsocket.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _ASYNCSOCKET_H_
-#define _ASYNCSOCKET_H_
-
-#include "talk/base/sigslot.h"
-
-namespace talk_base {
-  class SocketAddress;
-}
-
-namespace buzz {
-
-class AsyncSocket {
-public:
-  enum State {
-    STATE_CLOSED = 0,      //!< Socket is not open.
-    STATE_CLOSING,         //!< Socket is closing but can have buffered data
-    STATE_CONNECTING,      //!< In the process of
-    STATE_OPEN,            //!< Socket is connected
-#if defined(FEATURE_ENABLE_SSL)
-    STATE_TLS_CONNECTING,  //!< Establishing TLS connection
-    STATE_TLS_OPEN,        //!< TLS connected
-#endif
-  };
-
-  enum Error {
-    ERROR_NONE = 0,         //!< No error
-    ERROR_WINSOCK,          //!< Winsock error
-    ERROR_DNS,              //!< Couldn't resolve host name
-    ERROR_WRONGSTATE,       //!< Call made while socket is in the wrong state
-#if defined(FEATURE_ENABLE_SSL)
-    ERROR_SSL,              //!< Something went wrong with OpenSSL
-#endif
-  };
-
-  virtual ~AsyncSocket() {}
-  virtual State state() = 0;
-  virtual Error error() = 0;
-  virtual int GetError() = 0;    // winsock error code
-
-  virtual bool Connect(const talk_base::SocketAddress& addr) = 0;
-  virtual bool Read(char * data, size_t len, size_t* len_read) = 0;
-  virtual bool Write(const char * data, size_t len) = 0;
-  virtual bool Close() = 0;
-#if defined(FEATURE_ENABLE_SSL)
-  // We allow matching any passed domain.  This allows us to avoid
-  // handling the valuable certificates for logins into proxies.  If
-  // both names are passed as empty, we do not require a match.
-  virtual bool StartTls(const std::string & domainname) = 0;
-#endif
-
-  sigslot::signal0<> SignalConnected;
-  sigslot::signal0<> SignalSSLConnected;
-  sigslot::signal0<> SignalClosed;
-  sigslot::signal0<> SignalRead;
-  sigslot::signal0<> SignalError;
-};
-
-}
-
-#endif
diff --git a/third_party/libjingle/source/talk/xmpp/constants.cc b/third_party/libjingle/source/talk/xmpp/constants.cc
deleted file mode 100644
index 421fd8e..0000000
--- a/third_party/libjingle/source/talk/xmpp/constants.cc
+++ /dev/null
@@ -1,556 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/xmpp/constants.h"
-
-#include <string>
-
-#include "talk/base/basicdefs.h"
-#include "talk/xmllite/xmlconstants.h"
-#include "talk/xmllite/xmlelement.h"
-#include "talk/xmllite/qname.h"
-#include "talk/xmpp/jid.h"
-
-namespace buzz {
-
-// TODO: Remove static objects of complex types, particularly
-// Jid and QName.
-
-const char NS_CLIENT[] = "jabber:client";
-const char NS_SERVER[] = "jabber:server";
-const char NS_STREAM[] = "http://etherx.jabber.org/streams";
-const char NS_XSTREAM[] = "urn:ietf:params:xml:ns:xmpp-streams";
-const char NS_TLS[] = "urn:ietf:params:xml:ns:xmpp-tls";
-const char NS_SASL[] = "urn:ietf:params:xml:ns:xmpp-sasl";
-const char NS_BIND[] = "urn:ietf:params:xml:ns:xmpp-bind";
-const char NS_DIALBACK[] = "jabber:server:dialback";
-const char NS_SESSION[] = "urn:ietf:params:xml:ns:xmpp-session";
-const char NS_STANZA[] = "urn:ietf:params:xml:ns:xmpp-stanzas";
-const char NS_PRIVACY[] = "jabber:iq:privacy";
-const char NS_ROSTER[] = "jabber:iq:roster";
-const char NS_VCARD[] = "vcard-temp";
-const char NS_AVATAR_HASH[] = "google:avatar";
-const char NS_VCARD_UPDATE[] = "vcard-temp:x:update";
-const char STR_CLIENT[] = "client";
-const char STR_SERVER[] = "server";
-const char STR_STREAM[] = "stream";
-
-const char STR_GET[] = "get";
-const char STR_SET[] = "set";
-const char STR_RESULT[] = "result";
-const char STR_ERROR[] = "error";
-
-const char STR_FORM[] = "form";
-const char STR_SUBMIT[] = "submit";
-const char STR_TEXT_SINGLE[] = "text-single";
-const char STR_LIST_SINGLE[] = "list-single";
-const char STR_LIST_MULTI[] = "list-multi";
-const char STR_HIDDEN[] = "hidden";
-const char STR_FORM_TYPE[] = "FORM_TYPE";
-
-const char STR_FROM[] = "from";
-const char STR_TO[] = "to";
-const char STR_BOTH[] = "both";
-const char STR_REMOVE[] = "remove";
-
-const char STR_TYPE[] = "type";
-const char STR_NAME[] = "name";
-const char STR_ID[] = "id";
-const char STR_JID[] = "jid";
-const char STR_SUBSCRIPTION[] = "subscription";
-const char STR_ASK[] = "ask";
-const char STR_X[] = "x";
-const char STR_GOOGLE_COM[] = "google.com";
-const char STR_GMAIL_COM[] = "gmail.com";
-const char STR_GOOGLEMAIL_COM[] = "googlemail.com";
-const char STR_DEFAULT_DOMAIN[] = "default.talk.google.com";
-const char STR_TALK_GOOGLE_COM[] = "talk.google.com";
-const char STR_TALKX_L_GOOGLE_COM[] = "talkx.l.google.com";
-const char STR_XMPP_GOOGLE_COM[] = "xmpp.google.com";
-const char STR_XMPPX_L_GOOGLE_COM[] = "xmppx.l.google.com";
-
-#ifdef FEATURE_ENABLE_VOICEMAIL
-const char STR_VOICEMAIL[] = "voicemail";
-const char STR_OUTGOINGVOICEMAIL[] = "outgoingvoicemail";
-#endif
-
-const char STR_UNAVAILABLE[] = "unavailable";
-
-const char STR_GOOGLE_MUC_LOOKUP_JID[] = "lookup.groupchat.google.com";
-const char STR_MUC_ROOMCONFIG_ROOMNAME[] = "muc#roomconfig_roomname";
-const char STR_MUC_ROOMCONFIG_FEATURES[] = "muc#roomconfig_features";
-const char STR_MUC_ROOM_FEATURE_ENTERPRISE[] = "muc_enterprise";
-const char STR_MUC_ROOMCONFIG[] = "http://jabber.org/protocol/muc#roomconfig";
-
-const StaticQName QN_STREAM_STREAM = { NS_STREAM, STR_STREAM };
-const StaticQName QN_STREAM_FEATURES = { NS_STREAM, "features" };
-const StaticQName QN_STREAM_ERROR = { NS_STREAM, "error" };
-
-const StaticQName QN_XSTREAM_BAD_FORMAT = { NS_XSTREAM, "bad-format" };
-const StaticQName QN_XSTREAM_BAD_NAMESPACE_PREFIX =
-    { NS_XSTREAM, "bad-namespace-prefix" };
-const StaticQName QN_XSTREAM_CONFLICT = { NS_XSTREAM, "conflict" };
-const StaticQName QN_XSTREAM_CONNECTION_TIMEOUT =
-    { NS_XSTREAM, "connection-timeout" };
-const StaticQName QN_XSTREAM_HOST_GONE = { NS_XSTREAM, "host-gone" };
-const StaticQName QN_XSTREAM_HOST_UNKNOWN = { NS_XSTREAM, "host-unknown" };
-const StaticQName QN_XSTREAM_IMPROPER_ADDRESSIING =
-     { NS_XSTREAM, "improper-addressing" };
-const StaticQName QN_XSTREAM_INTERNAL_SERVER_ERROR =
-    { NS_XSTREAM, "internal-server-error" };
-const StaticQName QN_XSTREAM_INVALID_FROM = { NS_XSTREAM, "invalid-from" };
-const StaticQName QN_XSTREAM_INVALID_ID = { NS_XSTREAM, "invalid-id" };
-const StaticQName QN_XSTREAM_INVALID_NAMESPACE =
-    { NS_XSTREAM, "invalid-namespace" };
-const StaticQName QN_XSTREAM_INVALID_XML = { NS_XSTREAM, "invalid-xml" };
-const StaticQName QN_XSTREAM_NOT_AUTHORIZED = { NS_XSTREAM, "not-authorized" };
-const StaticQName QN_XSTREAM_POLICY_VIOLATION =
-    { NS_XSTREAM, "policy-violation" };
-const StaticQName QN_XSTREAM_REMOTE_CONNECTION_FAILED =
-    { NS_XSTREAM, "remote-connection-failed" };
-const StaticQName QN_XSTREAM_RESOURCE_CONSTRAINT =
-    { NS_XSTREAM, "resource-constraint" };
-const StaticQName QN_XSTREAM_RESTRICTED_XML = { NS_XSTREAM, "restricted-xml" };
-const StaticQName QN_XSTREAM_SEE_OTHER_HOST = { NS_XSTREAM, "see-other-host" };
-const StaticQName QN_XSTREAM_SYSTEM_SHUTDOWN =
-    { NS_XSTREAM, "system-shutdown" };
-const StaticQName QN_XSTREAM_UNDEFINED_CONDITION =
-    { NS_XSTREAM, "undefined-condition" };
-const StaticQName QN_XSTREAM_UNSUPPORTED_ENCODING =
-    { NS_XSTREAM, "unsupported-encoding" };
-const StaticQName QN_XSTREAM_UNSUPPORTED_STANZA_TYPE =
-    { NS_XSTREAM, "unsupported-stanza-type" };
-const StaticQName QN_XSTREAM_UNSUPPORTED_VERSION =
-    { NS_XSTREAM, "unsupported-version" };
-const StaticQName QN_XSTREAM_XML_NOT_WELL_FORMED =
-    { NS_XSTREAM, "xml-not-well-formed" };
-const StaticQName QN_XSTREAM_TEXT = { NS_XSTREAM, "text" };
-
-const StaticQName QN_TLS_STARTTLS = { NS_TLS, "starttls" };
-const StaticQName QN_TLS_REQUIRED = { NS_TLS, "required" };
-const StaticQName QN_TLS_PROCEED = { NS_TLS, "proceed" };
-const StaticQName QN_TLS_FAILURE = { NS_TLS, "failure" };
-
-const StaticQName QN_SASL_MECHANISMS = { NS_SASL, "mechanisms" };
-const StaticQName QN_SASL_MECHANISM = { NS_SASL, "mechanism" };
-const StaticQName QN_SASL_AUTH = { NS_SASL, "auth" };
-const StaticQName QN_SASL_CHALLENGE = { NS_SASL, "challenge" };
-const StaticQName QN_SASL_RESPONSE = { NS_SASL, "response" };
-const StaticQName QN_SASL_ABORT = { NS_SASL, "abort" };
-const StaticQName QN_SASL_SUCCESS = { NS_SASL, "success" };
-const StaticQName QN_SASL_FAILURE = { NS_SASL, "failure" };
-const StaticQName QN_SASL_ABORTED = { NS_SASL, "aborted" };
-const StaticQName QN_SASL_INCORRECT_ENCODING =
-    { NS_SASL, "incorrect-encoding" };
-const StaticQName QN_SASL_INVALID_AUTHZID = { NS_SASL, "invalid-authzid" };
-const StaticQName QN_SASL_INVALID_MECHANISM = { NS_SASL, "invalid-mechanism" };
-const StaticQName QN_SASL_MECHANISM_TOO_WEAK =
-    { NS_SASL, "mechanism-too-weak" };
-const StaticQName QN_SASL_NOT_AUTHORIZED = { NS_SASL, "not-authorized" };
-const StaticQName QN_SASL_TEMPORARY_AUTH_FAILURE =
-    { NS_SASL, "temporary-auth-failure" };
-
-// These are non-standard.
-const char NS_GOOGLE_AUTH_PROTOCOL[] =
-    "http://www.google.com/talk/protocol/auth";
-const StaticQName QN_GOOGLE_AUTH_CLIENT_USES_FULL_BIND_RESULT =
-    { NS_GOOGLE_AUTH_PROTOCOL, "client-uses-full-bind-result" };
-const char NS_GOOGLE_AUTH_OLD[] = "google:auth";
-const StaticQName QN_GOOGLE_ALLOW_NON_GOOGLE_ID_XMPP_LOGIN =
-    { NS_GOOGLE_AUTH_PROTOCOL, "allow-non-google-login" };
-
-const StaticQName QN_DIALBACK_RESULT = { NS_DIALBACK, "result" };
-const StaticQName QN_DIALBACK_VERIFY = { NS_DIALBACK, "verify" };
-
-const StaticQName QN_STANZA_BAD_REQUEST = { NS_STANZA, "bad-request" };
-const StaticQName QN_STANZA_CONFLICT = { NS_STANZA, "conflict" };
-const StaticQName QN_STANZA_FEATURE_NOT_IMPLEMENTED =
-    { NS_STANZA, "feature-not-implemented" };
-const StaticQName QN_STANZA_FORBIDDEN = { NS_STANZA, "forbidden" };
-const StaticQName QN_STANZA_GONE = { NS_STANZA, "gone" };
-const StaticQName QN_STANZA_INTERNAL_SERVER_ERROR =
-    { NS_STANZA, "internal-server-error" };
-const StaticQName QN_STANZA_ITEM_NOT_FOUND = { NS_STANZA, "item-not-found" };
-const StaticQName QN_STANZA_JID_MALFORMED = { NS_STANZA, "jid-malformed" };
-const StaticQName QN_STANZA_NOT_ACCEPTABLE = { NS_STANZA, "not-acceptable" };
-const StaticQName QN_STANZA_NOT_ALLOWED = { NS_STANZA, "not-allowed" };
-const StaticQName QN_STANZA_PAYMENT_REQUIRED =
-    { NS_STANZA, "payment-required" };
-const StaticQName QN_STANZA_RECIPIENT_UNAVAILABLE =
-    { NS_STANZA, "recipient-unavailable" };
-const StaticQName QN_STANZA_REDIRECT = { NS_STANZA, "redirect" };
-const StaticQName QN_STANZA_REGISTRATION_REQUIRED =
-    { NS_STANZA, "registration-required" };
-const StaticQName QN_STANZA_REMOTE_SERVER_NOT_FOUND =
-    { NS_STANZA, "remote-server-not-found" };
-const StaticQName QN_STANZA_REMOTE_SERVER_TIMEOUT =
-    { NS_STANZA, "remote-server-timeout" };
-const StaticQName QN_STANZA_RESOURCE_CONSTRAINT =
-    { NS_STANZA, "resource-constraint" };
-const StaticQName QN_STANZA_SERVICE_UNAVAILABLE =
-    { NS_STANZA, "service-unavailable" };
-const StaticQName QN_STANZA_SUBSCRIPTION_REQUIRED =
-    { NS_STANZA, "subscription-required" };
-const StaticQName QN_STANZA_UNDEFINED_CONDITION =
-    { NS_STANZA, "undefined-condition" };
-const StaticQName QN_STANZA_UNEXPECTED_REQUEST =
-    { NS_STANZA, "unexpected-request" };
-const StaticQName QN_STANZA_TEXT = { NS_STANZA, "text" };
-
-const StaticQName QN_BIND_BIND = { NS_BIND, "bind" };
-const StaticQName QN_BIND_RESOURCE = { NS_BIND, "resource" };
-const StaticQName QN_BIND_JID = { NS_BIND, "jid" };
-
-const StaticQName QN_MESSAGE = { NS_CLIENT, "message" };
-const StaticQName QN_BODY = { NS_CLIENT, "body" };
-const StaticQName QN_SUBJECT = { NS_CLIENT, "subject" };
-const StaticQName QN_THREAD = { NS_CLIENT, "thread" };
-const StaticQName QN_PRESENCE = { NS_CLIENT, "presence" };
-const StaticQName QN_SHOW = { NS_CLIENT, "show" };
-const StaticQName QN_STATUS = { NS_CLIENT, "status" };
-const StaticQName QN_LANG = { NS_CLIENT, "lang" };
-const StaticQName QN_PRIORITY = { NS_CLIENT, "priority" };
-const StaticQName QN_IQ = { NS_CLIENT, "iq" };
-const StaticQName QN_ERROR = { NS_CLIENT, "error" };
-
-const StaticQName QN_SERVER_MESSAGE = { NS_SERVER, "message" };
-const StaticQName QN_SERVER_BODY = { NS_SERVER, "body" };
-const StaticQName QN_SERVER_SUBJECT = { NS_SERVER, "subject" };
-const StaticQName QN_SERVER_THREAD = { NS_SERVER, "thread" };
-const StaticQName QN_SERVER_PRESENCE = { NS_SERVER, "presence" };
-const StaticQName QN_SERVER_SHOW = { NS_SERVER, "show" };
-const StaticQName QN_SERVER_STATUS = { NS_SERVER, "status" };
-const StaticQName QN_SERVER_LANG = { NS_SERVER, "lang" };
-const StaticQName QN_SERVER_PRIORITY = { NS_SERVER, "priority" };
-const StaticQName QN_SERVER_IQ = { NS_SERVER, "iq" };
-const StaticQName QN_SERVER_ERROR = { NS_SERVER, "error" };
-
-const StaticQName QN_SESSION_SESSION = { NS_SESSION, "session" };
-
-const StaticQName QN_PRIVACY_QUERY = { NS_PRIVACY, "query" };
-const StaticQName QN_PRIVACY_ACTIVE = { NS_PRIVACY, "active" };
-const StaticQName QN_PRIVACY_DEFAULT = { NS_PRIVACY, "default" };
-const StaticQName QN_PRIVACY_LIST = { NS_PRIVACY, "list" };
-const StaticQName QN_PRIVACY_ITEM = { NS_PRIVACY, "item" };
-const StaticQName QN_PRIVACY_IQ = { NS_PRIVACY, "iq" };
-const StaticQName QN_PRIVACY_MESSAGE = { NS_PRIVACY, "message" };
-const StaticQName QN_PRIVACY_PRESENCE_IN = { NS_PRIVACY, "presence-in" };
-const StaticQName QN_PRIVACY_PRESENCE_OUT = { NS_PRIVACY, "presence-out" };
-
-const StaticQName QN_ROSTER_QUERY = { NS_ROSTER, "query" };
-const StaticQName QN_ROSTER_ITEM = { NS_ROSTER, "item" };
-const StaticQName QN_ROSTER_GROUP = { NS_ROSTER, "group" };
-
-const StaticQName QN_VCARD = { NS_VCARD, "vCard" };
-const StaticQName QN_VCARD_FN = { NS_VCARD, "FN" };
-const StaticQName QN_VCARD_PHOTO = { NS_VCARD, "PHOTO" };
-const StaticQName QN_VCARD_PHOTO_BINVAL = { NS_VCARD, "BINVAL" };
-const StaticQName QN_VCARD_AVATAR_HASH = { NS_AVATAR_HASH, "hash" };
-const StaticQName QN_VCARD_AVATAR_HASH_MODIFIED =
-    { NS_AVATAR_HASH, "modified" };
-
-const StaticQName QN_NAME = { STR_EMPTY, "name" };
-const StaticQName QN_AFFILIATION = { STR_EMPTY, "affiliation" };
-const StaticQName QN_ROLE = { STR_EMPTY, "role" };
-
-#if defined(FEATURE_ENABLE_PSTN)
-const StaticQName QN_VCARD_TEL = { NS_VCARD, "TEL" };
-const StaticQName QN_VCARD_VOICE = { NS_VCARD, "VOICE" };
-const StaticQName QN_VCARD_HOME = { NS_VCARD, "HOME" };
-const StaticQName QN_VCARD_WORK = { NS_VCARD, "WORK" };
-const StaticQName QN_VCARD_CELL = { NS_VCARD, "CELL" };
-const StaticQName QN_VCARD_NUMBER = { NS_VCARD, "NUMBER" };
-#endif
-
-const StaticQName QN_XML_LANG = { NS_XML, "lang" };
-
-const StaticQName QN_ENCODING = { STR_EMPTY, STR_ENCODING };
-const StaticQName QN_VERSION = { STR_EMPTY, STR_VERSION };
-const StaticQName QN_TO = { STR_EMPTY, "to" };
-const StaticQName QN_FROM = { STR_EMPTY, "from" };
-const StaticQName QN_TYPE = { STR_EMPTY, "type" };
-const StaticQName QN_ID = { STR_EMPTY, "id" };
-const StaticQName QN_CODE = { STR_EMPTY, "code" };
-
-const StaticQName QN_VALUE = { STR_EMPTY, "value" };
-const StaticQName QN_ACTION = { STR_EMPTY, "action" };
-const StaticQName QN_ORDER = { STR_EMPTY, "order" };
-const StaticQName QN_MECHANISM = { STR_EMPTY, "mechanism" };
-const StaticQName QN_ASK = { STR_EMPTY, "ask" };
-const StaticQName QN_JID = { STR_EMPTY, "jid" };
-const StaticQName QN_NICK = { STR_EMPTY, "nick" };
-const StaticQName QN_SUBSCRIPTION = { STR_EMPTY, "subscription" };
-const StaticQName QN_TITLE1 = { STR_EMPTY, "title1" };
-const StaticQName QN_TITLE2 = { STR_EMPTY, "title2" };
-const StaticQName QN_SOURCE = { STR_EMPTY, "source" };
-const StaticQName QN_TIME = { STR_EMPTY, "time" };
-
-const StaticQName QN_XMLNS_CLIENT = { NS_XMLNS, STR_CLIENT };
-const StaticQName QN_XMLNS_SERVER = { NS_XMLNS, STR_SERVER };
-const StaticQName QN_XMLNS_STREAM = { NS_XMLNS, STR_STREAM };
-
-
-// Presence
-const char STR_SHOW_AWAY[] = "away";
-const char STR_SHOW_CHAT[] = "chat";
-const char STR_SHOW_DND[] = "dnd";
-const char STR_SHOW_XA[] = "xa";
-const char STR_SHOW_OFFLINE[] = "offline";
-
-// Subscription
-const char STR_SUBSCRIBE[] = "subscribe";
-const char STR_SUBSCRIBED[] = "subscribed";
-const char STR_UNSUBSCRIBE[] = "unsubscribe";
-const char STR_UNSUBSCRIBED[] = "unsubscribed";
-
-// Google Invite
-const char NS_GOOGLE_INVITE[] = "google:subscribe";
-const StaticQName QN_INVITATION = { NS_GOOGLE_INVITE, "invitation" };
-const StaticQName QN_INVITE_NAME = { NS_GOOGLE_INVITE, "name" };
-const StaticQName QN_INVITE_SUBJECT = { NS_GOOGLE_INVITE, "subject" };
-const StaticQName QN_INVITE_MESSAGE = { NS_GOOGLE_INVITE, "body" };
-
-// PubSub: http://xmpp.org/extensions/xep-0060.html
-const char NS_PUBSUB[] = "http://jabber.org/protocol/pubsub";
-const StaticQName QN_PUBSUB = { NS_PUBSUB, "pubsub" };
-const StaticQName QN_PUBSUB_ITEMS = { NS_PUBSUB, "items" };
-const StaticQName QN_PUBSUB_ITEM = { NS_PUBSUB, "item" };
-const StaticQName QN_PUBSUB_PUBLISH = { NS_PUBSUB, "publish" };
-const StaticQName QN_PUBSUB_RETRACT = { NS_PUBSUB, "retract" };
-const StaticQName QN_ATTR_PUBLISHER = { STR_EMPTY, "publisher" };
-
-const char NS_PUBSUB_EVENT[] = "http://jabber.org/protocol/pubsub#event";
-const StaticQName QN_NODE = { STR_EMPTY, "node" };
-const StaticQName QN_PUBSUB_EVENT = { NS_PUBSUB_EVENT, "event" };
-const StaticQName QN_PUBSUB_EVENT_ITEMS = { NS_PUBSUB_EVENT, "items" };
-const StaticQName QN_PUBSUB_EVENT_ITEM = { NS_PUBSUB_EVENT, "item" };
-const StaticQName QN_PUBSUB_EVENT_RETRACT = { NS_PUBSUB_EVENT, "retract" };
-const StaticQName QN_NOTIFY = { STR_EMPTY, "notify" };
-
-const char NS_PRESENTER[] = "google:presenter";
-const StaticQName QN_PRESENTER_PRESENTER = { NS_PRESENTER, "presenter" };
-const StaticQName QN_PRESENTER_PRESENTATION_ITEM =
-    { NS_PRESENTER, "presentation-item" };
-const StaticQName QN_PRESENTER_PRESENTATION_TYPE =
-    { NS_PRESENTER, "presentation-type" };
-const StaticQName QN_PRESENTER_PRESENTATION_ID =
-    { NS_PRESENTER, "presentation-id" };
-
-// JEP 0030
-const StaticQName QN_CATEGORY = { STR_EMPTY, "category" };
-const StaticQName QN_VAR = { STR_EMPTY, "var" };
-const char NS_DISCO_INFO[] = "http://jabber.org/protocol/disco#info";
-const char NS_DISCO_ITEMS[] = "http://jabber.org/protocol/disco#items";
-const StaticQName QN_DISCO_INFO_QUERY = { NS_DISCO_INFO, "query" };
-const StaticQName QN_DISCO_IDENTITY = { NS_DISCO_INFO, "identity" };
-const StaticQName QN_DISCO_FEATURE = { NS_DISCO_INFO, "feature" };
-
-const StaticQName QN_DISCO_ITEMS_QUERY = { NS_DISCO_ITEMS, "query" };
-const StaticQName QN_DISCO_ITEM = { NS_DISCO_ITEMS, "item" };
-
-// JEP 0020
-const char NS_FEATURE[] = "http://jabber.org/protocol/feature-neg";
-const StaticQName QN_FEATURE_FEATURE = { NS_FEATURE, "feature" };
-
-// JEP 0004
-const char NS_XDATA[] = "jabber:x:data";
-const StaticQName QN_XDATA_X = { NS_XDATA, "x" };
-const StaticQName QN_XDATA_INSTRUCTIONS = { NS_XDATA, "instructions" };
-const StaticQName QN_XDATA_TITLE = { NS_XDATA, "title" };
-const StaticQName QN_XDATA_FIELD = { NS_XDATA, "field" };
-const StaticQName QN_XDATA_REPORTED = { NS_XDATA, "reported" };
-const StaticQName QN_XDATA_ITEM = { NS_XDATA, "item" };
-const StaticQName QN_XDATA_DESC = { NS_XDATA, "desc" };
-const StaticQName QN_XDATA_REQUIRED = { NS_XDATA, "required" };
-const StaticQName QN_XDATA_VALUE = { NS_XDATA, "value" };
-const StaticQName QN_XDATA_OPTION = { NS_XDATA, "option" };
-
-// JEP 0045
-const char NS_MUC[] = "http://jabber.org/protocol/muc";
-const StaticQName QN_MUC_X = { NS_MUC, "x" };
-const StaticQName QN_MUC_ITEM = { NS_MUC, "item" };
-const StaticQName QN_MUC_AFFILIATION = { NS_MUC, "affiliation" };
-const StaticQName QN_MUC_ROLE = { NS_MUC, "role" };
-const char STR_AFFILIATION_NONE[] = "none";
-const char STR_ROLE_PARTICIPANT[] = "participant";
-
-const char NS_MUC_OWNER[] = "http://jabber.org/protocol/muc#owner";
-const StaticQName QN_MUC_OWNER_QUERY = { NS_MUC_OWNER, "query" };
-
-const char NS_MUC_USER[] = "http://jabber.org/protocol/muc#user";
-const StaticQName QN_MUC_USER_CONTINUE = { NS_MUC_USER, "continue" };
-const StaticQName QN_MUC_USER_X = { NS_MUC_USER, "x" };
-const StaticQName QN_MUC_USER_ITEM = { NS_MUC_USER, "item" };
-const StaticQName QN_MUC_USER_STATUS = { NS_MUC_USER, "status" };
-
-// JEP 0055 - Jabber Search
-const char NS_SEARCH[] = "jabber:iq:search";
-const StaticQName QN_SEARCH_QUERY = { NS_SEARCH, "query" };
-const StaticQName QN_SEARCH_ITEM = { NS_SEARCH, "item" };
-const StaticQName QN_SEARCH_ROOM_NAME = { NS_SEARCH, "room-name" };
-const StaticQName QN_SEARCH_ROOM_DOMAIN = { NS_SEARCH, "room-domain" };
-const StaticQName QN_SEARCH_ROOM_JID = { NS_SEARCH, "room-jid" };
-
-// JEP 0115
-const char NS_CAPS[] = "http://jabber.org/protocol/caps";
-const StaticQName QN_CAPS_C = { NS_CAPS, "c" };
-const StaticQName QN_VER = { STR_EMPTY, "ver" };
-const StaticQName QN_EXT = { STR_EMPTY, "ext" };
-
-// JEP 0153
-const char kNSVCard[] = "vcard-temp:x:update";
-const StaticQName kQnVCardX = { kNSVCard, "x" };
-const StaticQName kQnVCardPhoto = { kNSVCard, "photo" };
-
-// JEP 0172 User Nickname
-const char NS_NICKNAME[] = "http://jabber.org/protocol/nick";
-const StaticQName QN_NICKNAME = { NS_NICKNAME, "nick" };
-
-// JEP 0085 chat state
-const char NS_CHATSTATE[] = "http://jabber.org/protocol/chatstates";
-const StaticQName QN_CS_ACTIVE = { NS_CHATSTATE, "active" };
-const StaticQName QN_CS_COMPOSING = { NS_CHATSTATE, "composing" };
-const StaticQName QN_CS_PAUSED = { NS_CHATSTATE, "paused" };
-const StaticQName QN_CS_INACTIVE = { NS_CHATSTATE, "inactive" };
-const StaticQName QN_CS_GONE = { NS_CHATSTATE, "gone" };
-
-// JEP 0091 Delayed Delivery
-const char kNSDelay[] = "jabber:x:delay";
-const StaticQName kQnDelayX = { kNSDelay, "x" };
-const StaticQName kQnStamp = { STR_EMPTY, "stamp" };
-
-// Google time stamping (higher resolution)
-const char kNSTimestamp[] = "google:timestamp";
-const StaticQName kQnTime = { kNSTimestamp, "time" };
-const StaticQName kQnMilliseconds = { STR_EMPTY, "ms" };
-
-// Jingle Info
-const char NS_JINGLE_INFO[] = "google:jingleinfo";
-const StaticQName QN_JINGLE_INFO_QUERY = { NS_JINGLE_INFO, "query" };
-const StaticQName QN_JINGLE_INFO_STUN = { NS_JINGLE_INFO, "stun" };
-const StaticQName QN_JINGLE_INFO_RELAY = { NS_JINGLE_INFO, "relay" };
-const StaticQName QN_JINGLE_INFO_SERVER = { NS_JINGLE_INFO, "server" };
-const StaticQName QN_JINGLE_INFO_TOKEN = { NS_JINGLE_INFO, "token" };
-const StaticQName QN_JINGLE_INFO_HOST = { STR_EMPTY, "host" };
-const StaticQName QN_JINGLE_INFO_TCP = { STR_EMPTY, "tcp" };
-const StaticQName QN_JINGLE_INFO_UDP = { STR_EMPTY, "udp" };
-const StaticQName QN_JINGLE_INFO_TCPSSL = { STR_EMPTY, "tcpssl" };
-
-// Call Performance Logging
-const char NS_GOOGLE_CALLPERF_STATS[] = "google:call-perf-stats";
-const StaticQName QN_CALLPERF_STATS =
-    { NS_GOOGLE_CALLPERF_STATS, "callPerfStats" };
-const StaticQName QN_CALLPERF_SESSIONID = { STR_EMPTY, "sessionId" };
-const StaticQName QN_CALLPERF_LOCALUSER = { STR_EMPTY, "localUser" };
-const StaticQName QN_CALLPERF_REMOTEUSER = { STR_EMPTY, "remoteUser" };
-const StaticQName QN_CALLPERF_STARTTIME = { STR_EMPTY, "startTime" };
-const StaticQName QN_CALLPERF_CALL_LENGTH = { STR_EMPTY, "callLength" };
-const StaticQName QN_CALLPERF_CALL_ACCEPTED = { STR_EMPTY, "callAccepted" };
-const StaticQName QN_CALLPERF_CALL_ERROR_CODE = { STR_EMPTY, "callErrorCode" };
-const StaticQName QN_CALLPERF_TERMINATE_CODE = { STR_EMPTY, "terminateCode" };
-const StaticQName QN_CALLPERF_DATAPOINT =
-    { NS_GOOGLE_CALLPERF_STATS, "dataPoint" };
-const StaticQName QN_CALLPERF_DATAPOINT_TIME = { STR_EMPTY, "timeStamp" };
-const StaticQName QN_CALLPERF_DATAPOINT_FRACTION_LOST =
-    { STR_EMPTY, "fraction_lost" };
-const StaticQName QN_CALLPERF_DATAPOINT_CUM_LOST = { STR_EMPTY, "cum_lost" };
-const StaticQName QN_CALLPERF_DATAPOINT_EXT_MAX = { STR_EMPTY, "ext_max" };
-const StaticQName QN_CALLPERF_DATAPOINT_JITTER = { STR_EMPTY, "jitter" };
-const StaticQName QN_CALLPERF_DATAPOINT_RTT = { STR_EMPTY, "RTT" };
-const StaticQName QN_CALLPERF_DATAPOINT_BYTES_R =
-    { STR_EMPTY, "bytesReceived" };
-const StaticQName QN_CALLPERF_DATAPOINT_PACKETS_R =
-    { STR_EMPTY, "packetsReceived" };
-const StaticQName QN_CALLPERF_DATAPOINT_BYTES_S = { STR_EMPTY, "bytesSent" };
-const StaticQName QN_CALLPERF_DATAPOINT_PACKETS_S =
-    { STR_EMPTY, "packetsSent" };
-const StaticQName QN_CALLPERF_DATAPOINT_PROCESS_CPU =
-    { STR_EMPTY, "processCpu" };
-const StaticQName QN_CALLPERF_DATAPOINT_SYSTEM_CPU = { STR_EMPTY, "systemCpu" };
-const StaticQName QN_CALLPERF_DATAPOINT_CPUS = { STR_EMPTY, "cpus" };
-const StaticQName QN_CALLPERF_CONNECTION =
-    { NS_GOOGLE_CALLPERF_STATS, "connection" };
-const StaticQName QN_CALLPERF_CONNECTION_LOCAL_ADDRESS =
-    { STR_EMPTY, "localAddress" };
-const StaticQName QN_CALLPERF_CONNECTION_REMOTE_ADDRESS =
-    { STR_EMPTY, "remoteAddress" };
-const StaticQName QN_CALLPERF_CONNECTION_FLAGS = { STR_EMPTY, "flags" };
-const StaticQName QN_CALLPERF_CONNECTION_RTT = { STR_EMPTY, "rtt" };
-const StaticQName QN_CALLPERF_CONNECTION_TOTAL_BYTES_S =
-    { STR_EMPTY, "totalBytesSent" };
-const StaticQName QN_CALLPERF_CONNECTION_BYTES_SECOND_S =
-    { STR_EMPTY, "bytesSecondSent" };
-const StaticQName QN_CALLPERF_CONNECTION_TOTAL_BYTES_R =
-    { STR_EMPTY, "totalBytesRecv" };
-const StaticQName QN_CALLPERF_CONNECTION_BYTES_SECOND_R =
-    { STR_EMPTY, "bytesSecondRecv" };
-const StaticQName QN_CALLPERF_CANDIDATE =
-    { NS_GOOGLE_CALLPERF_STATS, "candidate" };
-const StaticQName QN_CALLPERF_CANDIDATE_ENDPOINT = { STR_EMPTY, "endpoint" };
-const StaticQName QN_CALLPERF_CANDIDATE_PROTOCOL = { STR_EMPTY, "protocol" };
-const StaticQName QN_CALLPERF_CANDIDATE_ADDRESS = { STR_EMPTY, "address" };
-const StaticQName QN_CALLPERF_MEDIA = { NS_GOOGLE_CALLPERF_STATS, "media" };
-const StaticQName QN_CALLPERF_MEDIA_DIRECTION = { STR_EMPTY, "direction" };
-const StaticQName QN_CALLPERF_MEDIA_SSRC = { STR_EMPTY, "SSRC" };
-const StaticQName QN_CALLPERF_MEDIA_ENERGY = { STR_EMPTY, "energy" };
-const StaticQName QN_CALLPERF_MEDIA_FIR = { STR_EMPTY, "fir" };
-const StaticQName QN_CALLPERF_MEDIA_NACK = { STR_EMPTY, "nack" };
-const StaticQName QN_CALLPERF_MEDIA_FPS = { STR_EMPTY, "fps" };
-const StaticQName QN_CALLPERF_MEDIA_FPS_NETWORK = { STR_EMPTY, "fpsNetwork" };
-const StaticQName QN_CALLPERF_MEDIA_FPS_DECODED = { STR_EMPTY, "fpsDecoded" };
-const StaticQName QN_CALLPERF_MEDIA_JITTER_BUFFER_SIZE =
-    { STR_EMPTY, "jitterBufferSize" };
-const StaticQName QN_CALLPERF_MEDIA_PREFERRED_JITTER_BUFFER_SIZE =
-    { STR_EMPTY, "preferredJitterBufferSize" };
-const StaticQName QN_CALLPERF_MEDIA_TOTAL_PLAYOUT_DELAY =
-    { STR_EMPTY, "totalPlayoutDelay" };
-
-// Muc invites.
-const StaticQName QN_MUC_USER_INVITE = { NS_MUC_USER, "invite" };
-
-// Multiway audio/video.
-const char NS_GOOGLE_MUC_USER[] = "google:muc#user";
-const StaticQName QN_GOOGLE_MUC_USER_AVAILABLE_MEDIA =
-    { NS_GOOGLE_MUC_USER, "available-media" };
-const StaticQName QN_GOOGLE_MUC_USER_ENTRY = { NS_GOOGLE_MUC_USER, "entry" };
-const StaticQName QN_GOOGLE_MUC_USER_MEDIA = { NS_GOOGLE_MUC_USER, "media" };
-const StaticQName QN_GOOGLE_MUC_USER_TYPE = { NS_GOOGLE_MUC_USER, "type" };
-const StaticQName QN_GOOGLE_MUC_USER_SRC_ID = { NS_GOOGLE_MUC_USER, "src-id" };
-const StaticQName QN_GOOGLE_MUC_USER_STATUS = { NS_GOOGLE_MUC_USER, "status" };
-const StaticQName QN_LABEL = { STR_EMPTY, "label" };
-
-const char NS_GOOGLE_MUC_MEDIA[] = "google:muc#media";
-const StaticQName QN_GOOGLE_MUC_AUDIO_MUTE =
-    { NS_GOOGLE_MUC_MEDIA, "audio-mute" };
-const StaticQName QN_GOOGLE_MUC_VIDEO_MUTE =
-    { NS_GOOGLE_MUC_MEDIA, "video-mute" };
-const StaticQName QN_GOOGLE_MUC_RECORDING =
-    { NS_GOOGLE_MUC_MEDIA, "recording" };
-const StaticQName QN_GOOGLE_MUC_MEDIA_BLOCK = { NS_GOOGLE_MUC_MEDIA, "block" };
-const StaticQName QN_STATE_ATTR = { STR_EMPTY, "state" };
-
-}
diff --git a/third_party/libjingle/source/talk/xmpp/constants.h b/third_party/libjingle/source/talk/xmpp/constants.h
deleted file mode 100644
index ad7d829..0000000
--- a/third_party/libjingle/source/talk/xmpp/constants.h
+++ /dev/null
@@ -1,504 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_XMPP_CONSTANTS_H_
-#define TALK_XMPP_CONSTANTS_H_
-
-#include <string>
-#include "talk/xmllite/qname.h"
-#include "talk/xmpp/jid.h"
-
-namespace buzz {
-
-extern const char NS_CLIENT[];
-extern const char NS_SERVER[];
-extern const char NS_STREAM[];
-extern const char NS_XSTREAM[];
-extern const char NS_TLS[];
-extern const char NS_SASL[];
-extern const char NS_BIND[];
-extern const char NS_DIALBACK[];
-extern const char NS_SESSION[];
-extern const char NS_STANZA[];
-extern const char NS_PRIVACY[];
-extern const char NS_ROSTER[];
-extern const char NS_VCARD[];
-extern const char NS_AVATAR_HASH[];
-extern const char NS_VCARD_UPDATE[];
-extern const char STR_CLIENT[];
-extern const char STR_SERVER[];
-extern const char STR_STREAM[];
-
-extern const char STR_GET[];
-extern const char STR_SET[];
-extern const char STR_RESULT[];
-extern const char STR_ERROR[];
-
-extern const char STR_FORM[];
-extern const char STR_SUBMIT[];
-extern const char STR_TEXT_SINGLE[];
-extern const char STR_LIST_SINGLE[];
-extern const char STR_LIST_MULTI[];
-extern const char STR_HIDDEN[];
-extern const char STR_FORM_TYPE[];
-
-extern const char STR_FROM[];
-extern const char STR_TO[];
-extern const char STR_BOTH[];
-extern const char STR_REMOVE[];
-
-extern const char STR_TYPE[];
-extern const char STR_NAME[];
-extern const char STR_ID[];
-extern const char STR_JID[];
-extern const char STR_SUBSCRIPTION[];
-extern const char STR_ASK[];
-extern const char STR_X[];
-extern const char STR_GOOGLE_COM[];
-extern const char STR_GMAIL_COM[];
-extern const char STR_GOOGLEMAIL_COM[];
-extern const char STR_DEFAULT_DOMAIN[];
-extern const char STR_TALK_GOOGLE_COM[];
-extern const char STR_TALKX_L_GOOGLE_COM[];
-extern const char STR_XMPP_GOOGLE_COM[];
-extern const char STR_XMPPX_L_GOOGLE_COM[];
-
-#ifdef FEATURE_ENABLE_VOICEMAIL
-extern const char STR_VOICEMAIL[];
-extern const char STR_OUTGOINGVOICEMAIL[];
-#endif
-
-extern const char STR_UNAVAILABLE[];
-
-extern const char STR_GOOGLE_MUC_LOOKUP_JID[];
-extern const char STR_MUC_ROOMCONFIG_ROOMNAME[];
-extern const char STR_MUC_ROOMCONFIG_FEATURES[];
-extern const char STR_MUC_ROOM_FEATURE_ENTERPRISE[];
-extern const char STR_MUC_ROOMCONFIG[];
-
-extern const StaticQName QN_STREAM_STREAM;
-extern const StaticQName QN_STREAM_FEATURES;
-extern const StaticQName QN_STREAM_ERROR;
-
-extern const StaticQName QN_XSTREAM_BAD_FORMAT;
-extern const StaticQName QN_XSTREAM_BAD_NAMESPACE_PREFIX;
-extern const StaticQName QN_XSTREAM_CONFLICT;
-extern const StaticQName QN_XSTREAM_CONNECTION_TIMEOUT;
-extern const StaticQName QN_XSTREAM_HOST_GONE;
-extern const StaticQName QN_XSTREAM_HOST_UNKNOWN;
-extern const StaticQName QN_XSTREAM_IMPROPER_ADDRESSIING;
-extern const StaticQName QN_XSTREAM_INTERNAL_SERVER_ERROR;
-extern const StaticQName QN_XSTREAM_INVALID_FROM;
-extern const StaticQName QN_XSTREAM_INVALID_ID;
-extern const StaticQName QN_XSTREAM_INVALID_NAMESPACE;
-extern const StaticQName QN_XSTREAM_INVALID_XML;
-extern const StaticQName QN_XSTREAM_NOT_AUTHORIZED;
-extern const StaticQName QN_XSTREAM_POLICY_VIOLATION;
-extern const StaticQName QN_XSTREAM_REMOTE_CONNECTION_FAILED;
-extern const StaticQName QN_XSTREAM_RESOURCE_CONSTRAINT;
-extern const StaticQName QN_XSTREAM_RESTRICTED_XML;
-extern const StaticQName QN_XSTREAM_SEE_OTHER_HOST;
-extern const StaticQName QN_XSTREAM_SYSTEM_SHUTDOWN;
-extern const StaticQName QN_XSTREAM_UNDEFINED_CONDITION;
-extern const StaticQName QN_XSTREAM_UNSUPPORTED_ENCODING;
-extern const StaticQName QN_XSTREAM_UNSUPPORTED_STANZA_TYPE;
-extern const StaticQName QN_XSTREAM_UNSUPPORTED_VERSION;
-extern const StaticQName QN_XSTREAM_XML_NOT_WELL_FORMED;
-extern const StaticQName QN_XSTREAM_TEXT;
-
-extern const StaticQName QN_TLS_STARTTLS;
-extern const StaticQName QN_TLS_REQUIRED;
-extern const StaticQName QN_TLS_PROCEED;
-extern const StaticQName QN_TLS_FAILURE;
-
-extern const StaticQName QN_SASL_MECHANISMS;
-extern const StaticQName QN_SASL_MECHANISM;
-extern const StaticQName QN_SASL_AUTH;
-extern const StaticQName QN_SASL_CHALLENGE;
-extern const StaticQName QN_SASL_RESPONSE;
-extern const StaticQName QN_SASL_ABORT;
-extern const StaticQName QN_SASL_SUCCESS;
-extern const StaticQName QN_SASL_FAILURE;
-extern const StaticQName QN_SASL_ABORTED;
-extern const StaticQName QN_SASL_INCORRECT_ENCODING;
-extern const StaticQName QN_SASL_INVALID_AUTHZID;
-extern const StaticQName QN_SASL_INVALID_MECHANISM;
-extern const StaticQName QN_SASL_MECHANISM_TOO_WEAK;
-extern const StaticQName QN_SASL_NOT_AUTHORIZED;
-extern const StaticQName QN_SASL_TEMPORARY_AUTH_FAILURE;
-
-// These are non-standard.
-extern const char NS_GOOGLE_AUTH[];
-extern const char NS_GOOGLE_AUTH_PROTOCOL[];
-extern const StaticQName QN_GOOGLE_AUTH_CLIENT_USES_FULL_BIND_RESULT;
-extern const StaticQName QN_GOOGLE_ALLOW_NON_GOOGLE_ID_XMPP_LOGIN;
-
-extern const StaticQName QN_DIALBACK_RESULT;
-extern const StaticQName QN_DIALBACK_VERIFY;
-
-extern const StaticQName QN_STANZA_BAD_REQUEST;
-extern const StaticQName QN_STANZA_CONFLICT;
-extern const StaticQName QN_STANZA_FEATURE_NOT_IMPLEMENTED;
-extern const StaticQName QN_STANZA_FORBIDDEN;
-extern const StaticQName QN_STANZA_GONE;
-extern const StaticQName QN_STANZA_INTERNAL_SERVER_ERROR;
-extern const StaticQName QN_STANZA_ITEM_NOT_FOUND;
-extern const StaticQName QN_STANZA_JID_MALFORMED;
-extern const StaticQName QN_STANZA_NOT_ACCEPTABLE;
-extern const StaticQName QN_STANZA_NOT_ALLOWED;
-extern const StaticQName QN_STANZA_PAYMENT_REQUIRED;
-extern const StaticQName QN_STANZA_RECIPIENT_UNAVAILABLE;
-extern const StaticQName QN_STANZA_REDIRECT;
-extern const StaticQName QN_STANZA_REGISTRATION_REQUIRED;
-extern const StaticQName QN_STANZA_REMOTE_SERVER_NOT_FOUND;
-extern const StaticQName QN_STANZA_REMOTE_SERVER_TIMEOUT;
-extern const StaticQName QN_STANZA_RESOURCE_CONSTRAINT;
-extern const StaticQName QN_STANZA_SERVICE_UNAVAILABLE;
-extern const StaticQName QN_STANZA_SUBSCRIPTION_REQUIRED;
-extern const StaticQName QN_STANZA_UNDEFINED_CONDITION;
-extern const StaticQName QN_STANZA_UNEXPECTED_REQUEST;
-extern const StaticQName QN_STANZA_TEXT;
-
-extern const StaticQName QN_BIND_BIND;
-extern const StaticQName QN_BIND_RESOURCE;
-extern const StaticQName QN_BIND_JID;
-
-extern const StaticQName QN_MESSAGE;
-extern const StaticQName QN_BODY;
-extern const StaticQName QN_SUBJECT;
-extern const StaticQName QN_THREAD;
-extern const StaticQName QN_PRESENCE;
-extern const StaticQName QN_SHOW;
-extern const StaticQName QN_STATUS;
-extern const StaticQName QN_LANG;
-extern const StaticQName QN_PRIORITY;
-extern const StaticQName QN_IQ;
-extern const StaticQName QN_ERROR;
-
-extern const StaticQName QN_SERVER_MESSAGE;
-extern const StaticQName QN_SERVER_BODY;
-extern const StaticQName QN_SERVER_SUBJECT;
-extern const StaticQName QN_SERVER_THREAD;
-extern const StaticQName QN_SERVER_PRESENCE;
-extern const StaticQName QN_SERVER_SHOW;
-extern const StaticQName QN_SERVER_STATUS;
-extern const StaticQName QN_SERVER_LANG;
-extern const StaticQName QN_SERVER_PRIORITY;
-extern const StaticQName QN_SERVER_IQ;
-extern const StaticQName QN_SERVER_ERROR;
-
-extern const StaticQName QN_SESSION_SESSION;
-
-extern const StaticQName QN_PRIVACY_QUERY;
-extern const StaticQName QN_PRIVACY_ACTIVE;
-extern const StaticQName QN_PRIVACY_DEFAULT;
-extern const StaticQName QN_PRIVACY_LIST;
-extern const StaticQName QN_PRIVACY_ITEM;
-extern const StaticQName QN_PRIVACY_IQ;
-extern const StaticQName QN_PRIVACY_MESSAGE;
-extern const StaticQName QN_PRIVACY_PRESENCE_IN;
-extern const StaticQName QN_PRIVACY_PRESENCE_OUT;
-
-extern const StaticQName QN_ROSTER_QUERY;
-extern const StaticQName QN_ROSTER_ITEM;
-extern const StaticQName QN_ROSTER_GROUP;
-
-extern const StaticQName QN_VCARD;
-extern const StaticQName QN_VCARD_FN;
-extern const StaticQName QN_VCARD_PHOTO;
-extern const StaticQName QN_VCARD_PHOTO_BINVAL;
-extern const StaticQName QN_VCARD_AVATAR_HASH;
-extern const StaticQName QN_VCARD_AVATAR_HASH_MODIFIED;
-
-#if defined(FEATURE_ENABLE_PSTN)
-extern const StaticQName QN_VCARD_TEL;
-extern const StaticQName QN_VCARD_VOICE;
-extern const StaticQName QN_VCARD_HOME;
-extern const StaticQName QN_VCARD_WORK;
-extern const StaticQName QN_VCARD_CELL;
-extern const StaticQName QN_VCARD_NUMBER;
-#endif
-
-#if defined(FEATURE_ENABLE_RICHPROFILES)
-extern const StaticQName QN_USER_PROFILE_QUERY;
-extern const StaticQName QN_USER_PROFILE_URL;
-
-extern const StaticQName QN_ATOM_FEED;
-extern const StaticQName QN_ATOM_ENTRY;
-extern const StaticQName QN_ATOM_TITLE;
-extern const StaticQName QN_ATOM_ID;
-extern const StaticQName QN_ATOM_MODIFIED;
-extern const StaticQName QN_ATOM_IMAGE;
-extern const StaticQName QN_ATOM_LINK;
-extern const StaticQName QN_ATOM_HREF;
-#endif
-
-extern const StaticQName QN_XML_LANG;
-
-extern const StaticQName QN_ENCODING;
-extern const StaticQName QN_VERSION;
-extern const StaticQName QN_TO;
-extern const StaticQName QN_FROM;
-extern const StaticQName QN_TYPE;
-extern const StaticQName QN_ID;
-extern const StaticQName QN_CODE;
-extern const StaticQName QN_NAME;
-extern const StaticQName QN_VALUE;
-extern const StaticQName QN_ACTION;
-extern const StaticQName QN_ORDER;
-extern const StaticQName QN_MECHANISM;
-extern const StaticQName QN_ASK;
-extern const StaticQName QN_JID;
-extern const StaticQName QN_NICK;
-extern const StaticQName QN_SUBSCRIPTION;
-extern const StaticQName QN_TITLE1;
-extern const StaticQName QN_TITLE2;
-extern const StaticQName QN_AFFILIATION;
-extern const StaticQName QN_ROLE;
-extern const StaticQName QN_TIME;
-
-extern const StaticQName QN_XMLNS_CLIENT;
-extern const StaticQName QN_XMLNS_SERVER;
-extern const StaticQName QN_XMLNS_STREAM;
-
-// Presence
-extern const char STR_SHOW_AWAY[];
-extern const char STR_SHOW_CHAT[];
-extern const char STR_SHOW_DND[];
-extern const char STR_SHOW_XA[];
-extern const char STR_SHOW_OFFLINE[];
-
-// Subscription
-extern const char STR_SUBSCRIBE[];
-extern const char STR_SUBSCRIBED[];
-extern const char STR_UNSUBSCRIBE[];
-extern const char STR_UNSUBSCRIBED[];
-
-// Google Invite
-extern const char NS_GOOGLE_SUBSCRIBE[];
-extern const StaticQName QN_INVITATION;
-extern const StaticQName QN_INVITE_NAME;
-extern const StaticQName QN_INVITE_SUBJECT;
-extern const StaticQName QN_INVITE_MESSAGE;
-
-// PubSub: http://xmpp.org/extensions/xep-0060.html
-extern const char NS_PUBSUB[];
-extern const StaticQName QN_PUBSUB;
-extern const StaticQName QN_PUBSUB_ITEMS;
-extern const StaticQName QN_PUBSUB_ITEM;
-extern const StaticQName QN_PUBSUB_PUBLISH;
-extern const StaticQName QN_PUBSUB_RETRACT;
-extern const StaticQName QN_ATTR_PUBLISHER;
-
-extern const char NS_PUBSUB_EVENT[];
-extern const StaticQName QN_NODE;
-extern const StaticQName QN_PUBSUB_EVENT;
-extern const StaticQName QN_PUBSUB_EVENT_ITEMS;
-extern const StaticQName QN_PUBSUB_EVENT_ITEM;
-extern const StaticQName QN_PUBSUB_EVENT_RETRACT;
-extern const StaticQName QN_NOTIFY;
-
-extern const char NS_PRESENTER[];
-extern const StaticQName QN_PRESENTER_PRESENTER;
-extern const StaticQName QN_PRESENTER_PRESENTATION_ITEM;
-extern const StaticQName QN_PRESENTER_PRESENTATION_TYPE;
-extern const StaticQName QN_PRESENTER_PRESENTATION_ID;
-
-// JEP 0030
-extern const StaticQName QN_CATEGORY;
-extern const StaticQName QN_VAR;
-extern const char NS_DISCO_INFO[];
-extern const char NS_DISCO_ITEMS[];
-
-extern const StaticQName QN_DISCO_INFO_QUERY;
-extern const StaticQName QN_DISCO_IDENTITY;
-extern const StaticQName QN_DISCO_FEATURE;
-
-extern const StaticQName QN_DISCO_ITEMS_QUERY;
-extern const StaticQName QN_DISCO_ITEM;
-
-// JEP 0020
-extern const char NS_FEATURE[];
-extern const StaticQName QN_FEATURE_FEATURE;
-
-// JEP 0004
-extern const char NS_XDATA[];
-extern const StaticQName QN_XDATA_X;
-extern const StaticQName QN_XDATA_INSTRUCTIONS;
-extern const StaticQName QN_XDATA_TITLE;
-extern const StaticQName QN_XDATA_FIELD;
-extern const StaticQName QN_XDATA_REPORTED;
-extern const StaticQName QN_XDATA_ITEM;
-extern const StaticQName QN_XDATA_DESC;
-extern const StaticQName QN_XDATA_REQUIRED;
-extern const StaticQName QN_XDATA_VALUE;
-extern const StaticQName QN_XDATA_OPTION;
-
-// JEP 0045
-extern const char NS_MUC[];
-extern const StaticQName QN_MUC_X;
-extern const StaticQName QN_MUC_ITEM;
-extern const StaticQName QN_MUC_AFFILIATION;
-extern const StaticQName QN_MUC_ROLE;
-extern const char STR_AFFILIATION_NONE[];
-extern const char STR_ROLE_PARTICIPANT[];
-
-extern const char NS_MUC_OWNER[];
-extern const StaticQName QN_MUC_OWNER_QUERY;
-
-extern const char NS_MUC_USER[];
-extern const StaticQName QN_MUC_USER_CONTINUE;
-extern const StaticQName QN_MUC_USER_X;
-extern const StaticQName QN_MUC_USER_ITEM;
-extern const StaticQName QN_MUC_USER_STATUS;
-
-// JEP 0055 - Jabber Search
-extern const char NS_SEARCH[];
-extern const StaticQName QN_SEARCH_QUERY;
-extern const StaticQName QN_SEARCH_ITEM;
-extern const StaticQName QN_SEARCH_ROOM_NAME;
-extern const StaticQName QN_SEARCH_ROOM_JID;
-extern const StaticQName QN_SEARCH_ROOM_DOMAIN;
-
-// JEP 0115
-extern const char NS_CAPS[];
-extern const StaticQName QN_CAPS_C;
-extern const StaticQName QN_VER;
-extern const StaticQName QN_EXT;
-
-
-// Avatar - JEP 0153
-extern const char kNSVCard[];
-extern const StaticQName kQnVCardX;
-extern const StaticQName kQnVCardPhoto;
-
-// JEP 0172 User Nickname
-extern const char NS_NICKNAME[];
-extern const StaticQName QN_NICKNAME;
-
-// JEP 0085 chat state
-extern const char NS_CHATSTATE[];
-extern const StaticQName QN_CS_ACTIVE;
-extern const StaticQName QN_CS_COMPOSING;
-extern const StaticQName QN_CS_PAUSED;
-extern const StaticQName QN_CS_INACTIVE;
-extern const StaticQName QN_CS_GONE;
-
-// JEP 0091 Delayed Delivery
-extern const char kNSDelay[];
-extern const StaticQName kQnDelayX;
-extern const StaticQName kQnStamp;
-
-// Google time stamping (higher resolution)
-extern const char kNSTimestamp[];
-extern const StaticQName kQnTime;
-extern const StaticQName kQnMilliseconds;
-
-extern const char NS_JINGLE_INFO[];
-extern const StaticQName QN_JINGLE_INFO_QUERY;
-extern const StaticQName QN_JINGLE_INFO_STUN;
-extern const StaticQName QN_JINGLE_INFO_RELAY;
-extern const StaticQName QN_JINGLE_INFO_SERVER;
-extern const StaticQName QN_JINGLE_INFO_TOKEN;
-extern const StaticQName QN_JINGLE_INFO_HOST;
-extern const StaticQName QN_JINGLE_INFO_TCP;
-extern const StaticQName QN_JINGLE_INFO_UDP;
-extern const StaticQName QN_JINGLE_INFO_TCPSSL;
-
-extern const char NS_GOOGLE_CALLPERF_STATS[];
-extern const StaticQName QN_CALLPERF_STATS;
-extern const StaticQName QN_CALLPERF_SESSIONID;
-extern const StaticQName QN_CALLPERF_LOCALUSER;
-extern const StaticQName QN_CALLPERF_REMOTEUSER;
-extern const StaticQName QN_CALLPERF_STARTTIME;
-extern const StaticQName QN_CALLPERF_CALL_LENGTH;
-extern const StaticQName QN_CALLPERF_CALL_ACCEPTED;
-extern const StaticQName QN_CALLPERF_CALL_ERROR_CODE;
-extern const StaticQName QN_CALLPERF_TERMINATE_CODE;
-extern const StaticQName QN_CALLPERF_DATAPOINT;
-extern const StaticQName QN_CALLPERF_DATAPOINT_TIME;
-extern const StaticQName QN_CALLPERF_DATAPOINT_FRACTION_LOST;
-extern const StaticQName QN_CALLPERF_DATAPOINT_CUM_LOST;
-extern const StaticQName QN_CALLPERF_DATAPOINT_EXT_MAX;
-extern const StaticQName QN_CALLPERF_DATAPOINT_JITTER;
-extern const StaticQName QN_CALLPERF_DATAPOINT_RTT;
-extern const StaticQName QN_CALLPERF_DATAPOINT_BYTES_R;
-extern const StaticQName QN_CALLPERF_DATAPOINT_PACKETS_R;
-extern const StaticQName QN_CALLPERF_DATAPOINT_BYTES_S;
-extern const StaticQName QN_CALLPERF_DATAPOINT_PACKETS_S;
-extern const StaticQName QN_CALLPERF_DATAPOINT_PROCESS_CPU;
-extern const StaticQName QN_CALLPERF_DATAPOINT_SYSTEM_CPU;
-extern const StaticQName QN_CALLPERF_DATAPOINT_CPUS;
-extern const StaticQName QN_CALLPERF_CONNECTION;
-extern const StaticQName QN_CALLPERF_CONNECTION_LOCAL_ADDRESS;
-extern const StaticQName QN_CALLPERF_CONNECTION_REMOTE_ADDRESS;
-extern const StaticQName QN_CALLPERF_CONNECTION_FLAGS;
-extern const StaticQName QN_CALLPERF_CONNECTION_RTT;
-extern const StaticQName QN_CALLPERF_CONNECTION_TOTAL_BYTES_S;
-extern const StaticQName QN_CALLPERF_CONNECTION_BYTES_SECOND_S;
-extern const StaticQName QN_CALLPERF_CONNECTION_TOTAL_BYTES_R;
-extern const StaticQName QN_CALLPERF_CONNECTION_BYTES_SECOND_R;
-extern const StaticQName QN_CALLPERF_CANDIDATE;
-extern const StaticQName QN_CALLPERF_CANDIDATE_ENDPOINT;
-extern const StaticQName QN_CALLPERF_CANDIDATE_PROTOCOL;
-extern const StaticQName QN_CALLPERF_CANDIDATE_ADDRESS;
-extern const StaticQName QN_CALLPERF_MEDIA;
-extern const StaticQName QN_CALLPERF_MEDIA_DIRECTION;
-extern const StaticQName QN_CALLPERF_MEDIA_SSRC;
-extern const StaticQName QN_CALLPERF_MEDIA_ENERGY;
-extern const StaticQName QN_CALLPERF_MEDIA_FIR;
-extern const StaticQName QN_CALLPERF_MEDIA_NACK;
-extern const StaticQName QN_CALLPERF_MEDIA_FPS;
-extern const StaticQName QN_CALLPERF_MEDIA_FPS_NETWORK;
-extern const StaticQName QN_CALLPERF_MEDIA_FPS_DECODED;
-extern const StaticQName QN_CALLPERF_MEDIA_JITTER_BUFFER_SIZE;
-extern const StaticQName QN_CALLPERF_MEDIA_PREFERRED_JITTER_BUFFER_SIZE;
-extern const StaticQName QN_CALLPERF_MEDIA_TOTAL_PLAYOUT_DELAY;
-
-// Muc invites.
-extern const StaticQName QN_MUC_USER_INVITE;
-
-// Multiway audio/video.
-extern const char NS_GOOGLE_MUC_USER[];
-extern const StaticQName QN_GOOGLE_MUC_USER_AVAILABLE_MEDIA;
-extern const StaticQName QN_GOOGLE_MUC_USER_ENTRY;
-extern const StaticQName QN_GOOGLE_MUC_USER_MEDIA;
-extern const StaticQName QN_GOOGLE_MUC_USER_TYPE;
-extern const StaticQName QN_GOOGLE_MUC_USER_SRC_ID;
-extern const StaticQName QN_GOOGLE_MUC_USER_STATUS;
-extern const StaticQName QN_LABEL;
-
-extern const char NS_GOOGLE_MUC_MEDIA[];
-extern const StaticQName QN_GOOGLE_MUC_AUDIO_MUTE;
-extern const StaticQName QN_GOOGLE_MUC_VIDEO_MUTE;
-extern const StaticQName QN_GOOGLE_MUC_RECORDING;
-extern const StaticQName QN_GOOGLE_MUC_MEDIA_BLOCK;
-extern const StaticQName QN_STATE_ATTR;
-
-}  // namespace buzz
-
-#endif  // TALK_XMPP_CONSTANTS_H_
diff --git a/third_party/libjingle/source/talk/xmpp/fakexmppclient.h b/third_party/libjingle/source/talk/xmpp/fakexmppclient.h
deleted file mode 100644
index 83b8e82..0000000
--- a/third_party/libjingle/source/talk/xmpp/fakexmppclient.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * libjingle
- * Copyright 2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// A fake XmppClient for use in unit tests.
-
-#ifndef TALK_XMPP_FAKEXMPPCLIENT_H_
-#define TALK_XMPP_FAKEXMPPCLIENT_H_
-
-#include <string>
-#include <vector>
-
-#include "talk/xmpp/xmpptask.h"
-
-namespace buzz {
-
-class XmlElement;
-
-class FakeXmppClient : public XmppTaskParentInterface,
-                       public XmppClientInterface {
- public:
-  explicit FakeXmppClient(talk_base::TaskParent* parent)
-      : XmppTaskParentInterface(parent) {
-  }
-
-  // As XmppTaskParentInterface
-  virtual XmppClientInterface* GetClient() {
-    return this;
-  }
-
-  virtual int ProcessStart() {
-    return STATE_RESPONSE;
-  }
-
-  // As XmppClientInterface
-  virtual XmppEngine::State GetState() const {
-    return XmppEngine::STATE_OPEN;
-  }
-
-  virtual const Jid& jid() const {
-    return jid_;
-  }
-
-  virtual std::string NextId() {
-    // Implement if needed for tests.
-    return "0";
-  }
-
-  virtual XmppReturnStatus SendStanza(const XmlElement* stanza) {
-    sent_stanzas_.push_back(stanza);
-    return XMPP_RETURN_OK;
-  }
-
-  const std::vector<const XmlElement*>& sent_stanzas() {
-    return sent_stanzas_;
-  }
-
-  virtual XmppReturnStatus SendStanzaError(
-      const XmlElement * pelOriginal,
-      XmppStanzaError code,
-      const std::string & text) {
-    // Implement if needed for tests.
-    return XMPP_RETURN_OK;
-  }
-
-  virtual void AddXmppTask(XmppTask* task,
-                           XmppEngine::HandlerLevel level) {
-    tasks_.push_back(task);
-  }
-
-  virtual void RemoveXmppTask(XmppTask* task) {
-    std::remove(tasks_.begin(), tasks_.end(), task);
-  }
-
-  // As FakeXmppClient
-  void set_jid(const Jid& jid) {
-    jid_ = jid;
-  }
-
-  // Takes ownership of stanza.
-  void HandleStanza(XmlElement* stanza) {
-    for (std::vector<XmppTask*>::iterator task = tasks_.begin();
-         task != tasks_.end(); ++task) {
-      if ((*task)->HandleStanza(stanza)) {
-        delete stanza;
-        return;
-      }
-    }
-    delete stanza;
-  }
-
- private:
-  Jid jid_;
-  std::vector<XmppTask*> tasks_;
-  std::vector<const XmlElement*> sent_stanzas_;
-};
-
-}  // namespace buzz
-
-#endif  // TALK_XMPP_FAKEXMPPCLIENT_H_
diff --git a/third_party/libjingle/source/talk/xmpp/hangoutpubsubclient.cc b/third_party/libjingle/source/talk/xmpp/hangoutpubsubclient.cc
deleted file mode 100644
index c99b1a6..0000000
--- a/third_party/libjingle/source/talk/xmpp/hangoutpubsubclient.cc
+++ /dev/null
@@ -1,571 +0,0 @@
-/*
- * libjingle
- * Copyright 2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/xmpp/hangoutpubsubclient.h"
-
-#include "talk/base/logging.h"
-#include "talk/xmpp/constants.h"
-#include "talk/xmpp/jid.h"
-#include "talk/xmllite/qname.h"
-#include "talk/xmllite/xmlelement.h"
-
-
-// Gives a high-level API for MUC call PubSub needs such as
-// presenter state, recording state, mute state, and remote mute.
-
-namespace buzz {
-
-namespace {
-const char kPresenting[] = "s";
-const char kNotPresenting[] = "o";
-const char kEmpty[] = "";
-
-const std::string GetPublisherNickFromPubSubItem(const XmlElement* item_elem) {
-  if (item_elem == NULL) {
-    return "";
-  }
-
-  return Jid(item_elem->Attr(QN_ATTR_PUBLISHER)).resource();
-}
-
-}  // namespace
-
-
-// Knows how to handle specific states and XML.
-template <typename C>
-class PubSubStateSerializer {
- public:
-  virtual ~PubSubStateSerializer() {}
-  virtual XmlElement* Write(const QName& state_name, const C& state) = 0;
-  virtual C Parse(const XmlElement* state_elem) = 0;
-};
-
-// Knows how to create "keys" for states, which determines their
-// uniqueness.  Most states are per-nick, but block is
-// per-blocker-and-blockee.  This is independent of itemid, especially
-// in the case of presenter state.
-class PubSubStateKeySerializer {
- public:
-  virtual ~PubSubStateKeySerializer() {}
-  virtual std::string GetKey(const std::string& publisher_nick,
-                             const std::string& published_nick) = 0;
-};
-
-class PublishedNickKeySerializer : public PubSubStateKeySerializer {
- public:
-  virtual std::string GetKey(const std::string& publisher_nick,
-                             const std::string& published_nick) {
-    return published_nick;
-  }
-};
-
-class PublisherAndPublishedNicksKeySerializer
-    : public PubSubStateKeySerializer {
- public:
-  virtual std::string GetKey(const std::string& publisher_nick,
-                             const std::string& published_nick) {
-    return publisher_nick + ":" + published_nick;
-  }
-};
-
-// A simple serialiazer where presence of item => true, lack of item
-// => false.
-class BoolStateSerializer : public PubSubStateSerializer<bool> {
-  virtual XmlElement* Write(const QName& state_name, const bool& state) {
-    if (!state) {
-      return NULL;
-    }
-
-    return new XmlElement(state_name, true);
-  }
-
-  virtual bool Parse(const XmlElement* state_elem) {
-    return state_elem != NULL;
-  }
-};
-
-// Adapts PubSubClient to be specifically suited for pub sub call
-// states.  Signals state changes and keeps track of keys, which are
-// normally nicks.
-// TODO: Expose this as a generally useful class, not just
-// private to hangouts.
-template <typename C>
-class PubSubStateClient : public sigslot::has_slots<> {
- public:
-  // Gets ownership of the serializers, but not the client.
-  PubSubStateClient(const std::string& publisher_nick,
-                    PubSubClient* client,
-                    const QName& state_name,
-                    C default_state,
-                    PubSubStateKeySerializer* key_serializer,
-                    PubSubStateSerializer<C>* state_serializer)
-      : publisher_nick_(publisher_nick),
-        client_(client),
-        state_name_(state_name),
-        default_state_(default_state) {
-    key_serializer_.reset(key_serializer);
-    state_serializer_.reset(state_serializer);
-    client_->SignalItems.connect(
-        this, &PubSubStateClient<C>::OnItems);
-    client_->SignalPublishResult.connect(
-        this, &PubSubStateClient<C>::OnPublishResult);
-    client_->SignalPublishError.connect(
-        this, &PubSubStateClient<C>::OnPublishError);
-    client_->SignalRetractResult.connect(
-        this, &PubSubStateClient<C>::OnRetractResult);
-    client_->SignalRetractError.connect(
-        this, &PubSubStateClient<C>::OnRetractError);
-  }
-
-  virtual ~PubSubStateClient() {}
-
-  virtual void Publish(const std::string& published_nick,
-                       const C& state,
-                       std::string* task_id_out) {
-    std::string key = key_serializer_->GetKey(publisher_nick_, published_nick);
-    std::string itemid = state_name_.LocalPart() + ":" + key;
-    if (StatesEqual(state, default_state_)) {
-      client_->RetractItem(itemid, task_id_out);
-    } else {
-      XmlElement* state_elem = state_serializer_->Write(state_name_, state);
-      state_elem->AddAttr(QN_NICK, published_nick);
-      client_->PublishItem(itemid, state_elem, task_id_out);
-    }
-  };
-
-  sigslot::signal1<const PubSubStateChange<C>&> SignalStateChange;
-  // Signal (task_id, item).  item is NULL for retract.
-  sigslot::signal2<const std::string&,
-                   const XmlElement*> SignalPublishResult;
-  // Signal (task_id, item, error stanza).  item is NULL for retract.
-  sigslot::signal3<const std::string&,
-                   const XmlElement*,
-                   const XmlElement*> SignalPublishError;
-
- protected:
-  // return false if retracted item (no info or state given)
-  virtual bool ParseStateItem(const PubSubItem& item,
-                              StateItemInfo* info_out,
-                              bool* state_out) {
-    const XmlElement* state_elem = item.elem->FirstNamed(state_name_);
-    if (state_elem == NULL) {
-      return false;
-    }
-
-    info_out->publisher_nick = GetPublisherNickFromPubSubItem(item.elem);
-    info_out->published_nick = state_elem->Attr(QN_NICK);
-    *state_out = state_serializer_->Parse(state_elem);
-    return true;
-  };
-
-  virtual bool StatesEqual(C state1, C state2) {
-    return state1 == state2;
-  }
-
-  PubSubClient* client() { return client_; }
-
- private:
-  void OnItems(PubSubClient* pub_sub_client,
-               const std::vector<PubSubItem>& items) {
-    for (std::vector<PubSubItem>::const_iterator item = items.begin();
-         item != items.end(); ++item) {
-      OnItem(*item);
-    }
-  }
-
-  void OnItem(const PubSubItem& item) {
-    const std::string& itemid = item.itemid;
-    StateItemInfo info;
-    C new_state;
-
-    bool retracted = !ParseStateItem(item, &info, &new_state);
-    if (retracted) {
-      bool known_itemid =
-          (info_by_itemid_.find(itemid) != info_by_itemid_.end());
-      if (!known_itemid) {
-        // Nothing to retract, and nothing to publish.
-        // Probably a different state type.
-        return;
-      } else {
-        info = info_by_itemid_[itemid];
-        info_by_itemid_.erase(itemid);
-        new_state = default_state_;
-      }
-    } else {
-      // TODO: Assert new key matches the known key. It
-      // shouldn't change!
-      info_by_itemid_[itemid] = info;
-    }
-
-    std::string key = key_serializer_->GetKey(
-        info.publisher_nick, info.published_nick);
-    bool has_old_state = (state_by_key_.find(key) != state_by_key_.end());
-    const C& old_state = has_old_state ? state_by_key_[key] : default_state_;
-    if ((retracted && !has_old_state) || StatesEqual(new_state, old_state)) {
-      // Nothing change, so don't bother signalling.
-      return;
-    }
-
-    if (retracted || StatesEqual(new_state, default_state_)) {
-      // We treat a default state similar to a retract.
-      state_by_key_.erase(key);
-    } else {
-      state_by_key_[key] = new_state;
-    }
-
-    PubSubStateChange<C> change;
-    change.publisher_nick = info.publisher_nick;
-    change.published_nick = info.published_nick;
-    change.old_state = old_state;
-    change.new_state = new_state;
-    SignalStateChange(change);
- }
-
-  void OnPublishResult(PubSubClient* pub_sub_client,
-                       const std::string& task_id,
-                       const XmlElement* item) {
-    SignalPublishResult(task_id, item);
-  }
-
-  void OnPublishError(PubSubClient* pub_sub_client,
-                      const std::string& task_id,
-                      const buzz::XmlElement* item,
-                      const buzz::XmlElement* stanza) {
-    SignalPublishError(task_id, item, stanza);
-  }
-
-  void OnRetractResult(PubSubClient* pub_sub_client,
-                       const std::string& task_id) {
-    // There's no point in differentiating between publish and retract
-    // errors, so we simplify by making them both signal a publish
-    // result.
-    const XmlElement* item = NULL;
-    SignalPublishResult(task_id, item);
-  }
-
-  void OnRetractError(PubSubClient* pub_sub_client,
-                      const std::string& task_id,
-                      const buzz::XmlElement* stanza) {
-    // There's no point in differentiating between publish and retract
-    // errors, so we simplify by making them both signal a publish
-    // error.
-    const XmlElement* item = NULL;
-    SignalPublishError(task_id, item, stanza);
-  }
-
-  std::string publisher_nick_;
-  PubSubClient* client_;
-  const QName state_name_;
-  C default_state_;
-  talk_base::scoped_ptr<PubSubStateKeySerializer> key_serializer_;
-  talk_base::scoped_ptr<PubSubStateSerializer<C> > state_serializer_;
-  // key => state
-  std::map<std::string, C> state_by_key_;
-  // itemid => StateItemInfo
-  std::map<std::string, StateItemInfo> info_by_itemid_;
-};
-
-class PresenterStateClient : public PubSubStateClient<bool> {
- public:
-  PresenterStateClient(const std::string& publisher_nick,
-                       PubSubClient* client,
-                       const QName& state_name,
-                       bool default_state)
-      : PubSubStateClient<bool>(
-          publisher_nick, client, state_name, default_state,
-          new PublishedNickKeySerializer(), NULL) {
-  }
-
-  virtual void Publish(const std::string& published_nick,
-                       const bool& state,
-                       std::string* task_id_out) {
-    XmlElement* presenter_elem = new XmlElement(QN_PRESENTER_PRESENTER, true);
-    // There's a dummy value, not used, but required.
-    presenter_elem->AddAttr(QN_JID, "dummy@value.net");
-    presenter_elem->AddAttr(QN_NICK, published_nick);
-
-    XmlElement* presentation_item_elem =
-        new XmlElement(QN_PRESENTER_PRESENTATION_ITEM, false);
-    const std::string& presentation_type = state ? kPresenting : kNotPresenting;
-    presentation_item_elem->AddAttr(
-        QN_PRESENTER_PRESENTATION_TYPE, presentation_type);
-
-    // The Presenter state is kind of dumb in that it doesn't use
-    // retracts.  It relies on setting the "type" to a special value.
-    std::string itemid = published_nick;
-    std::vector<XmlElement*> children;
-    children.push_back(presenter_elem);
-    children.push_back(presentation_item_elem);
-    client()->PublishItem(itemid, children, task_id_out);
-  }
-
- protected:
-  virtual bool ParseStateItem(const PubSubItem& item,
-                              StateItemInfo* info_out,
-                              bool* state_out) {
-    const XmlElement* presenter_elem =
-        item.elem->FirstNamed(QN_PRESENTER_PRESENTER);
-    const XmlElement* presentation_item_elem =
-        item.elem->FirstNamed(QN_PRESENTER_PRESENTATION_ITEM);
-    if (presentation_item_elem == NULL || presenter_elem == NULL) {
-      return false;
-    }
-
-    info_out->publisher_nick = GetPublisherNickFromPubSubItem(item.elem);
-    info_out->published_nick = presenter_elem->Attr(QN_NICK);
-    *state_out = (presentation_item_elem->Attr(
-        QN_PRESENTER_PRESENTATION_TYPE) != kNotPresenting);
-    return true;
-  }
-};
-
-HangoutPubSubClient::HangoutPubSubClient(XmppTaskParentInterface* parent,
-                                         const Jid& mucjid,
-                                         const std::string& nick)
-    : mucjid_(mucjid),
-      nick_(nick) {
-  presenter_client_.reset(new PubSubClient(parent, mucjid, NS_PRESENTER));
-  presenter_client_->SignalRequestError.connect(
-      this, &HangoutPubSubClient::OnPresenterRequestError);
-
-  media_client_.reset(new PubSubClient(parent, mucjid, NS_GOOGLE_MUC_MEDIA));
-  media_client_->SignalRequestError.connect(
-      this, &HangoutPubSubClient::OnMediaRequestError);
-
-  presenter_state_client_.reset(new PresenterStateClient(
-      nick_, presenter_client_.get(), QN_PRESENTER_PRESENTER, false));
-  presenter_state_client_->SignalStateChange.connect(
-      this, &HangoutPubSubClient::OnPresenterStateChange);
-  presenter_state_client_->SignalPublishResult.connect(
-      this, &HangoutPubSubClient::OnPresenterPublishResult);
-  presenter_state_client_->SignalPublishError.connect(
-      this, &HangoutPubSubClient::OnPresenterPublishError);
-
-  audio_mute_state_client_.reset(new PubSubStateClient<bool>(
-      nick_, media_client_.get(), QN_GOOGLE_MUC_AUDIO_MUTE, false,
-      new PublishedNickKeySerializer(), new BoolStateSerializer()));
-  // Can't just repeat because we need to watch for remote mutes.
-  audio_mute_state_client_->SignalStateChange.connect(
-      this, &HangoutPubSubClient::OnAudioMuteStateChange);
-  audio_mute_state_client_->SignalPublishResult.connect(
-      this, &HangoutPubSubClient::OnAudioMutePublishResult);
-  audio_mute_state_client_->SignalPublishError.connect(
-      this, &HangoutPubSubClient::OnAudioMutePublishError);
-
-  recording_state_client_.reset(new PubSubStateClient<bool>(
-      nick_, media_client_.get(), QN_GOOGLE_MUC_RECORDING, false,
-      new PublishedNickKeySerializer(), new BoolStateSerializer()));
-  recording_state_client_->SignalStateChange.connect(
-      this, &HangoutPubSubClient::OnRecordingStateChange);
-  recording_state_client_->SignalPublishResult.connect(
-      this, &HangoutPubSubClient::OnRecordingPublishResult);
-  recording_state_client_->SignalPublishError.connect(
-      this, &HangoutPubSubClient::OnRecordingPublishError);
-
-  media_block_state_client_.reset(new PubSubStateClient<bool>(
-      nick_, media_client_.get(), QN_GOOGLE_MUC_MEDIA_BLOCK, false,
-      new PublisherAndPublishedNicksKeySerializer(),
-      new BoolStateSerializer()));
-  media_block_state_client_->SignalStateChange.connect(
-      this, &HangoutPubSubClient::OnMediaBlockStateChange);
-  media_block_state_client_->SignalPublishResult.connect(
-      this, &HangoutPubSubClient::OnMediaBlockPublishResult);
-  media_block_state_client_->SignalPublishError.connect(
-      this, &HangoutPubSubClient::OnMediaBlockPublishError);
-}
-
-HangoutPubSubClient::~HangoutPubSubClient() {
-}
-
-void HangoutPubSubClient::RequestAll() {
-  presenter_client_->RequestItems();
-  media_client_->RequestItems();
-}
-
-void HangoutPubSubClient::OnPresenterRequestError(
-    PubSubClient* client, const XmlElement* stanza) {
-  SignalRequestError(client->node(), stanza);
-}
-
-void HangoutPubSubClient::OnMediaRequestError(
-    PubSubClient* client, const XmlElement* stanza) {
-  SignalRequestError(client->node(), stanza);
-}
-
-void HangoutPubSubClient::PublishPresenterState(
-    bool presenting, std::string* task_id_out) {
-  presenter_state_client_->Publish(nick_, presenting, task_id_out);
-}
-
-void HangoutPubSubClient::PublishAudioMuteState(
-    bool muted, std::string* task_id_out) {
-  audio_mute_state_client_->Publish(nick_, muted, task_id_out);
-}
-
-void HangoutPubSubClient::PublishRecordingState(
-    bool recording, std::string* task_id_out) {
-  recording_state_client_->Publish(nick_, recording, task_id_out);
-}
-
-// Remote mute is accomplished by setting another client's mute state.
-void HangoutPubSubClient::RemoteMute(
-    const std::string& mutee_nick, std::string* task_id_out) {
-  audio_mute_state_client_->Publish(mutee_nick, true, task_id_out);
-}
-
-// Block media is accomplished by setting another client's block
-// state, kind of like remote mute.
-void HangoutPubSubClient::BlockMedia(
-    const std::string& blockee_nick, std::string* task_id_out) {
-  media_block_state_client_->Publish(blockee_nick, true, task_id_out);
-}
-
-void HangoutPubSubClient::OnPresenterStateChange(
-    const PubSubStateChange<bool>& change) {
-  SignalPresenterStateChange(
-      change.published_nick, change.old_state, change.new_state);
-}
-
-void HangoutPubSubClient::OnPresenterPublishResult(
-    const std::string& task_id, const XmlElement* item) {
-  SignalPublishPresenterResult(task_id);
-}
-
-void HangoutPubSubClient::OnPresenterPublishError(
-    const std::string& task_id, const XmlElement* item,
-    const XmlElement* stanza) {
-  SignalPublishPresenterError(task_id, stanza);
-}
-
-// Since a remote mute is accomplished by another client setting our
-// mute state, if our state changes to muted, we should mute
-// ourselves.  Note that we never remote un-mute, though.
-void HangoutPubSubClient::OnAudioMuteStateChange(
-    const PubSubStateChange<bool>& change) {
-  bool was_muted = change.old_state;
-  bool is_muted = change.new_state;
-  bool remote_action = (!change.publisher_nick.empty() &&
-                        (change.publisher_nick != change.published_nick));
-  if (is_muted && remote_action) {
-    const std::string& mutee_nick = change.published_nick;
-    const std::string& muter_nick = change.publisher_nick;
-    bool should_mute_locally = (mutee_nick == nick_);
-    SignalRemoteMute(mutee_nick, muter_nick, should_mute_locally);
-  } else {
-    SignalAudioMuteStateChange(change.published_nick, was_muted, is_muted);
-  }
-}
-
-const std::string& GetAudioMuteNickFromItem(const XmlElement* item) {
-  if (item != NULL) {
-    const XmlElement* audio_mute_state =
-        item->FirstNamed(QN_GOOGLE_MUC_AUDIO_MUTE);
-    if (audio_mute_state != NULL) {
-      return audio_mute_state->Attr(QN_NICK);
-    }
-  }
-  return EmptyStringRef();
-}
-
-const std::string GetBlockeeNickFromItem(const XmlElement* item) {
-  if (item != NULL) {
-    const XmlElement* media_block_state =
-        item->FirstNamed(QN_GOOGLE_MUC_MEDIA_BLOCK);
-    if (media_block_state != NULL) {
-      return media_block_state->Attr(QN_NICK);
-    }
-  }
-  return "";
-}
-
-void HangoutPubSubClient::OnAudioMutePublishResult(
-    const std::string& task_id, const XmlElement* item) {
-  const std::string& mutee_nick = GetAudioMuteNickFromItem(item);
-  if (mutee_nick != nick_) {
-    SignalRemoteMuteResult(task_id, mutee_nick);
-  } else {
-    SignalPublishAudioMuteResult(task_id);
-  }
-}
-
-void HangoutPubSubClient::OnAudioMutePublishError(
-    const std::string& task_id, const XmlElement* item,
-    const XmlElement* stanza) {
-  const std::string& mutee_nick = GetAudioMuteNickFromItem(item);
-  if (mutee_nick != nick_) {
-    SignalRemoteMuteError(task_id, mutee_nick, stanza);
-  } else {
-    SignalPublishAudioMuteError(task_id, stanza);
-  }
-}
-
-void HangoutPubSubClient::OnRecordingStateChange(
-    const PubSubStateChange<bool>& change) {
-  SignalRecordingStateChange(
-      change.published_nick, change.old_state, change.new_state);
-}
-
-void HangoutPubSubClient::OnRecordingPublishResult(
-    const std::string& task_id, const XmlElement* item) {
-  SignalPublishRecordingResult(task_id);
-}
-
-void HangoutPubSubClient::OnRecordingPublishError(
-    const std::string& task_id, const XmlElement* item,
-    const XmlElement* stanza) {
-  SignalPublishRecordingError(task_id, stanza);
-}
-
-void HangoutPubSubClient::OnMediaBlockStateChange(
-    const PubSubStateChange<bool>& change) {
-  const std::string& blockee_nick = change.published_nick;
-  const std::string& blocker_nick = change.publisher_nick;
-
-  bool was_blockee = change.old_state;
-  bool is_blockee = change.new_state;
-  if (!was_blockee && is_blockee) {
-    SignalMediaBlock(blockee_nick, blocker_nick);
-  }
-  // TODO: Should we bother signaling unblock? Currently
-  // it isn't allowed, but it might happen when a participant leaves
-  // the room and the item is retracted.
-}
-
-void HangoutPubSubClient::OnMediaBlockPublishResult(
-    const std::string& task_id, const XmlElement* item) {
-  const std::string& blockee_nick = GetBlockeeNickFromItem(item);
-  SignalMediaBlockResult(task_id, blockee_nick);
-}
-
-void HangoutPubSubClient::OnMediaBlockPublishError(
-    const std::string& task_id, const XmlElement* item,
-    const XmlElement* stanza) {
-  const std::string& blockee_nick = GetBlockeeNickFromItem(item);
-  SignalMediaBlockError(task_id, blockee_nick, stanza);
-}
-
-}  // namespace buzz
diff --git a/third_party/libjingle/source/talk/xmpp/hangoutpubsubclient.h b/third_party/libjingle/source/talk/xmpp/hangoutpubsubclient.h
deleted file mode 100644
index ae9dc57..0000000
--- a/third_party/libjingle/source/talk/xmpp/hangoutpubsubclient.h
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * libjingle
- * Copyright 2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_XMPP_HANGOUTPUBSUBCLIENT_H_
-#define TALK_XMPP_HANGOUTPUBSUBCLIENT_H_
-
-#include <map>
-#include <string>
-#include <vector>
-
-#include "talk/base/scoped_ptr.h"
-#include "talk/base/sigslot.h"
-#include "talk/base/sigslotrepeater.h"
-#include "talk/xmpp/jid.h"
-#include "talk/xmpp/pubsubclient.h"
-
-// Gives a high-level API for MUC call PubSub needs such as
-// presenter state, recording state, mute state, and remote mute.
-
-namespace buzz {
-
-class Jid;
-class XmlElement;
-class XmppTaskParentInterface;
-
-// To handle retracts correctly, we need to remember certain details
-// about an item.  We could just cache the entire XML element, but
-// that would take more memory and require re-parsing.
-struct StateItemInfo {
-  std::string published_nick;
-  std::string publisher_nick;
-};
-
-// Represents a PubSub state change.  Usually, the key is the nick,
-// but not always.  It's a per-state-type thing.  Currently documented
-// at https://docs.google.com/a/google.com/document/d/
-// 1QyHu_ufyVdf0VICdfc_DtJbrOdrdIUm4eM73RZqnivI/edit?hl=en_US
-template <typename C>
-struct PubSubStateChange {
-  // The nick of the user changing the state.
-  std::string publisher_nick;
-  // The nick of the user whose state is changing.
-  std::string published_nick;
-  C old_state;
-  C new_state;
-};
-
-template <typename C> class PubSubStateClient;
-
-// A client tied to a specific MUC jid and local nick.  Provides ways
-// to get updates and publish state and events.  Must call
-// RequestAll() to start getting updates.
-class HangoutPubSubClient : public sigslot::has_slots<> {
- public:
-  HangoutPubSubClient(XmppTaskParentInterface* parent,
-                      const Jid& mucjid,
-                      const std::string& nick);
-  ~HangoutPubSubClient();
-  const Jid& mucjid() const { return mucjid_; }
-  const std::string& nick() const { return nick_; }
-
-  // Requests all of the different states and subscribes for updates.
-  // Responses and updates will be signalled via the various signals.
-  void RequestAll();
-  // Signal (nick, was_presenting, is_presenting)
-  sigslot::signal3<const std::string&, bool, bool> SignalPresenterStateChange;
-  // Signal (nick, was_muted, is_muted)
-  sigslot::signal3<const std::string&, bool, bool> SignalAudioMuteStateChange;
-  // Signal (nick, was_recording, is_recording)
-  sigslot::signal3<const std::string&, bool, bool> SignalRecordingStateChange;
-  // Signal (mutee_nick, muter_nick, should_mute_locally)
-  sigslot::signal3<const std::string&,
-                   const std::string&,
-                   bool> SignalRemoteMute;
-  // Signal (blockee_nick, blocker_nick)
-  sigslot::signal2<const std::string&, const std::string&> SignalMediaBlock;
-
-  // Signal (node, error stanza)
-  sigslot::signal2<const std::string&, const XmlElement*> SignalRequestError;
-
-  // On each of these, provide a task_id_out to get the task_id, which
-  // can be correlated to the error and result signals.
-  void PublishPresenterState(
-      bool presenting, std::string* task_id_out = NULL);
-  void PublishAudioMuteState(
-      bool muted, std::string* task_id_out = NULL);
-  void PublishRecordingState(
-      bool recording, std::string* task_id_out = NULL);
-  void RemoteMute(
-      const std::string& mutee_nick, std::string* task_id_out = NULL);
-  void BlockMedia(
-      const std::string& blockee_nick, std::string* task_id_out = NULL);
-
-  // Signal task_id
-  sigslot::signal1<const std::string&> SignalPublishAudioMuteResult;
-  sigslot::signal1<const std::string&> SignalPublishPresenterResult;
-  sigslot::signal1<const std::string&> SignalPublishRecordingResult;
-  // Signal (task_id, mutee_nick)
-  sigslot::signal2<const std::string&,
-                   const std::string&> SignalRemoteMuteResult;
-  // Signal (task_id, blockee_nick)
-  sigslot::signal2<const std::string&,
-                   const std::string&> SignalMediaBlockResult;
-
-  // Signal (task_id, error stanza)
-  sigslot::signal2<const std::string&,
-                   const XmlElement*> SignalPublishAudioMuteError;
-  sigslot::signal2<const std::string&,
-                   const XmlElement*> SignalPublishPresenterError;
-  sigslot::signal2<const std::string&,
-                   const XmlElement*> SignalPublishRecordingError;
-  sigslot::signal2<const std::string&,
-                   const XmlElement*> SignalPublishMediaBlockError;
-  // Signal (task_id, mutee_nick, error stanza)
-  sigslot::signal3<const std::string&,
-                   const std::string&,
-                   const XmlElement*> SignalRemoteMuteError;
-  // Signal (task_id, blockee_nick, error stanza)
-  sigslot::signal3<const std::string&,
-                   const std::string&,
-                   const XmlElement*> SignalMediaBlockError;
-
-
- private:
-  void OnPresenterRequestError(PubSubClient* client,
-                               const XmlElement* stanza);
-  void OnMediaRequestError(PubSubClient* client,
-                           const XmlElement* stanza);
-
-  void OnPresenterStateChange(const PubSubStateChange<bool>& change);
-  void OnPresenterPublishResult(const std::string& task_id,
-                               const XmlElement* item);
-  void OnPresenterPublishError(const std::string& task_id,
-                               const XmlElement* item,
-                               const XmlElement* stanza);
-  void OnAudioMuteStateChange(const PubSubStateChange<bool>& change);
-  void OnAudioMutePublishResult(const std::string& task_id,
-                               const XmlElement* item);
-  void OnAudioMutePublishError(const std::string& task_id,
-                               const XmlElement* item,
-                               const XmlElement* stanza);
-  void OnRecordingStateChange(const PubSubStateChange<bool>& change);
-  void OnRecordingPublishResult(const std::string& task_id,
-                               const XmlElement* item);
-  void OnRecordingPublishError(const std::string& task_id,
-                               const XmlElement* item,
-                               const XmlElement* stanza);
-  void OnMediaBlockStateChange(const PubSubStateChange<bool>& change);
-  void OnMediaBlockPublishResult(const std::string& task_id,
-                                 const XmlElement* item);
-  void OnMediaBlockPublishError(const std::string& task_id,
-                                const XmlElement* item,
-                                const XmlElement* stanza);
-  Jid mucjid_;
-  std::string nick_;
-  talk_base::scoped_ptr<PubSubClient> media_client_;
-  talk_base::scoped_ptr<PubSubClient> presenter_client_;
-  talk_base::scoped_ptr<PubSubStateClient<bool> > presenter_state_client_;
-  talk_base::scoped_ptr<PubSubStateClient<bool> > audio_mute_state_client_;
-  talk_base::scoped_ptr<PubSubStateClient<bool> > recording_state_client_;
-  talk_base::scoped_ptr<PubSubStateClient<bool> > media_block_state_client_;
-};
-
-}  // namespace buzz
-
-#endif  // TALK_XMPP_HANGOUTPUBSUBCLIENT_H_
diff --git a/third_party/libjingle/source/talk/xmpp/hangoutpubsubclient_unittest.cc b/third_party/libjingle/source/talk/xmpp/hangoutpubsubclient_unittest.cc
deleted file mode 100644
index f994992..0000000
--- a/third_party/libjingle/source/talk/xmpp/hangoutpubsubclient_unittest.cc
+++ /dev/null
@@ -1,619 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved
-
-
-#include <string>
-
-#include "talk/base/faketaskrunner.h"
-#include "talk/base/gunit.h"
-#include "talk/base/sigslot.h"
-#include "talk/xmllite/qname.h"
-#include "talk/xmllite/xmlelement.h"
-#include "talk/xmpp/constants.h"
-#include "talk/xmpp/jid.h"
-#include "talk/xmpp/fakexmppclient.h"
-#include "talk/xmpp/hangoutpubsubclient.h"
-
-class TestHangoutPubSubListener : public sigslot::has_slots<> {
- public:
-  TestHangoutPubSubListener() :
-      request_error_count(0),
-      publish_audio_mute_error_count(0),
-      publish_presenter_error_count(0),
-      publish_recording_error_count(0),
-      remote_mute_error_count(0) {
-  }
-
-  void OnPresenterStateChange(
-      const std::string& nick, bool was_presenting, bool is_presenting) {
-    last_presenter_nick = nick;
-    last_was_presenting = was_presenting;
-    last_is_presenting = is_presenting;
-  }
-
-  void OnAudioMuteStateChange(
-      const std::string& nick, bool was_muted, bool is_muted) {
-    last_audio_muted_nick = nick;
-    last_was_audio_muted = was_muted;
-    last_is_audio_muted = is_muted;
-  }
-
-  void OnRecordingStateChange(
-      const std::string& nick, bool was_recording, bool is_recording) {
-    last_recording_nick = nick;
-    last_was_recording = was_recording;
-    last_is_recording = is_recording;
-  }
-
-  void OnRemoteMute(
-      const std::string& mutee_nick,
-      const std::string& muter_nick,
-      bool should_mute_locally) {
-    last_mutee_nick = mutee_nick;
-    last_muter_nick = muter_nick;
-    last_should_mute = should_mute_locally;
-  }
-
-  void OnMediaBlock(
-      const std::string& blockee_nick,
-      const std::string& blocker_nick) {
-    last_blockee_nick = blockee_nick;
-    last_blocker_nick = blocker_nick;
-  }
-
-  void OnRequestError(const std::string& node, const buzz::XmlElement* stanza) {
-    ++request_error_count;
-    request_error_node = node;
-  }
-
-  void OnPublishAudioMuteError(const std::string& task_id,
-                               const buzz::XmlElement* stanza) {
-    ++publish_audio_mute_error_count;
-    error_task_id = task_id;
-  }
-
-  void OnPublishPresenterError(const std::string& task_id,
-                               const buzz::XmlElement* stanza) {
-    ++publish_presenter_error_count;
-    error_task_id = task_id;
-  }
-
-  void OnPublishRecordingError(const std::string& task_id,
-                               const buzz::XmlElement* stanza) {
-    ++publish_recording_error_count;
-    error_task_id = task_id;
-  }
-
-  void OnRemoteMuteResult(const std::string& task_id,
-                          const std::string& mutee_nick) {
-    result_task_id = task_id;
-    remote_mute_mutee_nick = mutee_nick;
-  }
-
-  void OnRemoteMuteError(const std::string& task_id,
-                         const std::string& mutee_nick,
-                         const buzz::XmlElement* stanza) {
-    ++remote_mute_error_count;
-    error_task_id = task_id;
-    remote_mute_mutee_nick = mutee_nick;
-  }
-
-  void OnMediaBlockResult(const std::string& task_id,
-                          const std::string& blockee_nick) {
-    result_task_id = task_id;
-    media_blockee_nick = blockee_nick;
-  }
-
-  void OnMediaBlockError(const std::string& task_id,
-                         const std::string& blockee_nick,
-                         const buzz::XmlElement* stanza) {
-    ++media_block_error_count;
-    error_task_id = task_id;
-    media_blockee_nick = blockee_nick;
-  }
-
-  std::string last_presenter_nick;
-  bool last_is_presenting;
-  bool last_was_presenting;
-  std::string last_audio_muted_nick;
-  bool last_is_audio_muted;
-  bool last_was_audio_muted;
-  std::string last_recording_nick;
-  bool last_is_recording;
-  bool last_was_recording;
-  std::string last_mutee_nick;
-  std::string last_muter_nick;
-  bool last_should_mute;
-  std::string last_blockee_nick;
-  std::string last_blocker_nick;
-
-  int request_error_count;
-  std::string request_error_node;
-  int publish_audio_mute_error_count;
-  int publish_presenter_error_count;
-  int publish_recording_error_count;
-  int remote_mute_error_count;
-  std::string result_task_id;
-  std::string error_task_id;
-  std::string remote_mute_mutee_nick;
-  int media_block_error_count;
-  std::string media_blockee_nick;
-};
-
-class HangoutPubSubClientTest : public testing::Test {
- public:
-  HangoutPubSubClientTest() :
-      pubsubjid("room@domain.com"),
-      nick("me") {
-
-    runner.reset(new talk_base::FakeTaskRunner());
-    xmpp_client = new buzz::FakeXmppClient(runner.get());
-    client.reset(new buzz::HangoutPubSubClient(xmpp_client, pubsubjid, nick));
-    listener.reset(new TestHangoutPubSubListener());
-    client->SignalPresenterStateChange.connect(
-        listener.get(), &TestHangoutPubSubListener::OnPresenterStateChange);
-    client->SignalAudioMuteStateChange.connect(
-        listener.get(), &TestHangoutPubSubListener::OnAudioMuteStateChange);
-    client->SignalRecordingStateChange.connect(
-        listener.get(), &TestHangoutPubSubListener::OnRecordingStateChange);
-    client->SignalRemoteMute.connect(
-        listener.get(), &TestHangoutPubSubListener::OnRemoteMute);
-    client->SignalMediaBlock.connect(
-        listener.get(), &TestHangoutPubSubListener::OnMediaBlock);
-    client->SignalRequestError.connect(
-        listener.get(), &TestHangoutPubSubListener::OnRequestError);
-    client->SignalPublishAudioMuteError.connect(
-        listener.get(), &TestHangoutPubSubListener::OnPublishAudioMuteError);
-    client->SignalPublishPresenterError.connect(
-        listener.get(), &TestHangoutPubSubListener::OnPublishPresenterError);
-    client->SignalPublishRecordingError.connect(
-        listener.get(), &TestHangoutPubSubListener::OnPublishRecordingError);
-    client->SignalRemoteMuteResult.connect(
-        listener.get(), &TestHangoutPubSubListener::OnRemoteMuteResult);
-    client->SignalRemoteMuteError.connect(
-        listener.get(), &TestHangoutPubSubListener::OnRemoteMuteError);
-    client->SignalMediaBlockResult.connect(
-        listener.get(), &TestHangoutPubSubListener::OnMediaBlockResult);
-    client->SignalMediaBlockError.connect(
-        listener.get(), &TestHangoutPubSubListener::OnMediaBlockError);
-  }
-
-  talk_base::scoped_ptr<talk_base::FakeTaskRunner> runner;
-  // xmpp_client deleted by deleting runner.
-  buzz::FakeXmppClient* xmpp_client;
-  talk_base::scoped_ptr<buzz::HangoutPubSubClient> client;
-  talk_base::scoped_ptr<TestHangoutPubSubListener> listener;
-  buzz::Jid pubsubjid;
-  std::string nick;
-};
-
-TEST_F(HangoutPubSubClientTest, TestRequest) {
-  ASSERT_EQ(0U, xmpp_client->sent_stanzas().size());
-
-  client->RequestAll();
-  std::string expected_presenter_request =
-      "<cli:iq type=\"get\" to=\"room@domain.com\" id=\"0\" "
-        "xmlns:cli=\"jabber:client\">"
-        "<pub:pubsub xmlns:pub=\"http://jabber.org/protocol/pubsub\">"
-          "<pub:items node=\"google:presenter\"/>"
-        "</pub:pubsub>"
-      "</cli:iq>";
-
-  std::string expected_media_request =
-      "<cli:iq type=\"get\" to=\"room@domain.com\" id=\"0\" "
-        "xmlns:cli=\"jabber:client\">"
-        "<pub:pubsub xmlns:pub=\"http://jabber.org/protocol/pubsub\">"
-          "<pub:items node=\"google:muc#media\"/>"
-        "</pub:pubsub>"
-      "</cli:iq>";
-
-  ASSERT_EQ(2U, xmpp_client->sent_stanzas().size());
-  EXPECT_EQ(expected_presenter_request, xmpp_client->sent_stanzas()[0]->Str());
-  EXPECT_EQ(expected_media_request, xmpp_client->sent_stanzas()[1]->Str());
-
-  std::string presenter_response =
-      "<iq xmlns='jabber:client' id='0' type='result' from='room@domain.com'>"
-      "  <pubsub xmlns='http://jabber.org/protocol/pubsub'>"
-      "    <items node='google:presenter'>"
-      "      <item id='12345'>"
-      "        <presenter xmlns='google:presenter' nick='presenting-nick'/>"
-      "        <pre:presentation-item xmlns:pre='google:presenter'"
-      "          pre:presentation-type='o'/>"
-      "      </item>"
-      // Some clients are "bad" in that they'll jam multiple states in
-      // all at once.  We have to deal with it.
-      "      <item id='12346'>"
-      "        <presenter xmlns='google:presenter' nick='presenting-nick'/>"
-      "        <pre:presentation-item xmlns:pre='google:presenter'"
-      "          pre:presentation-type='s'/>"
-      "      </item>"
-      "      <item id='12347'>"
-      "        <presenter xmlns='google:presenter' nick='presenting-nick2'/>"
-      "        <pre:presentation-item xmlns:pre='google:presenter'"
-      "          pre:presentation-type='s'/>"
-      "      </item>"
-      "    </items>"
-      "  </pubsub>"
-      "</iq>";
-
-  xmpp_client->HandleStanza(buzz::XmlElement::ForStr(presenter_response));
-  EXPECT_EQ("presenting-nick2", listener->last_presenter_nick);
-  EXPECT_FALSE(listener->last_was_presenting);
-  EXPECT_TRUE(listener->last_is_presenting);
-
-  std::string media_response =
-      "<iq xmlns='jabber:client' id='0' type='result' from='room@domain.com'>"
-      "  <pubsub xmlns='http://jabber.org/protocol/pubsub'>"
-      "    <items node='google:muc#media'>"
-      "      <item id='audio-mute:muted-nick'>"
-      "        <audio-mute nick='muted-nick' xmlns='google:muc#media'/>"
-      "      </item>"
-      "      <item id='recording:recording-nick'>"
-      "        <recording nick='recording-nick' xmlns='google:muc#media'/>"
-      "      </item>"
-      "    </items>"
-      "  </pubsub>"
-      "</iq>";
-
-  xmpp_client->HandleStanza(buzz::XmlElement::ForStr(media_response));
-  EXPECT_EQ("muted-nick", listener->last_audio_muted_nick);
-  EXPECT_FALSE(listener->last_was_audio_muted);
-  EXPECT_TRUE(listener->last_is_audio_muted);
-  EXPECT_EQ("recording-nick", listener->last_recording_nick);
-  EXPECT_FALSE(listener->last_was_recording);
-  EXPECT_TRUE(listener->last_is_recording);
-
-  std::string incoming_presenter_resets_message =
-      "<message xmlns='jabber:client' from='room@domain.com'>"
-      "  <event xmlns='http://jabber.org/protocol/pubsub#event'>"
-      "    <items node='google:presenter'>"
-      "      <item id='12348'>"
-      "        <presenter xmlns='google:presenter' nick='presenting-nick'/>"
-      "        <pre:presentation-item xmlns:pre='google:presenter'"
-      "          pre:presentation-type='o'/>"
-      "      </item>"
-      "    </items>"
-      "  </event>"
-      "</message>";
-
-  xmpp_client->HandleStanza(
-      buzz::XmlElement::ForStr(incoming_presenter_resets_message));
-  EXPECT_EQ("presenting-nick", listener->last_presenter_nick);
-  EXPECT_TRUE(listener->last_was_presenting);
-  EXPECT_FALSE(listener->last_is_presenting);
-
-  std::string incoming_presenter_retracts_message =
-      "<message xmlns='jabber:client' from='room@domain.com'>"
-      "  <event xmlns='http://jabber.org/protocol/pubsub#event'>"
-      "    <items node='google:presenter'>"
-      "      <retract id='12347'/>"
-      "    </items>"
-      "  </event>"
-      "</message>";
-
-  xmpp_client->HandleStanza(
-      buzz::XmlElement::ForStr(incoming_presenter_retracts_message));
-  EXPECT_EQ("presenting-nick2", listener->last_presenter_nick);
-  EXPECT_TRUE(listener->last_was_presenting);
-  EXPECT_FALSE(listener->last_is_presenting);
-
-  std::string incoming_media_retracts_message =
-      "<message xmlns='jabber:client' from='room@domain.com'>"
-      "  <event xmlns='http://jabber.org/protocol/pubsub#event'>"
-      "    <items node='google:muc#media'>"
-      "      <item id='audio-mute:muted-nick'>"
-      "      </item>"
-      "      <retract id='recording:recording-nick'/>"
-      "    </items>"
-      "  </event>"
-      "</message>";
-
-  xmpp_client->HandleStanza(
-      buzz::XmlElement::ForStr(incoming_media_retracts_message));
-  EXPECT_EQ("muted-nick", listener->last_audio_muted_nick);
-  EXPECT_TRUE(listener->last_was_audio_muted);
-  EXPECT_FALSE(listener->last_is_audio_muted);
-  EXPECT_EQ("recording-nick", listener->last_recording_nick);
-  EXPECT_TRUE(listener->last_was_recording);
-  EXPECT_FALSE(listener->last_is_recording);
-
-  std::string incoming_presenter_changes_message =
-      "<message xmlns='jabber:client' from='room@domain.com'>"
-      "  <event xmlns='http://jabber.org/protocol/pubsub#event'>"
-      "    <items node='google:presenter'>"
-      "      <item id='presenting-nick2'>"
-      "        <presenter xmlns='google:presenter' nick='presenting-nick2'/>"
-      "        <pre:presentation-item xmlns:pre='google:presenter'"
-      "          pre:presentation-type='s'/>"
-      "      </item>"
-      "    </items>"
-      "  </event>"
-      "</message>";
-
-  xmpp_client->HandleStanza(
-      buzz::XmlElement::ForStr(incoming_presenter_changes_message));
-  EXPECT_EQ("presenting-nick2", listener->last_presenter_nick);
-  EXPECT_FALSE(listener->last_was_presenting);
-  EXPECT_TRUE(listener->last_is_presenting);
-
-  std::string incoming_media_changes_message =
-      "<message xmlns='jabber:client' from='room@domain.com'>"
-      "  <event xmlns='http://jabber.org/protocol/pubsub#event'>"
-      "    <items node='google:muc#media'>"
-      "      <item id='audio-mute:muted-nick2'>"
-      "        <audio-mute nick='muted-nick2' xmlns='google:muc#media'/>"
-      "      </item>"
-      "      <item id='recording:recording-nick2'>"
-      "        <recording nick='recording-nick2' xmlns='google:muc#media'/>"
-      "      </item>"
-      "    </items>"
-      "  </event>"
-      "</message>";
-
-  xmpp_client->HandleStanza(
-      buzz::XmlElement::ForStr(incoming_media_changes_message));
-  EXPECT_EQ("muted-nick2", listener->last_audio_muted_nick);
-  EXPECT_FALSE(listener->last_was_audio_muted);
-  EXPECT_TRUE(listener->last_is_audio_muted);
-  EXPECT_EQ("recording-nick2", listener->last_recording_nick);
-  EXPECT_FALSE(listener->last_was_recording);
-  EXPECT_TRUE(listener->last_is_recording);
-
-  std::string incoming_remote_mute_message =
-      "<message xmlns='jabber:client' from='room@domain.com'>"
-      "  <event xmlns='http://jabber.org/protocol/pubsub#event'>"
-      "    <items node='google:muc#media'>"
-      "      <item id='audio-mute:mutee' publisher='room@domain.com/muter'>"
-      "        <audio-mute nick='mutee' xmlns='google:muc#media'/>"
-      "      </item>"
-      "    </items>"
-      "  </event>"
-      "</message>";
-
-  xmpp_client->HandleStanza(
-      buzz::XmlElement::ForStr(incoming_remote_mute_message));
-  EXPECT_EQ("mutee", listener->last_mutee_nick);
-  EXPECT_EQ("muter", listener->last_muter_nick);
-  EXPECT_FALSE(listener->last_should_mute);
-
-  std::string incoming_remote_mute_me_message =
-      "<message xmlns='jabber:client' from='room@domain.com'>"
-      "  <event xmlns='http://jabber.org/protocol/pubsub#event'>"
-      "    <items node='google:muc#media'>"
-      "      <item id='audio-mute:me' publisher='room@domain.com/muter'>"
-      "        <audio-mute nick='me' xmlns='google:muc#media'/>"
-      "      </item>"
-      "    </items>"
-      "  </event>"
-      "</message>";
-
-  xmpp_client->HandleStanza(
-      buzz::XmlElement::ForStr(incoming_remote_mute_me_message));
-  EXPECT_EQ("me", listener->last_mutee_nick);
-  EXPECT_EQ("muter", listener->last_muter_nick);
-  EXPECT_TRUE(listener->last_should_mute);
-
-  std::string incoming_media_block_message =
-      "<message xmlns='jabber:client' from='room@domain.com'>"
-      "  <event xmlns='http://jabber.org/protocol/pubsub#event'>"
-      "    <items node='google:muc#media'>"
-      "      <item id='block:blocker:blockee'"
-      "            publisher='room@domain.com/blocker'>"
-      "        <block nick='blockee' xmlns='google:muc#media'/>"
-      "      </item>"
-      "    </items>"
-      "  </event>"
-      "</message>";
-
-  xmpp_client->HandleStanza(
-      buzz::XmlElement::ForStr(incoming_media_block_message));
-  EXPECT_EQ("blockee", listener->last_blockee_nick);
-  EXPECT_EQ("blocker", listener->last_blocker_nick);
-}
-
-TEST_F(HangoutPubSubClientTest, TestRequestError) {
-  client->RequestAll();
-  std::string result_iq =
-      "<iq xmlns='jabber:client' id='0' type='error' from='room@domain.com'>"
-      "  <error type='auth'>"
-      "    <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>"
-      "  </error>"
-      "</iq>";
-
-  xmpp_client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
-  EXPECT_EQ(1, listener->request_error_count);
-  EXPECT_EQ("google:presenter", listener->request_error_node);
-}
-
-TEST_F(HangoutPubSubClientTest, TestPublish) {
-  client->PublishPresenterState(true);
-  std::string expected_presenter_iq =
-      "<cli:iq type=\"set\" to=\"room@domain.com\" id=\"0\" "
-        "xmlns:cli=\"jabber:client\">"
-        "<pubsub xmlns=\"http://jabber.org/protocol/pubsub\">"
-          "<publish node=\"google:presenter\">"
-            "<item id=\"me\">"
-              "<presenter xmlns=\"google:presenter\""
-              " jid=\"dummy@value.net\" nick=\"me\"/>"
-              "<pre:presentation-item"
-              " pre:presentation-type=\"s\" xmlns:pre=\"google:presenter\"/>"
-            "</item>"
-          "</publish>"
-        "</pubsub>"
-      "</cli:iq>";
-
-  ASSERT_EQ(1U, xmpp_client->sent_stanzas().size());
-  EXPECT_EQ(expected_presenter_iq,
-            xmpp_client->sent_stanzas()[0]->Str());
-
-  client->PublishAudioMuteState(true);
-  std::string expected_audio_mute_iq =
-      "<cli:iq type=\"set\" to=\"room@domain.com\" id=\"0\" "
-        "xmlns:cli=\"jabber:client\">"
-        "<pubsub xmlns=\"http://jabber.org/protocol/pubsub\">"
-          "<publish node=\"google:muc#media\">"
-            "<item id=\"audio-mute:me\">"
-              "<audio-mute xmlns=\"google:muc#media\" nick=\"me\"/>"
-            "</item>"
-          "</publish>"
-        "</pubsub>"
-      "</cli:iq>";
-
-  ASSERT_EQ(2U, xmpp_client->sent_stanzas().size());
-  EXPECT_EQ(expected_audio_mute_iq, xmpp_client->sent_stanzas()[1]->Str());
-
-  client->PublishRecordingState(true);
-  std::string expected_recording_iq =
-      "<cli:iq type=\"set\" to=\"room@domain.com\" id=\"0\" "
-        "xmlns:cli=\"jabber:client\">"
-        "<pubsub xmlns=\"http://jabber.org/protocol/pubsub\">"
-          "<publish node=\"google:muc#media\">"
-            "<item id=\"recording:me\">"
-              "<recording xmlns=\"google:muc#media\" nick=\"me\"/>"
-            "</item>"
-          "</publish>"
-        "</pubsub>"
-      "</cli:iq>";
-
-  ASSERT_EQ(3U, xmpp_client->sent_stanzas().size());
-  EXPECT_EQ(expected_recording_iq, xmpp_client->sent_stanzas()[2]->Str());
-
-  client->RemoteMute("mutee");
-  std::string expected_remote_mute_iq =
-      "<cli:iq type=\"set\" to=\"room@domain.com\" id=\"0\" "
-        "xmlns:cli=\"jabber:client\">"
-        "<pubsub xmlns=\"http://jabber.org/protocol/pubsub\">"
-          "<publish node=\"google:muc#media\">"
-            "<item id=\"audio-mute:mutee\">"
-              "<audio-mute xmlns=\"google:muc#media\" nick=\"mutee\"/>"
-            "</item>"
-          "</publish>"
-        "</pubsub>"
-      "</cli:iq>";
-
-  ASSERT_EQ(4U, xmpp_client->sent_stanzas().size());
-  EXPECT_EQ(expected_remote_mute_iq, xmpp_client->sent_stanzas()[3]->Str());
-
-  client->PublishPresenterState(false);
-  std::string expected_presenter_retract_iq =
-      "<cli:iq type=\"set\" to=\"room@domain.com\" id=\"0\" "
-        "xmlns:cli=\"jabber:client\">"
-        "<pubsub xmlns=\"http://jabber.org/protocol/pubsub\">"
-          "<publish node=\"google:presenter\">"
-            "<item id=\"me\">"
-              "<presenter xmlns=\"google:presenter\""
-              " jid=\"dummy@value.net\" nick=\"me\"/>"
-              "<pre:presentation-item"
-              " pre:presentation-type=\"o\" xmlns:pre=\"google:presenter\"/>"
-            "</item>"
-          "</publish>"
-        "</pubsub>"
-      "</cli:iq>";
-
-  ASSERT_EQ(5U, xmpp_client->sent_stanzas().size());
-  EXPECT_EQ(expected_presenter_retract_iq,
-            xmpp_client->sent_stanzas()[4]->Str());
-
-  client->PublishAudioMuteState(false);
-  std::string expected_audio_mute_retract_iq =
-      "<cli:iq type=\"set\" to=\"room@domain.com\" id=\"0\" "
-        "xmlns:cli=\"jabber:client\">"
-        "<pubsub xmlns=\"http://jabber.org/protocol/pubsub\">"
-          "<retract node=\"google:muc#media\" notify=\"true\">"
-            "<item id=\"audio-mute:me\"/>"
-          "</retract>"
-        "</pubsub>"
-      "</cli:iq>";
-
-  ASSERT_EQ(6U, xmpp_client->sent_stanzas().size());
-  EXPECT_EQ(expected_audio_mute_retract_iq,
-            xmpp_client->sent_stanzas()[5]->Str());
-
-  client->BlockMedia("blockee");
-  std::string expected_media_block_iq =
-      "<cli:iq type=\"set\" to=\"room@domain.com\" id=\"0\" "
-        "xmlns:cli=\"jabber:client\">"
-        "<pubsub xmlns=\"http://jabber.org/protocol/pubsub\">"
-          "<publish node=\"google:muc#media\">"
-            "<item id=\"block:me:blockee\">"
-              "<block xmlns=\"google:muc#media\" nick=\"blockee\"/>"
-            "</item>"
-          "</publish>"
-        "</pubsub>"
-      "</cli:iq>";
-
-  ASSERT_EQ(7U, xmpp_client->sent_stanzas().size());
-  EXPECT_EQ(expected_media_block_iq, xmpp_client->sent_stanzas()[6]->Str());
-}
-
-TEST_F(HangoutPubSubClientTest, TestPublishPresenterError) {
-  std::string result_iq =
-      "<iq xmlns='jabber:client' id='0' type='error' from='room@domain.com'/>";
-
-  client->PublishPresenterState(true);
-  xmpp_client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
-  EXPECT_EQ(1, listener->publish_presenter_error_count);
-  EXPECT_EQ("0", listener->error_task_id);
-}
-
-
-TEST_F(HangoutPubSubClientTest, TestPublishAudioMuteError) {
-  std::string result_iq =
-      "<iq xmlns='jabber:client' id='0' type='error' from='room@domain.com'/>";
-
-  client->PublishAudioMuteState(true);
-  xmpp_client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
-  EXPECT_EQ(1, listener->publish_audio_mute_error_count);
-  EXPECT_EQ("0", listener->error_task_id);
-}
-
-TEST_F(HangoutPubSubClientTest, TestPublishRecordingError) {
-  std::string result_iq =
-      "<iq xmlns='jabber:client' id='0' type='error' from='room@domain.com'/>";
-
-  client->PublishRecordingState(true);
-  xmpp_client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
-  EXPECT_EQ(1, listener->publish_recording_error_count);
-  EXPECT_EQ("0", listener->error_task_id);
-}
-
-TEST_F(HangoutPubSubClientTest, TestPublishRemoteMuteResult) {
-  std::string result_iq =
-      "<iq xmlns='jabber:client' id='0' type='result' from='room@domain.com'/>";
-
-  client->RemoteMute("joe");
-  xmpp_client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
-  EXPECT_EQ("joe", listener->remote_mute_mutee_nick);
-  EXPECT_EQ("0", listener->result_task_id);
-}
-
-TEST_F(HangoutPubSubClientTest, TestRemoteMuteError) {
-  std::string result_iq =
-      "<iq xmlns='jabber:client' id='0' type='error' from='room@domain.com'/>";
-
-  client->RemoteMute("joe");
-  xmpp_client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
-  EXPECT_EQ(1, listener->remote_mute_error_count);
-  EXPECT_EQ("joe", listener->remote_mute_mutee_nick);
-  EXPECT_EQ("0", listener->error_task_id);
-}
-
-TEST_F(HangoutPubSubClientTest, TestPublishMediaBlockResult) {
-  std::string result_iq =
-      "<iq xmlns='jabber:client' id='0' type='result' from='room@domain.com'/>";
-
-  client->BlockMedia("joe");
-  xmpp_client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
-  EXPECT_EQ("joe", listener->media_blockee_nick);
-  EXPECT_EQ("0", listener->result_task_id);
-}
-
-TEST_F(HangoutPubSubClientTest, TestMediaBlockError) {
-  std::string result_iq =
-      "<iq xmlns='jabber:client' id='0' type='error' from='room@domain.com'/>";
-
-  client->BlockMedia("joe");
-  xmpp_client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
-  EXPECT_EQ(1, listener->remote_mute_error_count);
-  EXPECT_EQ("joe", listener->media_blockee_nick);
-  EXPECT_EQ("0", listener->error_task_id);
-}
diff --git a/third_party/libjingle/source/talk/xmpp/iqtask.cc b/third_party/libjingle/source/talk/xmpp/iqtask.cc
deleted file mode 100644
index f54f630..0000000
--- a/third_party/libjingle/source/talk/xmpp/iqtask.cc
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * libjingle
- * Copyright 2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/xmpp/iqtask.h"
-
-#include "talk/xmpp/xmppclient.h"
-#include "talk/xmpp/constants.h"
-
-namespace buzz {
-
-static const int kDefaultIqTimeoutSecs = 15;
-
-IqTask::IqTask(XmppTaskParentInterface* parent,
-               const std::string& verb,
-               const buzz::Jid& to,
-               buzz::XmlElement* el)
-    : buzz::XmppTask(parent, buzz::XmppEngine::HL_SINGLE),
-      to_(to),
-      stanza_(MakeIq(verb, to_, task_id())) {
-  stanza_->AddElement(el);
-  set_timeout_seconds(kDefaultIqTimeoutSecs);
-}
-
-int IqTask::ProcessStart() {
-  buzz::XmppReturnStatus ret = SendStanza(stanza_.get());
-  // TODO: HandleError(NULL) if SendStanza fails?
-  return (ret == buzz::XMPP_RETURN_OK) ? STATE_RESPONSE : STATE_ERROR;
-}
-
-bool IqTask::HandleStanza(const buzz::XmlElement* stanza) {
-  if (!MatchResponseIq(stanza, to_, task_id()))
-    return false;
-
-  if (stanza->Attr(buzz::QN_TYPE) != buzz::STR_RESULT &&
-      stanza->Attr(buzz::QN_TYPE) != buzz::STR_ERROR) {
-    return false;
-  }
-
-  QueueStanza(stanza);
-  return true;
-}
-
-int IqTask::ProcessResponse() {
-  const buzz::XmlElement* stanza = NextStanza();
-  if (stanza == NULL)
-    return STATE_BLOCKED;
-
-  bool success = (stanza->Attr(buzz::QN_TYPE) == buzz::STR_RESULT);
-  if (success) {
-    HandleResult(stanza);
-  } else {
-    SignalError(this, stanza->FirstNamed(QN_ERROR));
-  }
-  return STATE_DONE;
-}
-
-int IqTask::OnTimeout() {
-  SignalError(this, NULL);
-  return XmppTask::OnTimeout();
-}
-
-}  // namespace buzz
diff --git a/third_party/libjingle/source/talk/xmpp/iqtask.h b/third_party/libjingle/source/talk/xmpp/iqtask.h
deleted file mode 100644
index 2228e6f..0000000
--- a/third_party/libjingle/source/talk/xmpp/iqtask.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * libjingle
- * Copyright 2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_XMPP_IQTASK_H_
-#define TALK_XMPP_IQTASK_H_
-
-#include <string>
-
-#include "talk/xmpp/xmpptask.h"
-#include "talk/xmpp/xmppengine.h"
-
-namespace buzz {
-
-class IqTask : public XmppTask {
- public:
-  IqTask(XmppTaskParentInterface* parent,
-         const std::string& verb, const Jid& to,
-         XmlElement* el);
-  virtual ~IqTask() {}
-
-  const XmlElement* stanza() const { return stanza_.get(); }
-
-  sigslot::signal2<IqTask*,
-                   const XmlElement*> SignalError;
-
- protected:
-  virtual void HandleResult(const XmlElement* element) = 0;
-
- private:
-  virtual int ProcessStart();
-  virtual bool HandleStanza(const XmlElement* stanza);
-  virtual int ProcessResponse();
-  virtual int OnTimeout();
-
-  Jid to_;
-  talk_base::scoped_ptr<XmlElement> stanza_;
-};
-
-}  // namespace buzz
-
-#endif  // TALK_XMPP_IQTASK_H_
diff --git a/third_party/libjingle/source/talk/xmpp/jid.cc b/third_party/libjingle/source/talk/xmpp/jid.cc
deleted file mode 100644
index 67bcc0a..0000000
--- a/third_party/libjingle/source/talk/xmpp/jid.cc
+++ /dev/null
@@ -1,510 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/xmpp/jid.h"
-
-#include <ctype.h>
-
-#include <algorithm>
-#include <string>
-
-#include "talk/base/common.h"
-#include "talk/base/logging.h"
-#include "talk/xmpp/constants.h"
-
-namespace buzz {
-
-Jid::Jid() : data_(NULL) {
-}
-
-Jid::Jid(bool is_special, const std::string & special) {
-  data_ = is_special ? new Data(special, STR_EMPTY, STR_EMPTY) : NULL;
-}
-
-Jid::Jid(const std::string & jid_string) {
-  if (jid_string.empty()) {
-    data_ = NULL;
-    return;
-  }
-
-  // First find the slash and slice off that part
-  size_t slash = jid_string.find('/');
-  std::string resource_name = (slash == std::string::npos ? STR_EMPTY :
-                    jid_string.substr(slash + 1));
-
-  // Now look for the node
-  std::string node_name;
-  size_t at = jid_string.find('@');
-  size_t domain_begin;
-  if (at < slash && at != std::string::npos) {
-    node_name = jid_string.substr(0, at);
-    domain_begin = at + 1;
-  } else {
-    domain_begin = 0;
-  }
-
-  // Now take what is left as the domain
-  size_t domain_length =
-    (  slash == std::string::npos
-     ? jid_string.length() - domain_begin
-     : slash - domain_begin);
-
-  // avoid allocating these constants repeatedly
-  std::string domain_name;
-
-  if (domain_length == 9  && jid_string.find("gmail.com", domain_begin) == domain_begin) {
-    domain_name = STR_GMAIL_COM;
-  }
-  else if (domain_length == 14 && jid_string.find("googlemail.com", domain_begin) == domain_begin) {
-    domain_name = STR_GOOGLEMAIL_COM;
-  }
-  else if (domain_length == 10 && jid_string.find("google.com", domain_begin) == domain_begin) {
-    domain_name = STR_GOOGLE_COM;
-  }
-  else {
-    domain_name = jid_string.substr(domain_begin, domain_length);
-  }
-
-  // If the domain is empty we have a non-valid jid and we should empty
-  // everything else out
-  if (domain_name.empty()) {
-    data_ = NULL;
-    return;
-  }
-
-  bool valid_node;
-  std::string validated_node = prepNode(node_name,
-      node_name.begin(), node_name.end(), &valid_node);
-  bool valid_domain;
-  std::string validated_domain = prepDomain(domain_name,
-      domain_name.begin(), domain_name.end(), &valid_domain);
-  bool valid_resource;
-  std::string validated_resource = prepResource(resource_name,
-      resource_name.begin(), resource_name.end(), &valid_resource);
-
-  if (!valid_node || !valid_domain || !valid_resource) {
-    data_ = NULL;
-    return;
-  }
-
-  data_ = new Data(validated_node, validated_domain, validated_resource);
-}
-
-Jid::Jid(const std::string & node_name,
-         const std::string & domain_name,
-         const std::string & resource_name) {
-  if (domain_name.empty()) {
-    data_ = NULL;
-    return;
-  }
-
-  bool valid_node;
-  std::string validated_node = prepNode(node_name,
-      node_name.begin(), node_name.end(), &valid_node);
-  bool valid_domain;
-  std::string validated_domain = prepDomain(domain_name,
-      domain_name.begin(), domain_name.end(), &valid_domain);
-  bool valid_resource;
-  std::string validated_resource = prepResource(resource_name,
-      resource_name.begin(), resource_name.end(), &valid_resource);
-
-  if (!valid_node || !valid_domain || !valid_resource) {
-    data_ = NULL;
-    return;
-  }
-
-  data_ = new Data(validated_node, validated_domain, validated_resource);
-}
-
-std::string Jid::Str() const {
-  if (!IsValid())
-    return STR_EMPTY;
-
-  std::string ret;
-
-  if (!data_->node_name_.empty())
-    ret = data_->node_name_ + "@";
-
-  ASSERT(data_->domain_name_ != STR_EMPTY);
-  ret += data_->domain_name_;
-
-  if (!data_->resource_name_.empty())
-    ret += "/" + data_->resource_name_;
-
-  return ret;
-}
-
-bool
-Jid::IsEmpty() const {
-  return data_ == NULL ||
-      (data_->node_name_.empty() && data_->domain_name_.empty() &&
-       data_->resource_name_.empty());
-}
-
-bool
-Jid::IsValid() const {
-  return data_ != NULL && !data_->domain_name_.empty();
-}
-
-bool
-Jid::IsBare() const {
-  if (IsEmpty()) {
-    LOG(LS_VERBOSE) << "Warning: Calling IsBare() on the empty jid";
-    return true;
-  }
-  return IsValid() &&
-         data_->resource_name_.empty();
-}
-
-bool
-Jid::IsFull() const {
-  return IsValid() &&
-         !data_->resource_name_.empty();
-}
-
-Jid
-Jid::BareJid() const {
-  if (!IsValid())
-    return Jid();
-  if (!IsFull())
-    return *this;
-  return Jid(data_->node_name_, data_->domain_name_, STR_EMPTY);
-}
-
-#if 0
-void
-Jid::set_node(const std::string & node_name) {
-    data_->node_name_ = node_name;
-}
-void
-Jid::set_domain(const std::string & domain_name) {
-    data_->domain_name_ = domain_name;
-}
-void
-Jid::set_resource(const std::string & res_name) {
-    data_->resource_name_ = res_name;
-}
-#endif
-
-bool
-Jid::BareEquals(const Jid & other) const {
-  return (other.data_ == data_ ||
-          (data_ != NULL &&
-          other.data_ != NULL &&
-          other.data_->node_name_ == data_->node_name_ &&
-          other.data_->domain_name_ == data_->domain_name_));
-}
-
-bool
-Jid::operator==(const Jid & other) const {
-  return (other.data_ == data_ ||
-          (data_ != NULL &&
-          other.data_ != NULL &&
-          other.data_->node_name_ == data_->node_name_ &&
-          other.data_->domain_name_ == data_->domain_name_ &&
-          other.data_->resource_name_ == data_->resource_name_));
-}
-
-int
-Jid::Compare(const Jid & other) const {
-  if (other.data_ == data_)
-    return 0;
-  if (data_ == NULL)
-    return -1;
-  if (other.data_ == NULL)
-    return 1;
-
-  int compare_result;
-  compare_result = data_->node_name_.compare(other.data_->node_name_);
-  if (0 != compare_result)
-    return compare_result;
-  compare_result = data_->domain_name_.compare(other.data_->domain_name_);
-  if (0 != compare_result)
-    return compare_result;
-  compare_result = data_->resource_name_.compare(other.data_->resource_name_);
-  return compare_result;
-}
-
-uint32 Jid::ComputeLameHash() const {
-  uint32 hash = 0;
-  // Hash the node portion
-  {
-    const std::string &str = node();
-    for (int i = 0; i < static_cast<int>(str.size()); ++i) {
-      hash = ((hash << 2) + hash) + str[i];
-    }
-  }
-
-  // Hash the domain portion
-  {
-    const std::string &str = domain();
-    for (int i = 0; i < static_cast<int>(str.size()); ++i)
-      hash = ((hash << 2) + hash) + str[i];
-  }
-
-  // Hash the resource portion
-  {
-    const std::string &str = resource();
-    for (int i = 0; i < static_cast<int>(str.size()); ++i)
-      hash = ((hash << 2) + hash) + str[i];
-  }
-
-  return hash;
-}
-
-// --- JID parsing code: ---
-
-// Checks and normalizes the node part of a JID.
-std::string
-Jid::prepNode(const std::string str, std::string::const_iterator start,
-    std::string::const_iterator end, bool *valid) {
-  *valid = false;
-  std::string result;
-
-  for (std::string::const_iterator i = start; i < end; i++) {
-    bool char_valid = true;
-    unsigned char ch = *i;
-    if (ch <= 0x7F) {
-      result += prepNodeAscii(ch, &char_valid);
-    }
-    else {
-      // TODO: implement the correct stringprep protocol for these
-      result += tolower(ch);
-    }
-    if (!char_valid) {
-      return STR_EMPTY;
-    }
-  }
-
-  if (result.length() > 1023) {
-    return STR_EMPTY;
-  }
-  *valid = true;
-  return result;
-}
-
-
-// Returns the appropriate mapping for an ASCII character in a node.
-char
-Jid::prepNodeAscii(char ch, bool *valid) {
-  *valid = true;
-  switch (ch) {
-    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G':
-    case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N':
-    case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U':
-    case 'V': case 'W': case 'X': case 'Y': case 'Z':
-      return (char)(ch + ('a' - 'A'));
-
-    case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05:
-    case 0x06: case 0x07: case 0x08: case 0x09: case 0x0A: case 0x0B:
-    case 0x0C: case 0x0D: case 0x0E: case 0x0F: case 0x10: case 0x11:
-    case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
-    case ' ': case '&': case '/': case ':': case '<': case '>': case '@':
-    case '\"': case '\'':
-    case 0x7F:
-      *valid = false;
-      return 0;
-
-    default:
-      return ch;
-  }
-}
-
-
-// Checks and normalizes the resource part of a JID.
-std::string
-Jid::prepResource(const std::string str, std::string::const_iterator start,
-    std::string::const_iterator end, bool *valid) {
-  *valid = false;
-  std::string result;
-
-  for (std::string::const_iterator i = start; i < end; i++) {
-    bool char_valid = true;
-    unsigned char ch = *i;
-    if (ch <= 0x7F) {
-      result += prepResourceAscii(ch, &char_valid);
-    }
-    else {
-      // TODO: implement the correct stringprep protocol for these
-      result += ch;
-    }
-  }
-
-  if (result.length() > 1023) {
-    return STR_EMPTY;
-  }
-  *valid = true;
-  return result;
-}
-
-// Returns the appropriate mapping for an ASCII character in a resource.
-char
-Jid::prepResourceAscii(char ch, bool *valid) {
-  *valid = true;
-  switch (ch) {
-    case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05:
-    case 0x06: case 0x07: case 0x08: case 0x09: case 0x0A: case 0x0B:
-    case 0x0C: case 0x0D: case 0x0E: case 0x0F: case 0x10: case 0x11:
-    case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
-    case 0x7F:
-      *valid = false;
-      return 0;
-
-    default:
-      return ch;
-  }
-}
-
-// Checks and normalizes the domain part of a JID.
-std::string
-Jid::prepDomain(const std::string str, std::string::const_iterator start,
-    std::string::const_iterator end, bool *valid) {
-  *valid = false;
-  std::string result;
-
-  // TODO: if the domain contains a ':', then we should parse it
-  // as an IPv6 address rather than giving an error about illegal domain.
-  prepDomain(str, start, end, &result, valid);
-  if (!*valid) {
-    return STR_EMPTY;
-  }
-
-  if (result.length() > 1023) {
-    return STR_EMPTY;
-  }
-  *valid = true;
-  return result;
-}
-
-
-// Checks and normalizes an IDNA domain.
-void
-Jid::prepDomain(const std::string str, std::string::const_iterator start,
-    std::string::const_iterator end, std::string *buf, bool *valid) {
-  *valid = false;
-  std::string::const_iterator last = start;
-  for (std::string::const_iterator i = start; i < end; i++) {
-    bool label_valid = true;
-    char ch = *i;
-    switch (ch) {
-      case 0x002E:
-#if 0 // FIX: This isn't UTF-8-aware.
-      case 0x3002:
-      case 0xFF0E:
-      case 0xFF61:
-#endif
-        prepDomainLabel(str, last, i, buf, &label_valid);
-        *buf += '.';
-        last = i + 1;
-        break;
-    }
-    if (!label_valid) {
-      return;
-    }
-  }
-  prepDomainLabel(str, last, end, buf, valid);
-}
-
-// Checks and normalizes a domain label.
-void
-Jid::prepDomainLabel(const std::string str, std::string::const_iterator start,
-    std::string::const_iterator end, std::string *buf, bool *valid) {
-  *valid = false;
-
-  int startLen = buf->length();
-  for (std::string::const_iterator i = start; i < end; i++) {
-    bool char_valid = true;
-    unsigned char ch = *i;
-    if (ch <= 0x7F) {
-      *buf += prepDomainLabelAscii(ch, &char_valid);
-    }
-    else {
-      // TODO: implement ToASCII for these
-      *buf += ch;
-    }
-    if (!char_valid) {
-      return;
-    }
-  }
-
-  int count = buf->length() - startLen;
-  if (count == 0) {
-    return;
-  }
-  else if (count > 63) {
-    return;
-  }
-
-  // Is this check needed? See comment in prepDomainLabelAscii.
-  if ((*buf)[startLen] == '-') {
-    return;
-  }
-  if ((*buf)[buf->length() - 1] == '-') {
-    return;
-  }
-  *valid = true;
-}
-
-
-// Returns the appropriate mapping for an ASCII character in a domain label.
-char
-Jid::prepDomainLabelAscii(char ch, bool *valid) {
-  *valid = true;
-  // TODO: A literal reading of the spec seems to say that we do
-  // not need to check for these illegal characters (an "internationalized
-  // domain label" runs ToASCII with UseSTD3... set to false).  But that
-  // can't be right.  We should at least be checking that there are no '/'
-  // or '@' characters in the domain.  Perhaps we should see what others
-  // do in this case.
-
-  switch (ch) {
-    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G':
-    case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N':
-    case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U':
-    case 'V': case 'W': case 'X': case 'Y': case 'Z':
-      return (char)(ch + ('a' - 'A'));
-
-    case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05:
-    case 0x06: case 0x07: case 0x08: case 0x09: case 0x0A: case 0x0B:
-    case 0x0C: case 0x0D: case 0x0E: case 0x0F: case 0x10: case 0x11:
-    case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
-    case 0x18: case 0x19: case 0x1A: case 0x1B: case 0x1C: case 0x1D:
-    case 0x1E: case 0x1F: case 0x20: case 0x21: case 0x22: case 0x23:
-    case 0x24: case 0x25: case 0x26: case 0x27: case 0x28: case 0x29:
-    case 0x2A: case 0x2B: case 0x2C: case 0x2E: case 0x2F: case 0x3A:
-    case 0x3B: case 0x3C: case 0x3D: case 0x3E: case 0x3F: case 0x40:
-    case 0x5B: case 0x5C: case 0x5D: case 0x5E: case 0x5F: case 0x60:
-    case 0x7B: case 0x7C: case 0x7D: case 0x7E: case 0x7F:
-      *valid = false;
-      return 0;
-
-    default:
-      return ch;
-  }
-}
-
-}
diff --git a/third_party/libjingle/source/talk/xmpp/jid.h b/third_party/libjingle/source/talk/xmpp/jid.h
deleted file mode 100644
index dd10f97..0000000
--- a/third_party/libjingle/source/talk/xmpp/jid.h
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_XMPP_JID_H_
-#define TALK_XMPP_JID_H_
-
-#include <string>
-#include "talk/base/basictypes.h"
-#include "talk/xmllite/xmlconstants.h"
-
-namespace buzz {
-
-//! The Jid class encapsulates and provides parsing help for Jids
-//! A Jid consists of three parts. The node, the domain and the resource.
-//!
-//! node@domain/resource
-//!
-//! The node and resource are both optional.  A valid jid is defined to have
-//! a domain.  A bare jid is defined to not have a resource and a full jid
-//! *does* have a resource.
-class Jid {
-public:
-  explicit Jid();
-  explicit Jid(const std::string & jid_string);
-  explicit Jid(const std::string & node_name,
-               const std::string & domain_name,
-               const std::string & resource_name);
-  explicit Jid(bool special, const std::string & special_string);
-  Jid(const Jid & jid) : data_(jid.data_) {
-    if (data_ != NULL) {
-      data_->AddRef();
-    }
-  }
-  Jid & operator=(const Jid & jid) {
-    if (jid.data_ != NULL) {
-      jid.data_->AddRef();
-    }
-    if (data_ != NULL) {
-      data_->Release();
-    }
-    data_ = jid.data_;
-    return *this;
-  }
-  ~Jid() {
-    if (data_ != NULL) {
-      data_->Release();
-    }
-  }
-
-  const std::string & node() const {
-    return !data_ ? EmptyStringRef() : data_->node_name_;
-  }
-  const std::string & domain() const {
-    return !data_ ? EmptyStringRef() : data_->domain_name_;
-  }
-  const std::string & resource() const {
-    return !data_ ? EmptyStringRef() : data_->resource_name_;
-  }
-
-  std::string Str() const;
-  Jid BareJid() const;
-
-  bool IsEmpty() const;
-  bool IsValid() const;
-  bool IsBare() const;
-  bool IsFull() const;
-
-  bool BareEquals(const Jid & other) const;
-
-  bool operator==(const Jid & other) const;
-  bool operator!=(const Jid & other) const { return !operator==(other); }
-
-  bool operator<(const Jid & other) const { return Compare(other) < 0; };
-  bool operator>(const Jid & other) const { return Compare(other) > 0; };
-
-  int Compare(const Jid & other) const;
-
-  // A quick and dirty hash.  Don't count on this producing a great
-  // distribution.
-  uint32 ComputeLameHash() const;
-
-private:
-
-  static std::string prepNode(const std::string str,
-      std::string::const_iterator start, std::string::const_iterator end,
-      bool *valid);
-  static char prepNodeAscii(char ch, bool *valid);
-  static std::string prepResource(const std::string str,
-      std::string::const_iterator start, std::string::const_iterator end,
-      bool *valid);
-  static char prepResourceAscii(char ch, bool *valid);
-  static std::string prepDomain(const std::string str,
-      std::string::const_iterator start,  std::string::const_iterator end,
-      bool *valid);
-  static void prepDomain(const std::string str,
-      std::string::const_iterator start, std::string::const_iterator end,
-      std::string *buf, bool *valid);
-  static void prepDomainLabel(const std::string str,
-      std::string::const_iterator start, std::string::const_iterator end,
-      std::string *buf, bool *valid);
-  static char prepDomainLabelAscii(char ch, bool *valid);
-
-  class Data {
-  public:
-    Data() : refcount_(1) {}
-    Data(const std::string & node, const std::string &domain,
-         const std::string & resource)
-        : node_name_(node),
-          domain_name_(domain),
-          resource_name_(resource),
-          refcount_(1) {
-    }
-    const std::string node_name_;
-    const std::string domain_name_;
-    const std::string resource_name_;
-
-    // TODO: ref-counter is not thread-safe here. Make it
-    // thread-safe or remove this optimization.
-    void AddRef() { refcount_++; }
-    void Release() { if (!--refcount_) delete this; }
-  private:
-    int refcount_;
-  };
-
-  Data * data_;
-};
-
-}
-
-#endif  // TALK_XMPP_JID_H_
diff --git a/third_party/libjingle/source/talk/xmpp/jid_unittest.cc b/third_party/libjingle/source/talk/xmpp/jid_unittest.cc
deleted file mode 100644
index b9597da..0000000
--- a/third_party/libjingle/source/talk/xmpp/jid_unittest.cc
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright 2004 Google Inc. All Rights Reserved
-
-
-#include "talk/base/gunit.h"
-#include "talk/xmpp/jid.h"
-
-using buzz::Jid;
-
-TEST(JidTest, TestDomain) {
-  Jid jid("dude");
-  EXPECT_EQ("", jid.node());
-  EXPECT_EQ("dude", jid.domain());
-  EXPECT_EQ("", jid.resource());
-  EXPECT_EQ("dude", jid.Str());
-  EXPECT_EQ("dude", jid.BareJid().Str());
-  EXPECT_TRUE(jid.IsValid());
-  EXPECT_TRUE(jid.IsBare());
-  EXPECT_FALSE(jid.IsFull());
-}
-
-TEST(JidTest, TestNodeDomain) {
-  Jid jid("walter@dude");
-  EXPECT_EQ("walter", jid.node());
-  EXPECT_EQ("dude", jid.domain());
-  EXPECT_EQ("", jid.resource());
-  EXPECT_EQ("walter@dude", jid.Str());
-  EXPECT_EQ("walter@dude", jid.BareJid().Str());
-  EXPECT_TRUE(jid.IsValid());
-  EXPECT_TRUE(jid.IsBare());
-  EXPECT_FALSE(jid.IsFull());
-}
-
-TEST(JidTest, TestDomainResource) {
-  Jid jid("dude/bowlingalley");
-  EXPECT_EQ("", jid.node());
-  EXPECT_EQ("dude", jid.domain());
-  EXPECT_EQ("bowlingalley", jid.resource());
-  EXPECT_EQ("dude/bowlingalley", jid.Str());
-  EXPECT_EQ("dude", jid.BareJid().Str());
-  EXPECT_TRUE(jid.IsValid());
-  EXPECT_FALSE(jid.IsBare());
-  EXPECT_TRUE(jid.IsFull());
-}
-
-TEST(JidTest, TestNodeDomainResource) {
-  Jid jid("walter@dude/bowlingalley");
-  EXPECT_EQ("walter", jid.node());
-  EXPECT_EQ("dude", jid.domain());
-  EXPECT_EQ("bowlingalley", jid.resource());
-  EXPECT_EQ("walter@dude/bowlingalley", jid.Str());
-  EXPECT_EQ("walter@dude", jid.BareJid().Str());
-  EXPECT_TRUE(jid.IsValid());
-  EXPECT_FALSE(jid.IsBare());
-  EXPECT_TRUE(jid.IsFull());
-}
-
-TEST(JidTest, TestNode) {
-  Jid jid("walter@");
-  EXPECT_EQ("", jid.node());
-  EXPECT_EQ("", jid.domain());
-  EXPECT_EQ("", jid.resource());
-  EXPECT_EQ("", jid.Str());
-  EXPECT_EQ("", jid.BareJid().Str());
-  EXPECT_FALSE(jid.IsValid());
-  EXPECT_TRUE(jid.IsBare());
-  EXPECT_FALSE(jid.IsFull());
-}
-
-TEST(JidTest, TestResource) {
-  Jid jid("/bowlingalley");
-  EXPECT_EQ("", jid.node());
-  EXPECT_EQ("", jid.domain());
-  EXPECT_EQ("", jid.resource());
-  EXPECT_EQ("", jid.Str());
-  EXPECT_EQ("", jid.BareJid().Str());
-  EXPECT_FALSE(jid.IsValid());
-  EXPECT_TRUE(jid.IsBare());
-  EXPECT_FALSE(jid.IsFull());
-}
-
-TEST(JidTest, TestNodeResource) {
-  Jid jid("walter@/bowlingalley");
-  EXPECT_EQ("", jid.node());
-  EXPECT_EQ("", jid.domain());
-  EXPECT_EQ("", jid.resource());
-  EXPECT_EQ("", jid.Str());
-  EXPECT_EQ("", jid.BareJid().Str());
-  EXPECT_FALSE(jid.IsValid());
-  EXPECT_TRUE(jid.IsBare());
-  EXPECT_FALSE(jid.IsFull());
-}
-
-TEST(JidTest, TestFunky) {
-  Jid jid("bowling@muchat/walter@dude");
-  EXPECT_EQ("bowling", jid.node());
-  EXPECT_EQ("muchat", jid.domain());
-  EXPECT_EQ("walter@dude", jid.resource());
-  EXPECT_EQ("bowling@muchat/walter@dude", jid.Str());
-  EXPECT_EQ("bowling@muchat", jid.BareJid().Str());
-  EXPECT_TRUE(jid.IsValid());
-  EXPECT_FALSE(jid.IsBare());
-  EXPECT_TRUE(jid.IsFull());
-}
-
-TEST(JidTest, TestFunky2) {
-  Jid jid("muchat/walter@dude");
-  EXPECT_EQ("", jid.node());
-  EXPECT_EQ("muchat", jid.domain());
-  EXPECT_EQ("walter@dude", jid.resource());
-  EXPECT_EQ("muchat/walter@dude", jid.Str());
-  EXPECT_EQ("muchat", jid.BareJid().Str());
-  EXPECT_TRUE(jid.IsValid());
-  EXPECT_FALSE(jid.IsBare());
-  EXPECT_TRUE(jid.IsFull());
-}
diff --git a/third_party/libjingle/source/talk/xmpp/mucroomconfigtask.cc b/third_party/libjingle/source/talk/xmpp/mucroomconfigtask.cc
deleted file mode 100644
index 272bd44..0000000
--- a/third_party/libjingle/source/talk/xmpp/mucroomconfigtask.cc
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * libjingle
- * Copyright 2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string>
-#include <vector>
-
-#include "talk/xmpp/mucroomconfigtask.h"
-
-#include "talk/base/scoped_ptr.h"
-#include "talk/xmpp/constants.h"
-
-namespace buzz {
-
-MucRoomConfigTask::MucRoomConfigTask(
-    XmppTaskParentInterface* parent,
-    const Jid& room_jid,
-    const std::string& room_name,
-    const std::vector<std::string>& room_features)
-    : IqTask(parent, STR_SET, room_jid,
-             MakeRequest(room_name, room_features)),
-      room_jid_(room_jid) {
-}
-
-XmlElement* MucRoomConfigTask::MakeRequest(
-    const std::string& room_name,
-    const std::vector<std::string>& room_features) {
-  buzz::XmlElement* owner_query = new
-      buzz::XmlElement(buzz::QN_MUC_OWNER_QUERY, true);
-
-  buzz::XmlElement* x_form = new buzz::XmlElement(buzz::QN_XDATA_X, true);
-  x_form->SetAttr(buzz::QN_TYPE, buzz::STR_FORM);
-
-  buzz::XmlElement* roomname_field =
-      new buzz::XmlElement(buzz::QN_XDATA_FIELD, false);
-  roomname_field->SetAttr(buzz::QN_VAR, buzz::STR_MUC_ROOMCONFIG_ROOMNAME);
-  roomname_field->SetAttr(buzz::QN_TYPE, buzz::STR_TEXT_SINGLE);
-
-  buzz::XmlElement* roomname_value =
-      new buzz::XmlElement(buzz::QN_XDATA_VALUE, false);
-  roomname_value->SetBodyText(room_name);
-
-  roomname_field->AddElement(roomname_value);
-  x_form->AddElement(roomname_field);
-
-  buzz::XmlElement* features_field =
-      new buzz::XmlElement(buzz::QN_XDATA_FIELD, false);
-  features_field->SetAttr(buzz::QN_VAR, buzz::STR_MUC_ROOMCONFIG_FEATURES);
-  features_field->SetAttr(buzz::QN_TYPE, buzz::STR_LIST_MULTI);
-
-  for (std::vector<std::string>::const_iterator feature = room_features.begin();
-       feature != room_features.end(); ++feature) {
-    buzz::XmlElement* features_value =
-        new buzz::XmlElement(buzz::QN_XDATA_VALUE, false);
-    features_value->SetBodyText(*feature);
-    features_field->AddElement(features_value);
-  }
-
-  x_form->AddElement(features_field);
-  owner_query->AddElement(x_form);
-  return owner_query;
-}
-
-void MucRoomConfigTask::HandleResult(const XmlElement* element) {
-  SignalResult(this);
-}
-
-}  // namespace buzz
diff --git a/third_party/libjingle/source/talk/xmpp/mucroomconfigtask.h b/third_party/libjingle/source/talk/xmpp/mucroomconfigtask.h
deleted file mode 100644
index ba0dbaa..0000000
--- a/third_party/libjingle/source/talk/xmpp/mucroomconfigtask.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * libjingle
- * Copyright 2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_XMPP_MUCROOMCONFIGTASK_H_
-#define TALK_XMPP_MUCROOMCONFIGTASK_H_
-
-#include <string>
-#include "talk/xmpp/iqtask.h"
-
-namespace buzz {
-
-// This task configures the muc room for document sharing and other enterprise
-// specific goodies.
-class MucRoomConfigTask : public IqTask {
- public:
-  MucRoomConfigTask(XmppTaskParentInterface* parent,
-                    const Jid& room_jid,
-                    const std::string& room_name,
-                    const std::vector<std::string>& room_features);
-
-  // Room configuration does not return any reasonable error
-  // values. The First config request configures the room, subseqent
-  // ones are just ignored by server and server returns empty
-  // response.
-  sigslot::signal1<MucRoomConfigTask*> SignalResult;
-
-  const Jid& room_jid() const { return room_jid_; }
-
- protected:
-  virtual void HandleResult(const XmlElement* stanza);
-
- private:
-  static XmlElement* MakeRequest(const std::string& room_name,
-                                 const std::vector<std::string>& room_features);
-  Jid room_jid_;
-};
-
-}  // namespace buzz
-
-#endif  // TALK_XMPP_MUCROOMCONFIGTASK_H_
diff --git a/third_party/libjingle/source/talk/xmpp/mucroomconfigtask_unittest.cc b/third_party/libjingle/source/talk/xmpp/mucroomconfigtask_unittest.cc
deleted file mode 100644
index e0a8aca..0000000
--- a/third_party/libjingle/source/talk/xmpp/mucroomconfigtask_unittest.cc
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * libjingle
- * Copyright 2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string>
-#include <vector>
-
-#include "talk/base/faketaskrunner.h"
-#include "talk/base/gunit.h"
-#include "talk/base/sigslot.h"
-#include "talk/xmllite/xmlelement.h"
-#include "talk/xmpp/constants.h"
-#include "talk/xmpp/fakexmppclient.h"
-#include "talk/xmpp/mucroomconfigtask.h"
-
-class MucRoomConfigListener : public sigslot::has_slots<> {
- public:
-  MucRoomConfigListener() : result_count(0), error_count(0) {}
-
-  void OnResult(buzz::MucRoomConfigTask*) {
-    ++result_count;
-  }
-
-  void OnError(buzz::IqTask* task,
-               const buzz::XmlElement* error) {
-    ++error_count;
-  }
-
-  int result_count;
-  int error_count;
-};
-
-class MucRoomConfigTaskTest : public testing::Test {
- public:
-  MucRoomConfigTaskTest() :
-      room_jid("muc-jid-ponies@domain.com"),
-      room_name("ponies") {
-  }
-
-  virtual void SetUp() {
-    runner = new talk_base::FakeTaskRunner();
-    xmpp_client = new buzz::FakeXmppClient(runner);
-    listener = new MucRoomConfigListener();
-  }
-
-  virtual void TearDown() {
-    delete listener;
-    // delete xmpp_client;  Deleted by deleting runner.
-    delete runner;
-  }
-
-  talk_base::FakeTaskRunner* runner;
-  buzz::FakeXmppClient* xmpp_client;
-  MucRoomConfigListener* listener;
-  buzz::Jid room_jid;
-  std::string room_name;
-};
-
-TEST_F(MucRoomConfigTaskTest, TestConfigEnterprise) {
-  ASSERT_EQ(0U, xmpp_client->sent_stanzas().size());
-
-  std::vector<std::string> room_features;
-  room_features.push_back("feature1");
-  room_features.push_back("feature2");
-  buzz::MucRoomConfigTask* task = new buzz::MucRoomConfigTask(
-      xmpp_client, room_jid, "ponies", room_features);
-  EXPECT_EQ(room_jid, task->room_jid());
-
-  task->SignalResult.connect(listener, &MucRoomConfigListener::OnResult);
-  task->Start();
-
-  std::string expected_iq =
-      "<cli:iq type=\"set\" to=\"muc-jid-ponies@domain.com\" id=\"0\" "
-        "xmlns:cli=\"jabber:client\">"
-        "<query xmlns=\"http://jabber.org/protocol/muc#owner\">"
-          "<x xmlns=\"jabber:x:data\" type=\"form\">"
-            "<field var=\"muc#roomconfig_roomname\" type=\"text-single\">"
-              "<value>ponies</value>"
-            "</field>"
-            "<field var=\"muc#roomconfig_features\" type=\"list-multi\">"
-              "<value>feature1</value>"
-              "<value>feature2</value>"
-            "</field>"
-          "</x>"
-        "</query>"
-      "</cli:iq>";
-
-  ASSERT_EQ(1U, xmpp_client->sent_stanzas().size());
-  EXPECT_EQ(expected_iq, xmpp_client->sent_stanzas()[0]->Str());
-
-  EXPECT_EQ(0, listener->result_count);
-  EXPECT_EQ(0, listener->error_count);
-
-  std::string response_iq =
-      "<iq xmlns='jabber:client' id='0' type='result'"
-      "  from='muc-jid-ponies@domain.com'>"
-      "</iq>";
-
-  xmpp_client->HandleStanza(buzz::XmlElement::ForStr(response_iq));
-
-  EXPECT_EQ(1, listener->result_count);
-  EXPECT_EQ(0, listener->error_count);
-}
-
-TEST_F(MucRoomConfigTaskTest, TestError) {
-  std::vector<std::string> room_features;
-  buzz::MucRoomConfigTask* task = new buzz::MucRoomConfigTask(
-      xmpp_client, room_jid, "ponies", room_features);
-  task->SignalError.connect(listener, &MucRoomConfigListener::OnError);
-  task->Start();
-
-  std::string error_iq =
-      "<iq xmlns='jabber:client' id='0' type='error'"
-      " from='muc-jid-ponies@domain.com'>"
-      "</iq>";
-
-  xmpp_client->HandleStanza(buzz::XmlElement::ForStr(error_iq));
-
-  EXPECT_EQ(0, listener->result_count);
-  EXPECT_EQ(1, listener->error_count);
-}
diff --git a/third_party/libjingle/source/talk/xmpp/mucroomlookuptask.cc b/third_party/libjingle/source/talk/xmpp/mucroomlookuptask.cc
deleted file mode 100644
index 278dc38..0000000
--- a/third_party/libjingle/source/talk/xmpp/mucroomlookuptask.cc
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * libjingle
- * Copyright 2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/xmpp/mucroomlookuptask.h"
-
-#include "talk/base/logging.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/xmpp/constants.h"
-
-
-namespace buzz {
-
-MucRoomLookupTask::MucRoomLookupTask(XmppTaskParentInterface* parent,
-                                     const Jid& lookup_server_jid,
-                                     const std::string& room_name,
-                                     const std::string& room_domain)
-    : IqTask(parent, STR_SET, lookup_server_jid,
-             MakeNameQuery(room_name, room_domain)) {
-}
-
-MucRoomLookupTask::MucRoomLookupTask(XmppTaskParentInterface* parent,
-                                     const Jid& lookup_server_jid,
-                                     const Jid& room_jid)
-    : IqTask(parent, STR_SET, lookup_server_jid,
-             MakeJidQuery(room_jid)) {
-}
-
-XmlElement* MucRoomLookupTask::MakeNameQuery(
-    const std::string& room_name, const std::string& room_domain) {
-  XmlElement* name_elem = new XmlElement(QN_SEARCH_ROOM_NAME, false);
-  name_elem->SetBodyText(room_name);
-
-  XmlElement* domain_elem = new XmlElement(QN_SEARCH_ROOM_DOMAIN, false);
-  domain_elem->SetBodyText(room_domain);
-
-  XmlElement* query = new XmlElement(QN_SEARCH_QUERY, true);
-  query->AddElement(name_elem);
-  query->AddElement(domain_elem);
-  return query;
-}
-
-XmlElement* MucRoomLookupTask::MakeJidQuery(const Jid& room_jid) {
-  XmlElement* jid_elem = new XmlElement(QN_SEARCH_ROOM_JID);
-  jid_elem->SetBodyText(room_jid.Str());
-
-  XmlElement* query = new XmlElement(QN_SEARCH_QUERY);
-  query->AddElement(jid_elem);
-  return query;
-}
-
-void MucRoomLookupTask::HandleResult(const XmlElement* stanza) {
-  const XmlElement* query_elem = stanza->FirstNamed(QN_SEARCH_QUERY);
-  if (query_elem == NULL) {
-    SignalError(this, NULL);
-    return;
-  }
-
-  const XmlElement* item_elem = query_elem->FirstNamed(QN_SEARCH_ITEM);
-  if (item_elem == NULL) {
-    SignalError(this, NULL);
-    return;
-  }
-
-  MucRoomInfo room;
-  room.jid = Jid(item_elem->Attr(buzz::QN_JID));
-  if (!room.jid.IsValid()) {
-    SignalError(this, NULL);
-    return;
-  }
-
-  const XmlElement* room_name_elem =
-      item_elem->FirstNamed(QN_SEARCH_ROOM_NAME);
-  if (room_name_elem != NULL) {
-    room.name = room_name_elem->BodyText();
-  }
-
-  const XmlElement* room_domain_elem =
-      item_elem->FirstNamed(QN_SEARCH_ROOM_DOMAIN);
-  if (room_domain_elem != NULL) {
-    room.domain = room_domain_elem->BodyText();
-  }
-
-  SignalResult(this, room);
-}
-
-}  // namespace buzz
diff --git a/third_party/libjingle/source/talk/xmpp/mucroomlookuptask.h b/third_party/libjingle/source/talk/xmpp/mucroomlookuptask.h
deleted file mode 100644
index ec5873c..0000000
--- a/third_party/libjingle/source/talk/xmpp/mucroomlookuptask.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * libjingle
- * Copyright 2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_XMPP_MUCROOMLOOKUPTASK_H_
-#define TALK_XMPP_MUCROOMLOOKUPTASK_H_
-
-#include <string>
-#include "talk/xmpp/iqtask.h"
-
-namespace buzz {
-
-struct MucRoomInfo {
-  Jid jid;
-  std::string name;
-  std::string domain;
-
-  std::string full_name() const {
-    return name + "@" + domain;
-  }
-};
-
-class MucRoomLookupTask : public IqTask {
- public:
-  MucRoomLookupTask(XmppTaskParentInterface* parent,
-                    const Jid& lookup_jid,
-                    const std::string& room_name,
-                    const std::string& room_domain);
-  MucRoomLookupTask(XmppTaskParentInterface* parent,
-                    const Jid& lookup_jid,
-                    const Jid& room_jid);
-
-  sigslot::signal2<MucRoomLookupTask*,
-                   const MucRoomInfo&> SignalResult;
-
- protected:
-  virtual void HandleResult(const XmlElement* element);
-
- private:
-  static XmlElement* MakeNameQuery(const std::string& room_name,
-                                   const std::string& room_domain);
-  static XmlElement* MakeJidQuery(const Jid& room_jid);
-};
-
-}  // namespace buzz
-
-#endif  // TALK_XMPP_MUCROOMLOOKUPTASK_H_
diff --git a/third_party/libjingle/source/talk/xmpp/mucroomlookuptask_unittest.cc b/third_party/libjingle/source/talk/xmpp/mucroomlookuptask_unittest.cc
deleted file mode 100644
index 99a78c7..0000000
--- a/third_party/libjingle/source/talk/xmpp/mucroomlookuptask_unittest.cc
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * libjingle
- * Copyright 2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string>
-#include <vector>
-
-#include "talk/base/faketaskrunner.h"
-#include "talk/base/gunit.h"
-#include "talk/base/sigslot.h"
-#include "talk/xmllite/xmlelement.h"
-#include "talk/xmpp/constants.h"
-#include "talk/xmpp/fakexmppclient.h"
-#include "talk/xmpp/mucroomlookuptask.h"
-
-class MucRoomLookupListener : public sigslot::has_slots<> {
- public:
-  MucRoomLookupListener() : error_count(0) {}
-
-  void OnResult(buzz::MucRoomLookupTask* task,
-                const buzz::MucRoomInfo& room) {
-    last_room = room;
-  }
-
-  void OnError(buzz::IqTask* task,
-               const buzz::XmlElement* error) {
-    ++error_count;
-  }
-
-  buzz::MucRoomInfo last_room;
-  int error_count;
-};
-
-class MucRoomLookupTaskTest : public testing::Test {
- public:
-  MucRoomLookupTaskTest() :
-      lookup_server_jid("lookup@domain.com"),
-      room_jid("muc-jid-ponies@domain.com"),
-      room_name("ponies"),
-      room_domain("domain.com"),
-      room_full_name("ponies@domain.com") {
-  }
-
-  virtual void SetUp() {
-    runner = new talk_base::FakeTaskRunner();
-    xmpp_client = new buzz::FakeXmppClient(runner);
-    listener = new MucRoomLookupListener();
-  }
-
-  virtual void TearDown() {
-    delete listener;
-    // delete xmpp_client;  Deleted by deleting runner.
-    delete runner;
-  }
-
-  talk_base::FakeTaskRunner* runner;
-  buzz::FakeXmppClient* xmpp_client;
-  MucRoomLookupListener* listener;
-  buzz::Jid lookup_server_jid;
-  buzz::Jid room_jid;
-  std::string room_name;
-  std::string room_domain;
-  std::string room_full_name;
-};
-
-TEST_F(MucRoomLookupTaskTest, TestLookupName) {
-  ASSERT_EQ(0U, xmpp_client->sent_stanzas().size());
-
-  buzz::MucRoomLookupTask* task = new buzz::MucRoomLookupTask(
-      xmpp_client, lookup_server_jid, room_name, room_domain);
-  task->SignalResult.connect(listener, &MucRoomLookupListener::OnResult);
-  task->Start();
-
-  std::string expected_iq =
-      "<cli:iq type=\"set\" to=\"lookup@domain.com\" id=\"0\" "
-        "xmlns:cli=\"jabber:client\">"
-        "<query xmlns=\"jabber:iq:search\">"
-          "<room-name>ponies</room-name>"
-          "<room-domain>domain.com</room-domain>"
-        "</query>"
-      "</cli:iq>";
-
-  ASSERT_EQ(1U, xmpp_client->sent_stanzas().size());
-  EXPECT_EQ(expected_iq, xmpp_client->sent_stanzas()[0]->Str());
-
-  EXPECT_EQ("", listener->last_room.name);
-
-  std::string response_iq =
-      "<iq xmlns='jabber:client' from='lookup@domain.com' id='0' type='result'>"
-      "  <query xmlns='jabber:iq:search'>"
-      "    <item jid='muc-jid-ponies@domain.com'>"
-      "      <room-name>ponies</room-name>"
-      "      <room-domain>domain.com</room-domain>"
-      "    </item>"
-      "  </query>"
-      "</iq>";
-
-  xmpp_client->HandleStanza(buzz::XmlElement::ForStr(response_iq));
-
-  EXPECT_EQ(room_name, listener->last_room.name);
-  EXPECT_EQ(room_domain, listener->last_room.domain);
-  EXPECT_EQ(room_jid, listener->last_room.jid);
-  EXPECT_EQ(room_full_name, listener->last_room.full_name());
-  EXPECT_EQ(0, listener->error_count);
-}
-
-TEST_F(MucRoomLookupTaskTest, TestError) {
-  buzz::MucRoomLookupTask* task = new buzz::MucRoomLookupTask(
-      xmpp_client, lookup_server_jid, room_name, room_domain);
-  task->SignalError.connect(listener, &MucRoomLookupListener::OnError);
-  task->Start();
-
-  std::string error_iq =
-      "<iq xmlns='jabber:client' id='0' type='error'"
-      "  from='lookup@domain.com'>"
-      "</iq>";
-
-  EXPECT_EQ(0, listener->error_count);
-  xmpp_client->HandleStanza(buzz::XmlElement::ForStr(error_iq));
-  EXPECT_EQ(1, listener->error_count);
-}
-
-TEST_F(MucRoomLookupTaskTest, TestBadJid) {
-  buzz::MucRoomLookupTask* task = new buzz::MucRoomLookupTask(
-      xmpp_client, lookup_server_jid, room_name, room_domain);
-  task->SignalError.connect(listener, &MucRoomLookupListener::OnError);
-  task->Start();
-
-  std::string response_iq =
-      "<iq xmlns='jabber:client' from='lookup@domain.com' id='0' type='result'>"
-      "  <query xmlns='jabber:iq:search'>"
-      "    <item/>"
-      "  </query>"
-      "</iq>";
-
-  EXPECT_EQ(0, listener->error_count);
-  xmpp_client->HandleStanza(buzz::XmlElement::ForStr(response_iq));
-  EXPECT_EQ(1, listener->error_count);
-}
diff --git a/third_party/libjingle/source/talk/xmpp/plainsaslhandler.h b/third_party/libjingle/source/talk/xmpp/plainsaslhandler.h
deleted file mode 100644
index e7d44b9..0000000
--- a/third_party/libjingle/source/talk/xmpp/plainsaslhandler.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _PLAINSASLHANDLER_H_
-#define _PLAINSASLHANDLER_H_
-
-#include "talk/xmpp/saslhandler.h"
-#include <algorithm>
-
-namespace buzz {
-
-class PlainSaslHandler : public SaslHandler {
-public:
-  PlainSaslHandler(const Jid & jid, const talk_base::CryptString & password, 
-      bool allow_plain) : jid_(jid), password_(password), 
-                          allow_plain_(allow_plain) {}
-    
-  virtual ~PlainSaslHandler() {}
-
-  // Should pick the best method according to this handler
-  // returns the empty string if none are suitable
-  virtual std::string ChooseBestSaslMechanism(const std::vector<std::string> & mechanisms, bool encrypted) {
-  
-    if (!encrypted && !allow_plain_) {
-      return "";
-    }
-    
-    std::vector<std::string>::const_iterator it = std::find(mechanisms.begin(), mechanisms.end(), "PLAIN");
-    if (it == mechanisms.end()) {
-      return "";
-    }
-    else {
-      return "PLAIN";
-    }
-  }
-
-  // Creates a SaslMechanism for the given mechanism name (you own it
-  // once you get it).  If not handled, return NULL.
-  virtual SaslMechanism * CreateSaslMechanism(const std::string & mechanism) {
-    if (mechanism == "PLAIN") {
-      return new SaslPlainMechanism(jid_, password_);
-    }
-    return NULL;
-  }
-  
-private:
-  Jid jid_;
-  talk_base::CryptString password_;
-  bool allow_plain_;
-};
-
-
-}
-
-#endif
-
diff --git a/third_party/libjingle/source/talk/xmpp/prexmppauth.h b/third_party/libjingle/source/talk/xmpp/prexmppauth.h
deleted file mode 100644
index dce5e0b..0000000
--- a/third_party/libjingle/source/talk/xmpp/prexmppauth.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _PREXMPPAUTH_H_
-#define _PREXMPPAUTH_H_
-
-#include "talk/base/cryptstring.h"
-#include "talk/base/sigslot.h"
-#include "talk/xmpp/saslhandler.h"
-
-namespace talk_base {
-  class SocketAddress;
-}
-
-namespace buzz {
-
-class Jid;
-class SaslMechanism;
-
-class CaptchaChallenge {
- public:
-  CaptchaChallenge() : captcha_needed_(false) {}
-  CaptchaChallenge(const std::string& token, const std::string& url) 
-    : captcha_needed_(true), captcha_token_(token), captcha_image_url_(url) {
-  }
-
-  bool captcha_needed() const { return captcha_needed_; }
-  const std::string& captcha_token() const { return captcha_token_; }
-
-  // This url is relative to the gaia server.  Once we have better tools
-  // for cracking URLs, we should probably make this a full URL
-  const std::string& captcha_image_url() const { return captcha_image_url_; }
-
- private:
-  bool captcha_needed_;
-  std::string captcha_token_;
-  std::string captcha_image_url_;
-};
-
-class PreXmppAuth : public SaslHandler {
-public:
-  virtual ~PreXmppAuth() {}
-  
-  virtual void StartPreXmppAuth(
-    const Jid & jid,
-    const talk_base::SocketAddress & server,
-    const talk_base::CryptString & pass,
-    const std::string & auth_cookie) = 0;
-  
-  sigslot::signal0<> SignalAuthDone;
-  
-  virtual bool IsAuthDone() const = 0;
-  virtual bool IsAuthorized() const = 0;
-  virtual bool HadError() const = 0;
-  virtual int GetError() const = 0;
-  virtual CaptchaChallenge GetCaptchaChallenge() const = 0;
-  virtual std::string GetAuthCookie() const = 0;
-};
-
-}
-
-#endif
diff --git a/third_party/libjingle/source/talk/xmpp/pubsubclient.cc b/third_party/libjingle/source/talk/xmpp/pubsubclient.cc
deleted file mode 100644
index 8d6d4c4..0000000
--- a/third_party/libjingle/source/talk/xmpp/pubsubclient.cc
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * libjingle
- * Copyright 2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/xmpp/pubsubclient.h"
-
-#include <string>
-#include <vector>
-
-#include "talk/xmpp/constants.h"
-#include "talk/xmpp/jid.h"
-#include "talk/xmpp/pubsubtasks.h"
-
-namespace buzz {
-
-void PubSubClient::RequestItems() {
-  PubSubRequestTask* request_task =
-      new PubSubRequestTask(parent_, pubsubjid_, node_);
-  request_task->SignalResult.connect(this, &PubSubClient::OnRequestResult);
-  request_task->SignalError.connect(this, &PubSubClient::OnRequestError);
-
-  PubSubReceiveTask* receive_task =
-      new PubSubReceiveTask(parent_, pubsubjid_, node_);
-  receive_task->SignalUpdate.connect(this, &PubSubClient::OnReceiveUpdate);
-
-  receive_task->Start();
-  request_task->Start();
-}
-
-void PubSubClient::PublishItem(
-    const std::string& itemid, XmlElement* payload, std::string* task_id_out) {
-  std::vector<XmlElement*> children;
-  children.push_back(payload);
-  PublishItem(itemid, children, task_id_out);
-}
-
-void PubSubClient::PublishItem(
-    const std::string& itemid, const std::vector<XmlElement*>& children,
-    std::string* task_id_out) {
-  PubSubPublishTask* publish_task =
-      new PubSubPublishTask(parent_, pubsubjid_, node_, itemid, children);
-  publish_task->SignalError.connect(this, &PubSubClient::OnPublishError);
-  publish_task->SignalResult.connect(this, &PubSubClient::OnPublishResult);
-  publish_task->Start();
-  if (task_id_out) {
-    *task_id_out = publish_task->task_id();
-  }
-}
-
-void PubSubClient::RetractItem(
-    const std::string& itemid, std::string* task_id_out) {
-  PubSubRetractTask* retract_task =
-      new PubSubRetractTask(parent_, pubsubjid_, node_, itemid);
-  retract_task->SignalError.connect(this, &PubSubClient::OnRetractError);
-  retract_task->SignalResult.connect(this, &PubSubClient::OnRetractResult);
-  retract_task->Start();
-  if (task_id_out) {
-    *task_id_out = retract_task->task_id();
-  }
-}
-
-void PubSubClient::OnRequestResult(PubSubRequestTask* task,
-                                   const std::vector<PubSubItem>& items) {
-  SignalItems(this, items);
-}
-
-void PubSubClient::OnRequestError(IqTask* task,
-                                  const XmlElement* stanza) {
-  SignalRequestError(this, stanza);
-}
-
-void PubSubClient::OnReceiveUpdate(PubSubReceiveTask* task,
-                                   const std::vector<PubSubItem>& items) {
-  SignalItems(this, items);
-}
-
-const XmlElement* GetItemFromStanza(const XmlElement* stanza) {
-  if (stanza != NULL) {
-    const XmlElement* pubsub = stanza->FirstNamed(QN_PUBSUB);
-    if (pubsub != NULL) {
-      const XmlElement* publish = pubsub->FirstNamed(QN_PUBSUB_PUBLISH);
-      if (publish != NULL) {
-        return publish->FirstNamed(QN_PUBSUB_ITEM);
-      }
-    }
-  }
-  return NULL;
-}
-
-void PubSubClient::OnPublishResult(PubSubPublishTask* task) {
-  const XmlElement* item = GetItemFromStanza(task->stanza());
-  SignalPublishResult(this, task->task_id(), item);
-}
-
-void PubSubClient::OnPublishError(IqTask* task,
-                                  const XmlElement* error_stanza) {
-  PubSubPublishTask* publish_task =
-      static_cast<PubSubPublishTask*>(task);
-  const XmlElement* item = GetItemFromStanza(publish_task->stanza());
-  SignalPublishError(this, publish_task->task_id(), item, error_stanza);
-}
-
-void PubSubClient::OnRetractResult(PubSubRetractTask* task) {
-  SignalRetractResult(this, task->task_id());
-}
-
-void PubSubClient::OnRetractError(IqTask* task,
-                                  const XmlElement* stanza) {
-  PubSubRetractTask* retract_task =
-      static_cast<PubSubRetractTask*>(task);
-  SignalRetractError(this, retract_task->task_id(), stanza);
-}
-
-}  // namespace buzz
diff --git a/third_party/libjingle/source/talk/xmpp/pubsubclient.h b/third_party/libjingle/source/talk/xmpp/pubsubclient.h
deleted file mode 100644
index 099765a..0000000
--- a/third_party/libjingle/source/talk/xmpp/pubsubclient.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * libjingle
- * Copyright 2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_XMPP_PUBSUBCLIENT_H_
-#define TALK_XMPP_PUBSUBCLIENT_H_
-
-#include <string>
-#include <vector>
-
-#include "talk/base/sigslot.h"
-#include "talk/base/sigslotrepeater.h"
-#include "talk/base/task.h"
-#include "talk/xmpp/jid.h"
-#include "talk/xmpp/pubsubtasks.h"
-
-// Easy to use clients built on top of the tasks for XEP-0060
-// (http://xmpp.org/extensions/xep-0060.html).
-
-namespace buzz {
-
-class Jid;
-class XmlElement;
-class XmppTaskParentInterface;
-
-// An easy-to-use pubsub client that handles the three tasks of
-// getting, publishing, and listening for updates.  Tied to a specific
-// pubsub jid and node.  All you have to do is RequestItems, listen
-// for SignalItems and PublishItems.
-class PubSubClient : public sigslot::has_slots<> {
- public:
-  PubSubClient(XmppTaskParentInterface* parent,
-               const Jid& pubsubjid,
-               const std::string& node)
-    : parent_(parent),
-      pubsubjid_(pubsubjid),
-      node_(node) {}
-
-  const std::string& node() const { return node_; }
-
-  // Requests the <pubsub><items>, which will be returned via
-  // SignalItems, or SignalRequestError if there is a failure.  Should
-  // auto-subscribe.
-  void RequestItems();
-  // Fired when either <pubsub><items> are returned or when
-  // <event><items> are received.
-  sigslot::signal2<PubSubClient*,
-                   const std::vector<PubSubItem>&> SignalItems;
-  // Signal (this, error stanza)
-  sigslot::signal2<PubSubClient*,
-                   const XmlElement*> SignalRequestError;
-  // Signal (this, task_id, item, error stanza)
-  sigslot::signal4<PubSubClient*,
-                   const std::string&,
-                   const XmlElement*,
-                   const XmlElement*> SignalPublishError;
-  // Signal (this, task_id, item)
-  sigslot::signal3<PubSubClient*,
-                   const std::string&,
-                   const XmlElement*> SignalPublishResult;
-  // Signal (this, task_id, error stanza)
-  sigslot::signal3<PubSubClient*,
-                   const std::string&,
-                   const XmlElement*> SignalRetractError;
-  // Signal (this, task_id)
-  sigslot::signal2<PubSubClient*,
-                   const std::string&> SignalRetractResult;
-
-  // Publish an item.  Takes ownership of payload.
-  void PublishItem(const std::string& itemid,
-                   XmlElement* payload,
-                   std::string* task_id_out);
-  // Publish an item.  Takes ownership of children.
-  void PublishItem(const std::string& itemid,
-                   const std::vector<XmlElement*>& children,
-                   std::string* task_id_out);
-  // Retract (delete) an item.
-  void RetractItem(const std::string& itemid,
-                   std::string* task_id_out);
-
- private:
-  void OnRequestError(IqTask* task,
-                      const XmlElement* stanza);
-  void OnRequestResult(PubSubRequestTask* task,
-                       const std::vector<PubSubItem>& items);
-  void OnReceiveUpdate(PubSubReceiveTask* task,
-                       const std::vector<PubSubItem>& items);
-  void OnPublishResult(PubSubPublishTask* task);
-  void OnPublishError(IqTask* task,
-                      const XmlElement* stanza);
-  void OnRetractResult(PubSubRetractTask* task);
-  void OnRetractError(IqTask* task,
-                      const XmlElement* stanza);
-
-  XmppTaskParentInterface* parent_;
-  Jid pubsubjid_;
-  std::string node_;
-};
-
-}  // namespace buzz
-
-#endif  // TALK_XMPP_PUBSUBCLIENT_H_
diff --git a/third_party/libjingle/source/talk/xmpp/pubsubclient_unittest.cc b/third_party/libjingle/source/talk/xmpp/pubsubclient_unittest.cc
deleted file mode 100644
index 2e4c511..0000000
--- a/third_party/libjingle/source/talk/xmpp/pubsubclient_unittest.cc
+++ /dev/null
@@ -1,271 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved
-
-
-#include <string>
-
-#include "talk/base/faketaskrunner.h"
-#include "talk/base/gunit.h"
-#include "talk/base/sigslot.h"
-#include "talk/xmllite/qname.h"
-#include "talk/xmllite/xmlelement.h"
-#include "talk/xmpp/constants.h"
-#include "talk/xmpp/fakexmppclient.h"
-#include "talk/xmpp/jid.h"
-#include "talk/xmpp/pubsubclient.h"
-
-struct HandledPubSubItem {
-  std::string itemid;
-  std::string payload;
-};
-
-class TestPubSubItemsListener : public sigslot::has_slots<> {
- public:
-  TestPubSubItemsListener() : error_count(0) {}
-
-  void OnItems(buzz::PubSubClient*,
-               const std::vector<buzz::PubSubItem>& items) {
-    for (std::vector<buzz::PubSubItem>::const_iterator item = items.begin();
-         item != items.end(); ++item) {
-      HandledPubSubItem handled_item;
-      handled_item.itemid = item->itemid;
-      if (item->elem->FirstElement() != NULL) {
-        handled_item.payload = item->elem->FirstElement()->Str();
-      }
-      this->items.push_back(handled_item);
-    }
-  }
-
-  void OnRequestError(buzz::PubSubClient* client,
-                      const buzz::XmlElement* stanza) {
-    error_count++;
-  }
-
-  void OnPublishResult(buzz::PubSubClient* client,
-                       const std::string& task_id,
-                       const buzz::XmlElement* item) {
-    result_task_id = task_id;
-  }
-
-  void OnPublishError(buzz::PubSubClient* client,
-                      const std::string& task_id,
-                      const buzz::XmlElement* item,
-                      const buzz::XmlElement* stanza) {
-    error_count++;
-    error_task_id = task_id;
-  }
-
-  void OnRetractResult(buzz::PubSubClient* client,
-                       const std::string& task_id) {
-    result_task_id = task_id;
-  }
-
-  void OnRetractError(buzz::PubSubClient* client,
-                      const std::string& task_id,
-                      const buzz::XmlElement* stanza) {
-    error_count++;
-    error_task_id = task_id;
-  }
-
-  std::vector<HandledPubSubItem> items;
-  int error_count;
-  std::string error_task_id;
-  std::string result_task_id;
-};
-
-class PubSubClientTest : public testing::Test {
- public:
-  PubSubClientTest() :
-      pubsubjid("room@domain.com"),
-      node("topic"),
-      itemid("key") {
-    runner.reset(new talk_base::FakeTaskRunner());
-    xmpp_client = new buzz::FakeXmppClient(runner.get());
-    client.reset(new buzz::PubSubClient(xmpp_client, pubsubjid, node));
-    listener.reset(new TestPubSubItemsListener());
-    client->SignalItems.connect(
-        listener.get(), &TestPubSubItemsListener::OnItems);
-    client->SignalRequestError.connect(
-        listener.get(), &TestPubSubItemsListener::OnRequestError);
-    client->SignalPublishResult.connect(
-        listener.get(), &TestPubSubItemsListener::OnPublishResult);
-    client->SignalPublishError.connect(
-        listener.get(), &TestPubSubItemsListener::OnPublishError);
-    client->SignalRetractResult.connect(
-        listener.get(), &TestPubSubItemsListener::OnRetractResult);
-    client->SignalRetractError.connect(
-        listener.get(), &TestPubSubItemsListener::OnRetractError);
-  }
-
-  talk_base::scoped_ptr<talk_base::FakeTaskRunner> runner;
-  // xmpp_client deleted by deleting runner.
-  buzz::FakeXmppClient* xmpp_client;
-  talk_base::scoped_ptr<buzz::PubSubClient> client;
-  talk_base::scoped_ptr<TestPubSubItemsListener> listener;
-  buzz::Jid pubsubjid;
-  std::string node;
-  std::string itemid;
-};
-
-TEST_F(PubSubClientTest, TestRequest) {
-  client->RequestItems();
-
-  std::string expected_iq =
-      "<cli:iq type=\"get\" to=\"room@domain.com\" id=\"0\" "
-        "xmlns:cli=\"jabber:client\">"
-        "<pub:pubsub xmlns:pub=\"http://jabber.org/protocol/pubsub\">"
-          "<pub:items node=\"topic\"/>"
-        "</pub:pubsub>"
-      "</cli:iq>";
-
-  ASSERT_EQ(1U, xmpp_client->sent_stanzas().size());
-  EXPECT_EQ(expected_iq, xmpp_client->sent_stanzas()[0]->Str());
-
-  std::string result_iq =
-      "<iq xmlns='jabber:client' id='0' type='result' from='room@domain.com'>"
-      "  <pubsub xmlns='http://jabber.org/protocol/pubsub'>"
-      "    <items node='topic'>"
-      "      <item id='key0'>"
-      "        <value0a/>"
-      "      </item>"
-      "      <item id='key1'>"
-      "        <value1a/>"
-      "      </item>"
-      "    </items>"
-      "  </pubsub>"
-      "</iq>";
-
-  xmpp_client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
-  ASSERT_EQ(2U, listener->items.size());
-  EXPECT_EQ("key0", listener->items[0].itemid);
-  EXPECT_EQ("<pub:value0a xmlns:pub=\"http://jabber.org/protocol/pubsub\"/>",
-            listener->items[0].payload);
-  EXPECT_EQ("key1", listener->items[1].itemid);
-  EXPECT_EQ("<pub:value1a xmlns:pub=\"http://jabber.org/protocol/pubsub\"/>",
-            listener->items[1].payload);
-
-  std::string items_message =
-      "<message xmlns='jabber:client' from='room@domain.com'>"
-      "  <event xmlns='http://jabber.org/protocol/pubsub#event'>"
-      "    <items node='topic'>"
-      "      <item id='key0'>"
-      "        <value0b/>"
-      "      </item>"
-      "      <item id='key1'>"
-      "        <value1b/>"
-      "      </item>"
-      "    </items>"
-      "  </event>"
-      "</message>";
-
-  xmpp_client->HandleStanza(buzz::XmlElement::ForStr(items_message));
-  ASSERT_EQ(4U, listener->items.size());
-  EXPECT_EQ("key0", listener->items[2].itemid);
-  EXPECT_EQ("<eve:value0b"
-            " xmlns:eve=\"http://jabber.org/protocol/pubsub#event\"/>",
-            listener->items[2].payload);
-  EXPECT_EQ("key1", listener->items[3].itemid);
-  EXPECT_EQ("<eve:value1b"
-            " xmlns:eve=\"http://jabber.org/protocol/pubsub#event\"/>",
-            listener->items[3].payload);
-}
-
-TEST_F(PubSubClientTest, TestRequestError) {
-  std::string result_iq =
-      "<iq xmlns='jabber:client' id='0' type='error' from='room@domain.com'>"
-      "  <error type='auth'>"
-      "    <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>"
-      "  </error>"
-      "</iq>";
-
-  client->RequestItems();
-  xmpp_client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
-  EXPECT_EQ(1, listener->error_count);
-}
-
-TEST_F(PubSubClientTest, TestPublish) {
-  buzz::XmlElement* payload =
-      new buzz::XmlElement(buzz::QName(buzz::NS_PUBSUB, "value"));
-
-  std::string task_id;
-  client->PublishItem(itemid, payload, &task_id);
-
-  std::string expected_iq =
-      "<cli:iq type=\"set\" to=\"room@domain.com\" id=\"0\" "
-        "xmlns:cli=\"jabber:client\">"
-        "<pubsub xmlns=\"http://jabber.org/protocol/pubsub\">"
-          "<publish node=\"topic\">"
-            "<item id=\"key\">"
-              "<value/>"
-            "</item>"
-          "</publish>"
-        "</pubsub>"
-      "</cli:iq>";
-
-  ASSERT_EQ(1U, xmpp_client->sent_stanzas().size());
-  EXPECT_EQ(expected_iq, xmpp_client->sent_stanzas()[0]->Str());
-
-  std::string result_iq =
-      "<iq xmlns='jabber:client' id='0' type='result' from='room@domain.com'/>";
-
-  xmpp_client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
-  EXPECT_EQ(task_id, listener->result_task_id);
-}
-
-TEST_F(PubSubClientTest, TestPublishError) {
-  buzz::XmlElement* payload =
-      new buzz::XmlElement(buzz::QName(buzz::NS_PUBSUB, "value"));
-
-  std::string task_id;
-  client->PublishItem(itemid, payload, &task_id);
-
-  std::string result_iq =
-      "<iq xmlns='jabber:client' id='0' type='error' from='room@domain.com'>"
-      "  <error type='auth'>"
-      "    <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>"
-      "  </error>"
-      "</iq>";
-
-  xmpp_client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
-  EXPECT_EQ(1, listener->error_count);
-  EXPECT_EQ(task_id, listener->error_task_id);
-}
-
-TEST_F(PubSubClientTest, TestRetract) {
-  std::string task_id;
-  client->RetractItem(itemid, &task_id);
-
-  std::string expected_iq =
-      "<cli:iq type=\"set\" to=\"room@domain.com\" id=\"0\" "
-        "xmlns:cli=\"jabber:client\">"
-        "<pubsub xmlns=\"http://jabber.org/protocol/pubsub\">"
-          "<retract node=\"topic\" notify=\"true\">"
-            "<item id=\"key\"/>"
-          "</retract>"
-        "</pubsub>"
-      "</cli:iq>";
-
-  ASSERT_EQ(1U, xmpp_client->sent_stanzas().size());
-  EXPECT_EQ(expected_iq, xmpp_client->sent_stanzas()[0]->Str());
-
-  std::string result_iq =
-      "<iq xmlns='jabber:client' id='0' type='result' from='room@domain.com'/>";
-
-  xmpp_client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
-  EXPECT_EQ(task_id, listener->result_task_id);
-}
-
-TEST_F(PubSubClientTest, TestRetractError) {
-  std::string task_id;
-  client->RetractItem(itemid, &task_id);
-
-  std::string result_iq =
-      "<iq xmlns='jabber:client' id='0' type='error' from='room@domain.com'>"
-      "  <error type='auth'>"
-      "    <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>"
-      "  </error>"
-      "</iq>";
-
-  xmpp_client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
-  EXPECT_EQ(1, listener->error_count);
-  EXPECT_EQ(task_id, listener->error_task_id);
-}
diff --git a/third_party/libjingle/source/talk/xmpp/pubsubtasks.cc b/third_party/libjingle/source/talk/xmpp/pubsubtasks.cc
deleted file mode 100644
index bbefbe5..0000000
--- a/third_party/libjingle/source/talk/xmpp/pubsubtasks.cc
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * libjingle
- * Copyright 2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/xmpp/pubsubtasks.h"
-
-#include <string>
-#include <vector>
-
-#include "talk/xmpp/constants.h"
-#include "talk/xmpp/receivetask.h"
-
-// An implementation of the tasks for XEP-0060
-// (http://xmpp.org/extensions/xep-0060.html).
-
-namespace buzz {
-
-namespace {
-
-bool IsPubSubEventItemsElem(const XmlElement* stanza,
-                            const std::string& expected_node) {
-  if (stanza->Name() != QN_MESSAGE) {
-    return false;
-  }
-
-  const XmlElement* event_elem = stanza->FirstNamed(QN_PUBSUB_EVENT);
-  if (event_elem == NULL) {
-    return false;
-  }
-
-  const XmlElement* items_elem = event_elem->FirstNamed(QN_PUBSUB_EVENT_ITEMS);
-  if (items_elem == NULL) {
-    return false;
-  }
-
-  const std::string& actual_node = items_elem->Attr(QN_NODE);
-  return (actual_node == expected_node);
-}
-
-
-// Creates <pubsub node="node"><items></pubsub>
-XmlElement* CreatePubSubItemsElem(const std::string& node) {
-  XmlElement* items_elem = new XmlElement(QN_PUBSUB_ITEMS, false);
-  items_elem->AddAttr(QN_NODE, node);
-  XmlElement* pubsub_elem = new XmlElement(QN_PUBSUB, false);
-  pubsub_elem->AddElement(items_elem);
-  return pubsub_elem;
-}
-
-// Creates <pubsub node="node"><publish><item id="itemid">payload</item>...
-// Takes ownership of payload.
-XmlElement* CreatePubSubPublishItemElem(
-    const std::string& node,
-    const std::string& itemid,
-    const std::vector<XmlElement*>& children) {
-  XmlElement* pubsub_elem = new XmlElement(QN_PUBSUB, true);
-  XmlElement* publish_elem = new XmlElement(QN_PUBSUB_PUBLISH, false);
-  publish_elem->AddAttr(QN_NODE, node);
-  XmlElement* item_elem = new XmlElement(QN_PUBSUB_ITEM, false);
-  item_elem->AddAttr(QN_ID, itemid);
-  for (std::vector<XmlElement*>::const_iterator child = children.begin();
-       child != children.end(); ++child) {
-    item_elem->AddElement(*child);
-  }
-  publish_elem->AddElement(item_elem);
-  pubsub_elem->AddElement(publish_elem);
-  return pubsub_elem;
-}
-
-// Creates <pubsub node="node"><publish><item id="itemid">payload</item>...
-// Takes ownership of payload.
-XmlElement* CreatePubSubRetractItemElem(const std::string& node,
-                                        const std::string& itemid) {
-  XmlElement* pubsub_elem = new XmlElement(QN_PUBSUB, true);
-  XmlElement* retract_elem = new XmlElement(QN_PUBSUB_RETRACT, false);
-  retract_elem->AddAttr(QN_NODE, node);
-  retract_elem->AddAttr(QN_NOTIFY, "true");
-  XmlElement* item_elem = new XmlElement(QN_PUBSUB_ITEM, false);
-  item_elem->AddAttr(QN_ID, itemid);
-  retract_elem->AddElement(item_elem);
-  pubsub_elem->AddElement(retract_elem);
-  return pubsub_elem;
-}
-
-void ParseItem(const XmlElement* item_elem,
-               std::vector<PubSubItem>* items) {
-  PubSubItem item;
-  item.itemid = item_elem->Attr(QN_ID);
-  item.elem = item_elem;
-  items->push_back(item);
-}
-
-// Right now, <retract>s are treated the same as items with empty
-// payloads.  We may want to change it in the future, but right now
-// it's sufficient for our needs.
-void ParseRetract(const XmlElement* retract_elem,
-                  std::vector<PubSubItem>* items) {
-  ParseItem(retract_elem, items);
-}
-
-void ParseEventItemsElem(const XmlElement* stanza,
-                         std::vector<PubSubItem>* items) {
-  const XmlElement* event_elem = stanza->FirstNamed(QN_PUBSUB_EVENT);
-  if (event_elem != NULL) {
-    const XmlElement* items_elem =
-        event_elem->FirstNamed(QN_PUBSUB_EVENT_ITEMS);
-    if (items_elem != NULL) {
-      for (const XmlElement* item_elem =
-             items_elem->FirstNamed(QN_PUBSUB_EVENT_ITEM);
-           item_elem != NULL;
-           item_elem = item_elem->NextNamed(QN_PUBSUB_EVENT_ITEM)) {
-        ParseItem(item_elem, items);
-      }
-      for (const XmlElement* retract_elem =
-             items_elem->FirstNamed(QN_PUBSUB_EVENT_RETRACT);
-           retract_elem != NULL;
-           retract_elem = retract_elem->NextNamed(QN_PUBSUB_EVENT_RETRACT)) {
-        ParseRetract(retract_elem, items);
-      }
-    }
-  }
-}
-
-void ParsePubSubItemsElem(const XmlElement* stanza,
-                          std::vector<PubSubItem>* items) {
-  const XmlElement* pubsub_elem = stanza->FirstNamed(QN_PUBSUB);
-  if (pubsub_elem != NULL) {
-    const XmlElement* items_elem = pubsub_elem->FirstNamed(QN_PUBSUB_ITEMS);
-    if (items_elem != NULL) {
-      for (const XmlElement* item_elem = items_elem->FirstNamed(QN_PUBSUB_ITEM);
-           item_elem != NULL;
-           item_elem = item_elem->NextNamed(QN_PUBSUB_ITEM)) {
-        ParseItem(item_elem, items);
-      }
-    }
-  }
-}
-
-}  // namespace
-
-PubSubRequestTask::PubSubRequestTask(XmppTaskParentInterface* parent,
-                                     const Jid& pubsubjid,
-                                     const std::string& node)
-    : IqTask(parent, STR_GET, pubsubjid, CreatePubSubItemsElem(node)) {
-}
-
-void PubSubRequestTask::HandleResult(const XmlElement* stanza) {
-  std::vector<PubSubItem> items;
-  ParsePubSubItemsElem(stanza, &items);
-  SignalResult(this, items);
-}
-
-bool PubSubReceiveTask::WantsStanza(const XmlElement* stanza) {
-  return MatchStanzaFrom(stanza, pubsubjid_) &&
-      IsPubSubEventItemsElem(stanza, node_);
-}
-
-void PubSubReceiveTask::ReceiveStanza(const XmlElement* stanza) {
-  std::vector<PubSubItem> items;
-  ParseEventItemsElem(stanza, &items);
-  SignalUpdate(this, items);
-}
-
-PubSubPublishTask::PubSubPublishTask(XmppTaskParentInterface* parent,
-                                     const Jid& pubsubjid,
-                                     const std::string& node,
-                                     const std::string& itemid,
-                                     const std::vector<XmlElement*>& children)
-    : IqTask(parent, STR_SET, pubsubjid,
-             CreatePubSubPublishItemElem(node, itemid, children)),
-      itemid_(itemid) {
-}
-
-void PubSubPublishTask::HandleResult(const XmlElement* stanza) {
-  SignalResult(this);
-}
-
-PubSubRetractTask::PubSubRetractTask(XmppTaskParentInterface* parent,
-                                     const Jid& pubsubjid,
-                                     const std::string& node,
-                                     const std::string& itemid)
-    : IqTask(parent, STR_SET, pubsubjid,
-             CreatePubSubRetractItemElem(node, itemid)),
-      itemid_(itemid) {
-}
-
-void PubSubRetractTask::HandleResult(const XmlElement* stanza) {
-  SignalResult(this);
-}
-
-}  // namespace buzz
diff --git a/third_party/libjingle/source/talk/xmpp/pubsubtasks.h b/third_party/libjingle/source/talk/xmpp/pubsubtasks.h
deleted file mode 100644
index f0a1581..0000000
--- a/third_party/libjingle/source/talk/xmpp/pubsubtasks.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * libjingle
- * Copyright 2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_XMPP_PUBSUBTASKS_H_
-#define TALK_XMPP_PUBSUBTASKS_H_
-
-#include <vector>
-
-#include "talk/base/sigslot.h"
-#include "talk/xmpp/iqtask.h"
-#include "talk/xmpp/receivetask.h"
-
-namespace buzz {
-
-// A PubSub itemid + payload.  Useful for signaling items.
-struct PubSubItem {
-  std::string itemid;
-  // The entire <item>, owned by the stanza handler.  To keep a
-  // reference after handling, make a copy.
-  const XmlElement* elem;
-};
-
-// An IqTask which gets a <pubsub><items> for a particular jid and
-// node, parses the items in the response and signals the items.
-class PubSubRequestTask : public IqTask {
- public:
-  PubSubRequestTask(XmppTaskParentInterface* parent,
-                    const Jid& pubsubjid,
-                    const std::string& node);
-
-  sigslot::signal2<PubSubRequestTask*,
-                   const std::vector<PubSubItem>&> SignalResult;
-  // SignalError inherited by IqTask.
- private:
-  virtual void HandleResult(const XmlElement* stanza);
-};
-
-// A ReceiveTask which listens for <event><items> of a particular
-// pubsub JID and node and then signals them items.
-class PubSubReceiveTask : public ReceiveTask {
- public:
-  PubSubReceiveTask(XmppTaskParentInterface* parent,
-                    const Jid& pubsubjid,
-                    const std::string& node)
-      : ReceiveTask(parent),
-        pubsubjid_(pubsubjid),
-        node_(node) {
-  }
-
-  sigslot::signal2<PubSubReceiveTask*,
-                   const std::vector<PubSubItem>&> SignalUpdate;
-
- protected:
-  virtual bool WantsStanza(const XmlElement* stanza);
-  virtual void ReceiveStanza(const XmlElement* stanza);
-
- private:
-  Jid pubsubjid_;
-  std::string node_;
-};
-
-// An IqTask which publishes a <pubsub><publish><item> to a particular
-// pubsub jid and node.
-class PubSubPublishTask : public IqTask {
- public:
-  // Takes ownership of children
-  PubSubPublishTask(XmppTaskParentInterface* parent,
-                    const Jid& pubsubjid,
-                    const std::string& node,
-                    const std::string& itemid,
-                    const std::vector<XmlElement*>& children);
-
-  const std::string& itemid() const { return itemid_; }
-
-  sigslot::signal1<PubSubPublishTask*> SignalResult;
-
- private:
-  // SignalError inherited by IqTask.
-  virtual void HandleResult(const XmlElement* stanza);
-
-  std::string itemid_;
-};
-
-// An IqTask which publishes a <pubsub><publish><retract> to a particular
-// pubsub jid and node.
-class PubSubRetractTask : public IqTask {
- public:
-  PubSubRetractTask(XmppTaskParentInterface* parent,
-                    const Jid& pubsubjid,
-                    const std::string& node,
-                    const std::string& itemid);
-
-  const std::string& itemid() const { return itemid_; }
-
-  sigslot::signal1<PubSubRetractTask*> SignalResult;
-
- private:
-  // SignalError inherited by IqTask.
-  virtual void HandleResult(const XmlElement* stanza);
-
-  std::string itemid_;
-};
-
-}  // namespace buzz
-
-#endif  // TALK_XMPP_PUBSUBTASKS_H_
diff --git a/third_party/libjingle/source/talk/xmpp/pubsubtasks_unittest.cc b/third_party/libjingle/source/talk/xmpp/pubsubtasks_unittest.cc
deleted file mode 100644
index 67fc306..0000000
--- a/third_party/libjingle/source/talk/xmpp/pubsubtasks_unittest.cc
+++ /dev/null
@@ -1,273 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved
-
-
-#include <string>
-
-#include "talk/base/faketaskrunner.h"
-#include "talk/base/gunit.h"
-#include "talk/base/sigslot.h"
-#include "talk/xmllite/qname.h"
-#include "talk/xmllite/xmlelement.h"
-#include "talk/xmpp/constants.h"
-#include "talk/xmpp/iqtask.h"
-#include "talk/xmpp/fakexmppclient.h"
-#include "talk/xmpp/jid.h"
-#include "talk/xmpp/pubsubtasks.h"
-
-struct HandledPubSubItem {
-  std::string itemid;
-  std::string payload;
-};
-
-class TestPubSubTasksListener : public sigslot::has_slots<> {
- public:
-  TestPubSubTasksListener() : result_count(0), error_count(0) {}
-
-  void OnReceiveUpdate(buzz::PubSubReceiveTask* task,
-                       const std::vector<buzz::PubSubItem>& items) {
-    OnItems(items);
-  }
-
-  void OnRequestResult(buzz::PubSubRequestTask* task,
-                       const std::vector<buzz::PubSubItem>& items) {
-    OnItems(items);
-  }
-
-  void OnItems(const std::vector<buzz::PubSubItem>& items) {
-    for (std::vector<buzz::PubSubItem>::const_iterator item = items.begin();
-         item != items.end(); ++item) {
-      HandledPubSubItem handled_item;
-      handled_item.itemid = item->itemid;
-      if (item->elem->FirstElement() != NULL) {
-        handled_item.payload = item->elem->FirstElement()->Str();
-      }
-      this->items.push_back(handled_item);
-    }
-  }
-
-  void OnPublishResult(buzz::PubSubPublishTask* task) {
-    ++result_count;
-  }
-
-  void OnRetractResult(buzz::PubSubRetractTask* task) {
-    ++result_count;
-  }
-
-  void OnError(buzz::IqTask* task, const buzz::XmlElement* stanza) {
-    ++error_count;
-  }
-
-  std::vector<HandledPubSubItem> items;
-  int result_count;
-  int error_count;
-};
-
-class PubSubTasksTest : public testing::Test {
- public:
-  PubSubTasksTest() :
-      pubsubjid("room@domain.com"),
-      node("topic"),
-      itemid("key") {
-    runner.reset(new talk_base::FakeTaskRunner());
-    client = new buzz::FakeXmppClient(runner.get());
-    listener.reset(new TestPubSubTasksListener());
-  }
-
-  talk_base::scoped_ptr<talk_base::FakeTaskRunner> runner;
-  // Client deleted by deleting runner.
-  buzz::FakeXmppClient* client;
-  talk_base::scoped_ptr<TestPubSubTasksListener> listener;
-  buzz::Jid pubsubjid;
-  std::string node;
-  std::string itemid;
-};
-
-TEST_F(PubSubTasksTest, TestRequest) {
-  buzz::PubSubRequestTask* task =
-      new buzz::PubSubRequestTask(client, pubsubjid, node);
-  task->SignalResult.connect(
-      listener.get(), &TestPubSubTasksListener::OnRequestResult);
-  task->Start();
-
-  std::string expected_iq =
-      "<cli:iq type=\"get\" to=\"room@domain.com\" id=\"0\" "
-        "xmlns:cli=\"jabber:client\">"
-        "<pub:pubsub xmlns:pub=\"http://jabber.org/protocol/pubsub\">"
-          "<pub:items node=\"topic\"/>"
-        "</pub:pubsub>"
-      "</cli:iq>";
-
-  ASSERT_EQ(1U, client->sent_stanzas().size());
-  EXPECT_EQ(expected_iq, client->sent_stanzas()[0]->Str());
-
-  std::string result_iq =
-      "<iq xmlns='jabber:client' id='0' type='result' from='room@domain.com'>"
-      "  <pubsub xmlns='http://jabber.org/protocol/pubsub'>"
-      "    <items node='topic'>"
-      "      <item id='key0'>"
-      "        <value0/>"
-      "      </item>"
-      "      <item id='key1'>"
-      "        <value1/>"
-      "      </item>"
-      "    </items>"
-      "  </pubsub>"
-      "</iq>";
-
-  client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
-
-  ASSERT_EQ(2U, listener->items.size());
-  EXPECT_EQ("key0", listener->items[0].itemid);
-  EXPECT_EQ("<pub:value0 xmlns:pub=\"http://jabber.org/protocol/pubsub\"/>",
-            listener->items[0].payload);
-  EXPECT_EQ("key1", listener->items[1].itemid);
-  EXPECT_EQ("<pub:value1 xmlns:pub=\"http://jabber.org/protocol/pubsub\"/>",
-            listener->items[1].payload);
-}
-
-TEST_F(PubSubTasksTest, TestRequestError) {
-  std::string result_iq =
-      "<iq xmlns='jabber:client' id='0' type='error' from='room@domain.com'>"
-      "  <error type='auth'>"
-      "    <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>"
-      "  </error>"
-      "</iq>";
-
-  buzz::PubSubRequestTask* task =
-      new buzz::PubSubRequestTask(client, pubsubjid, node);
-  task->SignalResult.connect(
-      listener.get(), &TestPubSubTasksListener::OnRequestResult);
-  task->SignalError.connect(
-      listener.get(), &TestPubSubTasksListener::OnError);
-  task->Start();
-  client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
-
-  EXPECT_EQ(0, listener->result_count);
-  EXPECT_EQ(1, listener->error_count);
-}
-
-TEST_F(PubSubTasksTest, TestReceive) {
-  std::string items_message =
-      "<message xmlns='jabber:client' from='room@domain.com'>"
-      "  <event xmlns='http://jabber.org/protocol/pubsub#event'>"
-      "    <items node='topic'>"
-      "      <item id='key0'>"
-      "        <value0/>"
-      "      </item>"
-      "      <item id='key1'>"
-      "        <value1/>"
-      "      </item>"
-      "    </items>"
-      "  </event>"
-      "</message>";
-
-  buzz::PubSubReceiveTask* task =
-      new buzz::PubSubReceiveTask(client, pubsubjid, node);
-  task->SignalUpdate.connect(
-      listener.get(), &TestPubSubTasksListener::OnReceiveUpdate);
-  task->Start();
-  client->HandleStanza(buzz::XmlElement::ForStr(items_message));
-
-  ASSERT_EQ(2U, listener->items.size());
-  EXPECT_EQ("key0", listener->items[0].itemid);
-  EXPECT_EQ(
-      "<eve:value0 xmlns:eve=\"http://jabber.org/protocol/pubsub#event\"/>",
-      listener->items[0].payload);
-  EXPECT_EQ("key1", listener->items[1].itemid);
-  EXPECT_EQ(
-      "<eve:value1 xmlns:eve=\"http://jabber.org/protocol/pubsub#event\"/>",
-      listener->items[1].payload);
-}
-
-TEST_F(PubSubTasksTest, TestPublish) {
-  buzz::XmlElement* payload =
-      new buzz::XmlElement(buzz::QName(buzz::NS_PUBSUB, "value"));
-  std::string expected_iq =
-      "<cli:iq type=\"set\" to=\"room@domain.com\" id=\"0\" "
-        "xmlns:cli=\"jabber:client\">"
-        "<pubsub xmlns=\"http://jabber.org/protocol/pubsub\">"
-          "<publish node=\"topic\">"
-            "<item id=\"key\">"
-              "<value/>"
-            "</item>"
-          "</publish>"
-        "</pubsub>"
-      "</cli:iq>";
-
-  std::vector<buzz::XmlElement*> children;
-  children.push_back(payload);
-  buzz::PubSubPublishTask* task =
-      new buzz::PubSubPublishTask(client, pubsubjid, node, itemid, children);
-  task->SignalResult.connect(
-      listener.get(), &TestPubSubTasksListener::OnPublishResult);
-  task->Start();
-
-  ASSERT_EQ(1U, client->sent_stanzas().size());
-  EXPECT_EQ(expected_iq, client->sent_stanzas()[0]->Str());
-
-  std::string result_iq =
-      "<iq xmlns='jabber:client' id='0' type='result' from='room@domain.com'/>";
-
-  client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
-
-  EXPECT_EQ(1, listener->result_count);
-  EXPECT_EQ(0, listener->error_count);
-}
-
-TEST_F(PubSubTasksTest, TestPublishError) {
-  buzz::XmlElement* payload =
-      new buzz::XmlElement(buzz::QName(buzz::NS_PUBSUB, "value"));
-
-  std::vector<buzz::XmlElement*> children;
-  children.push_back(payload);
-  buzz::PubSubPublishTask* task =
-      new buzz::PubSubPublishTask(client, pubsubjid, node, itemid, children);
-  task->SignalResult.connect(
-      listener.get(), &TestPubSubTasksListener::OnPublishResult);
-  task->SignalError.connect(
-      listener.get(), &TestPubSubTasksListener::OnError);
-  task->Start();
-
-  std::string result_iq =
-      "<iq xmlns='jabber:client' id='0' type='error' from='room@domain.com'>"
-      "  <error type='auth'>"
-      "    <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>"
-      "  </error>"
-      "</iq>";
-
-  client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
-
-  EXPECT_EQ(0, listener->result_count);
-  EXPECT_EQ(1, listener->error_count);
-}
-
-TEST_F(PubSubTasksTest, TestRetract) {
-  buzz::PubSubRetractTask* task =
-      new buzz::PubSubRetractTask(client, pubsubjid, node, itemid);
-  task->SignalResult.connect(
-      listener.get(), &TestPubSubTasksListener::OnRetractResult);
-  task->SignalError.connect(
-      listener.get(), &TestPubSubTasksListener::OnError);
-  task->Start();
-
-  std::string expected_iq =
-      "<cli:iq type=\"set\" to=\"room@domain.com\" id=\"0\" "
-        "xmlns:cli=\"jabber:client\">"
-        "<pubsub xmlns=\"http://jabber.org/protocol/pubsub\">"
-          "<retract node=\"topic\" notify=\"true\">"
-            "<item id=\"key\"/>"
-          "</retract>"
-        "</pubsub>"
-      "</cli:iq>";
-
-  ASSERT_EQ(1U, client->sent_stanzas().size());
-  EXPECT_EQ(expected_iq, client->sent_stanzas()[0]->Str());
-
-  std::string result_iq =
-      "<iq xmlns='jabber:client' id='0' type='result' from='room@domain.com'/>";
-
-  client->HandleStanza(buzz::XmlElement::ForStr(result_iq));
-
-  EXPECT_EQ(1, listener->result_count);
-  EXPECT_EQ(0, listener->error_count);
-}
diff --git a/third_party/libjingle/source/talk/xmpp/ratelimitmanager.cc b/third_party/libjingle/source/talk/xmpp/ratelimitmanager.cc
deleted file mode 100644
index 14667a7..0000000
--- a/third_party/libjingle/source/talk/xmpp/ratelimitmanager.cc
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2006, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <list>
-#include <string>
-
-#include "talk/xmpp/ratelimitmanager.h"
-
-namespace buzz {
-
-RateLimitManager::RateLimit* RateLimitManager::GetRateLimit(
-    const std::string event_name) {
-  RateLimitMap::iterator it = rate_limits_.find(event_name);
-  if (it != rate_limits_.end()) {
-    return it->second;
-  }
-  return NULL;
-}
-
-bool RateLimitManager::IsWithinRateLimit(const std::string event_name) {
-  RateLimit* current_rate = GetRateLimit(event_name);
-  if (current_rate) {
-    return current_rate->IsWithinRateLimit();
-  }
-  return true; // If no rate limit is set, then you must be under the limit
-}
-
-void RateLimitManager::UpdateRateLimit(const std::string event_name, 
-                                       int max_count, 
-                                       int per_x_seconds) {
-  RateLimit* current_rate = GetRateLimit(event_name);
-  if (!current_rate) {
-    current_rate = new RateLimit(max_count, per_x_seconds);
-    rate_limits_[event_name] = current_rate;
-  }
-  current_rate->UpdateRateLimit();
-}                            
-
-bool RateLimitManager::VerifyRateLimit(const std::string event_name, 
-                                       int max_count, 
-                                       int per_x_seconds) {
-  return VerifyRateLimit(event_name, max_count, per_x_seconds, false);
-}
-
-bool RateLimitManager::VerifyRateLimit(const std::string event_name, 
-                                       int max_count, 
-                                       int per_x_seconds, 
-                                       bool always_update) {
-  bool within_rate_limit = IsWithinRateLimit(event_name);
-  if (within_rate_limit || always_update) {
-    UpdateRateLimit(event_name, max_count, per_x_seconds);
-  }
-  return within_rate_limit;
-}
-
-}
diff --git a/third_party/libjingle/source/talk/xmpp/ratelimitmanager.h b/third_party/libjingle/source/talk/xmpp/ratelimitmanager.h
deleted file mode 100644
index 288084f..0000000
--- a/third_party/libjingle/source/talk/xmpp/ratelimitmanager.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2006, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _RATELIMITMANAGER_H_
-#define _RATELIMITMANAGER_H_
-
-#include "talk/base/timeutils.h"
-#include "talk/base/taskrunner.h"
-#include <map>
-
-namespace buzz {
-
-/////////////////////////////////////////////////////////////////////
-//
-// RATELIMITMANAGER
-//
-/////////////////////////////////////////////////////////////////////
-//
-// RateLimitManager imposes client-side rate limiting for xmpp tasks and
-// other events.  It ensures that no more than i events with a given name 
-// can occur within k seconds. 
-//
-// A buffer tracks the previous max_count events.  Before an event is allowed
-// to occur, it can check its rate limit with a call to VerifyRateLimit.  
-// VerifyRateLimit will look up the i-th to last event and if more than
-// k seconds have passed since then, it will return true and update the 
-// appropriate rate limits.  Else, it will return false. 
-//
-/////////////////////////////////////////////////////////////////////
-
-class RateLimitManager {
- public:
-
-  RateLimitManager() { };
-  ~RateLimitManager() { 
-    for (RateLimitMap::iterator it = rate_limits_.begin();
-         it != rate_limits_.end(); ++it) {
-      delete it->second;
-    }
-  };
-
-  // Checks if the event is under the defined rate limit and updates the
-  // rate limit if so.  Returns true if it's under the rate limit.
-  bool VerifyRateLimit(const std::string event_name, int max_count, 
-                       int per_x_seconds);
-
-  // Checks if the event is under the defined rate limit and updates the
-  // rate limit if so *or* if always_update = true.  
-  bool VerifyRateLimit(const std::string event_name, int max_count, 
-                       int per_x_seconds, bool always_update);
-
- private:
-  class RateLimit {
-   public:
-    RateLimit(int max, int per_x_secs) : counter_(0), max_count_(max),
-                                         per_x_seconds_(per_x_secs) {
-      event_times_ = new uint32[max_count_];                                                 
-      for (int i = 0; i < max_count_; i++) {
-        event_times_[i] = 0;
-      }
-    }
-
-    ~RateLimit() {
-      if (event_times_) {
-        delete[] event_times_;
-      }
-    }
-
-    // True iff the current time >= to the next song allowed time
-    bool IsWithinRateLimit() {
-      return (talk_base::TimeSince(NextTimeAllowedForCounter()) >= 0);
-    }
-    
-    // Updates time and counter for rate limit
-    void UpdateRateLimit() {
-      event_times_[counter_] = talk_base::Time();
-      counter_ = (counter_ + 1) % max_count_;
-    }
-
-   private:
-
-    // The time at which the i-th (where i = max_count) event occured
-    uint32 PreviousTimeAtCounter() {
-      return event_times_[counter_];
-    }
-
-    // The time that the next event is allowed to occur
-    uint32 NextTimeAllowedForCounter() {
-      return PreviousTimeAtCounter() + per_x_seconds_ * talk_base::kSecToMsec;
-    }
-
-    int counter_; // count modulo max_count of the current event
-    int max_count_; // max number of events that can occur within per_x_seconds
-    int per_x_seconds_; // interval size for rate limit
-    uint32* event_times_; // buffer of previous max_count event
-  };
-
-  typedef std::map<const std::string, RateLimit*> RateLimitMap;
-
-  // Maps from event name to its rate limit
-  RateLimitMap rate_limits_;
-
-  // Returns rate limit for event with specified name
-  RateLimit* GetRateLimit(const std::string event_name);
-
-  // True iff the current time >= to the next song allowed time
-  bool IsWithinRateLimit(const std::string event_name);
-
-  // Updates time and counter for rate limit
-  void UpdateRateLimit(const std::string event_name, int max_count, 
-                       int per_x_seconds); 
-
-};
-
-}
-
-#endif //_RATELIMITMANAGER_H_
diff --git a/third_party/libjingle/source/talk/xmpp/receivetask.cc b/third_party/libjingle/source/talk/xmpp/receivetask.cc
deleted file mode 100644
index 53fac7e..0000000
--- a/third_party/libjingle/source/talk/xmpp/receivetask.cc
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * libjingle
- * Copyright 2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/xmpp/receivetask.h"
-#include "talk/xmpp/constants.h"
-
-namespace buzz {
-
-bool ReceiveTask::HandleStanza(const XmlElement* stanza) {
-  if (WantsStanza(stanza)) {
-    QueueStanza(stanza);
-    return true;
-  }
-
-  return false;
-}
-
-int ReceiveTask::ProcessStart() {
-  const XmlElement* stanza = NextStanza();
-  if (stanza == NULL)
-    return STATE_BLOCKED;
-
-  ReceiveStanza(stanza);
-  return STATE_START;
-}
-
-}  // namespace buzz
diff --git a/third_party/libjingle/source/talk/xmpp/receivetask.h b/third_party/libjingle/source/talk/xmpp/receivetask.h
deleted file mode 100644
index b18e0f0..0000000
--- a/third_party/libjingle/source/talk/xmpp/receivetask.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * libjingle
- * Copyright 2011, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_XMPP_RECEIVETASK_H_
-#define TALK_XMPP_RECEIVETASK_H_
-
-#include "talk/xmpp/xmpptask.h"
-
-namespace buzz {
-
-// A base class for receiving stanzas.  Override WantsStanza to
-// indicate that a stanza should be received and ReceiveStanza to
-// process it.  Once started, ReceiveStanza will be called for all
-// stanzas that return true when passed to WantsStanza. This saves
-// you from having to remember how to setup the queueing and the task
-// states, etc.
-class ReceiveTask : public XmppTask {
- public:
-  explicit ReceiveTask(XmppTaskParentInterface* parent) :
-      XmppTask(parent, XmppEngine::HL_TYPE) {}
-  virtual int ProcessStart();
-
- protected:
-  virtual bool HandleStanza(const XmlElement* stanza);
-
-  // Return true if the stanza should be received.
-  virtual bool WantsStanza(const XmlElement* stanza) = 0;
-  // Process the received stanza.
-  virtual void ReceiveStanza(const XmlElement* stanza) = 0;
-};
-
-}  // namespace buzz
-
-#endif  // TALK_XMPP_RECEIVETASK_H_
diff --git a/third_party/libjingle/source/talk/xmpp/saslcookiemechanism.h b/third_party/libjingle/source/talk/xmpp/saslcookiemechanism.h
deleted file mode 100644
index fd65b94..0000000
--- a/third_party/libjingle/source/talk/xmpp/saslcookiemechanism.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _SASLCOOKIEMECHANISM_H_
-#define _SASLCOOKIEMECHANISM_H_
-
-#include "talk/xmllite/qname.h"
-#include "talk/xmllite/xmlelement.h"
-#include "talk/xmpp/saslmechanism.h"
-#include "talk/xmpp/constants.h"
-
-namespace buzz {
-
-class SaslCookieMechanism : public SaslMechanism {
-
-public:
-  SaslCookieMechanism(const std::string & mechanism,
-                      const std::string & username,
-                      const std::string & cookie,
-                      const std::string & token_service)
-    : mechanism_(mechanism),
-      username_(username),
-      cookie_(cookie),
-      token_service_(token_service) {}
-
-  SaslCookieMechanism(const std::string & mechanism,
-                      const std::string & username,
-                      const std::string & cookie)
-    : mechanism_(mechanism),
-      username_(username),
-      cookie_(cookie),
-      token_service_("") {}
-
-  virtual std::string GetMechanismName() { return mechanism_; }
-
-  virtual XmlElement * StartSaslAuth() {
-    // send initial request
-    XmlElement * el = new XmlElement(QN_SASL_AUTH, true);
-    el->AddAttr(QN_MECHANISM, mechanism_);
-    if (!token_service_.empty()) {
-      el->AddAttr(QName("http://www.google.com/talk/protocol/auth", "service"),
-                  token_service_);
-    }
-
-    std::string credential;
-    credential.append("\0", 1);
-    credential.append(username_);
-    credential.append("\0", 1);
-    credential.append(cookie_);
-    el->AddText(Base64Encode(credential));
-    return el;
-  }
-
-private:
-  std::string mechanism_;
-  std::string username_;
-  std::string cookie_;
-  std::string token_service_;
-};
-
-}
-
-#endif
diff --git a/third_party/libjingle/source/talk/xmpp/saslhandler.h b/third_party/libjingle/source/talk/xmpp/saslhandler.h
deleted file mode 100644
index bead8aa..0000000
--- a/third_party/libjingle/source/talk/xmpp/saslhandler.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _SASLHANDLER_H_
-#define _SASLHANDLER_H_
-
-#include <string>
-#include <vector>
-
-namespace buzz {
-
-class XmlElement;
-class SaslMechanism;
-
-// Creates mechanisms to deal with a given mechanism
-class SaslHandler {
-
-public:
-  
-  // Intended to be subclassed
-  virtual ~SaslHandler() {}
-
-  // Should pick the best method according to this handler
-  // returns the empty string if none are suitable
-  virtual std::string ChooseBestSaslMechanism(const std::vector<std::string> & mechanisms, bool encrypted) = 0;
-
-  // Creates a SaslMechanism for the given mechanism name (you own it
-  // once you get it).
-  // If not handled, return NULL.
-  virtual SaslMechanism * CreateSaslMechanism(const std::string & mechanism) = 0;
-};
-
-}
-
-#endif
diff --git a/third_party/libjingle/source/talk/xmpp/saslmechanism.cc b/third_party/libjingle/source/talk/xmpp/saslmechanism.cc
deleted file mode 100644
index 2645ac0..0000000
--- a/third_party/libjingle/source/talk/xmpp/saslmechanism.cc
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/base/base64.h"
-#include "talk/xmllite/xmlelement.h"
-#include "talk/xmpp/constants.h"
-#include "talk/xmpp/saslmechanism.h"
-
-using talk_base::Base64;
-
-namespace buzz {
-
-XmlElement *
-SaslMechanism::StartSaslAuth() {
-  return new XmlElement(QN_SASL_AUTH, true);
-}
-
-XmlElement *
-SaslMechanism::HandleSaslChallenge(const XmlElement * challenge) {
-  return new XmlElement(QN_SASL_ABORT, true);
-}
-
-void
-SaslMechanism::HandleSaslSuccess(const XmlElement * success) {
-}
-
-void
-SaslMechanism::HandleSaslFailure(const XmlElement * failure) {
-}
-
-std::string
-SaslMechanism::Base64Encode(const std::string & plain) {
-  return Base64::Encode(plain);
-}
-
-std::string
-SaslMechanism::Base64Decode(const std::string & encoded) {
-  return Base64::Decode(encoded, Base64::DO_LAX);
-}
-
-std::string
-SaslMechanism::Base64EncodeFromArray(const char * plain, size_t length) {
-  std::string result;
-  Base64::EncodeFromArray(plain, length, &result);
-  return result;
-}
-
-}
diff --git a/third_party/libjingle/source/talk/xmpp/saslmechanism.h b/third_party/libjingle/source/talk/xmpp/saslmechanism.h
deleted file mode 100644
index f2e5adc..0000000
--- a/third_party/libjingle/source/talk/xmpp/saslmechanism.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _SASLMECHANISM_H_
-#define _SASLMECHANISM_H_
-
-#include <string>
-
-namespace buzz {
-
-class XmlElement;
-
-
-// Defines a mechnanism to do SASL authentication.
-// Subclass instances should have a self-contained way to present
-// credentials.
-class SaslMechanism {
-
-public:
-  
-  // Intended to be subclassed
-  virtual ~SaslMechanism() {}
-
-  // Should return the name of the SASL mechanism, e.g., "PLAIN"
-  virtual std::string GetMechanismName() = 0;
-
-  // Should generate the initial "auth" request.  Default is just <auth/>.
-  virtual XmlElement * StartSaslAuth();
-
-  // Should respond to a SASL "<challenge>" request.  Default is
-  // to abort (for mechanisms that do not do challenge-response)
-  virtual XmlElement * HandleSaslChallenge(const XmlElement * challenge);
-
-  // Notification of a SASL "<success>".  Sometimes information
-  // is passed on success.
-  virtual void HandleSaslSuccess(const XmlElement * success);
-
-  // Notification of a SASL "<failure>".  Sometimes information
-  // for the user is passed on failure.
-  virtual void HandleSaslFailure(const XmlElement * failure);
-
-protected:
-  static std::string Base64Encode(const std::string & plain);
-  static std::string Base64Decode(const std::string & encoded);
-  static std::string Base64EncodeFromArray(const char * plain, size_t length);
-};
-
-}
-
-#endif
diff --git a/third_party/libjingle/source/talk/xmpp/saslplainmechanism.h b/third_party/libjingle/source/talk/xmpp/saslplainmechanism.h
deleted file mode 100644
index 72532e6..0000000
--- a/third_party/libjingle/source/talk/xmpp/saslplainmechanism.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _SASLPLAINMECHANISM_H_
-#define _SASLPLAINMECHANISM_H_
-
-#include "talk/base/cryptstring.h"
-#include "talk/xmpp/saslmechanism.h"
-
-namespace buzz {
-
-class SaslPlainMechanism : public SaslMechanism {
-
-public:
-  SaslPlainMechanism(const buzz::Jid user_jid, const talk_base::CryptString & password) :
-    user_jid_(user_jid), password_(password) {}
-
-  virtual std::string GetMechanismName() { return "PLAIN"; }
-    
-  virtual XmlElement * StartSaslAuth() {
-    // send initial request
-    XmlElement * el = new XmlElement(QN_SASL_AUTH, true);
-    el->AddAttr(QN_MECHANISM, "PLAIN");
-
-    talk_base::FormatCryptString credential;
-    credential.Append("\0", 1);
-    credential.Append(user_jid_.node());
-    credential.Append("\0", 1);
-    credential.Append(&password_);
-    el->AddText(Base64EncodeFromArray(credential.GetData(), credential.GetLength()));
-    return el;
-  }
-  
-private:
-  Jid user_jid_;
-  talk_base::CryptString password_;
-};
-
-}
-
-#endif
diff --git a/third_party/libjingle/source/talk/xmpp/util_unittest.cc b/third_party/libjingle/source/talk/xmpp/util_unittest.cc
deleted file mode 100644
index 91ecb69..0000000
--- a/third_party/libjingle/source/talk/xmpp/util_unittest.cc
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2004 Google, Inc. All Rights Reserved.
-// Author: Joe Beda
-
-#include <string>
-#include <sstream>
-#include <iostream>
-#include "talk/base/gunit.h"
-#include "talk/xmllite/xmlelement.h"
-#include "talk/xmpp/xmppengine.h"
-#include "talk/xmpp/util_unittest.h"
-
-namespace buzz {
-
-void XmppTestHandler::WriteOutput(const char * bytes, size_t len) {
-  output_ << std::string(bytes, len);
-}
-
-void XmppTestHandler::StartTls(const std::string & cname) {
-  output_ << "[START-TLS " << cname << "]";
-}
-
-void XmppTestHandler::CloseConnection() {
-  output_ << "[CLOSED]";
-}
-
-void XmppTestHandler::OnStateChange(int state) {
-  switch (static_cast<XmppEngine::State>(state)) {
-  case XmppEngine::STATE_START:
-    session_ << "[START]";
-    break;
-  case XmppEngine::STATE_OPENING:
-    session_ << "[OPENING]";
-    break;
-  case XmppEngine::STATE_OPEN:
-    session_ << "[OPEN]";
-    break;
-  case XmppEngine::STATE_CLOSED:
-    session_ << "[CLOSED]";
-    switch (engine_->GetError(NULL)) {
-    case XmppEngine::ERROR_NONE:
-      // do nothing
-      break;
-    case XmppEngine::ERROR_XML:
-      session_ << "[ERROR-XML]";
-      break;
-    case XmppEngine::ERROR_STREAM:
-      session_ << "[ERROR-STREAM]";
-      break;
-    case XmppEngine::ERROR_VERSION:
-      session_ << "[ERROR-VERSION]";
-      break;
-    case XmppEngine::ERROR_UNAUTHORIZED:
-      session_ << "[ERROR-UNAUTHORIZED]";
-      break;
-    case XmppEngine::ERROR_TLS:
-      session_ << "[ERROR-TLS]";
-      break;
-    case XmppEngine::ERROR_AUTH:
-      session_ << "[ERROR-AUTH]";
-      break;
-    case XmppEngine::ERROR_BIND:
-      session_ << "[ERROR-BIND]";
-      break;
-    case XmppEngine::ERROR_CONNECTION_CLOSED:
-      session_ << "[ERROR-CONNECTION-CLOSED]";
-      break;
-    case XmppEngine::ERROR_DOCUMENT_CLOSED:
-      session_ << "[ERROR-DOCUMENT-CLOSED]";
-      break;
-    }
-    break;
-  }
-}
-
-bool XmppTestHandler::HandleStanza(const XmlElement * stanza) {
-  stanza_ << stanza->Str();
-  return true;
-}
-
-std::string XmppTestHandler::OutputActivity() {
-  std::string result = output_.str();
-  output_.str("");
-  return result;
-}
-
-std::string XmppTestHandler::SessionActivity() {
-  std::string result = session_.str();
-  session_.str("");
-  return result;
-}
-
-std::string XmppTestHandler::StanzaActivity() {
-  std::string result = stanza_.str();
-  stanza_.str("");
-  return result;
-}
-
-}  // namespace buzz
diff --git a/third_party/libjingle/source/talk/xmpp/util_unittest.h b/third_party/libjingle/source/talk/xmpp/util_unittest.h
deleted file mode 100644
index bb0656c..0000000
--- a/third_party/libjingle/source/talk/xmpp/util_unittest.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_XMPP_UTIL_UNITTEST_H_
-#define TALK_XMPP_UTIL_UNITTEST_H_
-
-#include <string>
-#include <sstream>
-#include "talk/xmpp/xmppengine.h"
-
-namespace buzz {
-
-// This class captures callbacks from engine.
-class XmppTestHandler : public XmppOutputHandler,  public XmppSessionHandler,
-                        public XmppStanzaHandler {
- public:
-  explicit XmppTestHandler(XmppEngine* engine) : engine_(engine) {}
-  virtual ~XmppTestHandler() {}
-
-  void SetEngine(XmppEngine* engine);
-
-  // Output handler
-  virtual void WriteOutput(const char * bytes, size_t len);
-  virtual void StartTls(const std::string & cname);
-  virtual void CloseConnection();
-
-  // Session handler
-  virtual void OnStateChange(int state);
-
-  // Stanza handler
-  virtual bool HandleStanza(const XmlElement* stanza);
-
-  std::string OutputActivity();
-  std::string SessionActivity();
-  std::string StanzaActivity();
-
- private:
-  XmppEngine* engine_;
-  std::stringstream output_;
-  std::stringstream session_;
-  std::stringstream stanza_;
-};
-
-}  // namespace buzz
-
-inline std::ostream& operator<<(std::ostream& os, const buzz::Jid& jid) {
-  os << jid.Str();
-  return os;
-}
-
-#endif  // TALK_XMPP_UTIL_UNITTEST_H_
diff --git a/third_party/libjingle/source/talk/xmpp/xmppclient.cc b/third_party/libjingle/source/talk/xmpp/xmppclient.cc
deleted file mode 100644
index 563dc2a..0000000
--- a/third_party/libjingle/source/talk/xmpp/xmppclient.cc
+++ /dev/null
@@ -1,415 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "xmppclient.h"
-#include "xmpptask.h"
-#include "talk/base/sigslot.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/base/stringutils.h"
-#include "talk/xmpp/constants.h"
-#include "talk/xmpp/saslplainmechanism.h"
-#include "talk/xmpp/prexmppauth.h"
-#include "talk/xmpp/plainsaslhandler.h"
-
-namespace buzz {
-
-class XmppClient::Private :
-    public sigslot::has_slots<>,
-    public XmppSessionHandler,
-    public XmppOutputHandler {
-public:
-
-  Private(XmppClient * client) :
-    client_(client),
-    socket_(NULL),
-    engine_(NULL),
-    proxy_port_(0),
-    pre_engine_error_(XmppEngine::ERROR_NONE),
-    pre_engine_subcode_(0),
-    signal_closed_(false),
-    allow_plain_(false) {}
-
-  // the owner
-  XmppClient * const client_;
-
-  // the two main objects
-  talk_base::scoped_ptr<AsyncSocket> socket_;
-  talk_base::scoped_ptr<XmppEngine> engine_;
-  talk_base::scoped_ptr<PreXmppAuth> pre_auth_;
-  talk_base::CryptString pass_;
-  std::string auth_cookie_;
-  talk_base::SocketAddress server_;
-  std::string proxy_host_;
-  int proxy_port_;
-  XmppEngine::Error pre_engine_error_;
-  int pre_engine_subcode_;
-  CaptchaChallenge captcha_challenge_;
-  bool signal_closed_;
-  bool allow_plain_;
-
-  // implementations of interfaces
-  void OnStateChange(int state);
-  void WriteOutput(const char * bytes, size_t len);
-  void StartTls(const std::string & domainname);
-  void CloseConnection();
-
-  // slots for socket signals
-  void OnSocketConnected();
-  void OnSocketRead();
-  void OnSocketClosed();
-};
-
-bool IsTestServer(const std::string& server_name,
-                  const std::string& test_server_domain) {
-  return (!test_server_domain.empty() &&
-          talk_base::ends_with(server_name.c_str(),
-                               test_server_domain.c_str()));
-}
-
-XmppReturnStatus
-XmppClient::Connect(const XmppClientSettings & settings,
-    const std::string & lang, AsyncSocket * socket, PreXmppAuth * pre_auth) {
-  if (socket == NULL)
-    return XMPP_RETURN_BADARGUMENT;
-  if (d_->socket_.get() != NULL)
-    return XMPP_RETURN_BADSTATE;
-
-  d_->socket_.reset(socket);
-
-  d_->socket_->SignalConnected.connect(d_.get(), &Private::OnSocketConnected);
-  d_->socket_->SignalRead.connect(d_.get(), &Private::OnSocketRead);
-  d_->socket_->SignalClosed.connect(d_.get(), &Private::OnSocketClosed);
-
-  d_->engine_.reset(XmppEngine::Create());
-  d_->engine_->SetSessionHandler(d_.get());
-  d_->engine_->SetOutputHandler(d_.get());
-  if (!settings.resource().empty()) {
-    d_->engine_->SetRequestedResource(settings.resource());
-  }
-  d_->engine_->SetTls(settings.use_tls());
-
-  // The talk.google.com server returns a certificate with common-name:
-  //   CN="gmail.com" for @gmail.com accounts,
-  //   CN="googlemail.com" for @googlemail.com accounts,
-  //   CN="talk.google.com" for other accounts (such as @example.com),
-  // so we tweak the tls server setting for those other accounts to match the
-  // returned certificate CN of "talk.google.com".
-  // For other servers, we leave the strings empty, which causes the jid's
-  // domain to be used.  We do the same for gmail.com and googlemail.com as the
-  // returned CN matches the account domain in those cases.
-  std::string server_name = settings.server().IPAsString();
-  if (server_name == buzz::STR_TALK_GOOGLE_COM ||
-      server_name == buzz::STR_TALKX_L_GOOGLE_COM ||
-      server_name == buzz::STR_XMPP_GOOGLE_COM ||
-      server_name == buzz::STR_XMPPX_L_GOOGLE_COM ||
-      IsTestServer(server_name, settings.test_server_domain())) {
-    if (settings.host() != STR_GMAIL_COM &&
-        settings.host() != STR_GOOGLEMAIL_COM) {
-      d_->engine_->SetTlsServer("", STR_TALK_GOOGLE_COM);
-    }
-  }
-
-  // Set language
-  d_->engine_->SetLanguage(lang);
-
-  d_->engine_->SetUser(buzz::Jid(settings.user(), settings.host(), STR_EMPTY));
-
-  d_->pass_ = settings.pass();
-  d_->auth_cookie_ = settings.auth_cookie();
-  d_->server_ = settings.server();
-  d_->proxy_host_ = settings.proxy_host();
-  d_->proxy_port_ = settings.proxy_port();
-  d_->allow_plain_ = settings.allow_plain();
-  d_->pre_auth_.reset(pre_auth);
-
-  return XMPP_RETURN_OK;
-}
-
-XmppEngine::State
-XmppClient::GetState() const {
-  if (d_->engine_.get() == NULL)
-    return XmppEngine::STATE_NONE;
-  return d_->engine_->GetState();
-}
-
-XmppEngine::Error
-XmppClient::GetError(int *subcode) {
-  if (subcode) {
-    *subcode = 0;
-  }
-  if (d_->engine_.get() == NULL)
-    return XmppEngine::ERROR_NONE;
-  if (d_->pre_engine_error_ != XmppEngine::ERROR_NONE) {
-    if (subcode) {
-      *subcode = d_->pre_engine_subcode_;
-    }
-    return d_->pre_engine_error_;
-  }
-  return d_->engine_->GetError(subcode);
-}
-
-const XmlElement *
-XmppClient::GetStreamError() {
-  if (d_->engine_.get() == NULL) {
-    return NULL;
-  }
-  return d_->engine_->GetStreamError();
-}
-
-CaptchaChallenge XmppClient::GetCaptchaChallenge() {
-  if (d_->engine_.get() == NULL)
-    return CaptchaChallenge();
-  return d_->captcha_challenge_;
-}
-
-std::string
-XmppClient::GetAuthCookie() {
-  if (d_->engine_.get() == NULL)
-    return "";
-  return d_->auth_cookie_;
-}
-
-int
-XmppClient::ProcessStart() {
-  if (d_->pre_auth_.get()) {
-    d_->pre_auth_->SignalAuthDone.connect(this, &XmppClient::OnAuthDone);
-    d_->pre_auth_->StartPreXmppAuth(
-        d_->engine_->GetUser(), d_->server_, d_->pass_, d_->auth_cookie_);
-    d_->pass_.Clear(); // done with this;
-    return STATE_PRE_XMPP_LOGIN;
-  }
-  else {
-    d_->engine_->SetSaslHandler(new PlainSaslHandler(
-              d_->engine_->GetUser(), d_->pass_, d_->allow_plain_));
-    d_->pass_.Clear(); // done with this;
-    return STATE_START_XMPP_LOGIN;
-  }
-}
-
-void
-XmppClient::OnAuthDone() {
-  Wake();
-}
-
-int
-XmppClient::ProcessCookieLogin() {
-  // Don't know how this could happen, but crash reports show it as NULL
-  if (!d_->pre_auth_.get()) {
-    d_->pre_engine_error_ = XmppEngine::ERROR_AUTH;
-    EnsureClosed();
-    return STATE_ERROR;
-  }
-
-  // Wait until pre authentication is done is done
-  if (!d_->pre_auth_->IsAuthDone())
-    return STATE_BLOCKED;
-
-  if (!d_->pre_auth_->IsAuthorized()) {
-    // maybe split out a case when gaia is down?
-    if (d_->pre_auth_->HadError()) {
-      d_->pre_engine_error_ = XmppEngine::ERROR_AUTH;
-      d_->pre_engine_subcode_ = d_->pre_auth_->GetError();
-    }
-    else {
-      d_->pre_engine_error_ = XmppEngine::ERROR_UNAUTHORIZED;
-      d_->pre_engine_subcode_ = 0;
-      d_->captcha_challenge_ = d_->pre_auth_->GetCaptchaChallenge();
-    }
-    d_->pre_auth_.reset(NULL); // done with this
-    EnsureClosed();
-    return STATE_ERROR;
-  }
-
-  // Save auth cookie as a result
-  d_->auth_cookie_ = d_->pre_auth_->GetAuthCookie();
-
-  // transfer ownership of pre_auth_ to engine
-  d_->engine_->SetSaslHandler(d_->pre_auth_.release());
-  return STATE_START_XMPP_LOGIN;
-}
-
-int
-XmppClient::ProcessStartXmppLogin() {
-  // Done with pre-connect tasks - connect!
-  if (!d_->socket_->Connect(d_->server_)) {
-    EnsureClosed();
-    return STATE_ERROR;
-  }
-
-  return STATE_RESPONSE;
-}
-
-int
-XmppClient::ProcessResponse() {
-  // Hang around while we are connected.
-  if (!delivering_signal_ && (d_->engine_.get() == NULL ||
-    d_->engine_->GetState() == XmppEngine::STATE_CLOSED))
-    return STATE_DONE;
-  return STATE_BLOCKED;
-}
-
-XmppReturnStatus
-XmppClient::Disconnect() {
-  if (d_->socket_.get() == NULL)
-    return XMPP_RETURN_BADSTATE;
-  Abort();
-  d_->engine_->Disconnect();
-  d_->socket_.reset(NULL);
-  return XMPP_RETURN_OK;
-}
-
-XmppClient::XmppClient(TaskParent * parent)
-    : XmppTaskParentInterface(parent),
-      delivering_signal_(false),
-      valid_(false) {
-  d_.reset(new Private(this));
-  valid_ = true;
-}
-
-XmppClient::~XmppClient() {
-  valid_ = false;
-}
-
-const Jid &
-XmppClient::jid() const {
-  return d_->engine_->FullJid();
-}
-
-
-std::string
-XmppClient::NextId() {
-  return d_->engine_->NextId();
-}
-
-XmppReturnStatus
-XmppClient::SendStanza(const XmlElement * stanza) {
-  return d_->engine_->SendStanza(stanza);
-}
-
-XmppReturnStatus
-XmppClient::SendStanzaError(const XmlElement * old_stanza, XmppStanzaError xse, const std::string & message) {
-  return d_->engine_->SendStanzaError(old_stanza, xse, message);
-}
-
-XmppReturnStatus
-XmppClient::SendRaw(const std::string & text) {
-  return d_->engine_->SendRaw(text);
-}
-
-XmppEngine*
-XmppClient::engine() {
-  return d_->engine_.get();
-}
-
-void
-XmppClient::Private::OnSocketConnected() {
-  engine_->Connect();
-}
-
-void
-XmppClient::Private::OnSocketRead() {
-  char bytes[4096];
-  size_t bytes_read;
-  for (;;) {
-    if (!socket_->Read(bytes, sizeof(bytes), &bytes_read)) {
-      // TODO: deal with error information
-      return;
-    }
-
-    if (bytes_read == 0)
-      return;
-
-//#ifdef _DEBUG
-    client_->SignalLogInput(bytes, bytes_read);
-//#endif
-
-    engine_->HandleInput(bytes, bytes_read);
-  }
-}
-
-void
-XmppClient::Private::OnSocketClosed() {
-  int code = socket_->GetError();
-  engine_->ConnectionClosed(code);
-}
-
-void
-XmppClient::Private::OnStateChange(int state) {
-  if (state == XmppEngine::STATE_CLOSED) {
-    client_->EnsureClosed();
-  }
-  else {
-    client_->SignalStateChange((XmppEngine::State)state);
-  }
-  client_->Wake();
-}
-
-void
-XmppClient::Private::WriteOutput(const char * bytes, size_t len) {
-
-//#ifdef _DEBUG
-  client_->SignalLogOutput(bytes, len);
-//#endif
-
-  socket_->Write(bytes, len);
-  // TODO: deal with error information
-}
-
-void
-XmppClient::Private::StartTls(const std::string & domain) {
-#if defined(FEATURE_ENABLE_SSL)
-  socket_->StartTls(domain);
-#endif
-}
-
-void
-XmppClient::Private::CloseConnection() {
-  socket_->Close();
-}
-
-void
-XmppClient::AddXmppTask(XmppTask * task, XmppEngine::HandlerLevel level) {
-  d_->engine_->AddStanzaHandler(task, level);
-}
-
-void
-XmppClient::RemoveXmppTask(XmppTask * task) {
-  d_->engine_->RemoveStanzaHandler(task);
-}
-
-void
-XmppClient::EnsureClosed() {
-  if (!d_->signal_closed_) {
-    d_->signal_closed_ = true;
-    delivering_signal_ = true;
-    SignalStateChange(XmppEngine::STATE_CLOSED);
-    delivering_signal_ = false;
-  }
-}
-
-
-}
diff --git a/third_party/libjingle/source/talk/xmpp/xmppclient.h b/third_party/libjingle/source/talk/xmpp/xmppclient.h
deleted file mode 100644
index ad8b9a2..0000000
--- a/third_party/libjingle/source/talk/xmpp/xmppclient.h
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _XMPPCLIENT_H_
-#define _XMPPCLIENT_H_
-
-#include <string>
-#include "talk/base/basicdefs.h"
-#include "talk/base/sigslot.h"
-#include "talk/base/task.h"
-#include "talk/xmpp/asyncsocket.h"
-#include "talk/xmpp/xmppclientsettings.h"
-#include "talk/xmpp/xmppengine.h"
-#include "talk/xmpp/xmpptask.h"
-
-namespace buzz {
-
-class PreXmppAuth;
-class CaptchaChallenge;
-
-// Just some non-colliding number.  Could have picked "1".
-#define XMPP_CLIENT_TASK_CODE 0x366c1e47
-
-/////////////////////////////////////////////////////////////////////
-//
-// XMPPCLIENT
-//
-/////////////////////////////////////////////////////////////////////
-//
-// See Task first.  XmppClient is a parent task for XmppTasks.
-//
-// XmppClient is a task which is designed to be the parent task for
-// all tasks that depend on a single Xmpp connection.  If you want to,
-// for example, listen for subscription requests forever, then your
-// listener should be a task that is a child of the XmppClient that owns
-// the connection you are using.  XmppClient has all the utility methods
-// that basically drill through to XmppEngine.
-//
-// XmppClient is just a wrapper for XmppEngine, and if I were writing it
-// all over again, I would make XmppClient == XmppEngine.  Why?
-// XmppEngine needs tasks too, for example it has an XmppLoginTask which
-// should just be the same kind of Task instead of an XmppEngine specific
-// thing.  It would help do certain things like GAIA auth cleaner.
-//
-/////////////////////////////////////////////////////////////////////
-
-class XmppClient : public XmppTaskParentInterface,
-                   public XmppClientInterface,
-                   public sigslot::has_slots<>
-{
-public:
-  explicit XmppClient(talk_base::TaskParent * parent);
-  virtual ~XmppClient();
-
-  XmppReturnStatus Connect(const XmppClientSettings & settings,
-                           const std::string & lang,
-                           AsyncSocket * socket,
-                           PreXmppAuth * preauth);
-
-  virtual int ProcessStart();
-  virtual int ProcessResponse();
-  XmppReturnStatus Disconnect();
-
-  sigslot::signal1<XmppEngine::State> SignalStateChange;
-  XmppEngine::Error GetError(int *subcode);
-
-  // When there is a <stream:error> stanza, return the stanza
-  // so that they can be handled.
-  const XmlElement *GetStreamError();
-
-  // When there is an authentication error, we may have captcha info
-  // that the user can use to unlock their account
-  CaptchaChallenge GetCaptchaChallenge();
-
-  // When authentication is successful, this returns the service cookie
-  // (if we used GAIA authentication)
-  std::string GetAuthCookie();
-
-  XmppReturnStatus SendRaw(const std::string & text);
-
-  XmppEngine* engine();
-
-  sigslot::signal2<const char *, int> SignalLogInput;
-  sigslot::signal2<const char *, int> SignalLogOutput;
-
-  // As XmppTaskParentIntreface
-  virtual XmppClientInterface* GetClient() { return this; }
-
-  // As XmppClientInterface
-  virtual XmppEngine::State GetState() const;
-  virtual const Jid& jid() const;
-  virtual std::string NextId();
-  virtual XmppReturnStatus SendStanza(const XmlElement *stanza);
-  virtual XmppReturnStatus SendStanzaError(const XmlElement * pelOriginal,
-                                           XmppStanzaError code,
-                                           const std::string & text);
-  virtual void AddXmppTask(XmppTask *, XmppEngine::HandlerLevel);
-  virtual void RemoveXmppTask(XmppTask *);
-
- private:
-  friend class XmppTask;
-
-  void OnAuthDone();
-
-  // Internal state management
-  enum {
-    STATE_PRE_XMPP_LOGIN = STATE_NEXT,
-    STATE_START_XMPP_LOGIN = STATE_NEXT + 1,
-  };
-  int Process(int state) {
-    switch (state) {
-      case STATE_PRE_XMPP_LOGIN: return ProcessCookieLogin();
-      case STATE_START_XMPP_LOGIN: return ProcessStartXmppLogin();
-      default: return Task::Process(state);
-    }
-  }
-
-  std::string GetStateName(int state) const {
-    switch (state) {
-      case STATE_PRE_XMPP_LOGIN:      return "PRE_XMPP_LOGIN";
-      case STATE_START_XMPP_LOGIN:  return "START_XMPP_LOGIN";
-      default: return Task::GetStateName(state);
-    }
-  }
-
-  int ProcessCookieLogin();
-  int ProcessStartXmppLogin();
-  void EnsureClosed();
-
-  class Private;
-  friend class Private;
-  talk_base::scoped_ptr<Private> d_;
-
-  bool delivering_signal_;
-  bool valid_;
-};
-
-}
-
-#endif
diff --git a/third_party/libjingle/source/talk/xmpp/xmppclientsettings.h b/third_party/libjingle/source/talk/xmpp/xmppclientsettings.h
deleted file mode 100644
index 29dfeec..0000000
--- a/third_party/libjingle/source/talk/xmpp/xmppclientsettings.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _XMPPCLIENTSETTINGS_H_
-#define _XMPPCLIENTSETTINGS_H_
-
-#include "talk/p2p/base/port.h"
-#include "talk/base/cryptstring.h"
-#include "talk/xmpp/xmppengine.h"
-
-namespace buzz {
-
-class XmppUserSettings {
- public:
-  XmppUserSettings()
-    : use_tls_(buzz::TLS_DISABLED),
-      allow_plain_(false) {
-  }
-
-  void set_user(const std::string & user) { user_ = user; }
-  void set_host(const std::string & host) { host_ = host; }
-  void set_pass(const talk_base::CryptString & pass) { pass_ = pass; }
-  void set_auth_cookie(const std::string & cookie) { auth_cookie_ = cookie; }
-  void set_resource(const std::string & resource) { resource_ = resource; }
-  void set_use_tls(const TlsOptions use_tls) { use_tls_ = use_tls; }
-  void set_allow_plain(bool f) { allow_plain_ = f; }
-  void set_test_server_domain(const std::string & test_server_domain) {
-    test_server_domain_ = test_server_domain;
-  }
-  void set_token_service(const std::string & token_service) {
-    token_service_ = token_service;
-  }
-
-  const std::string & user() const { return user_; }
-  const std::string & host() const { return host_; }
-  const talk_base::CryptString & pass() const { return pass_; }
-  const std::string & auth_cookie() const { return auth_cookie_; }
-  const std::string & resource() const { return resource_; }
-  TlsOptions use_tls() const { return use_tls_; }
-  bool allow_plain() const { return allow_plain_; }
-  const std::string & test_server_domain() const { return test_server_domain_; }
-  const std::string & token_service() const { return token_service_; }
-
- private:
-  std::string user_;
-  std::string host_;
-  talk_base::CryptString pass_;
-  std::string auth_cookie_;
-  std::string resource_;
-  TlsOptions use_tls_;
-  bool allow_plain_;
-  std::string test_server_domain_;
-  std::string token_service_;
-};
-
-class XmppClientSettings : public XmppUserSettings {
- public:
-  XmppClientSettings()
-    : protocol_(cricket::PROTO_TCP),
-      proxy_(talk_base::PROXY_NONE),
-      proxy_port_(80),
-      use_proxy_auth_(false) {
-  }
-
-  void set_server(const talk_base::SocketAddress & server) {
-      server_ = server;
-  }
-  void set_protocol(cricket::ProtocolType protocol) { protocol_ = protocol; }
-  void set_proxy(talk_base::ProxyType f) { proxy_ = f; }
-  void set_proxy_host(const std::string & host) { proxy_host_ = host; }
-  void set_proxy_port(int port) { proxy_port_ = port; };
-  void set_use_proxy_auth(bool f) { use_proxy_auth_ = f; }
-  void set_proxy_user(const std::string & user) { proxy_user_ = user; }
-  void set_proxy_pass(const talk_base::CryptString & pass) { proxy_pass_ = pass; }
-
-  const talk_base::SocketAddress & server() const { return server_; }
-  cricket::ProtocolType protocol() const { return protocol_; }
-  talk_base::ProxyType proxy() const { return proxy_; }
-  const std::string & proxy_host() const { return proxy_host_; }
-  int proxy_port() const { return proxy_port_; }
-  bool use_proxy_auth() const { return use_proxy_auth_; }
-  const std::string & proxy_user() const { return proxy_user_; }
-  const talk_base::CryptString & proxy_pass() const { return proxy_pass_; }
-
- private:
-  talk_base::SocketAddress server_;
-  cricket::ProtocolType protocol_;
-  talk_base::ProxyType proxy_;
-  std::string proxy_host_;
-  int proxy_port_;
-  bool use_proxy_auth_;
-  std::string proxy_user_;
-  talk_base::CryptString proxy_pass_;
-};
-
-}
-
-#endif
diff --git a/third_party/libjingle/source/talk/xmpp/xmppengine.h b/third_party/libjingle/source/talk/xmpp/xmppengine.h
deleted file mode 100644
index e1b35a3..0000000
--- a/third_party/libjingle/source/talk/xmpp/xmppengine.h
+++ /dev/null
@@ -1,349 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _xmppengine_h_
-#define _xmppengine_h_
-
-// also part of the API
-#include "talk/xmpp/jid.h"
-#include "talk/xmllite/qname.h"
-#include "talk/xmllite/xmlelement.h"
-
-
-namespace buzz {
-
-class XmppEngine;
-class SaslHandler;
-typedef void * XmppIqCookie;
-
-//! XMPP stanza error codes.
-//! Used in XmppEngine.SendStanzaError().
-enum XmppStanzaError {
-  XSE_BAD_REQUEST,
-  XSE_CONFLICT,
-  XSE_FEATURE_NOT_IMPLEMENTED,
-  XSE_FORBIDDEN,
-  XSE_GONE,
-  XSE_INTERNAL_SERVER_ERROR,
-  XSE_ITEM_NOT_FOUND,
-  XSE_JID_MALFORMED,
-  XSE_NOT_ACCEPTABLE,
-  XSE_NOT_ALLOWED,
-  XSE_PAYMENT_REQUIRED,
-  XSE_RECIPIENT_UNAVAILABLE,
-  XSE_REDIRECT,
-  XSE_REGISTRATION_REQUIRED,
-  XSE_SERVER_NOT_FOUND,
-  XSE_SERVER_TIMEOUT,
-  XSE_RESOURCE_CONSTRAINT,
-  XSE_SERVICE_UNAVAILABLE,
-  XSE_SUBSCRIPTION_REQUIRED,
-  XSE_UNDEFINED_CONDITION,
-  XSE_UNEXPECTED_REQUEST,
-};
-
-// XmppReturnStatus
-//    This is used by API functions to synchronously return status.
-enum XmppReturnStatus {
-  XMPP_RETURN_OK,
-  XMPP_RETURN_BADARGUMENT,
-  XMPP_RETURN_BADSTATE,
-  XMPP_RETURN_PENDING,
-  XMPP_RETURN_UNEXPECTED,
-  XMPP_RETURN_NOTYETIMPLEMENTED,
-};
-
-// TlsOptions
-//    This is used by API to identify TLS setting.
-enum TlsOptions {
-  TLS_DISABLED,
-  TLS_ENABLED,
-  TLS_REQUIRED
-};
-
-//! Callback for socket output for an XmppEngine connection.
-//! Register via XmppEngine.SetOutputHandler.  An XmppEngine
-//! can call back to this handler while it is processing
-//! Connect, SendStanza, SendIq, Disconnect, or HandleInput.
-class XmppOutputHandler {
-public:
-  virtual ~XmppOutputHandler() {}
-
-  //! Deliver the specified bytes to the XMPP socket.
-  virtual void WriteOutput(const char * bytes, size_t len) = 0;
-
-  //! Initiate TLS encryption on the socket.
-  //! The implementation must verify that the SSL
-  //! certificate matches the given domainname.
-  virtual void StartTls(const std::string & domainname) = 0;
-
-  //! Called when engine wants the connecton closed.
-  virtual void CloseConnection() = 0;
-};
-
-//! Callback to deliver engine state change notifications
-//! to the object managing the engine.
-class XmppSessionHandler {
-public:
-  virtual ~XmppSessionHandler() {}
-  //! Called when engine changes state. Argument is new state.
-  virtual void OnStateChange(int state) = 0;
-};
-
-//! Callback to deliver stanzas to an Xmpp application module.
-//! Register via XmppEngine.SetDefaultSessionHandler or via
-//! XmppEngine.AddSessionHAndler.  
-class XmppStanzaHandler {
-public:
-  virtual ~XmppStanzaHandler() {}
-  //! Process the given stanza.
-  //! The handler must return true if it has handled the stanza.
-  //! A false return value causes the stanza to be passed on to
-  //! the next registered handler.
-  virtual bool HandleStanza(const XmlElement * stanza) = 0;
-};
-
-//! Callback to deliver iq responses (results and errors).
-//! Register while sending an iq via XmppEngine.SendIq.
-//! Iq responses are routed to matching XmppIqHandlers in preference
-//! to sending to any registered SessionHandlers.
-class XmppIqHandler {
-public:
-  virtual ~XmppIqHandler() {}
-  //! Called to handle the iq response.
-  //! The response may be either a result or an error, and will have
-  //! an 'id' that matches the request and a 'from' that matches the
-  //! 'to' of the request.  Called no more than once; once this is
-  //! called, the handler is automatically unregistered.
-  virtual void IqResponse(XmppIqCookie cookie, const XmlElement * pelStanza) = 0;
-};
-
-//! The XMPP connection engine.
-//! This engine implements the client side of the 'core' XMPP protocol.
-//! To use it, register an XmppOutputHandler to handle socket output
-//! and pass socket input to HandleInput.  Then application code can
-//! set up the connection with a user, password, and other settings,
-//! and then call Connect() to initiate the connection.
-//! An application can listen for events and receive stanzas by
-//! registering an XmppStanzaHandler via AddStanzaHandler().
-class XmppEngine {
-public:
-  static XmppEngine * Create();
-  virtual ~XmppEngine() {}
-
-  //! Error codes. See GetError().
-  enum Error {
-    ERROR_NONE = 0,         //!< No error
-    ERROR_XML,              //!< Malformed XML or encoding error
-    ERROR_STREAM,           //!< XMPP stream error - see GetStreamError()
-    ERROR_VERSION,          //!< XMPP version error
-    ERROR_UNAUTHORIZED,     //!< User is not authorized (rejected credentials)
-    ERROR_TLS,              //!< TLS could not be negotiated
-    ERROR_AUTH,             //!< Authentication could not be negotiated
-    ERROR_BIND,             //!< Resource or session binding could not be negotiated
-    ERROR_CONNECTION_CLOSED,//!< Connection closed by output handler.
-    ERROR_DOCUMENT_CLOSED,  //!< Closed by </stream:stream>
-    ERROR_SOCKET,           //!< Socket error
-    ERROR_NETWORK_TIMEOUT,  //!< Some sort of timeout (eg., we never got the roster)
-    ERROR_MISSING_USERNAME  //!< User has a Google Account but no nickname
-  };
-
-  //! States.  See GetState().
-  enum State {
-    STATE_NONE = 0,        //!< Nonexistent state
-    STATE_START,           //!< Initial state.
-    STATE_OPENING,         //!< Exchanging stream headers, authenticating and so on.
-    STATE_OPEN,            //!< Authenticated and bound.
-    STATE_CLOSED,          //!< Session closed, possibly due to error.
-  };
-
-  // SOCKET INPUT AND OUTPUT ------------------------------------------------
-
-  //! Registers the handler for socket output
-  virtual XmppReturnStatus SetOutputHandler(XmppOutputHandler *pxoh) = 0;
-
-  //! Provides socket input to the engine
-  virtual XmppReturnStatus HandleInput(const char * bytes, size_t len) = 0;
-
-  //! Advises the engine that the socket has closed
-  virtual XmppReturnStatus ConnectionClosed(int subcode) = 0;
-
-  // SESSION SETUP ---------------------------------------------------------
-
-  //! Indicates the (bare) JID for the user to use.
-  virtual XmppReturnStatus SetUser(const Jid & jid)= 0;
-
-  //! Get the login (bare) JID.
-  virtual const Jid & GetUser() = 0;
-
-  //! Provides different methods for credentials for login.
-  //! Takes ownership of this object; deletes when login is done
-  virtual XmppReturnStatus SetSaslHandler(SaslHandler * h) = 0;
-
-  //! Sets whether TLS will be used within the connection (default true).
-  virtual XmppReturnStatus SetTls(TlsOptions useTls) = 0;
-
-  //! Sets an alternate domain from which we allows TLS certificates.
-  //! This is for use in the case where a we want to allow a proxy to
-  //! serve up its own certificate rather than one owned by the underlying
-  //! domain.
-  virtual XmppReturnStatus SetTlsServer(const std::string & proxy_hostname, 
-                                        const std::string & proxy_domain) = 0;
-
-  //! Gets whether TLS will be used within the connection.
-  virtual TlsOptions GetTls() = 0;
-
-  //! Sets the request resource name, if any (optional).
-  //! Note that the resource name may be overridden by the server; after
-  //! binding, the actual resource name is available as part of FullJid().
-  virtual XmppReturnStatus SetRequestedResource(const std::string& resource) = 0;
-
-  //! Gets the request resource name.
-  virtual const std::string & GetRequestedResource() = 0;
-
-  //! Sets language
-  virtual void SetLanguage(const std::string & lang) = 0;
-
-  // SESSION MANAGEMENT ---------------------------------------------------
-
-  //! Set callback for state changes.
-  virtual XmppReturnStatus SetSessionHandler(XmppSessionHandler* handler) = 0;
-
-  //! Initiates the XMPP connection.
-  //! After supplying connection settings, call this once to initiate,
-  //! (optionally) encrypt, authenticate, and bind the connection.
-  virtual XmppReturnStatus Connect() = 0;
-
-  //! The current engine state.
-  virtual State GetState() = 0;
-
-  //! Returns true if the connection is encrypted (under TLS)
-  virtual bool IsEncrypted() = 0;
-
-  //! The error code.
-  //! Consult this after XmppOutputHandler.OnClose().
-  virtual Error GetError(int *subcode) = 0;
-
-  //! The stream:error stanza, when the error is XmppEngine::ERROR_STREAM.
-  //! Notice the stanza returned is owned by the XmppEngine and
-  //! is deleted when the engine is destroyed.
-  virtual const XmlElement * GetStreamError() = 0;
-
-  //! Closes down the connection.
-  //! Sends CloseConnection to output, and disconnects and registered
-  //! session handlers.  After Disconnect completes, it is guaranteed
-  //! that no further callbacks will be made.
-  virtual XmppReturnStatus Disconnect() = 0;
-
-  // APPLICATION USE -------------------------------------------------------
-
-  enum HandlerLevel {
-    HL_NONE = 0,
-    HL_PEEK,   //!< Sees messages before all other processing; cannot abort
-    HL_SINGLE, //!< Watches for a single message, e.g., by id and sender
-    HL_SENDER, //!< Watches for a type of message from a specific sender
-    HL_TYPE,   //!< Watches a type of message, e.g., all groupchat msgs
-    HL_ALL,    //!< Watches all messages - gets last shot
-    HL_COUNT,  //!< Count of handler levels
-  };
-
-  //! Adds a listener for session events.
-  //! Stanza delivery is chained to session handlers; the first to
-  //! return 'true' is the last to get each stanza.
-  virtual XmppReturnStatus AddStanzaHandler(XmppStanzaHandler* handler, HandlerLevel level = HL_PEEK) = 0;
-
-  //! Removes a listener for session events.
-  virtual XmppReturnStatus RemoveStanzaHandler(XmppStanzaHandler* handler) = 0;
-
-  //! Sends a stanza to the server.
-  virtual XmppReturnStatus SendStanza(const XmlElement * pelStanza) = 0;
-
-  //! Sends raw text to the server
-  virtual XmppReturnStatus SendRaw(const std::string & text) = 0;
-
-  //! Sends an iq to the server, and registers a callback for the result.
-  //! Returns the cookie passed to the result handler.
-  virtual XmppReturnStatus SendIq(const XmlElement* pelStanza,
-                                  XmppIqHandler* iq_handler,
-                                  XmppIqCookie* cookie) = 0;
-
-  //! Unregisters an iq callback handler given its cookie.
-  //! No callback will come to this handler after it's unregistered.
-  virtual XmppReturnStatus RemoveIqHandler(XmppIqCookie cookie,
-                                      XmppIqHandler** iq_handler) = 0;
-
-
-  //! Forms and sends an error in response to the given stanza.
-  //! Swaps to and from, sets type to "error", and adds error information
-  //! based on the passed code.  Text is optional and may be STR_EMPTY.
-  virtual XmppReturnStatus SendStanzaError(const XmlElement * pelOriginal,
-                                           XmppStanzaError code,
-                                           const std::string & text) = 0;
-
-  //! The fullly bound JID.
-  //! This JID is only valid after binding has succeeded.  If the value
-  //! is JID_NULL, the binding has not succeeded.
-  virtual const Jid & FullJid() = 0;
-
-  //! The next unused iq id for this connection.
-  //! Call this when building iq stanzas, to ensure that each iq
-  //! gets its own unique id.
-  virtual std::string NextId() = 0;
-
-};
-
-}
-
-
-// Move these to a better location
-
-#define XMPP_FAILED(x)                      \
-  ( (x) == buzz::XMPP_RETURN_OK ? false : true)   \
-
-
-#define XMPP_SUCCEEDED(x)                   \
-  ( (x) == buzz::XMPP_RETURN_OK ? true : false)   \
-
-#define IFR(x)                        \
-  do {                                \
-    xmpp_status = (x);                \
-    if (XMPP_FAILED(xmpp_status)) {   \
-      return xmpp_status;             \
-    }                                 \
-  } while (false)                     \
-
-
-#define IFC(x)                        \
-  do {                                \
-    xmpp_status = (x);                \
-    if (XMPP_FAILED(xmpp_status)) {   \
-      goto Cleanup;                   \
-    }                                 \
-  } while (false)                     \
-
-
-#endif
diff --git a/third_party/libjingle/source/talk/xmpp/xmppengine_unittest.cc b/third_party/libjingle/source/talk/xmpp/xmppengine_unittest.cc
deleted file mode 100644
index 46b79c6..0000000
--- a/third_party/libjingle/source/talk/xmpp/xmppengine_unittest.cc
+++ /dev/null
@@ -1,318 +0,0 @@
-// Copyright 2004 Google Inc. All Rights Reserved
-// Author: David Bau
-
-#include <string>
-#include <sstream>
-#include <iostream>
-#include "talk/base/common.h"
-#include "talk/base/gunit.h"
-#include "talk/xmllite/xmlelement.h"
-#include "talk/xmpp/constants.h"
-#include "talk/xmpp/util_unittest.h"
-#include "talk/xmpp/saslplainmechanism.h"
-#include "talk/xmpp/plainsaslhandler.h"
-#include "talk/xmpp/xmppengine.h"
-
-using buzz::Jid;
-using buzz::QName;
-using buzz::XmlElement;
-using buzz::XmppEngine;
-using buzz::XmppIqCookie;
-using buzz::XmppIqHandler;
-using buzz::XmppTestHandler;
-using buzz::QN_ID;
-using buzz::QN_IQ;
-using buzz::QN_TYPE;
-using buzz::QN_ROSTER_QUERY;
-using buzz::XMPP_RETURN_OK;
-using buzz::XMPP_RETURN_BADARGUMENT;
-
-// XmppEngineTestIqHandler
-//    This class grabs the response to an IQ stanza and stores it in a string.
-class XmppEngineTestIqHandler : public XmppIqHandler {
- public:
-  virtual void IqResponse(XmppIqCookie, const XmlElement * stanza) {
-    ss_ << stanza->Str();
-  }
-
-  std::string IqResponseActivity() {
-    std::string result = ss_.str();
-    ss_.str("");
-    return result;
-  }
-
- private:
-  std::stringstream ss_;
-};
-
-class XmppEngineTest : public testing::Test {
- public:
-  XmppEngine* engine() { return engine_.get(); }
-  XmppTestHandler* handler() { return handler_.get(); }
-  virtual void SetUp() {
-    engine_.reset(XmppEngine::Create());
-    handler_.reset(new XmppTestHandler(engine_.get()));
-
-    Jid jid("david@my-server");
-    talk_base::InsecureCryptStringImpl pass;
-    pass.password() = "david";
-    engine_->SetSessionHandler(handler_.get());
-    engine_->SetOutputHandler(handler_.get());
-    engine_->AddStanzaHandler(handler_.get());
-    engine_->SetUser(jid);
-    engine_->SetSaslHandler(
-        new buzz::PlainSaslHandler(jid, talk_base::CryptString(pass), true));
-  }
-  virtual void TearDown() {
-    handler_.reset();
-    engine_.reset();
-  }
-  void RunLogin();
-
- private:
-  talk_base::scoped_ptr<XmppEngine> engine_;
-  talk_base::scoped_ptr<XmppTestHandler> handler_;
-};
-
-void XmppEngineTest::RunLogin() {
-  // Connect
-  EXPECT_EQ(XmppEngine::STATE_START, engine()->GetState());
-  engine()->Connect();
-  EXPECT_EQ(XmppEngine::STATE_OPENING, engine()->GetState());
-
-  EXPECT_EQ("[OPENING]", handler_->SessionActivity());
-
-  EXPECT_EQ("<stream:stream to=\"my-server\" xml:lang=\"*\" version=\"1.0\" "
-           "xmlns:stream=\"http://etherx.jabber.org/streams\" "
-           "xmlns=\"jabber:client\">\r\n", handler_->OutputActivity());
-
-  std::string input =
-    "<stream:stream id=\"a5f2d8c9\" version=\"1.0\" "
-    "xmlns:stream=\"http://etherx.jabber.org/streams\" "
-    "xmlns=\"jabber:client\">";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  input =
-    "<stream:features>"
-      "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'>"
-        "<required/>"
-      "</starttls>"
-      "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
-        "<mechanism>DIGEST-MD5</mechanism>"
-        "<mechanism>PLAIN</mechanism>"
-      "</mechanisms>"
-    "</stream:features>";
-  engine()->HandleInput(input.c_str(), input.length());
-  EXPECT_EQ("<starttls xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\"/>",
-      handler_->OutputActivity());
-
-  EXPECT_EQ("", handler_->SessionActivity());
-  EXPECT_EQ("", handler_->StanzaActivity());
-
-  input = "<proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>";
-  engine()->HandleInput(input.c_str(), input.length());
-  EXPECT_EQ("[START-TLS my-server]"
-           "<stream:stream to=\"my-server\" xml:lang=\"*\" "
-           "version=\"1.0\" xmlns:stream=\"http://etherx.jabber.org/streams\" "
-           "xmlns=\"jabber:client\">\r\n", handler_->OutputActivity());
-
-  EXPECT_EQ("", handler_->SessionActivity());
-  EXPECT_EQ("", handler_->StanzaActivity());
-
-  input = "<stream:stream id=\"01234567\" version=\"1.0\" "
-          "xmlns:stream=\"http://etherx.jabber.org/streams\" "
-          "xmlns=\"jabber:client\">";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  input =
-    "<stream:features>"
-      "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
-        "<mechanism>DIGEST-MD5</mechanism>"
-        "<mechanism>PLAIN</mechanism>"
-      "</mechanisms>"
-    "</stream:features>";
-  engine()->HandleInput(input.c_str(), input.length());
-  EXPECT_EQ("<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" "
-      "mechanism=\"PLAIN\" "
-      "auth:allow-non-google-login=\"true\" "
-      "auth:client-uses-full-bind-result=\"true\" "
-      "xmlns:auth=\"http://www.google.com/talk/protocol/auth\""
-      ">AGRhdmlkAGRhdmlk</auth>",
-      handler_->OutputActivity());
-
-  EXPECT_EQ("", handler_->SessionActivity());
-  EXPECT_EQ("", handler_->StanzaActivity());
-
-  input = "<success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>";
-  engine()->HandleInput(input.c_str(), input.length());
-  EXPECT_EQ("<stream:stream to=\"my-server\" xml:lang=\"*\" version=\"1.0\" "
-      "xmlns:stream=\"http://etherx.jabber.org/streams\" "
-      "xmlns=\"jabber:client\">\r\n", handler_->OutputActivity());
-
-  EXPECT_EQ("", handler_->SessionActivity());
-  EXPECT_EQ("", handler_->StanzaActivity());
-
-  input = "<stream:stream id=\"01234567\" version=\"1.0\" "
-      "xmlns:stream=\"http://etherx.jabber.org/streams\" "
-      "xmlns=\"jabber:client\">";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  input = "<stream:features>"
-          "<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>"
-          "<session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>"
-          "</stream:features>";
-  engine()->HandleInput(input.c_str(), input.length());
-  EXPECT_EQ("<iq type=\"set\" id=\"0\">"
-           "<bind xmlns=\"urn:ietf:params:xml:ns:xmpp-bind\"/></iq>",
-           handler_->OutputActivity());
-
-  EXPECT_EQ("", handler_->SessionActivity());
-  EXPECT_EQ("", handler_->StanzaActivity());
-
-  input = "<iq type='result' id='0'>"
-          "<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'><jid>"
-          "david@my-server/test</jid></bind></iq>";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  EXPECT_EQ("<iq type=\"set\" id=\"1\">"
-           "<session xmlns=\"urn:ietf:params:xml:ns:xmpp-session\"/></iq>",
-           handler_->OutputActivity());
-
-  EXPECT_EQ("", handler_->SessionActivity());
-  EXPECT_EQ("", handler_->StanzaActivity());
-
-  input = "<iq type='result' id='1'/>";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  EXPECT_EQ("[OPEN]", handler_->SessionActivity());
-  EXPECT_EQ("", handler_->StanzaActivity());
-  EXPECT_EQ(Jid("david@my-server/test"), engine()->FullJid());
-}
-
-// TestSuccessfulLogin()
-//    This function simply tests to see if a login works.  This includes
-//    encryption and authentication
-TEST_F(XmppEngineTest, TestSuccessfulLoginAndDisconnect) {
-  RunLogin();
-  engine()->Disconnect();
-  EXPECT_EQ("</stream:stream>[CLOSED]", handler()->OutputActivity());
-  EXPECT_EQ("[CLOSED]", handler()->SessionActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-}
-
-TEST_F(XmppEngineTest, TestSuccessfulLoginAndConnectionClosed) {
-  RunLogin();
-  engine()->ConnectionClosed(0);
-  EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
-  EXPECT_EQ("[CLOSED][ERROR-CONNECTION-CLOSED]", handler()->SessionActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-}
-
-
-// TestNotXmpp()
-//    This tests the error case when connecting to a non XMPP service
-TEST_F(XmppEngineTest, TestNotXmpp) {
-  // Connect
-  engine()->Connect();
-  EXPECT_EQ("<stream:stream to=\"my-server\" xml:lang=\"*\" version=\"1.0\" "
-          "xmlns:stream=\"http://etherx.jabber.org/streams\" "
-          "xmlns=\"jabber:client\">\r\n", handler()->OutputActivity());
-
-  // Send garbage response (courtesy of apache)
-  std::string input = "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
-  EXPECT_EQ("[OPENING][CLOSED][ERROR-XML]", handler()->SessionActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-}
-
-// TestPassthrough()
-//    This tests that arbitrary stanzas can be passed to the server through
-//    the engine.
-TEST_F(XmppEngineTest, TestPassthrough) {
-  // Queue up an app stanza
-  XmlElement application_stanza(QName("test", "app-stanza"));
-  application_stanza.AddText("this-is-a-test");
-  engine()->SendStanza(&application_stanza);
-
-  // Do the whole login handshake
-  RunLogin();
-
-  EXPECT_EQ("<test:app-stanza xmlns:test=\"test\">this-is-a-test"
-          "</test:app-stanza>", handler()->OutputActivity());
-
-  // do another stanza
-  XmlElement roster_get(QN_IQ);
-  roster_get.AddAttr(QN_TYPE, "get");
-  roster_get.AddAttr(QN_ID, engine()->NextId());
-  roster_get.AddElement(new XmlElement(QN_ROSTER_QUERY, true));
-  engine()->SendStanza(&roster_get);
-  EXPECT_EQ("<iq type=\"get\" id=\"2\"><query xmlns=\"jabber:iq:roster\"/>"
-          "</iq>", handler()->OutputActivity());
-
-  // now say the server ends the stream
-  engine()->HandleInput("</stream:stream>", 16);
-  EXPECT_EQ("[CLOSED][ERROR-DOCUMENT-CLOSED]", handler()->SessionActivity());
-  EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-}
-
-// TestIqCallback()
-//    This tests the routing of Iq stanzas and responses.
-TEST_F(XmppEngineTest, TestIqCallback) {
-  XmppEngineTestIqHandler iq_response;
-  XmppIqCookie cookie;
-
-  // Do the whole login handshake
-  RunLogin();
-
-  // Build an iq request
-  XmlElement roster_get(QN_IQ);
-  roster_get.AddAttr(QN_TYPE, "get");
-  roster_get.AddAttr(QN_ID, engine()->NextId());
-  roster_get.AddElement(new XmlElement(QN_ROSTER_QUERY, true));
-  engine()->SendIq(&roster_get, &iq_response, &cookie);
-  EXPECT_EQ("<iq type=\"get\" id=\"2\"><query xmlns=\"jabber:iq:roster\"/>"
-          "</iq>", handler()->OutputActivity());
-  EXPECT_EQ("", handler()->SessionActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-  EXPECT_EQ("", iq_response.IqResponseActivity());
-
-  // now say the server responds to the iq
-  std::string input = "<iq type='result' id='2'>"
-                      "<query xmlns='jabber:iq:roster'><item>foo</item>"
-                      "</query></iq>";
-  engine()->HandleInput(input.c_str(), input.length());
-  EXPECT_EQ("", handler()->OutputActivity());
-  EXPECT_EQ("", handler()->SessionActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-  EXPECT_EQ("<cli:iq type=\"result\" id=\"2\" xmlns:cli=\"jabber:client\">"
-          "<query xmlns=\"jabber:iq:roster\"><item>foo</item></query>"
-          "</cli:iq>", iq_response.IqResponseActivity());
-
-  EXPECT_EQ(XMPP_RETURN_BADARGUMENT, engine()->RemoveIqHandler(cookie, NULL));
-
-  // Do it again with another id to test cancel
-  roster_get.SetAttr(QN_ID, engine()->NextId());
-  engine()->SendIq(&roster_get, &iq_response, &cookie);
-  EXPECT_EQ("<iq type=\"get\" id=\"3\"><query xmlns=\"jabber:iq:roster\"/>"
-          "</iq>", handler()->OutputActivity());
-  EXPECT_EQ("", handler()->SessionActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-  EXPECT_EQ("", iq_response.IqResponseActivity());
-
-  // cancel the handler this time
-  EXPECT_EQ(XMPP_RETURN_OK, engine()->RemoveIqHandler(cookie, NULL));
-
-  // now say the server responds to the iq: the iq handler should not get it.
-  input = "<iq type='result' id='3'><query xmlns='jabber:iq:roster'><item>bar"
-          "</item></query></iq>";
-  engine()->HandleInput(input.c_str(), input.length());
-  EXPECT_EQ("<cli:iq type=\"result\" id=\"3\" xmlns:cli=\"jabber:client\">"
-          "<query xmlns=\"jabber:iq:roster\"><item>bar</item></query>"
-          "</cli:iq>", handler()->StanzaActivity());
-  EXPECT_EQ("", iq_response.IqResponseActivity());
-  EXPECT_EQ("", handler()->OutputActivity());
-  EXPECT_EQ("", handler()->SessionActivity());
-}
diff --git a/third_party/libjingle/source/talk/xmpp/xmppengineimpl.cc b/third_party/libjingle/source/talk/xmpp/xmppengineimpl.cc
deleted file mode 100644
index eb539d1..0000000
--- a/third_party/libjingle/source/talk/xmpp/xmppengineimpl.cc
+++ /dev/null
@@ -1,463 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/xmpp/xmppengineimpl.h"
-
-#include <algorithm>
-#include <sstream>
-#include <vector>
-
-#include "talk/base/common.h"
-#include "talk/xmllite/xmlelement.h"
-#include "talk/xmllite/xmlprinter.h"
-#include "talk/xmpp/constants.h"
-#include "talk/xmpp/saslhandler.h"
-#include "talk/xmpp/xmpplogintask.h"
-
-namespace buzz {
-
-XmppEngine* XmppEngine::Create() {
-  return new XmppEngineImpl();
-}
-
-
-XmppEngineImpl::XmppEngineImpl()
-    : stanza_parse_handler_(this),
-      stanza_parser_(&stanza_parse_handler_),
-      engine_entered_(0),
-      password_(),
-      requested_resource_(STR_EMPTY),
-      tls_option_(buzz::TLS_REQUIRED),
-      login_task_(new XmppLoginTask(this)),
-      next_id_(0),
-      state_(STATE_START),
-      encrypted_(false),
-      error_code_(ERROR_NONE),
-      subcode_(0),
-      stream_error_(NULL),
-      raised_reset_(false),
-      output_handler_(NULL),
-      session_handler_(NULL),
-      iq_entries_(new IqEntryVector()),
-      sasl_handler_(NULL),
-      output_(new std::stringstream()) {
-  for (int i = 0; i < HL_COUNT; i+= 1) {
-    stanza_handlers_[i].reset(new StanzaHandlerVector());
-  }
-
-  xmlns_stack_.AddXmlns("stream", "http://etherx.jabber.org/streams");
-  xmlns_stack_.AddXmlns("", "jabber:client");
-}
-
-XmppEngineImpl::~XmppEngineImpl() {
-  DeleteIqCookies();
-}
-
-XmppReturnStatus XmppEngineImpl::SetOutputHandler(
-    XmppOutputHandler* output_handler) {
-  if (state_ != STATE_START)
-    return XMPP_RETURN_BADSTATE;
-
-  output_handler_ = output_handler;
-
-  return XMPP_RETURN_OK;
-}
-
-XmppReturnStatus XmppEngineImpl::SetSessionHandler(
-    XmppSessionHandler* session_handler) {
-  if (state_ != STATE_START)
-    return XMPP_RETURN_BADSTATE;
-
-  session_handler_ = session_handler;
-
-  return XMPP_RETURN_OK;
-}
-
-XmppReturnStatus XmppEngineImpl::HandleInput(
-    const char* bytes, size_t len) {
-  if (state_ < STATE_OPENING || state_ > STATE_OPEN)
-    return XMPP_RETURN_BADSTATE;
-
-  EnterExit ee(this);
-
-  // TODO: The return value of the xml parser is not checked.
-  stanza_parser_.Parse(bytes, len, false);
-
-  return XMPP_RETURN_OK;
-}
-
-XmppReturnStatus XmppEngineImpl::ConnectionClosed(int subcode) {
-  if (state_ != STATE_CLOSED) {
-    EnterExit ee(this);
-    // If told that connection closed and not already closed,
-    // then connection was unpexectedly dropped.
-    if (subcode) {
-      SignalError(ERROR_SOCKET, subcode);
-    } else {
-      SignalError(ERROR_CONNECTION_CLOSED, 0);  // no subcode
-    }
-  }
-  return XMPP_RETURN_OK;
-}
-
-XmppReturnStatus XmppEngineImpl::SetTls(TlsOptions useTls) {
-  if (state_ != STATE_START)
-    return XMPP_RETURN_BADSTATE;
-  tls_option_ = useTls;
-  return XMPP_RETURN_OK;
-}
-
-XmppReturnStatus XmppEngineImpl::SetTlsServer(
-    const std::string& tls_server_hostname,
-    const std::string& tls_server_domain) {
-  if (state_ != STATE_START)
-    return XMPP_RETURN_BADSTATE;
-
-  tls_server_hostname_ = tls_server_hostname;
-  tls_server_domain_= tls_server_domain;
-
-  return XMPP_RETURN_OK;
-}
-
-TlsOptions XmppEngineImpl::GetTls() {
-  return tls_option_;
-}
-
-XmppReturnStatus XmppEngineImpl::SetUser(const Jid& jid) {
-  if (state_ != STATE_START)
-    return XMPP_RETURN_BADSTATE;
-
-  user_jid_ = jid;
-
-  return XMPP_RETURN_OK;
-}
-
-const Jid& XmppEngineImpl::GetUser() {
-  return user_jid_;
-}
-
-XmppReturnStatus XmppEngineImpl::SetSaslHandler(SaslHandler* sasl_handler) {
-  if (state_ != STATE_START)
-    return XMPP_RETURN_BADSTATE;
-
-  sasl_handler_.reset(sasl_handler);
-  return XMPP_RETURN_OK;
-}
-
-XmppReturnStatus XmppEngineImpl::SetRequestedResource(
-    const std::string& resource) {
-  if (state_ != STATE_START)
-    return XMPP_RETURN_BADSTATE;
-
-  requested_resource_ = resource;
-
-  return XMPP_RETURN_OK;
-}
-
-const std::string& XmppEngineImpl::GetRequestedResource() {
-  return requested_resource_;
-}
-
-XmppReturnStatus XmppEngineImpl::AddStanzaHandler(
-    XmppStanzaHandler* stanza_handler,
-    XmppEngine::HandlerLevel level) {
-  if (state_ == STATE_CLOSED)
-    return XMPP_RETURN_BADSTATE;
-
-  stanza_handlers_[level]->push_back(stanza_handler);
-
-  return XMPP_RETURN_OK;
-}
-
-XmppReturnStatus XmppEngineImpl::RemoveStanzaHandler(
-    XmppStanzaHandler* stanza_handler) {
-  bool found = false;
-
-  for (int level = 0; level < HL_COUNT; level += 1) {
-    StanzaHandlerVector::iterator new_end =
-      std::remove(stanza_handlers_[level]->begin(),
-      stanza_handlers_[level]->end(),
-      stanza_handler);
-
-    if (new_end != stanza_handlers_[level]->end()) {
-      stanza_handlers_[level]->erase(new_end, stanza_handlers_[level]->end());
-      found = true;
-    }
-  }
-
-  if (!found)
-    return XMPP_RETURN_BADARGUMENT;
-
-  return XMPP_RETURN_OK;
-}
-
-XmppReturnStatus XmppEngineImpl::Connect() {
-  if (state_ != STATE_START)
-    return XMPP_RETURN_BADSTATE;
-
-  EnterExit ee(this);
-
-  // get the login task started
-  state_ = STATE_OPENING;
-  if (login_task_.get()) {
-    login_task_->IncomingStanza(NULL, false);
-    if (login_task_->IsDone())
-      login_task_.reset();
-  }
-
-  return XMPP_RETURN_OK;
-}
-
-XmppReturnStatus XmppEngineImpl::SendStanza(const XmlElement* element) {
-  if (state_ == STATE_CLOSED)
-    return XMPP_RETURN_BADSTATE;
-
-  EnterExit ee(this);
-
-  if (login_task_.get()) {
-    // still handshaking - then outbound stanzas are queued
-    login_task_->OutgoingStanza(element);
-  } else {
-    // handshake done - send straight through
-    InternalSendStanza(element);
-  }
-
-  return XMPP_RETURN_OK;
-}
-
-XmppReturnStatus XmppEngineImpl::SendRaw(const std::string& text) {
-  if (state_ == STATE_CLOSED || login_task_.get())
-    return XMPP_RETURN_BADSTATE;
-
-  EnterExit ee(this);
-
-  (*output_) << text;
-
-  return XMPP_RETURN_OK;
-}
-
-std::string XmppEngineImpl::NextId() {
-  std::stringstream ss;
-  ss << next_id_++;
-  return ss.str();
-}
-
-XmppReturnStatus XmppEngineImpl::Disconnect() {
-  if (state_ != STATE_CLOSED) {
-    EnterExit ee(this);
-    if (state_ == STATE_OPEN)
-      *output_ << "</stream:stream>";
-    state_ = STATE_CLOSED;
-  }
-
-  return XMPP_RETURN_OK;
-}
-
-void XmppEngineImpl::IncomingStart(const XmlElement* start) {
-  if (HasError() || raised_reset_)
-    return;
-
-  if (login_task_.get()) {
-    // start-stream should go to login task
-    login_task_->IncomingStanza(start, true);
-    if (login_task_->IsDone())
-      login_task_.reset();
-  }
-  else {
-    // if not logging in, it's an error to see a start
-    SignalError(ERROR_XML, 0);
-  }
-}
-
-void XmppEngineImpl::IncomingStanza(const XmlElement* stanza) {
-  if (HasError() || raised_reset_)
-    return;
-
-  if (stanza->Name() == QN_STREAM_ERROR) {
-    // Explicit XMPP stream error
-    SignalStreamError(stanza);
-  } else if (login_task_.get()) {
-    // Handle login handshake
-    login_task_->IncomingStanza(stanza, false);
-    if (login_task_->IsDone())
-      login_task_.reset();
-  } else if (HandleIqResponse(stanza)) {
-    // iq is handled by above call
-  } else {
-    // give every "peek" handler a shot at all stanzas
-    for (size_t i = 0; i < stanza_handlers_[HL_PEEK]->size(); i += 1) {
-      (*stanza_handlers_[HL_PEEK])[i]->HandleStanza(stanza);
-    }
-
-    // give other handlers a shot in precedence order, stopping after handled
-    for (int level = HL_SINGLE; level <= HL_ALL; level += 1) {
-      for (size_t i = 0; i < stanza_handlers_[level]->size(); i += 1) {
-        if ((*stanza_handlers_[level])[i]->HandleStanza(stanza))
-          return;
-      }
-    }
-
-    // If nobody wants to handle a stanza then send back an error.
-    // Only do this for IQ stanzas as messages should probably just be dropped
-    // and presence stanzas should certainly be dropped.
-    std::string type = stanza->Attr(QN_TYPE);
-    if (stanza->Name() == QN_IQ &&
-        !(type == "error" || type == "result")) {
-      SendStanzaError(stanza, XSE_FEATURE_NOT_IMPLEMENTED, STR_EMPTY);
-    }
-  }
-}
-
-void XmppEngineImpl::IncomingEnd(bool isError) {
-  if (HasError() || raised_reset_)
-    return;
-
-  SignalError(isError ? ERROR_XML : ERROR_DOCUMENT_CLOSED, 0);
-}
-
-void XmppEngineImpl::InternalSendStart(const std::string& to) {
-  std::string hostname = tls_server_hostname_;
-  if (hostname.empty())
-    hostname = to;
-
-  // If not language is specified, the spec says use *
-  std::string lang = lang_;
-  if (lang.length() == 0)
-    lang = "*";
-
-  // send stream-beginning
-  // note, we put a \r\n at tne end fo the first line to cause non-XMPP
-  // line-oriented servers (e.g., Apache) to reveal themselves more quickly.
-  *output_ << "<stream:stream to=\"" << hostname << "\" "
-           << "xml:lang=\"" << lang << "\" "
-           << "version=\"1.0\" "
-           << "xmlns:stream=\"http://etherx.jabber.org/streams\" "
-           << "xmlns=\"jabber:client\">\r\n";
-}
-
-void XmppEngineImpl::InternalSendStanza(const XmlElement* element) {
-  // It should really never be necessary to set a FROM attribute on a stanza.
-  // It is implied by the bind on the stream and if you get it wrong
-  // (by flipping from/to on a message?) the server will close the stream.
-  ASSERT(!element->HasAttr(QN_FROM));
-
-  XmlPrinter::PrintXml(output_.get(), element, &xmlns_stack_);
-}
-
-std::string XmppEngineImpl::ChooseBestSaslMechanism(
-    const std::vector<std::string>& mechanisms, bool encrypted) {
-  return sasl_handler_->ChooseBestSaslMechanism(mechanisms, encrypted);
-}
-
-SaslMechanism* XmppEngineImpl::GetSaslMechanism(const std::string& name) {
-  return sasl_handler_->CreateSaslMechanism(name);
-}
-
-void XmppEngineImpl::SignalBound(const Jid& fullJid) {
-  if (state_ == STATE_OPENING) {
-    bound_jid_ = fullJid;
-    state_ = STATE_OPEN;
-  }
-}
-
-void XmppEngineImpl::SignalStreamError(const XmlElement* stream_error) {
-  if (state_ != STATE_CLOSED) {
-    stream_error_.reset(new XmlElement(*stream_error));
-    SignalError(ERROR_STREAM, 0);
-  }
-}
-
-void XmppEngineImpl::SignalError(Error error_code, int sub_code) {
-  if (state_ != STATE_CLOSED) {
-    error_code_ = error_code;
-    subcode_ = sub_code;
-    state_ = STATE_CLOSED;
-  }
-}
-
-bool XmppEngineImpl::HasError() {
-  return error_code_ != ERROR_NONE;
-}
-
-void XmppEngineImpl::StartTls(const std::string& domain) {
-  if (output_handler_) {
-    // As substitute for the real (login jid's) domain, we permit
-    // verifying a tls_server_domain_ instead, if one was passed.
-    // This allows us to avoid running a proxy that needs to handle
-    // valuable certificates.
-    output_handler_->StartTls(
-      tls_server_domain_.empty() ? domain : tls_server_domain_);
-    encrypted_ = true;
-  }
-}
-
-XmppEngineImpl::EnterExit::EnterExit(XmppEngineImpl* engine)
-    : engine_(engine),
-  state_(engine->state_),
-  error_(engine->error_code_) {
-  engine->engine_entered_ += 1;
-}
-
-XmppEngineImpl::EnterExit::~EnterExit()  {
- XmppEngineImpl* engine = engine_;
-
- engine->engine_entered_ -= 1;
-
- bool closing = (engine->state_ != state_ &&
-       engine->state_ == STATE_CLOSED);
- bool flushing = closing || (engine->engine_entered_ == 0);
-
- if (engine->output_handler_ && flushing) {
-   std::string output = engine->output_->str();
-   if (output.length() > 0)
-     engine->output_handler_->WriteOutput(output.c_str(), output.length());
-   engine->output_->str("");
-
-   if (closing) {
-     engine->output_handler_->CloseConnection();
-     engine->output_handler_ = 0;
-   }
- }
-
- if (engine->engine_entered_)
-   return;
-
- if (engine->raised_reset_) {
-   engine->stanza_parser_.Reset();
-   engine->raised_reset_ = false;
- }
-
- if (engine->session_handler_) {
-   if (engine->state_ != state_)
-     engine->session_handler_->OnStateChange(engine->state_);
-   // Note: Handling of OnStateChange(CLOSED) should allow for the
-   // deletion of the engine, so no members should be accessed
-   // after this line.
- }
-}
-
-}  // namespace buzz
diff --git a/third_party/libjingle/source/talk/xmpp/xmppengineimpl.h b/third_party/libjingle/source/talk/xmpp/xmppengineimpl.h
deleted file mode 100644
index 1fdb2a0..0000000
--- a/third_party/libjingle/source/talk/xmpp/xmppengineimpl.h
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_XMPP_XMPPENGINEIMPL_H_
-#define TALK_XMPP_XMPPENGINEIMPL_H_
-
-#include <sstream>
-#include <vector>
-#include "talk/xmpp/xmppengine.h"
-#include "talk/xmpp/xmppstanzaparser.h"
-
-namespace buzz {
-
-class XmppLoginTask;
-class XmppEngine;
-class XmppIqEntry;
-class SaslHandler;
-class SaslMechanism;
-
-//! The XMPP connection engine.
-//! This engine implements the client side of the 'core' XMPP protocol.
-//! To use it, register an XmppOutputHandler to handle socket output
-//! and pass socket input to HandleInput.  Then application code can
-//! set up the connection with a user, password, and other settings,
-//! and then call Connect() to initiate the connection.
-//! An application can listen for events and receive stanzas by
-//! registering an XmppStanzaHandler via AddStanzaHandler().
-class XmppEngineImpl : public XmppEngine {
- public:
-  XmppEngineImpl();
-  virtual ~XmppEngineImpl();
-
-  // SOCKET INPUT AND OUTPUT ------------------------------------------------
-
-  //! Registers the handler for socket output
-  virtual XmppReturnStatus SetOutputHandler(XmppOutputHandler *pxoh);
-
-  //! Provides socket input to the engine
-  virtual XmppReturnStatus HandleInput(const char* bytes, size_t len);
-
-  //! Advises the engine that the socket has closed
-  virtual XmppReturnStatus ConnectionClosed(int subcode);
-
-  // SESSION SETUP ---------------------------------------------------------
-
-  //! Indicates the (bare) JID for the user to use.
-  virtual XmppReturnStatus SetUser(const Jid& jid);
-
-  //! Get the login (bare) JID.
-  virtual const Jid& GetUser();
-
-  //! Indicates the autentication to use.  Takes ownership of the object.
-  virtual XmppReturnStatus SetSaslHandler(SaslHandler* sasl_handler);
-
-  //! Sets whether TLS will be used within the connection (default true).
-  virtual XmppReturnStatus SetTls(TlsOptions useTls);
-
-  //! Sets an alternate domain from which we allows TLS certificates.
-  //! This is for use in the case where a we want to allow a proxy to
-  //! serve up its own certificate rather than one owned by the underlying
-  //! domain.
-  virtual XmppReturnStatus SetTlsServer(const std::string& proxy_hostname,
-                                        const std::string& proxy_domain);
-
-  //! Gets whether TLS will be used within the connection.
-  virtual TlsOptions GetTls();
-
-  //! Sets the request resource name, if any (optional).
-  //! Note that the resource name may be overridden by the server; after
-  //! binding, the actual resource name is available as part of FullJid().
-  virtual XmppReturnStatus SetRequestedResource(const std::string& resource);
-
-  //! Gets the request resource name.
-  virtual const std::string& GetRequestedResource();
-
-  //! Sets language
-  virtual void SetLanguage(const std::string& lang) {
-    lang_ = lang;
-  }
-
-  // SESSION MANAGEMENT ---------------------------------------------------
-
-  //! Set callback for state changes.
-  virtual XmppReturnStatus SetSessionHandler(XmppSessionHandler* handler);
-
-  //! Initiates the XMPP connection.
-  //! After supplying connection settings, call this once to initiate,
-  //! (optionally) encrypt, authenticate, and bind the connection.
-  virtual XmppReturnStatus Connect();
-
-  //! The current engine state.
-  virtual State GetState() { return state_; }
-
-  //! Returns true if the connection is encrypted (under TLS)
-  virtual bool IsEncrypted() { return encrypted_; }
-
-  //! The error code.
-  //! Consult this after XmppOutputHandler.OnClose().
-  virtual Error GetError(int *subcode) {
-     if (subcode) {
-       *subcode = subcode_;
-     }
-     return error_code_;
-  }
-
-  //! The stream:error stanza, when the error is XmppEngine::ERROR_STREAM.
-  //! Notice the stanza returned is owned by the XmppEngine and
-  //! is deleted when the engine is destroyed.
-  virtual const XmlElement* GetStreamError() { return stream_error_.get(); }
-
-  //! Closes down the connection.
-  //! Sends CloseConnection to output, and disconnects and registered
-  //! session handlers.  After Disconnect completes, it is guaranteed
-  //! that no further callbacks will be made.
-  virtual XmppReturnStatus Disconnect();
-
-  // APPLICATION USE -------------------------------------------------------
-
-  //! Adds a listener for session events.
-  //! Stanza delivery is chained to session handlers; the first to
-  //! return 'true' is the last to get each stanza.
-  virtual XmppReturnStatus AddStanzaHandler(XmppStanzaHandler* handler,
-                                            XmppEngine::HandlerLevel level);
-
-  //! Removes a listener for session events.
-  virtual XmppReturnStatus RemoveStanzaHandler(XmppStanzaHandler* handler);
-
-  //! Sends a stanza to the server.
-  virtual XmppReturnStatus SendStanza(const XmlElement* stanza);
-
-  //! Sends raw text to the server
-  virtual XmppReturnStatus SendRaw(const std::string& text);
-
-  //! Sends an iq to the server, and registers a callback for the result.
-  //! Returns the cookie passed to the result handler.
-  virtual XmppReturnStatus SendIq(const XmlElement* stanza,
-                                  XmppIqHandler* iq_handler,
-                                  XmppIqCookie* cookie);
-
-  //! Unregisters an iq callback handler given its cookie.
-  //! No callback will come to this handler after it's unregistered.
-  virtual XmppReturnStatus RemoveIqHandler(XmppIqCookie cookie,
-                                      XmppIqHandler** iq_handler);
-
-  //! Forms and sends an error in response to the given stanza.
-  //! Swaps to and from, sets type to "error", and adds error information
-  //! based on the passed code.  Text is optional and may be STR_EMPTY.
-  virtual XmppReturnStatus SendStanzaError(const XmlElement* pelOriginal,
-                                           XmppStanzaError code,
-                                           const std::string& text);
-
-  //! The fullly bound JID.
-  //! This JID is only valid after binding has succeeded.  If the value
-  //! is JID_NULL, the binding has not succeeded.
-  virtual const Jid& FullJid() { return bound_jid_; }
-
-  //! The next unused iq id for this connection.
-  //! Call this when building iq stanzas, to ensure that each iq
-  //! gets its own unique id.
-  virtual std::string NextId();
-
- private:
-  friend class XmppLoginTask;
-  friend class XmppIqEntry;
-
-  void IncomingStanza(const XmlElement *stanza);
-  void IncomingStart(const XmlElement *stanza);
-  void IncomingEnd(bool isError);
-
-  void InternalSendStart(const std::string& domainName);
-  void InternalSendStanza(const XmlElement* stanza);
-  std::string ChooseBestSaslMechanism(
-      const std::vector<std::string>& mechanisms, bool encrypted);
-  SaslMechanism* GetSaslMechanism(const std::string& name);
-  void SignalBound(const Jid& fullJid);
-  void SignalStreamError(const XmlElement* streamError);
-  void SignalError(Error errorCode, int subCode);
-  bool HasError();
-  void DeleteIqCookies();
-  bool HandleIqResponse(const XmlElement* element);
-  void StartTls(const std::string& domain);
-  void RaiseReset() { raised_reset_ = true; }
-
-  class StanzaParseHandler : public XmppStanzaParseHandler {
-   public:
-    StanzaParseHandler(XmppEngineImpl* outer) : outer_(outer) {}
-    virtual ~StanzaParseHandler() {}
-
-    virtual void StartStream(const XmlElement* stream) {
-      outer_->IncomingStart(stream);
-    }
-    virtual void Stanza(const XmlElement* stanza) {
-      outer_->IncomingStanza(stanza);
-    }
-    virtual void EndStream() {
-      outer_->IncomingEnd(false);
-    }
-    virtual void XmlError() {
-      outer_->IncomingEnd(true);
-    }
-
-   private:
-    XmppEngineImpl* const outer_;
-  };
-
-  class EnterExit {
-   public:
-    EnterExit(XmppEngineImpl* engine);
-    ~EnterExit();
-   private:
-    XmppEngineImpl* engine_;
-    State state_;
-    Error error_;
-
-  };
-
-  friend class StanzaParseHandler;
-  friend class EnterExit;
-
-  StanzaParseHandler stanza_parse_handler_;
-  XmppStanzaParser stanza_parser_;
-
-  // state
-  int engine_entered_;
-  Jid user_jid_;
-  std::string password_;
-  std::string requested_resource_;
-  TlsOptions tls_option_;
-  std::string tls_server_hostname_;
-  std::string tls_server_domain_;
-  talk_base::scoped_ptr<XmppLoginTask> login_task_;
-  std::string lang_;
-
-  int next_id_;
-  Jid bound_jid_;
-  State state_;
-  bool encrypted_;
-  Error error_code_;
-  int subcode_;
-  talk_base::scoped_ptr<XmlElement> stream_error_;
-  bool raised_reset_;
-  XmppOutputHandler* output_handler_;
-  XmppSessionHandler* session_handler_;
-
-  XmlnsStack xmlns_stack_;
-
-  typedef std::vector<XmppStanzaHandler*> StanzaHandlerVector;
-  talk_base::scoped_ptr<StanzaHandlerVector> stanza_handlers_[HL_COUNT];
-
-  typedef std::vector<XmppIqEntry*> IqEntryVector;
-  talk_base::scoped_ptr<IqEntryVector> iq_entries_;
-
-  talk_base::scoped_ptr<SaslHandler> sasl_handler_;
-
-  talk_base::scoped_ptr<std::stringstream> output_;
-};
-
-}  // namespace buzz
-
-#endif  // TALK_XMPP_XMPPENGINEIMPL_H_
diff --git a/third_party/libjingle/source/talk/xmpp/xmppengineimpl_iq.cc b/third_party/libjingle/source/talk/xmpp/xmppengineimpl_iq.cc
deleted file mode 100644
index 5834b90..0000000
--- a/third_party/libjingle/source/talk/xmpp/xmppengineimpl_iq.cc
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <vector>
-#include <algorithm>
-#include "talk/base/common.h"
-#include "talk/xmpp/xmppengineimpl.h"
-#include "talk/xmpp/constants.h"
-
-namespace buzz {
-
-class XmppIqEntry {
-  XmppIqEntry(const std::string & id, const std::string & to,
-               XmppEngine * pxce, XmppIqHandler * iq_handler) :
-    id_(id),
-    to_(to),
-    engine_(pxce),
-    iq_handler_(iq_handler) {
-  }
-
-private:
-  friend class XmppEngineImpl;
-
-  const std::string id_;
-  const std::string to_;
-  XmppEngine * const engine_;
-  XmppIqHandler * const iq_handler_;
-};
-
-
-XmppReturnStatus
-XmppEngineImpl::SendIq(const XmlElement * element, XmppIqHandler * iq_handler,
-  XmppIqCookie* cookie) {
-  if (state_ == STATE_CLOSED)
-    return XMPP_RETURN_BADSTATE;
-  if (NULL == iq_handler)
-    return XMPP_RETURN_BADARGUMENT;
-  if (!element || element->Name() != QN_IQ)
-    return XMPP_RETURN_BADARGUMENT;
-
-  const std::string& type = element->Attr(QN_TYPE);
-  if (type != "get" && type != "set")
-    return XMPP_RETURN_BADARGUMENT;
-
-  if (!element->HasAttr(QN_ID))
-    return XMPP_RETURN_BADARGUMENT;
-  const std::string& id = element->Attr(QN_ID);
-
-  XmppIqEntry * iq_entry = new XmppIqEntry(id,
-                                              element->Attr(QN_TO),
-                                              this, iq_handler);
-  iq_entries_->push_back(iq_entry);
-  SendStanza(element);
-
-  if (cookie)
-    *cookie = iq_entry;
-
-  return XMPP_RETURN_OK;
-}
-
-
-XmppReturnStatus
-XmppEngineImpl::RemoveIqHandler(XmppIqCookie cookie,
-    XmppIqHandler ** iq_handler) {
-
-  std::vector<XmppIqEntry*, std::allocator<XmppIqEntry*> >::iterator pos;
-
-  pos = std::find(iq_entries_->begin(),
-                  iq_entries_->end(),
-                  reinterpret_cast<XmppIqEntry*>(cookie));
-
-  if (pos == iq_entries_->end())
-    return XMPP_RETURN_BADARGUMENT;
-
-  XmppIqEntry* entry = *pos;
-  iq_entries_->erase(pos);
-  if (iq_handler)
-    *iq_handler = entry->iq_handler_;
-  delete entry;
-
-  return XMPP_RETURN_OK;
-}
-
-void
-XmppEngineImpl::DeleteIqCookies() {
-  for (size_t i = 0; i < iq_entries_->size(); i += 1) {
-    XmppIqEntry * iq_entry_ = (*iq_entries_)[i];
-    (*iq_entries_)[i] = NULL;
-    delete iq_entry_;
-  }
-  iq_entries_->clear();
-}
-
-static void
-AecImpl(XmlElement * error_element, const QName & name,
-        const char * type, const char * code) {
-  error_element->AddElement(new XmlElement(QN_ERROR));
-  error_element->AddAttr(QN_CODE, code, 1);
-  error_element->AddAttr(QN_TYPE, type, 1);
-  error_element->AddElement(new XmlElement(name, true), 1);
-}
-
-
-static void
-AddErrorCode(XmlElement * error_element, XmppStanzaError code) {
-  switch (code) {
-    case XSE_BAD_REQUEST:
-      AecImpl(error_element, QN_STANZA_BAD_REQUEST, "modify", "400");
-      break;
-    case XSE_CONFLICT:
-      AecImpl(error_element, QN_STANZA_CONFLICT, "cancel", "409");
-      break;
-    case XSE_FEATURE_NOT_IMPLEMENTED:
-      AecImpl(error_element, QN_STANZA_FEATURE_NOT_IMPLEMENTED,
-              "cancel", "501");
-      break;
-    case XSE_FORBIDDEN:
-      AecImpl(error_element, QN_STANZA_FORBIDDEN, "auth", "403");
-      break;
-    case XSE_GONE:
-      AecImpl(error_element, QN_STANZA_GONE, "modify", "302");
-      break;
-    case XSE_INTERNAL_SERVER_ERROR:
-      AecImpl(error_element, QN_STANZA_INTERNAL_SERVER_ERROR, "wait", "500");
-      break;
-    case XSE_ITEM_NOT_FOUND:
-      AecImpl(error_element, QN_STANZA_ITEM_NOT_FOUND, "cancel", "404");
-      break;
-    case XSE_JID_MALFORMED:
-      AecImpl(error_element, QN_STANZA_JID_MALFORMED, "modify", "400");
-      break;
-    case XSE_NOT_ACCEPTABLE:
-      AecImpl(error_element, QN_STANZA_NOT_ACCEPTABLE, "cancel", "406");
-      break;
-    case XSE_NOT_ALLOWED:
-      AecImpl(error_element, QN_STANZA_NOT_ALLOWED, "cancel", "405");
-      break;
-    case XSE_PAYMENT_REQUIRED:
-      AecImpl(error_element, QN_STANZA_PAYMENT_REQUIRED, "auth", "402");
-      break;
-    case XSE_RECIPIENT_UNAVAILABLE:
-      AecImpl(error_element, QN_STANZA_RECIPIENT_UNAVAILABLE, "wait", "404");
-      break;
-    case XSE_REDIRECT:
-      AecImpl(error_element, QN_STANZA_REDIRECT, "modify", "302");
-      break;
-    case XSE_REGISTRATION_REQUIRED:
-      AecImpl(error_element, QN_STANZA_REGISTRATION_REQUIRED, "auth", "407");
-      break;
-    case XSE_SERVER_NOT_FOUND:
-      AecImpl(error_element, QN_STANZA_REMOTE_SERVER_NOT_FOUND,
-              "cancel", "404");
-      break;
-    case XSE_SERVER_TIMEOUT:
-      AecImpl(error_element, QN_STANZA_REMOTE_SERVER_TIMEOUT, "wait", "502");
-      break;
-    case XSE_RESOURCE_CONSTRAINT:
-      AecImpl(error_element, QN_STANZA_RESOURCE_CONSTRAINT, "wait", "500");
-      break;
-    case XSE_SERVICE_UNAVAILABLE:
-      AecImpl(error_element, QN_STANZA_SERVICE_UNAVAILABLE, "cancel", "503");
-      break;
-    case XSE_SUBSCRIPTION_REQUIRED:
-      AecImpl(error_element, QN_STANZA_SUBSCRIPTION_REQUIRED, "auth", "407");
-      break;
-    case XSE_UNDEFINED_CONDITION:
-      AecImpl(error_element, QN_STANZA_UNDEFINED_CONDITION, "wait", "500");
-      break;
-    case XSE_UNEXPECTED_REQUEST:
-      AecImpl(error_element, QN_STANZA_UNEXPECTED_REQUEST, "wait", "400");
-      break;
-  }
-}
-
-
-XmppReturnStatus
-XmppEngineImpl::SendStanzaError(const XmlElement * element_original,
-                                XmppStanzaError code,
-                                const std::string & text) {
-
-  if (state_ == STATE_CLOSED)
-    return XMPP_RETURN_BADSTATE;
-
-  XmlElement error_element(element_original->Name());
-  error_element.AddAttr(QN_TYPE, "error");
-
-  // copy attrs, copy 'from' to 'to' and strip 'from'
-  for (const XmlAttr * attribute = element_original->FirstAttr();
-       attribute; attribute = attribute->NextAttr()) {
-    QName name = attribute->Name();
-    if (name == QN_TO)
-      continue; // no need to put a from attr.  Server will stamp stanza
-    else if (name == QN_FROM)
-      name = QN_TO;
-    else if (name == QN_TYPE)
-      continue;
-    error_element.AddAttr(name, attribute->Value());
-  }
-
-  // copy children
-  for (const XmlChild * child = element_original->FirstChild();
-       child;
-       child = child->NextChild()) {
-    if (child->IsText()) {
-      error_element.AddText(child->AsText()->Text());
-    } else {
-      error_element.AddElement(new XmlElement(*(child->AsElement())));
-    }
-  }
-
-  // add error information
-  AddErrorCode(&error_element, code);
-  if (text != STR_EMPTY) {
-    XmlElement * text_element = new XmlElement(QN_STANZA_TEXT, true);
-    text_element->AddText(text);
-    error_element.AddElement(text_element);
-  }
-
-  SendStanza(&error_element);
-
-  return XMPP_RETURN_OK;
-}
-
-
-bool
-XmppEngineImpl::HandleIqResponse(const XmlElement * element) {
-  if (iq_entries_->empty())
-    return false;
-  if (element->Name() != QN_IQ)
-    return false;
-  std::string type = element->Attr(QN_TYPE);
-  if (type != "result" && type != "error")
-    return false;
-  if (!element->HasAttr(QN_ID))
-    return false;
-  std::string id = element->Attr(QN_ID);
-  std::string from = element->Attr(QN_FROM);
-
-  for (std::vector<XmppIqEntry *>::iterator it = iq_entries_->begin();
-       it != iq_entries_->end(); it += 1) {
-    XmppIqEntry * iq_entry = *it;
-    if (iq_entry->id_ == id && iq_entry->to_ == from) {
-      iq_entries_->erase(it);
-      iq_entry->iq_handler_->IqResponse(iq_entry, element);
-      delete iq_entry;
-      return true;
-    }
-  }
-
-  return false;
-}
-
-}
diff --git a/third_party/libjingle/source/talk/xmpp/xmpplogintask.cc b/third_party/libjingle/source/talk/xmpp/xmpplogintask.cc
deleted file mode 100644
index 726802d..0000000
--- a/third_party/libjingle/source/talk/xmpp/xmpplogintask.cc
+++ /dev/null
@@ -1,397 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/xmpp/xmpplogintask.h"
-
-#include <string>
-#include <vector>
-
-#include "talk/base/base64.h"
-#include "talk/base/common.h"
-#include "talk/xmllite/xmlelement.h"
-#include "talk/xmpp/constants.h"
-#include "talk/xmpp/jid.h"
-#include "talk/xmpp/saslmechanism.h"
-#include "talk/xmpp/xmppengineimpl.h"
-
-using talk_base::ConstantLabel;
-
-namespace buzz {
-
-#ifdef _DEBUG
-const ConstantLabel XmppLoginTask::LOGINTASK_STATES[] = {
-  KLABEL(LOGINSTATE_INIT),
-  KLABEL(LOGINSTATE_STREAMSTART_SENT),
-  KLABEL(LOGINSTATE_STARTED_XMPP),
-  KLABEL(LOGINSTATE_TLS_INIT),
-  KLABEL(LOGINSTATE_AUTH_INIT),
-  KLABEL(LOGINSTATE_BIND_INIT),
-  KLABEL(LOGINSTATE_TLS_REQUESTED),
-  KLABEL(LOGINSTATE_SASL_RUNNING),
-  KLABEL(LOGINSTATE_BIND_REQUESTED),
-  KLABEL(LOGINSTATE_SESSION_REQUESTED),
-  KLABEL(LOGINSTATE_DONE),
-  LASTLABEL
-};
-#endif  // _DEBUG
-XmppLoginTask::XmppLoginTask(XmppEngineImpl * pctx) :
-  pctx_(pctx),
-  authNeeded_(true),
-  allowNonGoogleLogin_(true),
-  state_(LOGINSTATE_INIT),
-  pelStanza_(NULL),
-  isStart_(false),
-  iqId_(STR_EMPTY),
-  pelFeatures_(NULL),
-  fullJid_(STR_EMPTY),
-  streamId_(STR_EMPTY),
-  pvecQueuedStanzas_(new std::vector<XmlElement *>()),
-  sasl_mech_(NULL) {
-}
-
-XmppLoginTask::~XmppLoginTask() {
-  for (size_t i = 0; i < pvecQueuedStanzas_->size(); i += 1)
-    delete (*pvecQueuedStanzas_)[i];
-}
-
-void
-XmppLoginTask::IncomingStanza(const XmlElement *element, bool isStart) {
-  pelStanza_ = element;
-  isStart_ = isStart;
-  Advance();
-  pelStanza_ = NULL;
-  isStart_ = false;
-}
-
-const XmlElement *
-XmppLoginTask::NextStanza() {
-  const XmlElement * result = pelStanza_;
-  pelStanza_ = NULL;
-  return result;
-}
-
-bool
-XmppLoginTask::Advance() {
-
-  for (;;) {
-
-    const XmlElement * element = NULL;
-
-#if _DEBUG
-    LOG(LS_VERBOSE) << "XmppLoginTask::Advance - "
-      << talk_base::ErrorName(state_, LOGINTASK_STATES);
-#endif  // _DEBUG
-
-    switch (state_) {
-
-      case LOGINSTATE_INIT: {
-        pctx_->RaiseReset();
-        pelFeatures_.reset(NULL);
-
-        // The proper domain to verify against is the real underlying
-        // domain - i.e., the domain that owns the JID.  Our XmppEngineImpl
-        // also allows matching against a proxy domain instead, if it is told
-        // to do so - see the implementation of XmppEngineImpl::StartTls and
-        // XmppEngine::SetTlsServerDomain to see how you can use that feature
-        pctx_->InternalSendStart(pctx_->user_jid_.domain());
-        state_ = LOGINSTATE_STREAMSTART_SENT;
-        break;
-      }
-
-      case LOGINSTATE_STREAMSTART_SENT: {
-        if (NULL == (element = NextStanza()))
-          return true;
-
-        if (!isStart_ || !HandleStartStream(element))
-          return Failure(XmppEngine::ERROR_VERSION);
-
-        state_ = LOGINSTATE_STARTED_XMPP;
-        return true;
-      }
-
-      case LOGINSTATE_STARTED_XMPP: {
-        if (NULL == (element = NextStanza()))
-          return true;
-
-        if (!HandleFeatures(element))
-          return Failure(XmppEngine::ERROR_VERSION);
-
-        bool tls_present = (GetFeature(QN_TLS_STARTTLS) != NULL);
-        // Error if TLS required but not present.
-        if (pctx_->tls_option_ == buzz::TLS_REQUIRED && !tls_present) {
-          return Failure(XmppEngine::ERROR_TLS);
-        }
-        // Use TLS if required or enabled, and also available
-        if ((pctx_->tls_option_ == buzz::TLS_REQUIRED ||
-            pctx_->tls_option_ == buzz::TLS_ENABLED) && tls_present) {
-          state_ = LOGINSTATE_TLS_INIT;
-          continue;
-        }
-
-        if (authNeeded_) {
-          state_ = LOGINSTATE_AUTH_INIT;
-          continue;
-        }
-
-        state_ = LOGINSTATE_BIND_INIT;
-        continue;
-      }
-
-      case LOGINSTATE_TLS_INIT: {
-        const XmlElement * pelTls = GetFeature(QN_TLS_STARTTLS);
-        if (!pelTls)
-          return Failure(XmppEngine::ERROR_TLS);
-
-        XmlElement el(QN_TLS_STARTTLS, true);
-        pctx_->InternalSendStanza(&el);
-        state_ = LOGINSTATE_TLS_REQUESTED;
-        continue;
-      }
-
-      case LOGINSTATE_TLS_REQUESTED: {
-        if (NULL == (element = NextStanza()))
-          return true;
-        if (element->Name() != QN_TLS_PROCEED)
-          return Failure(XmppEngine::ERROR_TLS);
-
-        // The proper domain to verify against is the real underlying
-        // domain - i.e., the domain that owns the JID.  Our XmppEngineImpl
-        // also allows matching against a proxy domain instead, if it is told
-        // to do so - see the implementation of XmppEngineImpl::StartTls and
-        // XmppEngine::SetTlsServerDomain to see how you can use that feature
-        pctx_->StartTls(pctx_->user_jid_.domain());
-        pctx_->tls_option_ = buzz::TLS_ENABLED;
-        state_ = LOGINSTATE_INIT;
-        continue;
-      }
-
-      case LOGINSTATE_AUTH_INIT: {
-        const XmlElement * pelSaslAuth = GetFeature(QN_SASL_MECHANISMS);
-        if (!pelSaslAuth) {
-          return Failure(XmppEngine::ERROR_AUTH);
-        }
-
-        // Collect together the SASL auth mechanisms presented by the server
-        std::vector<std::string> mechanisms;
-        for (const XmlElement * pelMech =
-             pelSaslAuth->FirstNamed(QN_SASL_MECHANISM);
-             pelMech;
-             pelMech = pelMech->NextNamed(QN_SASL_MECHANISM)) {
-
-          mechanisms.push_back(pelMech->BodyText());
-        }
-
-        // Given all the mechanisms, choose the best
-        std::string choice(pctx_->ChooseBestSaslMechanism(mechanisms, pctx_->IsEncrypted()));
-        if (choice.empty()) {
-          return Failure(XmppEngine::ERROR_AUTH);
-        }
-
-        // No recognized auth mechanism - that's an error
-        sasl_mech_.reset(pctx_->GetSaslMechanism(choice));
-        if (sasl_mech_.get() == NULL) {
-          return Failure(XmppEngine::ERROR_AUTH);
-        }
-
-        // OK, let's start it.
-        XmlElement * auth = sasl_mech_->StartSaslAuth();
-        if (auth == NULL) {
-          return Failure(XmppEngine::ERROR_AUTH);
-        }
-        if (allowNonGoogleLogin_) {
-          // Setting the following two attributes is required to support
-          // non-google ids.
-
-          // Allow login with non-google id accounts.
-          auth->SetAttr(QN_GOOGLE_ALLOW_NON_GOOGLE_ID_XMPP_LOGIN, "true");
-
-          // Allow login with either the non-google id or the friendly email.
-          auth->SetAttr(QN_GOOGLE_AUTH_CLIENT_USES_FULL_BIND_RESULT, "true");
-        }
-
-        pctx_->InternalSendStanza(auth);
-        delete auth;
-        state_ = LOGINSTATE_SASL_RUNNING;
-        continue;
-      }
-
-      case LOGINSTATE_SASL_RUNNING: {
-        if (NULL == (element = NextStanza()))
-          return true;
-        if (element->Name().Namespace() != NS_SASL)
-          return Failure(XmppEngine::ERROR_AUTH);
-        if (element->Name() == QN_SASL_CHALLENGE) {
-          XmlElement * response = sasl_mech_->HandleSaslChallenge(element);
-          if (response == NULL) {
-            return Failure(XmppEngine::ERROR_AUTH);
-          }
-          pctx_->InternalSendStanza(response);
-          delete response;
-          state_ = LOGINSTATE_SASL_RUNNING;
-          continue;
-        }
-        if (element->Name() != QN_SASL_SUCCESS) {
-          return Failure(XmppEngine::ERROR_UNAUTHORIZED);
-        }
-
-        // Authenticated!
-        authNeeded_ = false;
-        state_ = LOGINSTATE_INIT;
-        continue;
-      }
-
-      case LOGINSTATE_BIND_INIT: {
-        const XmlElement * pelBindFeature = GetFeature(QN_BIND_BIND);
-        const XmlElement * pelSessionFeature = GetFeature(QN_SESSION_SESSION);
-        if (!pelBindFeature || !pelSessionFeature)
-          return Failure(XmppEngine::ERROR_BIND);
-
-        XmlElement iq(QN_IQ);
-        iq.AddAttr(QN_TYPE, "set");
-
-        iqId_ = pctx_->NextId();
-        iq.AddAttr(QN_ID, iqId_);
-        iq.AddElement(new XmlElement(QN_BIND_BIND, true));
-
-        if (pctx_->requested_resource_ != STR_EMPTY) {
-          iq.AddElement(new XmlElement(QN_BIND_RESOURCE), 1);
-          iq.AddText(pctx_->requested_resource_, 2);
-        }
-        pctx_->InternalSendStanza(&iq);
-        state_ = LOGINSTATE_BIND_REQUESTED;
-        continue;
-      }
-
-      case LOGINSTATE_BIND_REQUESTED: {
-        if (NULL == (element = NextStanza()))
-          return true;
-
-        if (element->Name() != QN_IQ || element->Attr(QN_ID) != iqId_ ||
-            element->Attr(QN_TYPE) == "get" || element->Attr(QN_TYPE) == "set")
-          return true;
-
-        if (element->Attr(QN_TYPE) != "result" || element->FirstElement() == NULL ||
-            element->FirstElement()->Name() != QN_BIND_BIND)
-          return Failure(XmppEngine::ERROR_BIND);
-
-        fullJid_ = Jid(element->FirstElement()->TextNamed(QN_BIND_JID));
-        if (!fullJid_.IsFull()) {
-          return Failure(XmppEngine::ERROR_BIND);
-        }
-
-        // now request session
-        XmlElement iq(QN_IQ);
-        iq.AddAttr(QN_TYPE, "set");
-
-        iqId_ = pctx_->NextId();
-        iq.AddAttr(QN_ID, iqId_);
-        iq.AddElement(new XmlElement(QN_SESSION_SESSION, true));
-        pctx_->InternalSendStanza(&iq);
-
-        state_ = LOGINSTATE_SESSION_REQUESTED;
-        continue;
-      }
-
-      case LOGINSTATE_SESSION_REQUESTED: {
-        if (NULL == (element = NextStanza()))
-          return true;
-        if (element->Name() != QN_IQ || element->Attr(QN_ID) != iqId_ ||
-            element->Attr(QN_TYPE) == "get" || element->Attr(QN_TYPE) == "set")
-          return false;
-
-        if (element->Attr(QN_TYPE) != "result")
-          return Failure(XmppEngine::ERROR_BIND);
-
-        pctx_->SignalBound(fullJid_);
-        FlushQueuedStanzas();
-        state_ = LOGINSTATE_DONE;
-        return true;
-      }
-
-      case LOGINSTATE_DONE:
-        return false;
-    }
-  }
-}
-
-bool
-XmppLoginTask::HandleStartStream(const XmlElement *element) {
-
-  if (element->Name() != QN_STREAM_STREAM)
-    return false;
-
-  if (element->Attr(QN_XMLNS) != "jabber:client")
-    return false;
-
-  if (element->Attr(QN_VERSION) != "1.0")
-    return false;
-
-  if (!element->HasAttr(QN_ID))
-    return false;
-
-  streamId_ = element->Attr(QN_ID);
-
-  return true;
-}
-
-bool
-XmppLoginTask::HandleFeatures(const XmlElement *element) {
-  if (element->Name() != QN_STREAM_FEATURES)
-    return false;
-
-  pelFeatures_.reset(new XmlElement(*element));
-  return true;
-}
-
-const XmlElement *
-XmppLoginTask::GetFeature(const QName & name) {
-  return pelFeatures_->FirstNamed(name);
-}
-
-bool
-XmppLoginTask::Failure(XmppEngine::Error reason) {
-  state_ = LOGINSTATE_DONE;
-  pctx_->SignalError(reason, 0);
-  return false;
-}
-
-void
-XmppLoginTask::OutgoingStanza(const XmlElement * element) {
-  XmlElement * pelCopy = new XmlElement(*element);
-  pvecQueuedStanzas_->push_back(pelCopy);
-}
-
-void
-XmppLoginTask::FlushQueuedStanzas() {
-  for (size_t i = 0; i < pvecQueuedStanzas_->size(); i += 1) {
-    pctx_->InternalSendStanza((*pvecQueuedStanzas_)[i]);
-    delete (*pvecQueuedStanzas_)[i];
-  }
-  pvecQueuedStanzas_->clear();
-}
-
-}
diff --git a/third_party/libjingle/source/talk/xmpp/xmpplogintask.h b/third_party/libjingle/source/talk/xmpp/xmpplogintask.h
deleted file mode 100644
index 9b3f5ae..0000000
--- a/third_party/libjingle/source/talk/xmpp/xmpplogintask.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_XMPP_LOGINTASK_H_
-#define TALK_XMPP_LOGINTASK_H_
-
-#include <string>
-#include <vector>
-
-#include "talk/base/logging.h"
-#include "talk/base/scoped_ptr.h"
-#include "talk/xmpp/jid.h"
-#include "talk/xmpp/xmppengine.h"
-
-namespace buzz {
-
-class XmlElement;
-class XmppEngineImpl;
-class SaslMechanism;
-
-
-// TODO: Rename to LoginTask.
-class XmppLoginTask {
-
-public:
-  XmppLoginTask(XmppEngineImpl *pctx);
-  ~XmppLoginTask();
-
-  bool IsDone()
-    { return state_ == LOGINSTATE_DONE; }
-  void IncomingStanza(const XmlElement * element, bool isStart);
-  void OutgoingStanza(const XmlElement *element);
-  void set_allow_non_google_login(bool b)
-    { allowNonGoogleLogin_ = b; }
-
-private:
-  enum LoginTaskState {
-    LOGINSTATE_INIT = 0,
-    LOGINSTATE_STREAMSTART_SENT,
-    LOGINSTATE_STARTED_XMPP,
-    LOGINSTATE_TLS_INIT,
-    LOGINSTATE_AUTH_INIT,
-    LOGINSTATE_BIND_INIT,
-    LOGINSTATE_TLS_REQUESTED,
-    LOGINSTATE_SASL_RUNNING,
-    LOGINSTATE_BIND_REQUESTED,
-    LOGINSTATE_SESSION_REQUESTED,
-    LOGINSTATE_DONE,
-  };
-
-  const XmlElement * NextStanza();
-  bool Advance();
-  bool HandleStartStream(const XmlElement * element);
-  bool HandleFeatures(const XmlElement * element);
-  const XmlElement * GetFeature(const QName & name);
-  bool Failure(XmppEngine::Error reason);
-  void FlushQueuedStanzas();
-
-  XmppEngineImpl * pctx_;
-  bool authNeeded_;
-  bool allowNonGoogleLogin_;
-  LoginTaskState state_;
-  const XmlElement * pelStanza_;
-  bool isStart_;
-  std::string iqId_;
-  talk_base::scoped_ptr<XmlElement> pelFeatures_;
-  Jid fullJid_;
-  std::string streamId_;
-  talk_base::scoped_ptr<std::vector<XmlElement *> > pvecQueuedStanzas_;
-
-  talk_base::scoped_ptr<SaslMechanism> sasl_mech_;
-
-#ifdef _DEBUG
-  static const talk_base::ConstantLabel LOGINTASK_STATES[];
-#endif  // _DEBUG
-};
-
-}
-
-#endif  //  TALK_XMPP_LOGINTASK_H_
diff --git a/third_party/libjingle/source/talk/xmpp/xmpplogintask_unittest.cc b/third_party/libjingle/source/talk/xmpp/xmpplogintask_unittest.cc
deleted file mode 100644
index 51af81a..0000000
--- a/third_party/libjingle/source/talk/xmpp/xmpplogintask_unittest.cc
+++ /dev/null
@@ -1,614 +0,0 @@
-// Copyright 2004 Google Inc. All Rights Reserved
-
-
-#include <string>
-#include <sstream>
-#include <iostream>
-#include "talk/base/common.h"
-#include "talk/base/cryptstring.h"
-#include "talk/base/gunit.h"
-#include "talk/xmllite/xmlelement.h"
-#include "talk/xmpp/util_unittest.h"
-#include "talk/xmpp/constants.h"
-#include "talk/xmpp/saslplainmechanism.h"
-#include "talk/xmpp/plainsaslhandler.h"
-#include "talk/xmpp/xmppengine.h"
-
-using buzz::Jid;
-using buzz::QName;
-using buzz::XmlElement;
-using buzz::XmppEngine;
-using buzz::XmppTestHandler;
-
-enum XlttStage {
-  XLTT_STAGE_CONNECT = 0,
-  XLTT_STAGE_STREAMSTART,
-  XLTT_STAGE_TLS_FEATURES,
-  XLTT_STAGE_TLS_PROCEED,
-  XLTT_STAGE_ENCRYPTED_START,
-  XLTT_STAGE_AUTH_FEATURES,
-  XLTT_STAGE_AUTH_SUCCESS,
-  XLTT_STAGE_AUTHENTICATED_START,
-  XLTT_STAGE_BIND_FEATURES,
-  XLTT_STAGE_BIND_SUCCESS,
-  XLTT_STAGE_SESSION_SUCCESS,
-};
-
-class XmppLoginTaskTest : public testing::Test {
- public:
-  XmppEngine* engine() { return engine_.get(); }
-  XmppTestHandler* handler() { return handler_.get(); }
-  virtual void SetUp() {
-    engine_.reset(XmppEngine::Create());
-    handler_.reset(new XmppTestHandler(engine_.get()));
-
-    Jid jid("david@my-server");
-    talk_base::InsecureCryptStringImpl pass;
-    pass.password() = "david";
-    engine_->SetSessionHandler(handler_.get());
-    engine_->SetOutputHandler(handler_.get());
-    engine_->AddStanzaHandler(handler_.get());
-    engine_->SetUser(jid);
-    engine_->SetSaslHandler(
-        new buzz::PlainSaslHandler(jid, talk_base::CryptString(pass), true));
-  }
-  virtual void TearDown() {
-    handler_.reset();
-    engine_.reset();
-  }
-  void RunPartialLogin(XlttStage startstage, XlttStage endstage);
-  void SetTlsOptions(buzz::TlsOptions option);
-
- private:
-  talk_base::scoped_ptr<XmppEngine> engine_;
-  talk_base::scoped_ptr<XmppTestHandler> handler_;
-};
-
-void XmppLoginTaskTest::SetTlsOptions(buzz::TlsOptions option) {
-  engine_->SetTls(option);
-}
-void XmppLoginTaskTest::RunPartialLogin(XlttStage startstage,
-                                        XlttStage endstage) {
-  std::string input;
-
-  switch (startstage) {
-    case XLTT_STAGE_CONNECT: {
-      engine_->Connect();
-      XmlElement appStanza(QName("test", "app-stanza"));
-      appStanza.AddText("this-is-a-test");
-      engine_->SendStanza(&appStanza);
-
-      EXPECT_EQ("<stream:stream to=\"my-server\" xml:lang=\"*\" "
-          "version=\"1.0\" xmlns:stream=\"http://etherx.jabber.org/streams\" "
-          "xmlns=\"jabber:client\">\r\n", handler_->OutputActivity());
-      EXPECT_EQ("[OPENING]", handler_->SessionActivity());
-      EXPECT_EQ("", handler_->StanzaActivity());
-      if (endstage == XLTT_STAGE_CONNECT)
-        return;
-    }
-
-    case XLTT_STAGE_STREAMSTART: {
-      input = "<stream:stream id=\"a5f2d8c9\" version=\"1.0\" "
-          "xmlns:stream=\"http://etherx.jabber.org/streams\" "
-          "xmlns=\"jabber:client\">";
-      engine_->HandleInput(input.c_str(), input.length());
-      EXPECT_EQ("", handler_->StanzaActivity());
-      EXPECT_EQ("", handler_->SessionActivity());
-      EXPECT_EQ("", handler_->OutputActivity());
-      if (endstage == XLTT_STAGE_STREAMSTART)
-        return;
-    }
-
-    case XLTT_STAGE_TLS_FEATURES: {
-      input = "<stream:features>"
-        "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>"
-       "</stream:features>";
-      engine_->HandleInput(input.c_str(), input.length());
-      EXPECT_EQ("<starttls xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\"/>",
-          handler_->OutputActivity());
-      EXPECT_EQ("", handler_->StanzaActivity());
-      EXPECT_EQ("", handler_->SessionActivity());
-      if (endstage == XLTT_STAGE_TLS_FEATURES)
-        return;
-    }
-
-    case XLTT_STAGE_TLS_PROCEED: {
-      input = std::string("<proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>");
-      engine_->HandleInput(input.c_str(), input.length());
-      EXPECT_EQ("[START-TLS my-server]"
-          "<stream:stream to=\"my-server\" xml:lang=\"*\" "
-          "version=\"1.0\" xmlns:stream=\"http://etherx.jabber.org/streams\" "
-          "xmlns=\"jabber:client\">\r\n", handler_->OutputActivity());
-      EXPECT_EQ("", handler_->StanzaActivity());
-      EXPECT_EQ("", handler_->SessionActivity());
-       if (endstage == XLTT_STAGE_TLS_PROCEED)
-        return;
-    }
-
-    case XLTT_STAGE_ENCRYPTED_START: {
-      input = std::string("<stream:stream id=\"01234567\" version=\"1.0\" "
-          "xmlns:stream=\"http://etherx.jabber.org/streams\" "
-          "xmlns=\"jabber:client\">");
-      engine_->HandleInput(input.c_str(), input.length());
-      EXPECT_EQ("", handler_->StanzaActivity());
-      EXPECT_EQ("", handler_->SessionActivity());
-      EXPECT_EQ("", handler_->OutputActivity());
-      if (endstage == XLTT_STAGE_ENCRYPTED_START)
-        return;
-    }
-
-    case XLTT_STAGE_AUTH_FEATURES: {
-      input = "<stream:features>"
-        "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
-          "<mechanism>DIGEST-MD5</mechanism>"
-          "<mechanism>PLAIN</mechanism>"
-        "</mechanisms>"
-       "</stream:features>";
-      engine_->HandleInput(input.c_str(), input.length());
-      EXPECT_EQ("<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" "
-          "mechanism=\"PLAIN\" "
-          "auth:allow-non-google-login=\"true\" "
-          "auth:client-uses-full-bind-result=\"true\" "
-          "xmlns:auth=\"http://www.google.com/talk/protocol/auth\""
-          ">AGRhdmlkAGRhdmlk</auth>",
-          handler_->OutputActivity());
-      EXPECT_EQ("", handler_->StanzaActivity());
-      EXPECT_EQ("", handler_->SessionActivity());
-       if (endstage == XLTT_STAGE_AUTH_FEATURES)
-        return;
-    }
-
-    case XLTT_STAGE_AUTH_SUCCESS: {
-      input = "<success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>";
-      engine_->HandleInput(input.c_str(), input.length());
-      EXPECT_EQ("<stream:stream to=\"my-server\" xml:lang=\"*\" "
-          "version=\"1.0\" xmlns:stream=\"http://etherx.jabber.org/streams\" "
-          "xmlns=\"jabber:client\">\r\n", handler_->OutputActivity());
-      EXPECT_EQ("", handler_->StanzaActivity());
-      EXPECT_EQ("", handler_->SessionActivity());
-       if (endstage == XLTT_STAGE_AUTH_SUCCESS)
-        return;
-    }
-
-    case XLTT_STAGE_AUTHENTICATED_START: {
-      input = std::string("<stream:stream id=\"01234567\" version=\"1.0\" "
-          "xmlns:stream=\"http://etherx.jabber.org/streams\" "
-          "xmlns=\"jabber:client\">");
-      engine_->HandleInput(input.c_str(), input.length());
-      EXPECT_EQ("", handler_->StanzaActivity());
-      EXPECT_EQ("", handler_->SessionActivity());
-      EXPECT_EQ("", handler_->OutputActivity());
-      if (endstage == XLTT_STAGE_AUTHENTICATED_START)
-        return;
-    }
-
-    case XLTT_STAGE_BIND_FEATURES: {
-      input = "<stream:features>"
-          "<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>"
-          "<session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>"
-        "</stream:features>";
-      engine_->HandleInput(input.c_str(), input.length());
-      EXPECT_EQ("<iq type=\"set\" id=\"0\">"
-          "<bind xmlns=\"urn:ietf:params:xml:ns:xmpp-bind\"/></iq>",
-          handler_->OutputActivity());
-      EXPECT_EQ("", handler_->StanzaActivity());
-      EXPECT_EQ("", handler_->SessionActivity());
-      if (endstage == XLTT_STAGE_BIND_FEATURES)
-        return;
-    }
-
-    case XLTT_STAGE_BIND_SUCCESS: {
-      input = "<iq type='result' id='0'>"
-          "<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>"
-          "<jid>david@my-server/test</jid></bind></iq>";
-      engine_->HandleInput(input.c_str(), input.length());
-      EXPECT_EQ("<iq type=\"set\" id=\"1\">"
-          "<session xmlns=\"urn:ietf:params:xml:ns:xmpp-session\"/></iq>",
-          handler_->OutputActivity());
-      EXPECT_EQ("", handler_->StanzaActivity());
-      EXPECT_EQ("", handler_->SessionActivity());
-      if (endstage == XLTT_STAGE_BIND_SUCCESS)
-        return;
-    }
-
-    case XLTT_STAGE_SESSION_SUCCESS: {
-      input = "<iq type='result' id='1'/>";
-      engine_->HandleInput(input.c_str(), input.length());
-      EXPECT_EQ("<test:app-stanza xmlns:test=\"test\">this-is-a-test"
-          "</test:app-stanza>", handler_->OutputActivity());
-      EXPECT_EQ("[OPEN]", handler_->SessionActivity());
-      EXPECT_EQ("", handler_->StanzaActivity());
-      if (endstage == XLTT_STAGE_SESSION_SUCCESS)
-        return;
-    }
-  }
-}
-
-TEST_F(XmppLoginTaskTest, TestUtf8Good) {
-  RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_CONNECT);
-
-  std::string input = "<?xml version='1.0' encoding='UTF-8'?>"
-      "<stream:stream id=\"a5f2d8c9\" version=\"1.0\" "
-      "xmlns:stream=\"http://etherx.jabber.org/streams\" "
-      "xmlns=\"jabber:client\">";
-  engine()->HandleInput(input.c_str(), input.length());
-  EXPECT_EQ("", handler()->OutputActivity());
-  EXPECT_EQ("", handler()->SessionActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-}
-
-TEST_F(XmppLoginTaskTest, TestNonUtf8Bad) {
-  RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_CONNECT);
-
-  std::string input = "<?xml version='1.0' encoding='ISO-8859-1'?>"
-      "<stream:stream id=\"a5f2d8c9\" version=\"1.0\" "
-      "xmlns:stream=\"http://etherx.jabber.org/streams\" "
-      "xmlns=\"jabber:client\">";
-  engine()->HandleInput(input.c_str(), input.length());
-  EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
-  EXPECT_EQ("[CLOSED][ERROR-XML]", handler()->SessionActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-}
-
-TEST_F(XmppLoginTaskTest, TestNoFeatures) {
-  RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_STREAMSTART);
-
-  std::string input = "<iq type='get' id='1'/>";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
-  EXPECT_EQ("[CLOSED][ERROR-VERSION]", handler()->SessionActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-}
-
-TEST_F(XmppLoginTaskTest, TestTlsRequiredNotPresent) {
-  RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_STREAMSTART);
-
-  std::string input = "<stream:features>"
-      "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
-        "<mechanism>DIGEST-MD5</mechanism>"
-        "<mechanism>PLAIN</mechanism>"
-      "</mechanisms>"
-     "</stream:features>";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
-  EXPECT_EQ("[CLOSED][ERROR-TLS]", handler()->SessionActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-}
-
-TEST_F(XmppLoginTaskTest, TestTlsRequeiredAndPresent) {
-  RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_STREAMSTART);
-
-  std::string input = "<stream:features>"
-      "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'>"
-        "<required/>"
-      "</starttls>"
-      "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
-        "<mechanism>X-GOOGLE-TOKEN</mechanism>"
-        "<mechanism>PLAIN</mechanism>"
-        "<mechanism>X-OAUTH2</mechanism>"
-      "</mechanisms>"
-     "</stream:features>";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  EXPECT_EQ("<starttls xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\"/>",
-      handler()->OutputActivity());
-  EXPECT_EQ("", handler()->SessionActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-}
-
-TEST_F(XmppLoginTaskTest, TestTlsEnabledNotPresent) {
-  SetTlsOptions(buzz::TLS_ENABLED);
-  RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_STREAMSTART);
-
-  std::string input = "<stream:features>"
-      "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
-        "<mechanism>DIGEST-MD5</mechanism>"
-        "<mechanism>PLAIN</mechanism>"
-      "</mechanisms>"
-     "</stream:features>";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  EXPECT_EQ("<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" "
-      "mechanism=\"PLAIN\" auth:allow-non-google-login=\"true\" "
-      "auth:client-uses-full-bind-result=\"true\" "
-      "xmlns:auth=\"http://www.google.com/talk/protocol/auth\""
-      ">AGRhdmlkAGRhdmlk</auth>", handler()->OutputActivity());
-  EXPECT_EQ("", handler()->SessionActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-}
-
-TEST_F(XmppLoginTaskTest, TestTlsEnabledAndPresent) {
-  SetTlsOptions(buzz::TLS_ENABLED);
-  RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_STREAMSTART);
-
-  std::string input = "<stream:features>"
-      "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
-        "<mechanism>X-GOOGLE-TOKEN</mechanism>"
-        "<mechanism>PLAIN</mechanism>"
-        "<mechanism>X-OAUTH2</mechanism>"
-      "</mechanisms>"
-      "</stream:features>";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  EXPECT_EQ("<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" "
-      "mechanism=\"PLAIN\" auth:allow-non-google-login=\"true\" "
-      "auth:client-uses-full-bind-result=\"true\" "
-      "xmlns:auth=\"http://www.google.com/talk/protocol/auth\""
-      ">AGRhdmlkAGRhdmlk</auth>", handler()->OutputActivity());
-  EXPECT_EQ("", handler()->SessionActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-}
-
-TEST_F(XmppLoginTaskTest, TestTlsDisabledNotPresent) {
-  SetTlsOptions(buzz::TLS_DISABLED);
-  RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_STREAMSTART);
-
-    std::string input = "<stream:features>"
-      "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
-        "<mechanism>DIGEST-MD5</mechanism>"
-        "<mechanism>PLAIN</mechanism>"
-      "</mechanisms>"
-     "</stream:features>";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  EXPECT_EQ("<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" "
-      "mechanism=\"PLAIN\" auth:allow-non-google-login=\"true\" "
-      "auth:client-uses-full-bind-result=\"true\" "
-      "xmlns:auth=\"http://www.google.com/talk/protocol/auth\""
-      ">AGRhdmlkAGRhdmlk</auth>", handler()->OutputActivity());
-  EXPECT_EQ("", handler()->SessionActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-}
-
-TEST_F(XmppLoginTaskTest, TestTlsDisabledAndPresent) {
-  SetTlsOptions(buzz::TLS_DISABLED);
-  RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_STREAMSTART);
-
-  std::string input = "<stream:features>"
-      "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
-        "<mechanism>X-GOOGLE-TOKEN</mechanism>"
-        "<mechanism>PLAIN</mechanism>"
-        "<mechanism>X-OAUTH2</mechanism>"
-      "</mechanisms>"
-      "</stream:features>";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  EXPECT_EQ("<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" "
-      "mechanism=\"PLAIN\" auth:allow-non-google-login=\"true\" "
-      "auth:client-uses-full-bind-result=\"true\" "
-      "xmlns:auth=\"http://www.google.com/talk/protocol/auth\""
-      ">AGRhdmlkAGRhdmlk</auth>", handler()->OutputActivity());
-  EXPECT_EQ("", handler()->SessionActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-}
-
-TEST_F(XmppLoginTaskTest, TestTlsFailure) {
-  RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_TLS_FEATURES);
-
-  std::string input = "<failure xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
-  EXPECT_EQ("[CLOSED][ERROR-TLS]", handler()->SessionActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-}
-
-TEST_F(XmppLoginTaskTest, TestTlsBadStream) {
-  RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_TLS_PROCEED);
-
-  std::string input = "<wrongtag>";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
-  EXPECT_EQ("[CLOSED][ERROR-VERSION]", handler()->SessionActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-}
-
-TEST_F(XmppLoginTaskTest, TestMissingSaslPlain) {
-  RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_ENCRYPTED_START);
-
-  std::string input = "<stream:features>"
-        "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
-          "<mechanism>DIGEST-MD5</mechanism>"
-        "</mechanisms>"
-       "</stream:features>";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
-  EXPECT_EQ("[CLOSED][ERROR-AUTH]", handler()->SessionActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-}
-
-TEST_F(XmppLoginTaskTest, TestWrongPassword) {
-  RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_AUTH_FEATURES);
-
-  std::string input = "<failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
-  EXPECT_EQ("[CLOSED][ERROR-UNAUTHORIZED]", handler()->SessionActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-}
-
-TEST_F(XmppLoginTaskTest, TestAuthBadStream) {
-  RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_AUTH_SUCCESS);
-
-  std::string input = "<wrongtag>";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
-  EXPECT_EQ("[CLOSED][ERROR-VERSION]", handler()->SessionActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-}
-
-TEST_F(XmppLoginTaskTest, TestMissingBindFeature) {
-  RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_AUTHENTICATED_START);
-
-  std::string input = "<stream:features>"
-          "<session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>"
-        "</stream:features>";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
-  EXPECT_EQ("[CLOSED][ERROR-BIND]", handler()->SessionActivity());
-}
-
-TEST_F(XmppLoginTaskTest, TestMissingSessionFeature) {
-  RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_AUTHENTICATED_START);
-
-  std::string input = "<stream:features>"
-          "<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>"
-        "</stream:features>";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
-  EXPECT_EQ("[CLOSED][ERROR-BIND]", handler()->SessionActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-}
-
-/* TODO: Handle this case properly inside XmppLoginTask.
-TEST_F(XmppLoginTaskTest, TestBindFailure1) {
-  // check wrong JID
-  RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_BIND_FEATURES);
-
-  std::string input = "<iq type='result' id='0'>"
-      "<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>"
-      "<jid>davey@my-server/test</jid></bind></iq>";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
-  EXPECT_EQ("[CLOSED][ERROR-BIND]", handler()->SessionActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-}
-*/
-
-TEST_F(XmppLoginTaskTest, TestBindFailure2) {
-  // check missing JID
-  RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_BIND_FEATURES);
-
-  std::string input = "<iq type='result' id='0'>"
-      "<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/></iq>";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
-  EXPECT_EQ("[CLOSED][ERROR-BIND]", handler()->SessionActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-}
-
-TEST_F(XmppLoginTaskTest, TestBindFailure3) {
-  // check plain failure
-  RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_BIND_FEATURES);
-
-  std::string input = "<iq type='error' id='0'/>";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
-  EXPECT_EQ("[CLOSED][ERROR-BIND]", handler()->SessionActivity());
-  EXPECT_EQ("", handler()->StanzaActivity());
-}
-
-TEST_F(XmppLoginTaskTest, TestBindFailure4) {
-  // check wrong id to ignore
-  RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_BIND_FEATURES);
-
-  std::string input = "<iq type='error' id='1'/>";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  // continue after an ignored iq
-  RunPartialLogin(XLTT_STAGE_BIND_SUCCESS, XLTT_STAGE_SESSION_SUCCESS);
-}
-
-TEST_F(XmppLoginTaskTest, TestSessionFailurePlain1) {
-  RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_BIND_SUCCESS);
-
-  std::string input = "<iq type='error' id='1'/>";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
-  EXPECT_EQ("[CLOSED][ERROR-BIND]", handler()->SessionActivity());
-}
-
-TEST_F(XmppLoginTaskTest, TestSessionFailurePlain2) {
-  RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_BIND_SUCCESS);
-
-  // check reverse iq to ignore
-  // TODO: consider queueing or passing through?
-  std::string input = "<iq type='get' id='1'/>";
-  engine()->HandleInput(input.c_str(), input.length());
-
-  EXPECT_EQ("", handler()->OutputActivity());
-  EXPECT_EQ("", handler()->SessionActivity());
-
-  // continue after an ignored iq
-  RunPartialLogin(XLTT_STAGE_SESSION_SUCCESS, XLTT_STAGE_SESSION_SUCCESS);
-}
-
-TEST_F(XmppLoginTaskTest, TestBadXml) {
-  int errorKind = 0;
-  for (XlttStage stage = XLTT_STAGE_CONNECT;
-      stage <= XLTT_STAGE_SESSION_SUCCESS;
-      stage = static_cast<XlttStage>(stage + 1)) {
-    RunPartialLogin(XLTT_STAGE_CONNECT, stage);
-
-    std::string input;
-    switch (errorKind++ % 5) {
-      case 0: input = "&syntax;"; break;
-      case 1: input = "<nons:iq/>"; break;
-      case 2: input = "<iq a='b' a='dupe'/>"; break;
-      case 3: input = "<>"; break;
-      case 4: input = "<iq a='<wrong>'>"; break;
-    }
-
-    engine()->HandleInput(input.c_str(), input.length());
-
-    EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
-    EXPECT_EQ("[CLOSED][ERROR-XML]", handler()->SessionActivity());
-
-    TearDown();
-    SetUp();
-  }
-}
-
-TEST_F(XmppLoginTaskTest, TestStreamError) {
-  for (XlttStage stage = XLTT_STAGE_CONNECT;
-      stage <= XLTT_STAGE_SESSION_SUCCESS;
-      stage = static_cast<XlttStage>(stage + 1)) {
-    switch (stage) {
-      case XLTT_STAGE_CONNECT:
-      case XLTT_STAGE_TLS_PROCEED:
-      case XLTT_STAGE_AUTH_SUCCESS:
-        continue;
-      default:
-        break;
-    }
-
-    RunPartialLogin(XLTT_STAGE_CONNECT, stage);
-
-    std::string input = "<stream:error>"
-        "<xml-not-well-formed xmlns='urn:ietf:params:xml:ns:xmpp-streams'/>"
-        "<text xml:lang='en' xmlns='urn:ietf:params:xml:ns:xmpp-streams'>"
-        "Some special application diagnostic information!"
-        "</text>"
-        "<escape-your-data xmlns='application-ns'/>"
-        "</stream:error>";
-
-    engine()->HandleInput(input.c_str(), input.length());
-
-    EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
-    EXPECT_EQ("[CLOSED][ERROR-STREAM]", handler()->SessionActivity());
-
-    EXPECT_EQ("<str:error xmlns:str=\"http://etherx.jabber.org/streams\">"
-        "<xml-not-well-formed xmlns=\"urn:ietf:params:xml:ns:xmpp-streams\"/>"
-        "<text xml:lang=\"en\" xmlns=\"urn:ietf:params:xml:ns:xmpp-streams\">"
-        "Some special application diagnostic information!"
-        "</text>"
-        "<escape-your-data xmlns=\"application-ns\"/>"
-        "</str:error>", engine()->GetStreamError()->Str());
-
-    TearDown();
-    SetUp();
-  }
-}
-
diff --git a/third_party/libjingle/source/talk/xmpp/xmppstanzaparser.cc b/third_party/libjingle/source/talk/xmpp/xmppstanzaparser.cc
deleted file mode 100644
index 6c3ef5f..0000000
--- a/third_party/libjingle/source/talk/xmpp/xmppstanzaparser.cc
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/xmpp/xmppstanzaparser.h"
-
-#include "talk/xmllite/xmlelement.h"
-#include "talk/base/common.h"
-#include "talk/xmpp/constants.h"
-#ifdef EXPAT_RELATIVE_PATH
-#include "expat.h"
-#else
-#include "third_party/expat/v2_0_1/Source/lib/expat.h"
-#endif
-
-namespace buzz {
-
-XmppStanzaParser::XmppStanzaParser(XmppStanzaParseHandler *psph) :
-  psph_(psph),
-  innerHandler_(this),
-  parser_(&innerHandler_),
-  depth_(0),
-  builder_() {
-}
-
-void
-XmppStanzaParser::Reset() {
-  parser_.Reset();
-  depth_ = 0;
-  builder_.Reset();
-}
-
-void
-XmppStanzaParser::IncomingStartElement(
-    XmlParseContext * pctx, const char * name, const char ** atts) {
-  if (depth_++ == 0) {
-    XmlElement * pelStream = XmlBuilder::BuildElement(pctx, name, atts);
-    if (pelStream == NULL) {
-      pctx->RaiseError(XML_ERROR_SYNTAX);
-      return;
-    }
-    psph_->StartStream(pelStream);
-    delete pelStream;
-    return;
-  }
-
-  builder_.StartElement(pctx, name, atts);
-}
-
-void
-XmppStanzaParser::IncomingCharacterData(
-    XmlParseContext * pctx, const char * text, int len) {
-  if (depth_ > 1) {
-    builder_.CharacterData(pctx, text, len);
-  }
-}
-
-void
-XmppStanzaParser::IncomingEndElement(
-    XmlParseContext * pctx, const char * name) {
-  if (--depth_ == 0) {
-    psph_->EndStream();
-    return;
-  }
-
-  builder_.EndElement(pctx, name);
-
-  if (depth_ == 1) {
-    XmlElement *element = builder_.CreateElement();
-    psph_->Stanza(element);
-    delete element;
-  }
-}
-
-void
-XmppStanzaParser::IncomingError(
-    XmlParseContext * pctx, XML_Error errCode) {
-  UNUSED(pctx);
-  UNUSED(errCode);
-  psph_->XmlError();
-}
-
-}
diff --git a/third_party/libjingle/source/talk/xmpp/xmppstanzaparser.h b/third_party/libjingle/source/talk/xmpp/xmppstanzaparser.h
deleted file mode 100644
index c6f8b08..0000000
--- a/third_party/libjingle/source/talk/xmpp/xmppstanzaparser.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2005, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _xmppstanzaparser_h_
-#define _xmppstanzaparser_h_
-
-#include "talk/xmllite/xmlparser.h"
-#include "talk/xmllite/xmlbuilder.h"
-
-
-namespace buzz {
-
-class XmlElement;
-
-class XmppStanzaParseHandler {
-public:
-  virtual ~XmppStanzaParseHandler() {}
-  virtual void StartStream(const XmlElement * pelStream) = 0;
-  virtual void Stanza(const XmlElement * pelStanza) = 0;
-  virtual void EndStream() = 0;
-  virtual void XmlError() = 0;
-};
-
-class XmppStanzaParser {
-public:
-  XmppStanzaParser(XmppStanzaParseHandler *psph);
-  bool Parse(const char * data, size_t len, bool isFinal)
-    { return parser_.Parse(data, len, isFinal); }
-  void Reset();
-
-private:
-  class ParseHandler : public XmlParseHandler {
-  public:
-    ParseHandler(XmppStanzaParser * outer) : outer_(outer) {}
-    virtual void StartElement(XmlParseContext * pctx,
-               const char * name, const char ** atts)
-      { outer_->IncomingStartElement(pctx, name, atts); }
-    virtual void EndElement(XmlParseContext * pctx,
-               const char * name)
-      { outer_->IncomingEndElement(pctx, name); }
-    virtual void CharacterData(XmlParseContext * pctx,
-               const char * text, int len)
-      { outer_->IncomingCharacterData(pctx, text, len); }
-    virtual void Error(XmlParseContext * pctx,
-               XML_Error errCode)
-      { outer_->IncomingError(pctx, errCode); }
-  private:
-    XmppStanzaParser * const outer_;
-  };
-
-  friend class ParseHandler;
-
-  void IncomingStartElement(XmlParseContext * pctx,
-               const char * name, const char ** atts);
-  void IncomingEndElement(XmlParseContext * pctx,
-               const char * name);
-  void IncomingCharacterData(XmlParseContext * pctx,
-               const char * text, int len);
-  void IncomingError(XmlParseContext * pctx,
-               XML_Error errCode);
-
-  XmppStanzaParseHandler * psph_;
-  ParseHandler innerHandler_;
-  XmlParser parser_;
-  int depth_;
-  XmlBuilder builder_;
-
- };
-
-
-}
-
-#endif
diff --git a/third_party/libjingle/source/talk/xmpp/xmppstanzaparser_unittest.cc b/third_party/libjingle/source/talk/xmpp/xmppstanzaparser_unittest.cc
deleted file mode 100644
index 06faf87..0000000
--- a/third_party/libjingle/source/talk/xmpp/xmppstanzaparser_unittest.cc
+++ /dev/null
@@ -1,168 +0,0 @@
-// Copyright 2004 Google Inc. All Rights Reserved
-
-
-#include <string>
-#include <sstream>
-#include <iostream>
-#include "talk/base/common.h"
-#include "talk/base/gunit.h"
-#include "talk/xmllite/xmlelement.h"
-#include "talk/xmpp/xmppstanzaparser.h"
-
-using buzz::QName;
-using buzz::XmlElement;
-using buzz::XmppStanzaParser;
-using buzz::XmppStanzaParseHandler;
-
-class XmppStanzaParserTestHandler : public XmppStanzaParseHandler {
- public:
-  virtual void StartStream(const XmlElement * element) {
-    ss_ << "START" << element->Str();
-  }
-  virtual void Stanza(const XmlElement * element) {
-    ss_ << "STANZA" << element->Str();
-  }
-  virtual void EndStream() {
-    ss_ << "END";
-  }
-  virtual void XmlError() {
-    ss_ << "ERROR";
-  }
-
-  std::string Str() {
-    return ss_.str();
-  }
-
-  std::string StrClear() {
-    std::string result = ss_.str();
-    ss_.str("");
-    return result;
-  }
-
- private:
-  std::stringstream ss_;
-};
-
-
-TEST(XmppStanzaParserTest, TestTrivial) {
-  XmppStanzaParserTestHandler handler;
-  XmppStanzaParser parser(&handler);
-  std::string fragment;
-
-  fragment = "<trivial/>";
-  parser.Parse(fragment.c_str(), fragment.length(), false);
-  EXPECT_EQ("START<trivial/>END", handler.StrClear());
-}
-
-TEST(XmppStanzaParserTest, TestStanzaAtATime) {
-  XmppStanzaParserTestHandler handler;
-  XmppStanzaParser parser(&handler);
-  std::string fragment;
-
-  fragment = "<stream:stream id='abc' xmlns='j:c' xmlns:stream='str'>";
-  parser.Parse(fragment.c_str(), fragment.length(), false);
-  EXPECT_EQ("START<stream:stream id=\"abc\" xmlns=\"j:c\" "
-      "xmlns:stream=\"str\"/>", handler.StrClear());
-
-  fragment = "<message type='foo'><body>hello</body></message>";
-  parser.Parse(fragment.c_str(), fragment.length(), false);
-  EXPECT_EQ("STANZA<c:message type=\"foo\" xmlns:c=\"j:c\">"
-      "<c:body>hello</c:body></c:message>", handler.StrClear());
-
-  fragment = " SOME TEXT TO IGNORE ";
-  parser.Parse(fragment.c_str(), fragment.length(), false);
-  EXPECT_EQ("", handler.StrClear());
-
-  fragment = "<iq type='set' id='123'><abc xmlns='def'/></iq>";
-  parser.Parse(fragment.c_str(), fragment.length(), false);
-  EXPECT_EQ("STANZA<c:iq type=\"set\" id=\"123\" xmlns:c=\"j:c\">"
-      "<abc xmlns=\"def\"/></c:iq>", handler.StrClear());
-
-  fragment = "</stream:stream>";
-  parser.Parse(fragment.c_str(), fragment.length(), false);
-  EXPECT_EQ("END", handler.StrClear());
-}
-
-TEST(XmppStanzaParserTest, TestFragmentedStanzas) {
-  XmppStanzaParserTestHandler handler;
-  XmppStanzaParser parser(&handler);
-  std::string fragment;
-
-  fragment = "<stream:stream id='abc' xmlns='j:c' xml";
-  parser.Parse(fragment.c_str(), fragment.length(), false);
-  EXPECT_EQ("", handler.StrClear());
-
-  fragment = "ns:stream='str'><message type='foo'><body>hel";
-  parser.Parse(fragment.c_str(), fragment.length(), false);
-  EXPECT_EQ("START<stream:stream id=\"abc\" xmlns=\"j:c\" "
-      "xmlns:stream=\"str\"/>", handler.StrClear());
-
-  fragment = "lo</body></message> IGNORE ME <iq type='set' id='123'>"
-      "<abc xmlns='def'/></iq></st";
-  parser.Parse(fragment.c_str(), fragment.length(), false);
-  EXPECT_EQ("STANZA<c:message type=\"foo\" xmlns:c=\"j:c\">"
-      "<c:body>hello</c:body></c:message>STANZA<c:iq type=\"set\" id=\"123\" "
-      "xmlns:c=\"j:c\"><abc xmlns=\"def\"/></c:iq>", handler.StrClear());
-
-  fragment = "ream:stream>";
-  parser.Parse(fragment.c_str(), fragment.length(), false);
-  EXPECT_EQ("END", handler.StrClear());
-}
-
-TEST(XmppStanzaParserTest, TestReset) {
-  XmppStanzaParserTestHandler handler;
-  XmppStanzaParser parser(&handler);
-  std::string fragment;
-
-  fragment = "<stream:stream id='abc' xmlns='j:c' xml";
-  parser.Parse(fragment.c_str(), fragment.length(), false);
-  EXPECT_EQ("", handler.StrClear());
-
-  parser.Reset();
-  fragment = "<stream:stream id='abc' xmlns='j:c' xml";
-  parser.Parse(fragment.c_str(), fragment.length(), false);
-  EXPECT_EQ("", handler.StrClear());
-
-  fragment = "ns:stream='str'><message type='foo'><body>hel";
-  parser.Parse(fragment.c_str(), fragment.length(), false);
-  EXPECT_EQ("START<stream:stream id=\"abc\" xmlns=\"j:c\" "
-      "xmlns:stream=\"str\"/>", handler.StrClear());
-  parser.Reset();
-
-  fragment = "<stream:stream id='abc' xmlns='j:c' xmlns:stream='str'>";
-  parser.Parse(fragment.c_str(), fragment.length(), false);
-  EXPECT_EQ("START<stream:stream id=\"abc\" xmlns=\"j:c\" "
-      "xmlns:stream=\"str\"/>", handler.StrClear());
-
-  fragment = "<message type='foo'><body>hello</body></message>";
-  parser.Parse(fragment.c_str(), fragment.length(), false);
-  EXPECT_EQ("STANZA<c:message type=\"foo\" xmlns:c=\"j:c\">"
-      "<c:body>hello</c:body></c:message>", handler.StrClear());
-}
-
-TEST(XmppStanzaParserTest, TestError) {
-  XmppStanzaParserTestHandler handler;
-  XmppStanzaParser parser(&handler);
-  std::string fragment;
-
-  fragment = "<-foobar/>";
-  parser.Parse(fragment.c_str(), fragment.length(), false);
-  EXPECT_EQ("ERROR", handler.StrClear());
-
-  parser.Reset();
-  fragment = "<stream:stream/>";
-  parser.Parse(fragment.c_str(), fragment.length(), false);
-  EXPECT_EQ("ERROR", handler.StrClear());
-  parser.Reset();
-
-  fragment = "ns:stream='str'><message type='foo'><body>hel";
-  parser.Parse(fragment.c_str(), fragment.length(), false);
-  EXPECT_EQ("ERROR", handler.StrClear());
-  parser.Reset();
-
-  fragment = "<stream:stream xmlns:stream='st' xmlns='jc'>"
-      "<foo/><bar><st:foobar/></bar>";
-  parser.Parse(fragment.c_str(), fragment.length(), false);
-  EXPECT_EQ("START<stream:stream xmlns:stream=\"st\" xmlns=\"jc\"/>STANZA"
-      "<jc:foo xmlns:jc=\"jc\"/>ERROR", handler.StrClear());
-}
diff --git a/third_party/libjingle/source/talk/xmpp/xmpptask.cc b/third_party/libjingle/source/talk/xmpp/xmpptask.cc
deleted file mode 100644
index be32e55..0000000
--- a/third_party/libjingle/source/talk/xmpp/xmpptask.cc
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2006, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products 
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/xmpp/xmpptask.h"
-#include "talk/xmpp/xmppclient.h"
-#include "talk/xmpp/xmppengine.h"
-#include "talk/xmpp/constants.h"
-#include "talk/xmpp/ratelimitmanager.h"
-
-namespace buzz {
-
-RateLimitManager task_rate_manager;
-
-XmppClientInterface::XmppClientInterface() {
-}
-
-XmppClientInterface::~XmppClientInterface() {
-}
-
-XmppTask::XmppTask(XmppTaskParentInterface* parent,
-                   XmppEngine::HandlerLevel level)
-    : XmppTaskBase(parent), stopped_(false) {
-#ifdef _DEBUG
-  debug_force_timeout_ = false;
-#endif
-
-  id_ = GetClient()->NextId();
-  GetClient()->AddXmppTask(this, level);
-  GetClient()->SignalDisconnected.connect(this, &XmppTask::OnDisconnect);
-}
-
-XmppTask::~XmppTask() {
-  StopImpl();
-}
-
-void XmppTask::StopImpl() {
-  while (NextStanza() != NULL) {}
-  if (!stopped_) {
-    GetClient()->RemoveXmppTask(this);
-    GetClient()->SignalDisconnected.disconnect(this);
-    stopped_ = true;
-  }
-}
-
-XmppReturnStatus XmppTask::SendStanza(const XmlElement* stanza) {
-  if (stopped_)
-    return XMPP_RETURN_BADSTATE;
-  return GetClient()->SendStanza(stanza);
-}
-
-XmppReturnStatus XmppTask::SendStanzaError(const XmlElement* element_original,
-                                           XmppStanzaError code,
-                                           const std::string& text) {
-  if (stopped_)
-    return XMPP_RETURN_BADSTATE;
-  return GetClient()->SendStanzaError(element_original, code, text);
-}
-
-void XmppTask::Stop() {
-  StopImpl();
-  Task::Stop();
-}
-
-void XmppTask::OnDisconnect() {
-  Error();
-}
-
-void XmppTask::QueueStanza(const XmlElement* stanza) {
-#ifdef _DEBUG
-  if (debug_force_timeout_)
-    return;
-#endif
-
-  stanza_queue_.push_back(new XmlElement(*stanza));
-  Wake();
-}
-
-const XmlElement* XmppTask::NextStanza() {
-  XmlElement* result = NULL;
-  if (!stanza_queue_.empty()) {
-    result = stanza_queue_.front();
-    stanza_queue_.pop_front();
-  }
-  next_stanza_.reset(result);
-  return result;
-}
-
-XmlElement* XmppTask::MakeIq(const std::string& type,
-                             const buzz::Jid& to,
-                             const std::string& id) {
-  XmlElement* result = new XmlElement(QN_IQ);
-  if (!type.empty())
-    result->AddAttr(QN_TYPE, type);
-  if (!to.IsEmpty())
-    result->AddAttr(QN_TO, to.Str());
-  if (!id.empty())
-    result->AddAttr(QN_ID, id);
-  return result;
-}
-
-XmlElement* XmppTask::MakeIqResult(const XmlElement * query) {
-  XmlElement* result = new XmlElement(QN_IQ);
-  result->AddAttr(QN_TYPE, STR_RESULT);
-  if (query->HasAttr(QN_FROM)) {
-    result->AddAttr(QN_TO, query->Attr(QN_FROM));
-  }
-  result->AddAttr(QN_ID, query->Attr(QN_ID));
-  return result;
-}
-
-bool XmppTask::MatchResponseIq(const XmlElement* stanza,
-                               const Jid& to,
-                               const std::string& id) {
-  if (stanza->Name() != QN_IQ)
-    return false;
-
-  if (stanza->Attr(QN_ID) != id)
-    return false;
-
-  return MatchStanzaFrom(stanza, to);
-}
-
-bool XmppTask::MatchStanzaFrom(const XmlElement* stanza,
-                               const Jid& to) {
-  Jid from(stanza->Attr(QN_FROM));
-  if (from == to)
-    return true;
-
-  // We address the server as "", check if we are doing so here.
-  if (!to.IsEmpty())
-    return false;
-
-  // It is legal for the server to identify itself with "domain" or
-  // "myself@domain"
-  Jid me = GetClient()->jid();
-  return (from == Jid(me.domain())) || (from == me.BareJid());
-}
-
-bool XmppTask::MatchRequestIq(const XmlElement* stanza,
-                              const std::string& type,
-                              const QName& qn) {
-  if (stanza->Name() != QN_IQ)
-    return false;
-
-  if (stanza->Attr(QN_TYPE) != type)
-    return false;
-
-  if (stanza->FirstNamed(qn) == NULL)
-    return false;
-
-  return true;
-}
-
-bool XmppTask::VerifyTaskRateLimit(const std::string task_name, int max_count, 
-                                   int per_x_seconds) {
-  return task_rate_manager.VerifyRateLimit(task_name, max_count, 
-                                           per_x_seconds);
-}
-
-}
diff --git a/third_party/libjingle/source/talk/xmpp/xmpptask.h b/third_party/libjingle/source/talk/xmpp/xmpptask.h
deleted file mode 100644
index 6a88f98..0000000
--- a/third_party/libjingle/source/talk/xmpp/xmpptask.h
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2006, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_XMPP_XMPPTASK_H_
-#define TALK_XMPP_XMPPTASK_H_
-
-#include <string>
-#include <deque>
-#include "talk/base/sigslot.h"
-#include "talk/base/task.h"
-#include "talk/base/taskparent.h"
-#include "talk/xmpp/xmppengine.h"
-
-namespace buzz {
-
-/////////////////////////////////////////////////////////////////////
-//
-// XMPPTASK
-//
-/////////////////////////////////////////////////////////////////////
-//
-// See Task and XmppClient first.
-//
-// XmppTask is a task that is designed to go underneath XmppClient and be
-// useful there.  It has a way of finding its XmppClient parent so you
-// can have it nested arbitrarily deep under an XmppClient and it can
-// still find the XMPP services.
-//
-// Tasks register themselves to listen to particular kinds of stanzas
-// that are sent out by the client.  Rather than processing stanzas
-// right away, they should decide if they own the sent stanza,
-// and if so, queue it and Wake() the task, or if a stanza does not belong
-// to you, return false right away so the next XmppTask can take a crack.
-// This technique (synchronous recognize, but asynchronous processing)
-// allows you to have arbitrary logic for recognizing stanzas yet still,
-// for example, disconnect a client while processing a stanza -
-// without reentrancy problems.
-//
-/////////////////////////////////////////////////////////////////////
-
-class XmppTask;
-
-// XmppClientInterface is an abstract interface for sending and
-// handling stanzas.  It can be implemented for unit tests or
-// different network environments.  It will usually be implemented by
-// XmppClient.
-class XmppClientInterface {
- public:
-  XmppClientInterface();
-  virtual ~XmppClientInterface();
-
-  virtual XmppEngine::State GetState() const = 0;
-  virtual const Jid& jid() const = 0;
-  virtual std::string NextId() = 0;
-  virtual XmppReturnStatus SendStanza(const XmlElement* stanza) = 0;
-  virtual XmppReturnStatus SendStanzaError(const XmlElement* original_stanza,
-                                           XmppStanzaError error_code,
-                                           const std::string& message) = 0;
-  virtual void AddXmppTask(XmppTask* task, XmppEngine::HandlerLevel level) = 0;
-  virtual void RemoveXmppTask(XmppTask* task) = 0;
-  sigslot::signal0<> SignalDisconnected;
-
-  DISALLOW_EVIL_CONSTRUCTORS(XmppClientInterface);
-};
-
-// XmppTaskParentInterface is the interface require for any parent of
-// an XmppTask.  It needs, for example, a way to get an
-// XmppClientInterface.
-
-// We really ought to inherit from a TaskParentInterface, but we tried
-// that and it's way too complicated to change
-// Task/TaskParent/TaskRunner.  For now, this works.
-class XmppTaskParentInterface : public talk_base::Task {
- public:
-  explicit XmppTaskParentInterface(talk_base::TaskParent* parent)
-      : Task(parent) {
-  }
-  virtual ~XmppTaskParentInterface() {}
-
-  virtual XmppClientInterface* GetClient() = 0;
-
-  DISALLOW_EVIL_CONSTRUCTORS(XmppTaskParentInterface);
-};
-
-class XmppTaskBase : public XmppTaskParentInterface {
- public:
-  explicit XmppTaskBase(XmppTaskParentInterface* parent)
-      : XmppTaskParentInterface(parent),
-        parent_(parent) {
-  }
-  virtual ~XmppTaskBase() {}
-
-  virtual XmppClientInterface* GetClient() {
-    return parent_->GetClient();
-  }
-
- protected:
-  XmppTaskParentInterface* parent_;
-
-  DISALLOW_EVIL_CONSTRUCTORS(XmppTaskBase);
-};
-
-class XmppTask : public XmppTaskBase,
-                 public XmppStanzaHandler,
-                 public sigslot::has_slots<>
-{
- public:
-  XmppTask(XmppTaskParentInterface* parent,
-           XmppEngine::HandlerLevel level = XmppEngine::HL_NONE);
-  virtual ~XmppTask();
-
-  std::string task_id() const { return id_; }
-  void set_task_id(std::string id) { id_ = id; }
-
-#ifdef _DEBUG
-  void set_debug_force_timeout(const bool f) { debug_force_timeout_ = f; }
-#endif
-
-  virtual bool HandleStanza(const XmlElement* stanza) { return false; }
-
- protected:
-  XmppReturnStatus SendStanza(const XmlElement* stanza);
-  XmppReturnStatus SetResult(const std::string& code);
-  XmppReturnStatus SendStanzaError(const XmlElement* element_original,
-                                   XmppStanzaError code,
-                                   const std::string& text);
-
-  virtual void Stop();
-  virtual void OnDisconnect();
-
-  virtual void QueueStanza(const XmlElement* stanza);
-  const XmlElement* NextStanza();
-
-  bool MatchStanzaFrom(const XmlElement* stanza, const Jid& match_jid);
-
-  bool MatchResponseIq(const XmlElement* stanza, const Jid& to,
-                       const std::string& task_id);
-
-  static bool MatchRequestIq(const XmlElement* stanza, const std::string& type,
-                             const QName& qn);
-  static XmlElement *MakeIqResult(const XmlElement* query);
-  static XmlElement *MakeIq(const std::string& type,
-                            const Jid& to, const std::string& task_id);
-
-  // Returns true if the task is under the specified rate limit and updates the
-  // rate limit accordingly
-  bool VerifyTaskRateLimit(const std::string task_name, int max_count,
-                           int per_x_seconds);
-
-private:
-  void StopImpl();
-
-  bool stopped_;
-  std::deque<XmlElement*> stanza_queue_;
-  talk_base::scoped_ptr<XmlElement> next_stanza_;
-  std::string id_;
-
-#ifdef _DEBUG
-  bool debug_force_timeout_;
-#endif
-};
-
-}  // namespace buzz
-
-#endif // TALK_XMPP_XMPPTASK_H_
