diff --git a/include/gtest/gtest.h b/include/gtest/gtest.h
index 66653d1c..2b1c9782 100644
--- a/include/gtest/gtest.h
+++ b/include/gtest/gtest.h
@@ -418,6 +418,9 @@ class TestResult {
   // of successful test parts and the number of failed test parts.
   int total_part_count() const;
 
+  // Returns the number of the test properties.
+  int test_property_count() const;
+
   // Returns true iff the test passed (i.e. no test part failed).
   bool Passed() const { return !Failed(); }
 
@@ -436,6 +439,15 @@ class TestResult {
   // Sets the elapsed time.
   void set_elapsed_time(TimeInMillis elapsed) { elapsed_time_ = elapsed; }
 
+  // Returns the i-th test part result among all the results. i can range
+  // from 0 to test_property_count() - 1. If i is not in that range, returns
+  // NULL.
+  const TestPartResult* GetTestPartResult(int i) const;
+
+  // Returns the i-th test property. i can range from 0 to
+  // test_property_count() - 1. If i is not in that range, returns NULL.
+  const TestProperty* GetTestProperty(int i) const;
+
   // Adds a test part result to the list.
   void AddTestPartResult(const TestPartResult& test_part_result);
 
@@ -639,6 +651,10 @@ class TestCase {
   // Returns the elapsed time, in milliseconds.
   internal::TimeInMillis elapsed_time() const { return elapsed_time_; }
 
+  // Returns the i-th test among all the tests. i can range from 0 to
+  // total_test_count() - 1. If i is not in that range, returns NULL.
+  const TestInfo* GetTestInfo(int i) const;
+
   // Adds a TestInfo to this test case.  Will delete the TestInfo upon
   // destruction of the TestCase object.
   void AddTestInfo(TestInfo * test_info);
@@ -799,7 +815,50 @@ class UnitTest {
   // Accessors for the implementation object.
   internal::UnitTestImpl* impl() { return impl_; }
   const internal::UnitTestImpl* impl() const { return impl_; }
+
  private:
+  // Gets the number of successful test cases.
+  int successful_test_case_count() const;
+
+  // Gets the number of failed test cases.
+  int failed_test_case_count() const;
+
+  // Gets the number of all test cases.
+  int total_test_case_count() const;
+
+  // Gets the number of all test cases that contain at least one test
+  // that should run.
+  int test_case_to_run_count() const;
+
+  // Gets the number of successful tests.
+  int successful_test_count() const;
+
+  // Gets the number of failed tests.
+  int failed_test_count() const;
+
+  // Gets the number of disabled tests.
+  int disabled_test_count() const;
+
+  // Gets the number of all tests.
+  int total_test_count() const;
+
+  // Gets the number of tests that should run.
+  int test_to_run_count() const;
+
+  // Gets the elapsed time, in milliseconds.
+  internal::TimeInMillis elapsed_time() const;
+
+  // Returns true iff the unit test passed (i.e. all test cases passed).
+  bool Passed() const;
+
+  // Returns true iff the unit test failed (i.e. some test case failed
+  // or something outside of all tests failed).
+  bool Failed() const;
+
+  // Gets the i-th test case among all the test cases. i can range from 0 to
+  // total_test_case_count() - 1. If i is not in that range, returns NULL.
+  const internal::TestCase* GetTestCase(int i) const;
+
   // ScopedTrace is a friend as it needs to modify the per-thread
   // trace stack, which is a private member of UnitTest.
   friend class internal::ScopedTrace;
diff --git a/include/gtest/internal/gtest-tuple.h b/include/gtest/internal/gtest-tuple.h
index be23e8eb..5ef49203 100644
--- a/include/gtest/internal/gtest-tuple.h
+++ b/include/gtest/internal/gtest-tuple.h
@@ -38,18 +38,38 @@
 
 #include <utility>  // For ::std::pair.
 
+// The compiler used in Symbian 5th Edition (__S60_50__) has a bug
+// that prevents us from declaring the tuple template as a friend (it
+// complains that tuple is redefined).  This hack bypasses the bug by
+// declaring the members that should otherwise be private as public.
+#if defined(__SYMBIAN32__) && __S60_50__
+#define GTEST_DECLARE_TUPLE_AS_FRIEND_ public:
+#else
+#define GTEST_DECLARE_TUPLE_AS_FRIEND_ \
+    template <GTEST_10_TYPENAMES_(U)> friend class tuple; \
+   private:
+#endif
+
 // GTEST_n_TUPLE_(T) is the type of an n-tuple.
 #define GTEST_0_TUPLE_(T) tuple<>
-#define GTEST_1_TUPLE_(T) tuple<T##0>
-#define GTEST_2_TUPLE_(T) tuple<T##0, T##1>
-#define GTEST_3_TUPLE_(T) tuple<T##0, T##1, T##2>
-#define GTEST_4_TUPLE_(T) tuple<T##0, T##1, T##2, T##3>
-#define GTEST_5_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4>
-#define GTEST_6_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5>
-#define GTEST_7_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6>
-#define GTEST_8_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, T##7>
+#define GTEST_1_TUPLE_(T) tuple<T##0, void, void, void, void, void, void, \
+    void, void, void>
+#define GTEST_2_TUPLE_(T) tuple<T##0, T##1, void, void, void, void, void, \
+    void, void, void>
+#define GTEST_3_TUPLE_(T) tuple<T##0, T##1, T##2, void, void, void, void, \
+    void, void, void>
+#define GTEST_4_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, void, void, void, \
+    void, void, void>
+#define GTEST_5_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, void, void, \
+    void, void, void>
+#define GTEST_6_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, void, \
+    void, void, void>
+#define GTEST_7_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \
+    void, void, void>
+#define GTEST_8_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \
+    T##7, void, void>
 #define GTEST_9_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \
-    T##7, T##8>
+    T##7, T##8, void>
 #define GTEST_10_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \
     T##7, T##8, T##9>
 
@@ -162,7 +182,6 @@ template <GTEST_1_TYPENAMES_(T)>
 class GTEST_1_TUPLE_(T) {
  public:
   template <int k> friend class gtest_internal::Get;
-  template <GTEST_10_TYPENAMES_(U)> friend class tuple;
 
   tuple() {}
 
@@ -180,7 +199,8 @@ class GTEST_1_TUPLE_(T) {
     return CopyFrom(t);
   }
 
- private:
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
   template <GTEST_1_TYPENAMES_(U)>
   tuple& CopyFrom(const GTEST_1_TUPLE_(U)& t) {
     f0_ = t.f0_;
@@ -194,7 +214,6 @@ template <GTEST_2_TYPENAMES_(T)>
 class GTEST_2_TUPLE_(T) {
  public:
   template <int k> friend class gtest_internal::Get;
-  template <GTEST_10_TYPENAMES_(U)> friend class tuple;
 
   tuple() {}
 
@@ -221,7 +240,8 @@ class GTEST_2_TUPLE_(T) {
     return *this;
   }
 
- private:
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
   template <GTEST_2_TYPENAMES_(U)>
   tuple& CopyFrom(const GTEST_2_TUPLE_(U)& t) {
     f0_ = t.f0_;
@@ -237,7 +257,6 @@ template <GTEST_3_TYPENAMES_(T)>
 class GTEST_3_TUPLE_(T) {
  public:
   template <int k> friend class gtest_internal::Get;
-  template <GTEST_10_TYPENAMES_(U)> friend class tuple;
 
   tuple() {}
 
@@ -256,7 +275,8 @@ class GTEST_3_TUPLE_(T) {
     return CopyFrom(t);
   }
 
- private:
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
   template <GTEST_3_TYPENAMES_(U)>
   tuple& CopyFrom(const GTEST_3_TUPLE_(U)& t) {
     f0_ = t.f0_;
@@ -274,7 +294,6 @@ template <GTEST_4_TYPENAMES_(T)>
 class GTEST_4_TUPLE_(T) {
  public:
   template <int k> friend class gtest_internal::Get;
-  template <GTEST_10_TYPENAMES_(U)> friend class tuple;
 
   tuple() {}
 
@@ -295,7 +314,8 @@ class GTEST_4_TUPLE_(T) {
     return CopyFrom(t);
   }
 
- private:
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
   template <GTEST_4_TYPENAMES_(U)>
   tuple& CopyFrom(const GTEST_4_TUPLE_(U)& t) {
     f0_ = t.f0_;
@@ -315,7 +335,6 @@ template <GTEST_5_TYPENAMES_(T)>
 class GTEST_5_TUPLE_(T) {
  public:
   template <int k> friend class gtest_internal::Get;
-  template <GTEST_10_TYPENAMES_(U)> friend class tuple;
 
   tuple() {}
 
@@ -337,7 +356,8 @@ class GTEST_5_TUPLE_(T) {
     return CopyFrom(t);
   }
 
- private:
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
   template <GTEST_5_TYPENAMES_(U)>
   tuple& CopyFrom(const GTEST_5_TUPLE_(U)& t) {
     f0_ = t.f0_;
@@ -359,7 +379,6 @@ template <GTEST_6_TYPENAMES_(T)>
 class GTEST_6_TUPLE_(T) {
  public:
   template <int k> friend class gtest_internal::Get;
-  template <GTEST_10_TYPENAMES_(U)> friend class tuple;
 
   tuple() {}
 
@@ -382,7 +401,8 @@ class GTEST_6_TUPLE_(T) {
     return CopyFrom(t);
   }
 
- private:
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
   template <GTEST_6_TYPENAMES_(U)>
   tuple& CopyFrom(const GTEST_6_TUPLE_(U)& t) {
     f0_ = t.f0_;
@@ -406,7 +426,6 @@ template <GTEST_7_TYPENAMES_(T)>
 class GTEST_7_TUPLE_(T) {
  public:
   template <int k> friend class gtest_internal::Get;
-  template <GTEST_10_TYPENAMES_(U)> friend class tuple;
 
   tuple() {}
 
@@ -429,7 +448,8 @@ class GTEST_7_TUPLE_(T) {
     return CopyFrom(t);
   }
 
- private:
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
   template <GTEST_7_TYPENAMES_(U)>
   tuple& CopyFrom(const GTEST_7_TUPLE_(U)& t) {
     f0_ = t.f0_;
@@ -455,7 +475,6 @@ template <GTEST_8_TYPENAMES_(T)>
 class GTEST_8_TUPLE_(T) {
  public:
   template <int k> friend class gtest_internal::Get;
-  template <GTEST_10_TYPENAMES_(U)> friend class tuple;
 
   tuple() {}
 
@@ -479,7 +498,8 @@ class GTEST_8_TUPLE_(T) {
     return CopyFrom(t);
   }
 
- private:
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
   template <GTEST_8_TYPENAMES_(U)>
   tuple& CopyFrom(const GTEST_8_TUPLE_(U)& t) {
     f0_ = t.f0_;
@@ -507,7 +527,6 @@ template <GTEST_9_TYPENAMES_(T)>
 class GTEST_9_TUPLE_(T) {
  public:
   template <int k> friend class gtest_internal::Get;
-  template <GTEST_10_TYPENAMES_(U)> friend class tuple;
 
   tuple() {}
 
@@ -531,7 +550,8 @@ class GTEST_9_TUPLE_(T) {
     return CopyFrom(t);
   }
 
- private:
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
   template <GTEST_9_TYPENAMES_(U)>
   tuple& CopyFrom(const GTEST_9_TUPLE_(U)& t) {
     f0_ = t.f0_;
@@ -561,7 +581,6 @@ template <GTEST_10_TYPENAMES_(T)>
 class tuple {
  public:
   template <int k> friend class gtest_internal::Get;
-  template <GTEST_10_TYPENAMES_(U)> friend class tuple;
 
   tuple() {}
 
@@ -586,7 +605,8 @@ class tuple {
     return CopyFrom(t);
   }
 
- private:
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
   template <GTEST_10_TYPENAMES_(U)>
   tuple& CopyFrom(const GTEST_10_TUPLE_(U)& t) {
     f0_ = t.f0_;
@@ -938,6 +958,7 @@ inline bool operator!=(const GTEST_10_TUPLE_(T)& t,
 #undef GTEST_9_TYPENAMES_
 #undef GTEST_10_TYPENAMES_
 
+#undef GTEST_DECLARE_TUPLE_AS_FRIEND_
 #undef GTEST_BY_REF_
 #undef GTEST_ADD_REF_
 #undef GTEST_TUPLE_ELEMENT_
diff --git a/include/gtest/internal/gtest-tuple.h.pump b/include/gtest/internal/gtest-tuple.h.pump
index 33fd6b6d..12821d8b 100644
--- a/include/gtest/internal/gtest-tuple.h.pump
+++ b/include/gtest/internal/gtest-tuple.h.pump
@@ -39,15 +39,29 @@ $$ This meta comment fixes auto-indentation in Emacs. }}
 
 #include <utility>  // For ::std::pair.
 
+// The compiler used in Symbian 5th Edition (__S60_50__) has a bug
+// that prevents us from declaring the tuple template as a friend (it
+// complains that tuple is redefined).  This hack bypasses the bug by
+// declaring the members that should otherwise be private as public.
+#if defined(__SYMBIAN32__) && __S60_50__
+#define GTEST_DECLARE_TUPLE_AS_FRIEND_ public:
+#else
+#define GTEST_DECLARE_TUPLE_AS_FRIEND_ \
+    template <GTEST_$(n)_TYPENAMES_(U)> friend class tuple; \
+   private:
+#endif
+
 
 $range i 0..n-1
 $range j 0..n
 $range k 1..n
 // GTEST_n_TUPLE_(T) is the type of an n-tuple.
+#define GTEST_0_TUPLE_(T) tuple<>
 
-$for j [[
-$range m 0..j-1
-#define GTEST_$(j)_TUPLE_(T) tuple<$for m, [[T##$m]]>
+$for k [[
+$range m 0..k-1
+$range m2 k..n-1
+#define GTEST_$(k)_TUPLE_(T) tuple<$for m, [[T##$m]]$for m2 [[, void]]>
 
 ]]
 
@@ -125,7 +139,6 @@ template <GTEST_$(k)_TYPENAMES_(T)>
 class $if k < n [[GTEST_$(k)_TUPLE_(T)]] $else [[tuple]] {
  public:
   template <int k> friend class gtest_internal::Get;
-  template <GTEST_$(n)_TYPENAMES_(U)> friend class tuple;
 
   tuple() {}
 
@@ -160,7 +173,8 @@ $if k == 2 [[
 
 ]]
 
- private:
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
   template <GTEST_$(k)_TYPENAMES_(U)>
   tuple& CopyFrom(const GTEST_$(k)_TUPLE_(U)& t) {
 
@@ -313,6 +327,7 @@ $for j [[
 
 ]]
 
+#undef GTEST_DECLARE_TUPLE_AS_FRIEND_
 #undef GTEST_BY_REF_
 #undef GTEST_ADD_REF_
 #undef GTEST_TUPLE_ELEMENT_
diff --git a/src/gtest-internal-inl.h b/src/gtest-internal-inl.h
index 589be02e..3abe9a26 100644
--- a/src/gtest-internal-inl.h
+++ b/src/gtest-internal-inl.h
@@ -430,6 +430,26 @@ class List {
     return NULL;
   }
 
+  // Returns a pointer to the i-th element of the list, or NULL if i is not
+  // in range [0, size()).
+  const E* GetElement(int i) const {
+    if (i < 0 || i >= size())
+      return NULL;
+
+    const ListNode<E>* node = Head();
+    for (int index = 0; index < i && node != NULL; ++index, node = node->next())
+      continue;
+
+    return node ? &(node->element()) : NULL;
+  }
+
+  // Returns the i-th element of the list, or default_value if i is not
+  // in range [0, size()).
+  E GetElementOr(int i, E default_value) const {
+    const E* element = GetElement(i);
+    return element ? *element : default_value;
+  }
+
  private:
   ListNode<E>* head_;  // The first node of the list.
   ListNode<E>* last_;  // The last node of the list.
@@ -765,6 +785,12 @@ class UnitTestImpl {
     return failed_test_case_count() > 0 || ad_hoc_test_result()->Failed();
   }
 
+  // Gets the i-th test case among all the test cases. i can range from 0 to
+  // total_test_case_count() - 1. If i is not in that range, returns NULL.
+  const TestCase* GetTestCase(int i) const {
+    return test_cases_.GetElementOr(i, NULL);
+  }
+
   // Returns the TestResult for the test that's currently running, or
   // the TestResult for the ad hoc test if no test is running.
   internal::TestResult* current_test_result();
diff --git a/src/gtest.cc b/src/gtest.cc
index f5b05b2d..ec176918 100644
--- a/src/gtest.cc
+++ b/src/gtest.cc
@@ -468,40 +468,80 @@ int UnitTestOptions::GTestShouldProcessSEH(DWORD exception_code) {
 class UnitTestEventListenerInterface {
  public:
   // The d'tor is pure virtual as this is an abstract class.
-  virtual ~UnitTestEventListenerInterface() = 0;
+  virtual ~UnitTestEventListenerInterface() {}
 
   // Called before the unit test starts.
-  virtual void OnUnitTestStart(const UnitTest*) {}
+  virtual void OnUnitTestStart(const UnitTest& unit_test) = 0;
 
   // Called after the unit test ends.
-  virtual void OnUnitTestEnd(const UnitTest*) {}
+  virtual void OnUnitTestEnd(const UnitTest& unit_test) = 0;
 
   // Called before the test case starts.
-  virtual void OnTestCaseStart(const TestCase*) {}
+  virtual void OnTestCaseStart(const TestCase& test_case) = 0;
 
   // Called after the test case ends.
-  virtual void OnTestCaseEnd(const TestCase*) {}
+  virtual void OnTestCaseEnd(const TestCase& test_case) = 0;
 
   // Called before the global set-up starts.
-  virtual void OnGlobalSetUpStart(const UnitTest*) {}
+  virtual void OnGlobalSetUpStart(const UnitTest& unit_test) = 0;
 
   // Called after the global set-up ends.
-  virtual void OnGlobalSetUpEnd(const UnitTest*) {}
+  virtual void OnGlobalSetUpEnd(const UnitTest& unit_test) = 0;
 
   // Called before the global tear-down starts.
-  virtual void OnGlobalTearDownStart(const UnitTest*) {}
+  virtual void OnGlobalTearDownStart(const UnitTest& unit_test) = 0;
 
   // Called after the global tear-down ends.
-  virtual void OnGlobalTearDownEnd(const UnitTest*) {}
+  virtual void OnGlobalTearDownEnd(const UnitTest& unit_test) = 0;
 
   // Called before the test starts.
-  virtual void OnTestStart(const TestInfo*) {}
+  virtual void OnTestStart(const TestInfo& test_info) = 0;
 
   // Called after the test ends.
-  virtual void OnTestEnd(const TestInfo*) {}
+  virtual void OnTestEnd(const TestInfo& test_info) = 0;
 
   // Called after an assertion.
-  virtual void OnNewTestPartResult(const TestPartResult*) {}
+  virtual void OnNewTestPartResult(const TestPartResult& test_part_result) = 0;
+};
+
+// The convenience class for users who need to override just one or two
+// methods and are not concerned that a possible change to a signature of
+// the methods they override will not be caught during the build.
+class EmptyTestEventListener : public UnitTestEventListenerInterface {
+ public:
+  // Called before the unit test starts.
+  virtual void OnUnitTestStart(const UnitTest& /*unit_test*/) {}
+
+  // Called after the unit test ends.
+  virtual void OnUnitTestEnd(const UnitTest& /*unit_test*/) {}
+
+  // Called before the test case starts.
+  virtual void OnTestCaseStart(const TestCase& /*test_case*/) {}
+
+  // Called after the test case ends.
+  virtual void OnTestCaseEnd(const TestCase& /*test_case&*/) {}
+
+  // Called before the global set-up starts.
+  virtual void OnGlobalSetUpStart(const UnitTest& /*unit_test*/) {}
+
+  // Called after the global set-up ends.
+  virtual void OnGlobalSetUpEnd(const UnitTest& /*unit_test*/) {}
+
+  // Called before the global tear-down starts.
+  virtual void OnGlobalTearDownStart(const UnitTest& /*unit_test*/) {}
+
+  // Called after the global tear-down ends.
+  virtual void OnGlobalTearDownEnd(const UnitTest& /*unit_test*/) {}
+
+  // Called before the test starts.
+  virtual void OnTestStart(const TestInfo& /*test_info*/) {}
+
+  // Called after the test ends.
+  virtual void OnTestEnd(const TestInfo& /*test_info*/) {}
+
+  // Called after an assertion.
+  virtual void OnNewTestPartResult(const TestPartResult& /*test_part_result*/) {
+  }
 };
 
 // The c'tor sets this object as the test part result reporter used by
@@ -638,7 +678,7 @@ DefaultGlobalTestPartResultReporter::DefaultGlobalTestPartResultReporter(
 void DefaultGlobalTestPartResultReporter::ReportTestPartResult(
     const TestPartResult& result) {
   unit_test_->current_test_result()->AddTestPartResult(result);
-  unit_test_->result_printer()->OnNewTestPartResult(&result);
+  unit_test_->result_printer()->OnNewTestPartResult(result);
 }
 
 DefaultPerThreadTestPartResultReporter::DefaultPerThreadTestPartResultReporter(
@@ -1790,6 +1830,19 @@ TestResult::TestResult()
 TestResult::~TestResult() {
 }
 
+// Returns the i-th test part result among all the results. i can range
+// from 0 to total_part_count() - 1. If i is not in that range, returns
+// NULL.
+const TestPartResult* TestResult::GetTestPartResult(int i) const {
+  return test_part_results_->GetElement(i);
+}
+
+// Returns the i-th test property. i can range from 0 to
+// test_property_count() - 1. If i is not in that range, returns NULL.
+const TestProperty* TestResult::GetTestProperty(int i) const {
+  return test_properties_->GetElement(i);
+}
+
 // Clears the test part results.
 void TestResult::ClearTestPartResults() {
   test_part_results_->Clear();
@@ -1887,6 +1940,11 @@ int TestResult::total_part_count() const {
   return test_part_results_->size();
 }
 
+// Returns the number of the test properties.
+int TestResult::test_property_count() const {
+  return test_properties_->size();
+}
+
 }  // namespace internal
 
 // class Test
@@ -2261,7 +2319,7 @@ void TestInfoImpl::Run() {
   // start.
   UnitTestEventListenerInterface* const result_printer =
     impl->result_printer();
-  result_printer->OnTestStart(parent_);
+  result_printer->OnTestStart(*parent_);
 
   const TimeInMillis start = GetTimeInMillis();
 
@@ -2304,7 +2362,7 @@ void TestInfoImpl::Run() {
   result_.set_elapsed_time(GetTimeInMillis() - start);
 
   // Notifies the unit test event listener that a test has just finished.
-  result_printer->OnTestEnd(parent_);
+  result_printer->OnTestEnd(*parent_);
 
   // Tells UnitTest to stop associating assertion results to this
   // test.
@@ -2366,6 +2424,12 @@ TestCase::~TestCase() {
   test_info_list_ = NULL;
 }
 
+// Returns the i-th test among all the tests. i can range from 0 to
+// total_test_count() - 1. If i is not in that range, returns NULL.
+const TestInfo* TestCase::GetTestInfo(int i) const {
+  return test_info_list_->GetElementOr(i, NULL);
+}
+
 // Adds a test to this test case.  Will delete the test upon
 // destruction of the TestCase object.
 void TestCase::AddTestInfo(TestInfo * test_info) {
@@ -2382,7 +2446,7 @@ void TestCase::Run() {
   UnitTestEventListenerInterface * const result_printer =
       impl->result_printer();
 
-  result_printer->OnTestCaseStart(this);
+  result_printer->OnTestCaseStart(*this);
   impl->os_stack_trace_getter()->UponLeavingGTest();
   set_up_tc_();
 
@@ -2392,7 +2456,7 @@ void TestCase::Run() {
 
   impl->os_stack_trace_getter()->UponLeavingGTest();
   tear_down_tc_();
-  result_printer->OnTestCaseEnd(this);
+  result_printer->OnTestCaseEnd(*this);
   impl->set_current_test_case(NULL);
 }
 
@@ -2425,15 +2489,9 @@ bool TestCase::ShouldRunTest(const TestInfo *test_info) {
 
 }  // namespace internal
 
-// class UnitTestEventListenerInterface
-
-// The virtual d'tor.
-UnitTestEventListenerInterface::~UnitTestEventListenerInterface() {
-}
-
 // A result printer that never prints anything.  Used in the child process
 // of an exec-style death test to avoid needless output clutter.
-class NullUnitTestResultPrinter : public UnitTestEventListenerInterface {};
+class NullUnitTestResultPrinter : public EmptyTestEventListener {};
 
 // Formats a countable noun.  Depending on its quantity, either the
 // singular form or the plural form is used. e.g.
@@ -2628,24 +2686,25 @@ class PrettyUnitTestResultPrinter : public UnitTestEventListenerInterface {
 
   // The following methods override what's in the
   // UnitTestEventListenerInterface class.
-  virtual void OnUnitTestStart(const UnitTest * unit_test);
-  virtual void OnGlobalSetUpStart(const UnitTest*);
-  virtual void OnTestCaseStart(const TestCase * test_case);
-  virtual void OnTestCaseEnd(const TestCase * test_case);
-  virtual void OnTestStart(const TestInfo * test_info);
-  virtual void OnNewTestPartResult(const TestPartResult * result);
-  virtual void OnTestEnd(const TestInfo * test_info);
-  virtual void OnGlobalTearDownStart(const UnitTest*);
-  virtual void OnUnitTestEnd(const UnitTest * unit_test);
+  virtual void OnUnitTestStart(const UnitTest& unit_test);
+  virtual void OnGlobalSetUpStart(const UnitTest& unit_test);
+  virtual void OnGlobalSetUpEnd(const UnitTest& /*unit_test*/) {}
+  virtual void OnTestCaseStart(const TestCase& test_case);
+  virtual void OnTestCaseEnd(const TestCase& test_case);
+  virtual void OnTestStart(const TestInfo& test_info);
+  virtual void OnNewTestPartResult(const TestPartResult& result);
+  virtual void OnTestEnd(const TestInfo& test_info);
+  virtual void OnGlobalTearDownStart(const UnitTest& unit_test);
+  virtual void OnGlobalTearDownEnd(const UnitTest& /*unit_test*/) {}
+  virtual void OnUnitTestEnd(const UnitTest& unit_test);
 
  private:
   internal::String test_case_name_;
 };
 
 // Called before the unit test starts.
-void PrettyUnitTestResultPrinter::OnUnitTestStart(
-    const UnitTest * unit_test) {
-  const char * const filter = GTEST_FLAG(filter).c_str();
+void PrettyUnitTestResultPrinter::OnUnitTestStart(const UnitTest& unit_test) {
+  const char* const filter = GTEST_FLAG(filter).c_str();
 
   // Prints the filter if it's not *.  This reminds the user that some
   // tests may be skipped.
@@ -2661,7 +2720,7 @@ void PrettyUnitTestResultPrinter::OnUnitTestStart(
                   internal::posix::GetEnv(kTestTotalShards));
   }
 
-  const internal::UnitTestImpl* const impl = unit_test->impl();
+  const internal::UnitTestImpl* const impl = unit_test.impl();
   ColoredPrintf(COLOR_GREEN,  "[==========] ");
   printf("Running %s from %s.\n",
          FormatTestCount(impl->test_to_run_count()).c_str(),
@@ -2669,62 +2728,61 @@ void PrettyUnitTestResultPrinter::OnUnitTestStart(
   fflush(stdout);
 }
 
-void PrettyUnitTestResultPrinter::OnGlobalSetUpStart(const UnitTest*) {
+void PrettyUnitTestResultPrinter::OnGlobalSetUpStart(
+    const UnitTest& /*unit_test*/) {
   ColoredPrintf(COLOR_GREEN,  "[----------] ");
   printf("Global test environment set-up.\n");
   fflush(stdout);
 }
 
-void PrettyUnitTestResultPrinter::OnTestCaseStart(
-    const TestCase * test_case) {
-  test_case_name_ = test_case->name();
+void PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) {
+  test_case_name_ = test_case.name();
   const internal::String counts =
-      FormatCountableNoun(test_case->test_to_run_count(), "test", "tests");
+      FormatCountableNoun(test_case.test_to_run_count(), "test", "tests");
   ColoredPrintf(COLOR_GREEN, "[----------] ");
   printf("%s from %s", counts.c_str(), test_case_name_.c_str());
-  if (test_case->comment()[0] == '\0') {
+  if (test_case.comment()[0] == '\0') {
     printf("\n");
   } else {
-    printf(", where %s\n", test_case->comment());
+    printf(", where %s\n", test_case.comment());
   }
   fflush(stdout);
 }
 
-void PrettyUnitTestResultPrinter::OnTestCaseEnd(
-    const TestCase * test_case) {
+void PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) {
   if (!GTEST_FLAG(print_time)) return;
 
-  test_case_name_ = test_case->name();
+  test_case_name_ = test_case.name();
   const internal::String counts =
-      FormatCountableNoun(test_case->test_to_run_count(), "test", "tests");
+      FormatCountableNoun(test_case.test_to_run_count(), "test", "tests");
   ColoredPrintf(COLOR_GREEN, "[----------] ");
   printf("%s from %s (%s ms total)\n\n",
          counts.c_str(), test_case_name_.c_str(),
-         internal::StreamableToString(test_case->elapsed_time()).c_str());
+         internal::StreamableToString(test_case.elapsed_time()).c_str());
   fflush(stdout);
 }
 
-void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo * test_info) {
+void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) {
   ColoredPrintf(COLOR_GREEN,  "[ RUN      ] ");
-  PrintTestName(test_case_name_.c_str(), test_info->name());
-  if (test_info->comment()[0] == '\0') {
+  PrintTestName(test_case_name_.c_str(), test_info.name());
+  if (test_info.comment()[0] == '\0') {
     printf("\n");
   } else {
-    printf(", where %s\n", test_info->comment());
+    printf(", where %s\n", test_info.comment());
   }
   fflush(stdout);
 }
 
-void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo * test_info) {
-  if (test_info->result()->Passed()) {
+void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) {
+  if (test_info.result()->Passed()) {
     ColoredPrintf(COLOR_GREEN, "[       OK ] ");
   } else {
     ColoredPrintf(COLOR_RED, "[  FAILED  ] ");
   }
-  PrintTestName(test_case_name_.c_str(), test_info->name());
+  PrintTestName(test_case_name_.c_str(), test_info.name());
   if (GTEST_FLAG(print_time)) {
     printf(" (%s ms)\n", internal::StreamableToString(
-           test_info->result()->elapsed_time()).c_str());
+           test_info.result()->elapsed_time()).c_str());
   } else {
     printf("\n");
   }
@@ -2733,17 +2791,18 @@ void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo * test_info) {
 
 // Called after an assertion failure.
 void PrettyUnitTestResultPrinter::OnNewTestPartResult(
-    const TestPartResult * result) {
+    const TestPartResult& result) {
   // If the test part succeeded, we don't need to do anything.
-  if (result->type() == TPRT_SUCCESS)
+  if (result.type() == TPRT_SUCCESS)
     return;
 
   // Print failure message from the assertion (e.g. expected this and got that).
-  PrintTestPartResult(*result);
+  PrintTestPartResult(result);
   fflush(stdout);
 }
 
-void PrettyUnitTestResultPrinter::OnGlobalTearDownStart(const UnitTest*) {
+void PrettyUnitTestResultPrinter::OnGlobalTearDownStart(
+    const UnitTest& /*unit_test*/) {
   ColoredPrintf(COLOR_GREEN,  "[----------] ");
   printf("Global test environment tear-down\n");
   fflush(stdout);
@@ -2788,9 +2847,8 @@ static void PrintFailedTestsPretty(const UnitTestImpl* impl) {
 
 }  // namespace internal
 
-void PrettyUnitTestResultPrinter::OnUnitTestEnd(
-    const UnitTest * unit_test) {
-  const internal::UnitTestImpl* const impl = unit_test->impl();
+void PrettyUnitTestResultPrinter::OnUnitTestEnd(const UnitTest& unit_test) {
+  const internal::UnitTestImpl* const impl = unit_test.impl();
 
   ColoredPrintf(COLOR_GREEN,  "[==========] ");
   printf("%s from %s ran.",
@@ -2841,17 +2899,17 @@ class UnitTestEventsRepeater : public UnitTestEventListenerInterface {
   virtual ~UnitTestEventsRepeater();
   void AddListener(UnitTestEventListenerInterface *listener);
 
-  virtual void OnUnitTestStart(const UnitTest* unit_test);
-  virtual void OnUnitTestEnd(const UnitTest* unit_test);
-  virtual void OnGlobalSetUpStart(const UnitTest* unit_test);
-  virtual void OnGlobalSetUpEnd(const UnitTest* unit_test);
-  virtual void OnGlobalTearDownStart(const UnitTest* unit_test);
-  virtual void OnGlobalTearDownEnd(const UnitTest* unit_test);
-  virtual void OnTestCaseStart(const TestCase* test_case);
-  virtual void OnTestCaseEnd(const TestCase* test_case);
-  virtual void OnTestStart(const TestInfo* test_info);
-  virtual void OnTestEnd(const TestInfo* test_info);
-  virtual void OnNewTestPartResult(const TestPartResult* result);
+  virtual void OnUnitTestStart(const UnitTest& unit_test);
+  virtual void OnUnitTestEnd(const UnitTest& unit_test);
+  virtual void OnGlobalSetUpStart(const UnitTest& unit_test);
+  virtual void OnGlobalSetUpEnd(const UnitTest& unit_test);
+  virtual void OnGlobalTearDownStart(const UnitTest& unit_test);
+  virtual void OnGlobalTearDownEnd(const UnitTest& unit_test);
+  virtual void OnTestCaseStart(const TestCase& test_case);
+  virtual void OnTestCaseEnd(const TestCase& test_case);
+  virtual void OnTestStart(const TestInfo& test_info);
+  virtual void OnTestEnd(const TestInfo& test_info);
+  virtual void OnNewTestPartResult(const TestPartResult& result);
 
  private:
   Listeners listeners_;
@@ -2875,7 +2933,7 @@ void UnitTestEventsRepeater::AddListener(
 // Since the methods are identical, use a macro to reduce boilerplate.
 // This defines a member that repeats the call to all listeners.
 #define GTEST_REPEATER_METHOD_(Name, Type) \
-void UnitTestEventsRepeater::Name(const Type* parameter) { \
+void UnitTestEventsRepeater::Name(const Type& parameter) { \
   for (ListenersNode* listener = listeners_.Head(); \
        listener != NULL; \
        listener = listener->next()) { \
@@ -2900,11 +2958,11 @@ GTEST_REPEATER_METHOD_(OnNewTestPartResult, TestPartResult)
 // End PrettyUnitTestResultPrinter
 
 // This class generates an XML output file.
-class XmlUnitTestResultPrinter : public UnitTestEventListenerInterface {
+class XmlUnitTestResultPrinter : public EmptyTestEventListener {
  public:
   explicit XmlUnitTestResultPrinter(const char* output_file);
 
-  virtual void OnUnitTestEnd(const UnitTest* unit_test);
+  virtual void OnUnitTestEnd(const UnitTest& unit_test);
 
  private:
   // Is c a whitespace character that is normalized to a space character
@@ -2944,7 +3002,7 @@ class XmlUnitTestResultPrinter : public UnitTestEventListenerInterface {
   static void PrintXmlTestCase(FILE* out, const TestCase* test_case);
 
   // Prints an XML summary of unit_test to output stream out.
-  static void PrintXmlUnitTest(FILE* out, const UnitTest* unit_test);
+  static void PrintXmlUnitTest(FILE* out, const UnitTest& unit_test);
 
   // Produces a string representing the test properties in a result as space
   // delimited XML attributes based on the property key="value" pairs.
@@ -2970,7 +3028,7 @@ XmlUnitTestResultPrinter::XmlUnitTestResultPrinter(const char* output_file)
 }
 
 // Called after the unit test ends.
-void XmlUnitTestResultPrinter::OnUnitTestEnd(const UnitTest* unit_test) {
+void XmlUnitTestResultPrinter::OnUnitTestEnd(const UnitTest& unit_test) {
   FILE* xmlout = NULL;
   internal::FilePath output_file(output_file_);
   internal::FilePath output_dir(output_file.RemoveFileName());
@@ -3149,8 +3207,8 @@ void XmlUnitTestResultPrinter::PrintXmlTestCase(FILE* out,
 
 // Prints an XML summary of unit_test to output stream out.
 void XmlUnitTestResultPrinter::PrintXmlUnitTest(FILE* out,
-                                                const UnitTest* unit_test) {
-  const internal::UnitTestImpl* const impl = unit_test->impl();
+                                                const UnitTest& unit_test) {
+  const internal::UnitTestImpl* const impl = unit_test.impl();
   fprintf(out, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
   fprintf(out,
           "<testsuites tests=\"%d\" failures=\"%d\" disabled=\"%d\" "
@@ -3267,6 +3325,64 @@ UnitTest * UnitTest::GetInstance() {
 #endif  // (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__)
 }
 
+// Gets the number of successful test cases.
+int UnitTest::successful_test_case_count() const {
+  return impl()->successful_test_case_count();
+}
+
+// Gets the number of failed test cases.
+int UnitTest::failed_test_case_count() const {
+  return impl()->failed_test_case_count();
+}
+
+// Gets the number of all test cases.
+int UnitTest::total_test_case_count() const {
+  return impl()->total_test_case_count();
+}
+
+// Gets the number of all test cases that contain at least one test
+// that should run.
+int UnitTest::test_case_to_run_count() const {
+  return impl()->test_case_to_run_count();
+}
+
+// Gets the number of successful tests.
+int UnitTest::successful_test_count() const {
+  return impl()->successful_test_count();
+}
+
+// Gets the number of failed tests.
+int UnitTest::failed_test_count() const { return impl()->failed_test_count(); }
+
+// Gets the number of disabled tests.
+int UnitTest::disabled_test_count() const {
+  return impl()->disabled_test_count();
+}
+
+// Gets the number of all tests.
+int UnitTest::total_test_count() const { return impl()->total_test_count(); }
+
+// Gets the number of tests that should run.
+int UnitTest::test_to_run_count() const { return impl()->test_to_run_count(); }
+
+// Gets the elapsed time, in milliseconds.
+internal::TimeInMillis UnitTest::elapsed_time() const {
+  return impl()->elapsed_time();
+}
+
+// Returns true iff the unit test passed (i.e. all test cases passed).
+bool UnitTest::Passed() const { return impl()->Passed(); }
+
+// Returns true iff the unit test failed (i.e. some test case failed
+// or something outside of all tests failed).
+bool UnitTest::Failed() const { return impl()->Failed(); }
+
+// Gets the i-th test case among all the test cases. i can range from 0 to
+// total_test_case_count() - 1. If i is not in that range, returns NULL.
+const TestCase* UnitTest::GetTestCase(int i) const {
+  return impl()->GetTestCase(i);
+}
+
 // Registers and returns a global test environment.  When a test
 // program is run, all global test environments will be set-up in the
 // order they were registered.  After all tests in the program have
@@ -3683,16 +3799,16 @@ int UnitTestImpl::RunAllTests() {
 
     // Tells the unit test event listener that the tests are about to
     // start.
-    printer->OnUnitTestStart(parent_);
+    printer->OnUnitTestStart(*parent_);
 
     const TimeInMillis start = GetTimeInMillis();
 
     // Runs each test case if there is at least one test to run.
     if (has_tests_to_run) {
       // Sets up all environments beforehand.
-      printer->OnGlobalSetUpStart(parent_);
+      printer->OnGlobalSetUpStart(*parent_);
       environments_.ForEach(SetUpEnvironment);
-      printer->OnGlobalSetUpEnd(parent_);
+      printer->OnGlobalSetUpEnd(*parent_);
 
       // Runs the tests only if there was no fatal failure during global
       // set-up.
@@ -3701,16 +3817,16 @@ int UnitTestImpl::RunAllTests() {
       }
 
       // Tears down all environments in reverse order afterwards.
-      printer->OnGlobalTearDownStart(parent_);
+      printer->OnGlobalTearDownStart(*parent_);
       environments_in_reverse_order_.ForEach(TearDownEnvironment);
-      printer->OnGlobalTearDownEnd(parent_);
+      printer->OnGlobalTearDownEnd(*parent_);
     }
 
     elapsed_time_ = GetTimeInMillis() - start;
 
     // Tells the unit test event listener that the tests have just
     // finished.
-    printer->OnUnitTestEnd(parent_);
+    printer->OnUnitTestEnd(*parent_);
 
     // Gets the result and clears it.
     if (!Passed()) {
diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc
index fe452f42..b1a161bb 100644
--- a/test/gtest_unittest.cc
+++ b/test/gtest_unittest.cc
@@ -148,7 +148,6 @@ using testing::internal::String;
 using testing::internal::TestProperty;
 using testing::internal::TestResult;
 using testing::internal::ThreadLocal;
-using testing::internal::UnitTestImpl;
 using testing::internal::WideStringToUtf8;
 
 // This line tests that we can define tests in an unnamed namespace.
@@ -526,6 +525,19 @@ TEST(ListTest, InsertAfterNotAtBeginning) {
   EXPECT_EQ(3, a.Last()->element());
 }
 
+// Tests the GetElement accessor.
+TEST(ListTest, GetElement) {
+  List<int> a;
+  a.PushBack(0);
+  a.PushBack(1);
+  a.PushBack(2);
+
+  EXPECT_EQ(&(a.Head()->element()), a.GetElement(0));
+  EXPECT_EQ(&(a.Head()->next()->element()), a.GetElement(1));
+  EXPECT_EQ(&(a.Head()->next()->next()->element()), a.GetElement(2));
+  EXPECT_TRUE(a.GetElement(3) == NULL);
+  EXPECT_TRUE(a.GetElement(-1) == NULL);
+}
 
 // Tests the String class.
 
@@ -1085,23 +1097,38 @@ class TestResultTest : public Test {
     delete r1;
     delete r2;
   }
+
+  // Helper that compares two two TestPartResults.
+  static void CompareTestPartResult(const TestPartResult* expected,
+                                    const TestPartResult* actual) {
+    ASSERT_TRUE(actual != NULL);
+    EXPECT_EQ(expected->type(), actual->type());
+    EXPECT_STREQ(expected->file_name(), actual->file_name());
+    EXPECT_EQ(expected->line_number(), actual->line_number());
+    EXPECT_STREQ(expected->summary(), actual->summary());
+    EXPECT_STREQ(expected->message(), actual->message());
+    EXPECT_EQ(expected->passed(), actual->passed());
+    EXPECT_EQ(expected->failed(), actual->failed());
+    EXPECT_EQ(expected->nonfatally_failed(), actual->nonfatally_failed());
+    EXPECT_EQ(expected->fatally_failed(), actual->fatally_failed());
+  }
 };
 
-// Tests TestResult::test_part_results()
+// Tests TestResult::test_part_results().
 TEST_F(TestResultTest, test_part_results) {
   ASSERT_EQ(0u, r0->test_part_results().size());
   ASSERT_EQ(1u, r1->test_part_results().size());
   ASSERT_EQ(2u, r2->test_part_results().size());
 }
 
-// Tests TestResult::successful_part_count()
+// Tests TestResult::successful_part_count().
 TEST_F(TestResultTest, successful_part_count) {
   ASSERT_EQ(0u, r0->successful_part_count());
   ASSERT_EQ(1u, r1->successful_part_count());
   ASSERT_EQ(1u, r2->successful_part_count());
 }
 
-// Tests TestResult::failed_part_count()
+// Tests TestResult::failed_part_count().
 TEST_F(TestResultTest, failed_part_count) {
   ASSERT_EQ(0u, r0->failed_part_count());
   ASSERT_EQ(0u, r1->failed_part_count());
@@ -1115,27 +1142,35 @@ TEST_F(TestResultTest, GetFailedPartCount) {
   ASSERT_EQ(1u, GetFailedPartCount(r2));
 }
 
-// Tests TestResult::total_part_count()
+// Tests TestResult::total_part_count().
 TEST_F(TestResultTest, total_part_count) {
   ASSERT_EQ(0u, r0->total_part_count());
   ASSERT_EQ(1u, r1->total_part_count());
   ASSERT_EQ(2u, r2->total_part_count());
 }
 
-// Tests TestResult::Passed()
+// Tests TestResult::Passed().
 TEST_F(TestResultTest, Passed) {
   ASSERT_TRUE(r0->Passed());
   ASSERT_TRUE(r1->Passed());
   ASSERT_FALSE(r2->Passed());
 }
 
-// Tests TestResult::Failed()
+// Tests TestResult::Failed().
 TEST_F(TestResultTest, Failed) {
   ASSERT_FALSE(r0->Failed());
   ASSERT_FALSE(r1->Failed());
   ASSERT_TRUE(r2->Failed());
 }
 
+// Tests TestResult::GetTestPartResult().
+TEST_F(TestResultTest, GetTestPartResult) {
+  CompareTestPartResult(pr1, r2->GetTestPartResult(0));
+  CompareTestPartResult(pr2, r2->GetTestPartResult(1));
+  EXPECT_TRUE(r2->GetTestPartResult(2) == NULL);
+  EXPECT_TRUE(r2->GetTestPartResult(-1) == NULL);
+}
+
 // Tests TestResult::test_properties() has no properties when none are added.
 TEST(TestResultPropertyTest, NoPropertiesFoundWhenNoneAreAdded) {
   TestResult test_result;
@@ -1195,6 +1230,49 @@ TEST(TestResultPropertyTest, OverridesValuesForDuplicateKeys) {
   EXPECT_STREQ("22", actual_property_2.value());
 }
 
+// Tests TestResult::test_property_count().
+TEST(TestResultPropertyTest, TestPropertyCount) {
+  TestResult test_result;
+  TestProperty property_1("key_1", "1");
+  TestProperty property_2("key_2", "2");
+
+  ASSERT_EQ(0, test_result.test_property_count());
+  test_result.RecordProperty(property_1);
+  ASSERT_EQ(1, test_result.test_property_count());
+  test_result.RecordProperty(property_2);
+  ASSERT_EQ(2, test_result.test_property_count());
+}
+
+// Tests TestResult::GetTestProperty().
+TEST(TestResultPropertyTest, GetTestProperty) {
+  TestResult test_result;
+  TestProperty property_1("key_1", "1");
+  TestProperty property_2("key_2", "2");
+  TestProperty property_3("key_3", "3");
+  test_result.RecordProperty(property_1);
+  test_result.RecordProperty(property_2);
+  test_result.RecordProperty(property_3);
+
+  const TestProperty* fetched_property_1 = test_result.GetTestProperty(0);
+  const TestProperty* fetched_property_2 = test_result.GetTestProperty(1);
+  const TestProperty* fetched_property_3 = test_result.GetTestProperty(2);
+
+  ASSERT_TRUE(fetched_property_1 != NULL);
+  EXPECT_STREQ("key_1", fetched_property_1->key());
+  EXPECT_STREQ("1", fetched_property_1->value());
+
+  ASSERT_TRUE(fetched_property_2 != NULL);
+  EXPECT_STREQ("key_2", fetched_property_2->key());
+  EXPECT_STREQ("2", fetched_property_2->value());
+
+  ASSERT_TRUE(fetched_property_3 != NULL);
+  EXPECT_STREQ("key_3", fetched_property_3->key());
+  EXPECT_STREQ("3", fetched_property_3->value());
+
+  ASSERT_TRUE(test_result.GetTestProperty(3) == NULL);
+  ASSERT_TRUE(test_result.GetTestProperty(-1) == NULL);
+}
+
 // When a property using a reserved key is supplied to this function, it tests
 // that a non-fatal failure is added, a fatal failure is not added, and that the
 // property is not recorded.
@@ -3061,6 +3139,10 @@ TEST(AssertionTest, ASSERT_EQ) {
 TEST(AssertionTest, ASSERT_EQ_NULL) {
   // A success.
   const char* p = NULL;
+  // Some older GCC versions may issue a spurious waring in this or the next
+  // assertion statement. This warning should not be suppressed with
+  // static_cast since the test verifies the ability to use bare NULL as the
+  // expected parameter to the macro.
   ASSERT_EQ(NULL, p);
 
   // A failure.
@@ -3614,6 +3696,10 @@ TEST(ExpectTest, EXPECT_EQ_Double) {
 TEST(ExpectTest, EXPECT_EQ_NULL) {
   // A success.
   const char* p = NULL;
+  // Some older GCC versions may issue a spurious waring in this or the next
+  // assertion statement. This warning should not be suppressed with
+  // static_cast since the test verifies the ability to use bare NULL as the
+  // expected parameter to the macro.
   EXPECT_EQ(NULL, p);
 
   // A failure.
@@ -5207,7 +5293,7 @@ class CurrentTestInfoTest : public Test {
     // There should be no tests running at this point.
     const TestInfo* test_info =
       UnitTest::GetInstance()->current_test_info();
-    EXPECT_EQ(NULL, test_info)
+    EXPECT_TRUE(test_info == NULL)
         << "There should be no tests running at this point.";
   }
 
@@ -5216,7 +5302,7 @@ class CurrentTestInfoTest : public Test {
   static void TearDownTestCase() {
     const TestInfo* test_info =
       UnitTest::GetInstance()->current_test_info();
-    EXPECT_EQ(NULL, test_info)
+    EXPECT_TRUE(test_info == NULL)
         << "There should be no tests running at this point.";
   }
 };