diff --git a/talk/app/webrtc/statscollector_unittest.cc b/talk/app/webrtc/statscollector_unittest.cc
index cce1645bc..9829832 100644
--- a/talk/app/webrtc/statscollector_unittest.cc
+++ b/talk/app/webrtc/statscollector_unittest.cc
@@ -30,6 +30,8 @@
 
 #include "talk/app/webrtc/mediastream.h"
 #include "talk/app/webrtc/videotrack.h"
+#include "talk/base/base64.h"
+#include "talk/base/fakesslidentity.h"
 #include "talk/base/gunit.h"
 #include "talk/media/base/fakemediaengine.h"
 #include "talk/media/devices/fakedevicemanager.h"
@@ -60,11 +62,12 @@
  public:
   explicit MockWebRtcSession(cricket::ChannelManager* channel_manager)
     : WebRtcSession(channel_manager, talk_base::Thread::Current(),
-                    NULL, NULL, NULL) {
+                    talk_base::Thread::Current(), NULL, NULL) {
   }
   MOCK_METHOD0(video_channel, cricket::VideoChannel*());
   MOCK_METHOD2(GetTrackIdBySsrc, bool(uint32, std::string*));
   MOCK_METHOD1(GetStats, bool(cricket::SessionStats*));
+  MOCK_METHOD1(GetTransport, cricket::Transport*(const std::string&));
 };
 
 class MockVideoMediaChannel : public cricket::FakeVideoMediaChannel {
@@ -76,8 +79,21 @@
   MOCK_METHOD1(GetStats, bool(cricket::VideoMediaInfo*));
 };
 
+bool GetValue(const webrtc::StatsReport* report,
+              const std::string& name,
+              std::string* value) {
+  webrtc::StatsReport::Values::const_iterator it = report->values.begin();
+  for (; it != report->values.end(); ++it) {
+    if (it->name == name) {
+      *value = it->value;
+      return true;
+    }
+  }
+  return false;
+}
+
 std::string ExtractStatsValue(const std::string& type,
-                              webrtc::StatsReports reports,
+                              const webrtc::StatsReports& reports,
                               const std::string name) {
   if (reports.empty()) {
     return kNoReports;
@@ -85,12 +101,9 @@
   for (size_t i = 0; i < reports.size(); ++i) {
     if (reports[i].type != type)
       continue;
-    webrtc::StatsReport::Values::const_iterator it =
-        reports[i].values.begin();
-    for (; it != reports[i].values.end(); ++it) {
-      if (it->name == name) {
-        return it->value;
-      }
+    std::string ret;
+    if (GetValue(&reports[i], name, &ret)) {
+      return ret;
     }
   }
 
@@ -99,9 +112,8 @@
 
 // Finds the |n|-th report of type |type| in |reports|.
 // |n| starts from 1 for finding the first report.
-const webrtc::StatsReport* FindNthReportByType(webrtc::StatsReports reports,
-                                               const std::string& type,
-                                               int n) {
+const webrtc::StatsReport* FindNthReportByType(
+    const webrtc::StatsReports& reports, const std::string& type, int n) {
   for (size_t i = 0; i < reports.size(); ++i) {
     if (reports[i].type == type) {
       n--;
@@ -112,7 +124,7 @@
   return NULL;
 }
 
-const webrtc::StatsReport* FindReportById(webrtc::StatsReports reports,
+const webrtc::StatsReport* FindReportById(const webrtc::StatsReports& reports,
                                           const std::string& id) {
   for (size_t i = 0; i < reports.size(); ++i) {
     if (reports[i].id == id) {
@@ -134,6 +146,42 @@
       webrtc::StatsReport::kStatsReportTypeBwe, reports, name);
 }
 
+std::string DerToPem(const std::string& der) {
+  return talk_base::SSLIdentity::DerToPem(
+        talk_base::kPemTypeCertificate,
+        reinterpret_cast<const unsigned char*>(der.c_str()),
+        der.length());
+}
+
+std::vector<std::string> DersToPems(
+    const std::vector<std::string>& ders) {
+  std::vector<std::string> pems(ders.size());
+  std::transform(ders.begin(), ders.end(), pems.begin(), DerToPem);
+  return pems;
+}
+
+void CheckCertChainReports(const webrtc::StatsReports& reports,
+                           const std::vector<std::string>& ders,
+                           const std::string& start_id) {
+  std::string certificate_id = start_id;
+  size_t i = 0;
+  while (true) {
+    const webrtc::StatsReport* report = FindReportById(reports, certificate_id);
+    ASSERT_TRUE(report != NULL);
+    std::string der_base64;
+    EXPECT_TRUE(GetValue(
+        report, webrtc::StatsReport::kStatsValueNameDer, &der_base64));
+    std::string der = talk_base::Base64::Decode(der_base64,
+                                                talk_base::Base64::DO_STRICT);
+    EXPECT_EQ(ders[i], der);
+    ++i;
+    if (!GetValue(
+        report, webrtc::StatsReport::kStatsValueNameIssuerId, &certificate_id))
+      break;
+  }
+  EXPECT_EQ(ders.size(), i);
+}
+
 class StatsCollectorTest : public testing::Test {
  protected:
   StatsCollectorTest()
@@ -147,6 +195,77 @@
     EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(Return(false));
   }
 
+  void TestCertificateReports(const talk_base::FakeSSLCertificate& local_cert,
+                              const std::vector<std::string>& local_ders,
+                              const talk_base::FakeSSLCertificate& remote_cert,
+                              const std::vector<std::string>& remote_ders) {
+    webrtc::StatsCollector stats;  // Implementation under test.
+    webrtc::StatsReports reports;  // returned values.
+    stats.set_session(&session_);
+
+    // Fake stats to process.
+    cricket::TransportChannelStats channel_stats;
+    channel_stats.component = 1;
+
+    cricket::TransportStats transport_stats;
+    transport_stats.content_name = "audio";
+    transport_stats.channel_stats.push_back(channel_stats);
+
+    cricket::SessionStats session_stats;
+    session_stats.transport_stats[transport_stats.content_name] =
+        transport_stats;
+
+    // Fake certificates to report.
+    talk_base::FakeSSLIdentity local_identity(local_cert);
+    talk_base::scoped_ptr<talk_base::FakeSSLCertificate> remote_cert_copy(
+        remote_cert.GetReference());
+
+    // Fake transport object.
+    talk_base::scoped_ptr<cricket::FakeTransport> transport(
+        new cricket::FakeTransport(
+            session_.signaling_thread(),
+            session_.worker_thread(),
+            transport_stats.content_name));
+    transport->SetIdentity(&local_identity);
+    cricket::FakeTransportChannel* channel =
+        static_cast<cricket::FakeTransportChannel*>(
+            transport->CreateChannel(channel_stats.component));
+    EXPECT_FALSE(channel == NULL);
+    channel->SetRemoteCertificate(remote_cert_copy.get());
+
+    // Configure MockWebRtcSession
+    EXPECT_CALL(session_, GetTransport(transport_stats.content_name))
+      .WillOnce(Return(transport.get()));
+    EXPECT_CALL(session_, GetStats(_))
+      .WillOnce(DoAll(SetArgPointee<0>(session_stats),
+                      Return(true)));
+    EXPECT_CALL(session_, video_channel())
+      .WillRepeatedly(ReturnNull());
+
+    stats.UpdateStats();
+
+    stats.GetStats(NULL, &reports);
+
+    const webrtc::StatsReport* channel_report = FindNthReportByType(
+        reports, webrtc::StatsReport::kStatsReportTypeComponent, 1);
+    EXPECT_TRUE(channel_report != NULL);
+
+    // Check local certificate chain.
+    std::string local_certificate_id = ExtractStatsValue(
+        webrtc::StatsReport::kStatsReportTypeComponent,
+        reports,
+        webrtc::StatsReport::kStatsValueNameLocalCertificateId);
+    EXPECT_NE(kNotFound, local_certificate_id);
+    CheckCertChainReports(reports, local_ders, local_certificate_id);
+
+    // Check remote certificate chain.
+    std::string remote_certificate_id = ExtractStatsValue(
+        webrtc::StatsReport::kStatsReportTypeComponent,
+        reports,
+        webrtc::StatsReport::kStatsValueNameRemoteCertificateId);
+    EXPECT_NE(kNotFound, remote_certificate_id);
+    CheckCertChainReports(reports, remote_ders, remote_certificate_id);
+  }
   cricket::FakeMediaEngine* media_engine_;
   talk_base::scoped_ptr<cricket::ChannelManager> channel_manager_;
   MockWebRtcSession session_;
@@ -439,4 +558,142 @@
   ASSERT_FALSE(transport_report == NULL);
 }
 
+// This test verifies that all chained certificates are correctly
+// reported
+TEST_F(StatsCollectorTest, DISABLED_ChainedCertificateReportsCreated) {
+  // Build local certificate chain.
+  std::vector<std::string> local_ders(5);
+  local_ders[0] = "These";
+  local_ders[1] = "are";
+  local_ders[2] = "some";
+  local_ders[3] = "der";
+  local_ders[4] = "values";
+  talk_base::FakeSSLCertificate local_cert(DersToPems(local_ders));
+
+  // Build remote certificate chain
+  std::vector<std::string> remote_ders(4);
+  remote_ders[0] = "A";
+  remote_ders[1] = "non-";
+  remote_ders[2] = "intersecting";
+  remote_ders[3] = "set";
+  talk_base::FakeSSLCertificate remote_cert(DersToPems(remote_ders));
+
+  TestCertificateReports(local_cert, local_ders, remote_cert, remote_ders);
+}
+
+// This test verifies that all certificates without chains are correctly
+// reported.
+TEST_F(StatsCollectorTest, DISABLED_ChainlessCertificateReportsCreated) {
+  // Build local certificate.
+  std::string local_der = "This is the local der.";
+  talk_base::FakeSSLCertificate local_cert(DerToPem(local_der));
+
+  // Build remote certificate.
+  std::string remote_der = "This is somebody else's der.";
+  talk_base::FakeSSLCertificate remote_cert(DerToPem(remote_der));
+
+  TestCertificateReports(local_cert, std::vector<std::string>(1, local_der),
+                         remote_cert, std::vector<std::string>(1, remote_der));
+}
+
+// This test verifies that the stats are generated correctly when no
+// transport is present.
+TEST_F(StatsCollectorTest, DISABLED_NoTransport) {
+  webrtc::StatsCollector stats;  // Implementation under test.
+  webrtc::StatsReports reports;  // returned values.
+  stats.set_session(&session_);
+
+  // Fake stats to process.
+  cricket::TransportChannelStats channel_stats;
+  channel_stats.component = 1;
+
+  cricket::TransportStats transport_stats;
+  transport_stats.content_name = "audio";
+  transport_stats.channel_stats.push_back(channel_stats);
+
+  cricket::SessionStats session_stats;
+  session_stats.transport_stats[transport_stats.content_name] =
+      transport_stats;
+
+  // Configure MockWebRtcSession
+  EXPECT_CALL(session_, GetTransport(transport_stats.content_name))
+    .WillOnce(ReturnNull());
+  EXPECT_CALL(session_, GetStats(_))
+    .WillOnce(DoAll(SetArgPointee<0>(session_stats),
+                    Return(true)));
+  EXPECT_CALL(session_, video_channel())
+    .WillRepeatedly(ReturnNull());
+
+  stats.UpdateStats();
+  stats.GetStats(NULL, &reports);
+
+  // Check that the local certificate is absent.
+  std::string local_certificate_id = ExtractStatsValue(
+      webrtc::StatsReport::kStatsReportTypeComponent,
+      reports,
+      webrtc::StatsReport::kStatsValueNameLocalCertificateId);
+  ASSERT_EQ(kNotFound, local_certificate_id);
+
+  // Check that the remote certificate is absent.
+  std::string remote_certificate_id = ExtractStatsValue(
+      webrtc::StatsReport::kStatsReportTypeComponent,
+      reports,
+      webrtc::StatsReport::kStatsValueNameRemoteCertificateId);
+  ASSERT_EQ(kNotFound, remote_certificate_id);
+}
+
+// This test verifies that the stats are generated correctly when the transport
+// does not have any certificates.
+TEST_F(StatsCollectorTest, DISABLED_NoCertificates) {
+  webrtc::StatsCollector stats;  // Implementation under test.
+  webrtc::StatsReports reports;  // returned values.
+  stats.set_session(&session_);
+
+  // Fake stats to process.
+  cricket::TransportChannelStats channel_stats;
+  channel_stats.component = 1;
+
+  cricket::TransportStats transport_stats;
+  transport_stats.content_name = "audio";
+  transport_stats.channel_stats.push_back(channel_stats);
+
+  cricket::SessionStats session_stats;
+  session_stats.transport_stats[transport_stats.content_name] =
+      transport_stats;
+
+  // Fake transport object.
+  talk_base::scoped_ptr<cricket::FakeTransport> transport(
+      new cricket::FakeTransport(
+          session_.signaling_thread(),
+          session_.worker_thread(),
+          transport_stats.content_name));
+
+  // Configure MockWebRtcSession
+  EXPECT_CALL(session_, GetTransport(transport_stats.content_name))
+    .WillOnce(Return(transport.get()));
+  EXPECT_CALL(session_, GetStats(_))
+    .WillOnce(DoAll(SetArgPointee<0>(session_stats),
+                    Return(true)));
+  EXPECT_CALL(session_, video_channel())
+    .WillRepeatedly(ReturnNull());
+
+  stats.UpdateStats();
+  stats.GetStats(NULL, &reports);
+
+  // Check that the local certificate is absent.
+  std::string local_certificate_id = ExtractStatsValue(
+      webrtc::StatsReport::kStatsReportTypeComponent,
+      reports,
+      webrtc::StatsReport::kStatsValueNameLocalCertificateId);
+  ASSERT_EQ(kNotFound, local_certificate_id);
+
+  // Check that the remote certificate is absent.
+  std::string remote_certificate_id = ExtractStatsValue(
+      webrtc::StatsReport::kStatsReportTypeComponent,
+      reports,
+      webrtc::StatsReport::kStatsValueNameRemoteCertificateId);
+  ASSERT_EQ(kNotFound, remote_certificate_id);
+}
+
+
 }  // namespace
