Implements --gmock_catch_leaked_mocks and Mock::AllowLeak.
diff --git a/Makefile.am b/Makefile.am
index f70a808..7a821a0 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -128,7 +128,7 @@
 TESTS += test/gmock-spec-builders_test
 check_PROGRAMS += test/gmock-spec-builders_test
 test_gmock_spec_builders_test_SOURCES = test/gmock-spec-builders_test.cc
-test_gmock_spec_builders_test_LDADD = $(GTEST_LIBS) lib/libgmock_main.la
+test_gmock_spec_builders_test_LDADD = $(GTEST_LIBS) lib/libgmock.la
 
 TESTS += test/gmock_test
 check_PROGRAMS += test/gmock_test
@@ -147,6 +147,11 @@
 # Python modules used by multiple Python tests below.
 dist_check_SCRIPTS += test/gmock_test_utils.py
 
+check_PROGRAMS += test/gmock_leak_test_
+test_gmock_leak_test__SOURCES = test/gmock_leak_test_.cc
+test_gmock_leak_test__LDADD = $(GTEST_LIBS) lib/libgmock_main.la
+dist_check_SCRIPTS += test/gmock_leak_test.py
+
 check_PROGRAMS += test/gmock_output_test_
 test_gmock_output_test__SOURCES = test/gmock_output_test_.cc
 test_gmock_output_test__LDADD = $(GTEST_LIBS) lib/libgmock_main.la
@@ -155,15 +160,17 @@
 
 # Enable all the python driven tests when we can run them.
 if HAVE_PYTHON
-TESTS += test/gmock_output_test.py
+TESTS += \
+    test/gmock_leak_test.py \
+    test/gmock_output_test.py
 endif
 
 # Nonstandard package files for distribution.
 EXTRA_DIST += \
-  CHANGES \
-  CONTRIBUTORS \
-  make/Makefile \
-  src/gmock-all.cc
+    CHANGES \
+    CONTRIBUTORS \
+    make/Makefile \
+    src/gmock-all.cc
 
 # Pump scripts for generating Google Mock headers.
 # TODO(chandlerc@google.com): automate the generation of *.h from *.h.pump.
@@ -199,4 +206,5 @@
     msvc/gmock_link_test.vcproj \
     msvc/gmock_main.vcproj \
     msvc/gmock_output_test_.vcproj \
+    msvc/gmock-spec-builders_test.vcproj \
     msvc/gmock_test.vcproj
diff --git a/include/gmock/gmock-spec-builders.h b/include/gmock/gmock-spec-builders.h
index 3b4c085..0fc43d6 100644
--- a/include/gmock/gmock-spec-builders.h
+++ b/include/gmock/gmock-spec-builders.h
@@ -246,6 +246,10 @@
  public:
   // The following public methods can be called concurrently.
 
+  // Tells Google Mock to ignore mock_obj when checking for leaked
+  // mock objects.
+  static void AllowLeak(const void* mock_obj);
+
   // Verifies and clears all expectations on the given mock object.
   // If the expectations aren't satisfied, generates one or more
   // Google Test non-fatal failures and returns false.
@@ -311,6 +315,13 @@
   static void Register(const void* mock_obj,
                        internal::UntypedFunctionMockerBase* mocker);
 
+  // Tells Google Mock where in the source code mock_obj is used in an
+  // ON_CALL or EXPECT_CALL.  In case mock_obj is leaked, this
+  // information helps the user identify which object it is.
+  // L < g_gmock_mutex
+  static void RegisterUseByOnCallOrExpectCall(
+      const void* mock_obj, const char* file, int line);
+
   // Unregisters a mock method; removes the owning mock object from
   // the registry when the last mock method associated with it has
   // been unregistered.  This is called only in the destructor of
@@ -1081,7 +1092,12 @@
   // Registers this function mocker and the mock object owning it;
   // returns a reference to the function mocker object.  This is only
   // called by the ON_CALL() and EXPECT_CALL() macros.
+  // L < g_gmock_mutex
   FunctionMocker<F>& RegisterOwner(const void* mock_obj) {
+    {
+      MutexLock l(&g_gmock_mutex);
+      mock_obj_ = mock_obj;
+    }
     Mock::Register(mock_obj, this);
     return *::testing::internal::down_cast<FunctionMocker<F>*>(this);
   }
@@ -1155,17 +1171,21 @@
   }
 
   // Adds and returns a default action spec for this mock function.
+  // L < g_gmock_mutex
   DefaultActionSpec<F>& AddNewDefaultActionSpec(
       const char* file, int line,
       const ArgumentMatcherTuple& m) {
+    Mock::RegisterUseByOnCallOrExpectCall(MockObject(), file, line);
     default_actions_.push_back(DefaultActionSpec<F>(file, line, m));
     return default_actions_.back();
   }
 
   // Adds and returns an expectation spec for this mock function.
+  // L < g_gmock_mutex
   Expectation<F>& AddNewExpectation(
       const char* file, int line,
       const ArgumentMatcherTuple& m) {
+    Mock::RegisterUseByOnCallOrExpectCall(MockObject(), file, line);
     const linked_ptr<Expectation<F> > expectation(
         new Expectation<F>(this, file, line, m));
     expectations_.push_back(expectation);
@@ -1314,10 +1334,13 @@
     }
   }
 
-  // Address of the mock object this mock method belongs to.
+  // Address of the mock object this mock method belongs to.  Only
+  // valid after this mock method has been called or
+  // ON_CALL/EXPECT_CALL has been invoked on it.
   const void* mock_obj_;  // Protected by g_gmock_mutex.
 
-  // Name of the function being mocked.
+  // Name of the function being mocked.  Only valid after this mock
+  // method has been called.
   const char* name_;  // Protected by g_gmock_mutex.
 
   // The current spec (either default action spec or expectation spec)
diff --git a/include/gmock/gmock.h b/include/gmock/gmock.h
index 41d175f..22e7028 100644
--- a/include/gmock/gmock.h
+++ b/include/gmock/gmock.h
@@ -68,6 +68,7 @@
 namespace testing {
 
 // Declares Google Mock flags that we want a user to use programmatically.
+GMOCK_DECLARE_bool_(catch_leaked_mocks);
 GMOCK_DECLARE_string_(verbose);
 
 // Initializes Google Mock.  This must be called before running the
diff --git a/include/gmock/internal/gmock-port.h b/include/gmock/internal/gmock-port.h
index cb35219..b98cb11 100644
--- a/include/gmock/internal/gmock-port.h
+++ b/include/gmock/internal/gmock-port.h
@@ -242,6 +242,21 @@
 typedef ::std::wstring wstring;
 #endif  // GTEST_HAS_GLOBAL_WSTRING
 
+// Prints the file location in the format native to the compiler.
+inline void FormatFileLocation(const char* file, int line, ::std::ostream* os) {
+  if (file == NULL)
+    file = "unknown file";
+  if (line < 0) {
+    *os << file << ":";
+  } else {
+#if _MSC_VER
+    *os << file << "(" << line << "):";
+#else
+    *os << file << ":" << line << ":";
+#endif
+  }
+}
+
 // INTERNAL IMPLEMENTATION - DO NOT USE.
 //
 // GMOCK_CHECK_ is an all mode assert. It aborts the program if the condition
@@ -260,26 +275,13 @@
 class GMockCheckProvider {
  public:
   GMockCheckProvider(const char* condition, const char* file, int line) {
-    FormatFileLocation(file, line);
+    FormatFileLocation(file, line, &::std::cerr);
     ::std::cerr << " ERROR: Condition " << condition << " failed. ";
   }
   ~GMockCheckProvider() {
     ::std::cerr << ::std::endl;
     abort();
   }
-  void FormatFileLocation(const char* file, int line) {
-    if (file == NULL)
-      file = "unknown file";
-    if (line < 0) {
-      ::std::cerr << file << ":";
-    } else {
-#if _MSC_VER
-      ::std::cerr << file << "(" << line << "):";
-#else
-      ::std::cerr << file << ":" << line << ":";
-#endif
-    }
-  }
   ::std::ostream& GetStream() { return ::std::cerr; }
 };
 #define GMOCK_CHECK_(condition) \
diff --git a/msvc/gmock-spec-builders_test.vcproj b/msvc/gmock-spec-builders_test.vcproj
new file mode 100755
index 0000000..8440742
--- /dev/null
+++ b/msvc/gmock-spec-builders_test.vcproj
@@ -0,0 +1,205 @@
+<?xml version="1.0" encoding="Windows-1252"?>

+<VisualStudioProject

+	ProjectType="Visual C++"

+	Version="8.00"

+	Name="gmock-spec-builders_test"

+	ProjectGUID="{46972604-5BE0-4493-BAE3-878DB825FDCB}"

+	RootNamespace="gmockspecbuilders_test"

+	Keyword="Win32Proj"

+	>

+	<Platforms>

+		<Platform

+			Name="Win32"

+		/>

+	</Platforms>

+	<ToolFiles>

+	</ToolFiles>

+	<Configurations>

+		<Configuration

+			Name="Debug|Win32"

+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"

+			IntermediateDirectory="$(ConfigurationName)"

+			ConfigurationType="1"

+			InheritedPropertySheets=".\gmock_config.vsprops"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				AdditionalIncludeDirectories="../include"

+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"

+				MinimalRebuild="true"

+				BasicRuntimeChecks="3"

+				RuntimeLibrary="1"

+				UsePrecompiledHeader="0"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="true"

+				DebugInformationFormat="4"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				LinkIncremental="2"

+				GenerateDebugInformation="true"

+				SubSystem="1"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Win32"

+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"

+			IntermediateDirectory="$(ConfigurationName)"

+			ConfigurationType="1"

+			InheritedPropertySheets=".\gmock_config.vsprops"

+			CharacterSet="1"

+			WholeProgramOptimization="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories="../include"

+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"

+				RuntimeLibrary="0"

+				UsePrecompiledHeader="0"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="true"

+				DebugInformationFormat="3"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				LinkIncremental="1"

+				GenerateDebugInformation="true"

+				SubSystem="1"

+				OptimizeReferences="2"

+				EnableCOMDATFolding="2"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+	</Configurations>

+	<References>

+		<ProjectReference

+			ReferencedProjectIdentifier="{34681F0D-CE45-415D-B5F2-5C662DFE3BD5}"

+			RelativePathToProject=".\gmock.vcproj"

+		/>

+	</References>

+	<Files>

+		<Filter

+			Name="Source Files"

+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"

+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"

+			>

+			<File

+				RelativePath="..\test\gmock-spec-builders_test.cc"

+				>

+			</File>

+		</Filter>

+		<Filter

+			Name="Header Files"

+			Filter="h;hpp;hxx;hm;inl;inc;xsd"

+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"

+			>

+		</Filter>

+		<Filter

+			Name="Resource Files"

+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"

+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"

+			>

+		</Filter>

+	</Files>

+	<Globals>

+	</Globals>

+</VisualStudioProject>

diff --git a/msvc/gmock.sln b/msvc/gmock.sln
index aeb6a61..cd1502a 100644
--- a/msvc/gmock.sln
+++ b/msvc/gmock.sln
@@ -11,6 +11,8 @@
 EndProject

 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gmock_main", "gmock_main.vcproj", "{E4EF614B-30DF-4954-8C53-580A0BF6B589}"

 EndProject

+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gmock-spec-builders_test", "gmock-spec-builders_test.vcproj", "{46972604-5BE0-4493-BAE3-878DB825FDCB}"

+EndProject

 Global

 	GlobalSection(SolutionConfigurationPlatforms) = preSolution

 		Debug|Win32 = Debug|Win32

@@ -37,6 +39,10 @@
 		{E4EF614B-30DF-4954-8C53-580A0BF6B589}.Debug|Win32.Build.0 = Debug|Win32

 		{E4EF614B-30DF-4954-8C53-580A0BF6B589}.Release|Win32.ActiveCfg = Release|Win32

 		{E4EF614B-30DF-4954-8C53-580A0BF6B589}.Release|Win32.Build.0 = Release|Win32

+		{46972604-5BE0-4493-BAE3-878DB825FDCB}.Debug|Win32.ActiveCfg = Debug|Win32

+		{46972604-5BE0-4493-BAE3-878DB825FDCB}.Debug|Win32.Build.0 = Debug|Win32

+		{46972604-5BE0-4493-BAE3-878DB825FDCB}.Release|Win32.ActiveCfg = Release|Win32

+		{46972604-5BE0-4493-BAE3-878DB825FDCB}.Release|Win32.Build.0 = Release|Win32

 	EndGlobalSection

 	GlobalSection(SolutionProperties) = preSolution

 		HideSolutionNode = FALSE

diff --git a/msvc/gmock_output_test_.vcproj b/msvc/gmock_output_test_.vcproj
index 051dd14..8e846ec 100644
--- a/msvc/gmock_output_test_.vcproj
+++ b/msvc/gmock_output_test_.vcproj
@@ -172,8 +172,8 @@
 	</Configurations>

 	<References>

 		<ProjectReference

-			ReferencedProjectIdentifier="{E4EF614B-30DF-4954-8C53-580A0BF6B589}"

-			RelativePathToProject=".\gmock_main.vcproj"

+			ReferencedProjectIdentifier="{34681F0D-CE45-415D-B5F2-5C662DFE3BD5}"

+			RelativePathToProject=".\gmock.vcproj"

 		/>

 	</References>

 	<Files>

diff --git a/msvc/gmock_test.vcproj b/msvc/gmock_test.vcproj
index 135b2e6..60e1b4b 100644
--- a/msvc/gmock_test.vcproj
+++ b/msvc/gmock_test.vcproj
@@ -227,10 +227,6 @@
 				>

 			</File>

 			<File

-				RelativePath="..\test\gmock-spec-builders_test.cc"

-				>

-			</File>

-			<File

 				RelativePath="..\test\gmock_test.cc"

 				>

 			</File>

diff --git a/src/gmock-spec-builders.cc b/src/gmock-spec-builders.cc
index 353bb2d..2bb7295 100644
--- a/src/gmock-spec-builders.cc
+++ b/src/gmock-spec-builders.cc
@@ -36,9 +36,17 @@
 
 #include <gmock/gmock-spec-builders.h>
 
+#include <stdlib.h>
+#include <iostream>  // NOLINT
+#include <map>
 #include <set>
+#include <gmock/gmock.h>
 #include <gtest/gtest.h>
 
+#if GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC
+#include <unistd.h>  // NOLINT
+#endif
+
 namespace testing {
 namespace internal {
 
@@ -148,10 +156,77 @@
 namespace {
 
 typedef std::set<internal::UntypedFunctionMockerBase*> FunctionMockers;
-typedef std::map<const void*, FunctionMockers> MockObjectRegistry;
 
-// Maps a mock object to the set of mock methods it owns.  Protected
-// by g_gmock_mutex.
+// The current state of a mock object.  Such information is needed for
+// detecting leaked mock objects and explicitly verifying a mock's
+// expectations.
+struct MockObjectState {
+  MockObjectState()
+      : first_used_file(NULL), first_used_line(-1), leakable(false) {}
+
+  // Where in the source file an ON_CALL or EXPECT_CALL is first
+  // invoked on this mock object.
+  const char* first_used_file;
+  int first_used_line;
+  bool leakable;  // true iff it's OK to leak the object.
+  FunctionMockers function_mockers;  // All registered methods of the object.
+};
+
+// A global registry holding the state of all mock objects that are
+// alive.  A mock object is added to this registry the first time
+// Mock::AllowLeak(), ON_CALL(), or EXPECT_CALL() is called on it.  It
+// is removed from the registry in the mock object's destructor.
+class MockObjectRegistry {
+ public:
+  // Maps a mock object (identified by its address) to its state.
+  typedef std::map<const void*, MockObjectState> StateMap;
+
+  // This destructor will be called when a program exits, after all
+  // tests in it have been run.  By then, there should be no mock
+  // object alive.  Therefore we report any living object as test
+  // failure, unless the user explicitly asked us to ignore it.
+  ~MockObjectRegistry() {
+    using ::std::cout;
+
+    if (!GMOCK_FLAG(catch_leaked_mocks))
+      return;
+
+    int leaked_count = 0;
+    for (StateMap::const_iterator it = states_.begin(); it != states_.end();
+         ++it) {
+      if (it->second.leakable)  // The user said it's fine to leak this object.
+        continue;
+
+      // TODO(wan@google.com): Print the type of the leaked object.
+      // This can help the user identify the leaked object.
+      cout << "\n";
+      const MockObjectState& state = it->second;
+      internal::FormatFileLocation(
+          state.first_used_file, state.first_used_line, &cout);
+      cout << " ERROR: this mock object should be deleted but never is. "
+           << "Its address is @" << it->first << ".";
+      leaked_count++;
+    }
+    if (leaked_count > 0) {
+      cout << "\nERROR: " << leaked_count
+           << " leaked mock " << (leaked_count == 1 ? "object" : "objects")
+           << " found at program exit.\n";
+      cout.flush();
+      ::std::cerr.flush();
+      // RUN_ALL_TESTS() has already returned when this destructor is
+      // called.  Therefore we cannot use the normal Google Test
+      // failure reporting mechanism.
+      _exit(1);  // We cannot call exit() as it is not reentrant and
+                 // may already have been called.
+    }
+  }
+
+  StateMap& states() { return states_; }
+ private:
+  StateMap states_;
+};
+
+// Protected by g_gmock_mutex.
 MockObjectRegistry g_mock_object_registry;
 
 // Maps a mock object to the reaction Google Mock should have when an
@@ -208,6 +283,14 @@
       internal::WARN : g_uninteresting_call_reaction[mock_obj];
 }
 
+// Tells Google Mock to ignore mock_obj when checking for leaked mock
+// objects.
+// L < g_gmock_mutex
+void Mock::AllowLeak(const void* mock_obj) {
+  internal::MutexLock l(&internal::g_gmock_mutex);
+  g_mock_object_registry.states()[mock_obj].leakable = true;
+}
+
 // Verifies and clears all expectations on the given mock object.  If
 // the expectations aren't satisfied, generates one or more Google
 // Test non-fatal failures and returns false.
@@ -233,7 +316,7 @@
 // L >= g_gmock_mutex
 bool Mock::VerifyAndClearExpectationsLocked(void* mock_obj) {
   internal::g_gmock_mutex.AssertHeld();
-  if (g_mock_object_registry.count(mock_obj) == 0) {
+  if (g_mock_object_registry.states().count(mock_obj) == 0) {
     // No EXPECT_CALL() was set on the given mock object.
     return true;
   }
@@ -241,7 +324,8 @@
   // Verifies and clears the expectations on each mock method in the
   // given mock object.
   bool expectations_met = true;
-  FunctionMockers& mockers = g_mock_object_registry[mock_obj];
+  FunctionMockers& mockers =
+      g_mock_object_registry.states()[mock_obj].function_mockers;
   for (FunctionMockers::const_iterator it = mockers.begin();
        it != mockers.end(); ++it) {
     if (!(*it)->VerifyAndClearExpectationsLocked()) {
@@ -259,7 +343,21 @@
 void Mock::Register(const void* mock_obj,
                     internal::UntypedFunctionMockerBase* mocker) {
   internal::MutexLock l(&internal::g_gmock_mutex);
-  g_mock_object_registry[mock_obj].insert(mocker);
+  g_mock_object_registry.states()[mock_obj].function_mockers.insert(mocker);
+}
+
+// Tells Google Mock where in the source code mock_obj is used in an
+// ON_CALL or EXPECT_CALL.  In case mock_obj is leaked, this
+// information helps the user identify which object it is.
+// L < g_gmock_mutex
+void Mock::RegisterUseByOnCallOrExpectCall(
+    const void* mock_obj, const char* file, int line) {
+  internal::MutexLock l(&internal::g_gmock_mutex);
+  MockObjectState& state = g_mock_object_registry.states()[mock_obj];
+  if (state.first_used_file == NULL) {
+    state.first_used_file = file;
+    state.first_used_line = line;
+  }
 }
 
 // Unregisters a mock method; removes the owning mock object from the
@@ -269,13 +367,14 @@
 // L >= g_gmock_mutex
 void Mock::UnregisterLocked(internal::UntypedFunctionMockerBase* mocker) {
   internal::g_gmock_mutex.AssertHeld();
-  for (MockObjectRegistry::iterator it = g_mock_object_registry.begin();
-       it != g_mock_object_registry.end(); ++it) {
-    FunctionMockers& mockers = it->second;
+  for (MockObjectRegistry::StateMap::iterator it =
+           g_mock_object_registry.states().begin();
+       it != g_mock_object_registry.states().end(); ++it) {
+    FunctionMockers& mockers = it->second.function_mockers;
     if (mockers.erase(mocker) > 0) {
       // mocker was in mockers and has been just removed.
       if (mockers.empty()) {
-        g_mock_object_registry.erase(it);
+        g_mock_object_registry.states().erase(it);
       }
       return;
     }
@@ -287,14 +386,15 @@
 void Mock::ClearDefaultActionsLocked(void* mock_obj) {
   internal::g_gmock_mutex.AssertHeld();
 
-  if (g_mock_object_registry.count(mock_obj) == 0) {
+  if (g_mock_object_registry.states().count(mock_obj) == 0) {
     // No ON_CALL() was set on the given mock object.
     return;
   }
 
   // Clears the default actions for each mock method in the given mock
   // object.
-  FunctionMockers& mockers = g_mock_object_registry[mock_obj];
+  FunctionMockers& mockers =
+      g_mock_object_registry.states()[mock_obj].function_mockers;
   for (FunctionMockers::const_iterator it = mockers.begin();
        it != mockers.end(); ++it) {
     (*it)->ClearDefaultActionsLocked();
diff --git a/src/gmock.cc b/src/gmock.cc
index c017917..dc9d3d2 100644
--- a/src/gmock.cc
+++ b/src/gmock.cc
@@ -34,6 +34,15 @@
 
 namespace testing {
 
+// TODO(wan@google.com): support using environment variables to
+// control the flag values, like what Google Test does.
+
+// TODO(wan@google.com): change the default value to true after people
+// have a chance to fix their leaked mocks.
+GMOCK_DEFINE_bool_(catch_leaked_mocks, false,
+                   "true iff Google Mock should report leaked mock objects "
+                   "as failures.");
+
 GMOCK_DEFINE_string_(verbose, internal::kWarningVerbosity,
                      "Controls how verbose Google Mock's output is."
                      "  Valid values:\n"
@@ -76,6 +85,24 @@
   return flag_end + 1;
 }
 
+// Parses a string for a Google Mock bool flag, in the form of
+// "--gmock_flag=value".
+//
+// On success, stores the value of the flag in *value, and returns
+// true.  On failure, returns false without changing *value.
+static bool ParseGoogleMockBoolFlag(const char* str, const char* flag,
+                                    bool* value) {
+  // Gets the value of the flag as a string.
+  const char* const value_str = ParseGoogleMockFlagValue(str, flag, true);
+
+  // Aborts if the parsing failed.
+  if (value_str == NULL) return false;
+
+  // Converts the string value to a bool.
+  *value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F');
+  return true;
+}
+
 // Parses a string for a Google Mock string flag, in the form of
 // "--gmock_flag=value".
 //
@@ -110,7 +137,9 @@
     const char* const arg = arg_string.c_str();
 
     // Do we see a Google Mock flag?
-    if (ParseGoogleMockStringFlag(arg, "verbose", &GMOCK_FLAG(verbose))) {
+    if (ParseGoogleMockBoolFlag(arg, "catch_leaked_mocks",
+                                &GMOCK_FLAG(catch_leaked_mocks)) ||
+        ParseGoogleMockStringFlag(arg, "verbose", &GMOCK_FLAG(verbose))) {
       // Yes.  Shift the remainder of the argv list left by one.  Note
       // that argv has (*argc + 1) elements, the last one always being
       // NULL.  The following loop moves the trailing NULL element as
diff --git a/test/gmock-spec-builders_test.cc b/test/gmock-spec-builders_test.cc
index 287a63e..e8c3902 100644
--- a/test/gmock-spec-builders_test.cc
+++ b/test/gmock-spec-builders_test.cc
@@ -1612,6 +1612,43 @@
 
 #endif  // 0
 
+TEST(AllowLeakTest, AllowsLeakingUnusedMockObject) {
+  MockA* a = new MockA;
+  Mock::AllowLeak(a);
+}
+
+TEST(AllowLeakTest, CanBeCalledBeforeOnCall) {
+  MockA* a = new MockA;
+  Mock::AllowLeak(a);
+  ON_CALL(*a, DoA(_)).WillByDefault(Return());
+  a->DoA(0);
+}
+
+TEST(AllowLeakTest, CanBeCalledAfterOnCall) {
+  MockA* a = new MockA;
+  ON_CALL(*a, DoA(_)).WillByDefault(Return());
+  Mock::AllowLeak(a);
+}
+
+TEST(AllowLeakTest, CanBeCalledBeforeExpectCall) {
+  MockA* a = new MockA;
+  Mock::AllowLeak(a);
+  EXPECT_CALL(*a, DoA(_));
+  a->DoA(0);
+}
+
+TEST(AllowLeakTest, CanBeCalledAfterExpectCall) {
+  MockA* a = new MockA;
+  EXPECT_CALL(*a, DoA(_)).Times(AnyNumber());
+  Mock::AllowLeak(a);
+}
+
+TEST(AllowLeakTest, WorksWhenBothOnCallAndExpectCallArePresent) {
+  MockA* a = new MockA;
+  ON_CALL(*a, DoA(_)).WillByDefault(Return());
+  EXPECT_CALL(*a, DoA(_)).Times(AnyNumber());
+  Mock::AllowLeak(a);
+}
 
 // Tests that we can verify and clear a mock object's expectations
 // when none of its methods has expectations.
@@ -1916,3 +1953,14 @@
 }
 
 }  // namespace
+
+int main(int argc, char **argv) {
+  testing::InitGoogleMock(&argc, argv);
+
+  // Ensures that the tests pass no matter what value of
+  // --gmock_catch_leaked_mocks and --gmock_verbose the user specifies.
+  testing::GMOCK_FLAG(catch_leaked_mocks) = true;
+  testing::GMOCK_FLAG(verbose) = testing::internal::kWarningVerbosity;
+
+  return RUN_ALL_TESTS();
+}
diff --git a/test/gmock_leak_test.py b/test/gmock_leak_test.py
new file mode 100755
index 0000000..51358f0
--- /dev/null
+++ b/test/gmock_leak_test.py
@@ -0,0 +1,84 @@
+#!/usr/bin/env python
+#
+# Copyright 2009, 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.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may 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.
+
+"""Tests that leaked mock objects can be caught be Google Mock."""
+
+__author__ = 'wan@google.com (Zhanyong Wan)'
+
+import gmock_test_utils
+import os
+import unittest
+
+IS_WINDOWS = os.name == 'nt'
+
+if IS_WINDOWS:
+  # TODO(wan@google.com): test the opt build too.  We should do it
+  # when Vlad Losev's work on Google Test's Python test driver is
+  # done, such that we can reuse the work.
+  PROGRAM = r'..\build.dbg\gmock_leak_test_.exe'
+else:
+  PROGRAM = 'gmock_leak_test_'
+
+PROGRAM_PATH = os.path.join(gmock_test_utils.GetBuildDir(), PROGRAM)
+TEST_WITH_EXPECT_CALL = PROGRAM_PATH + ' --gtest_filter=*ExpectCall*'
+TEST_WITH_ON_CALL = PROGRAM_PATH + ' --gtest_filter=*OnCall*'
+TEST_MULTIPLE_LEAKS = PROGRAM_PATH + ' --gtest_filter=*MultipleLeaked*'
+
+
+class GMockLeakTest(unittest.TestCase):
+
+  def testDoesNotCatchLeakedMockByDefault(self):
+    self.assertEquals(0, os.system(TEST_WITH_EXPECT_CALL))
+    self.assertEquals(0, os.system(TEST_WITH_ON_CALL))
+
+  def testDoesNotCatchLeakedMockWhenDisabled(self):
+    self.assertEquals(
+        0, os.system(TEST_WITH_EXPECT_CALL + ' --gmock_catch_leaked_mocks=0'))
+    self.assertEquals(
+        0, os.system(TEST_WITH_ON_CALL + ' --gmock_catch_leaked_mocks=0'))
+
+  def testCatchesLeakedMockWhenEnabled(self):
+    self.assertNotEqual(
+        os.system(TEST_WITH_EXPECT_CALL + ' --gmock_catch_leaked_mocks'), 0)
+    self.assertNotEqual(
+        os.system(TEST_WITH_ON_CALL + ' --gmock_catch_leaked_mocks'), 0)
+
+  def testCatchesLeakedMockWhenEnabledWithExplictFlagValue(self):
+    self.assertNotEqual(
+        os.system(TEST_WITH_EXPECT_CALL + ' --gmock_catch_leaked_mocks=1'), 0)
+
+  def testCatchesMultipleLeakedMocks(self):
+    self.assertNotEqual(
+        os.system(TEST_MULTIPLE_LEAKS + ' --gmock_catch_leaked_mocks'), 0)
+
+
+if __name__ == '__main__':
+  gmock_test_utils.Main()
diff --git a/test/gmock_leak_test_.cc b/test/gmock_leak_test_.cc
new file mode 100644
index 0000000..157bd7e
--- /dev/null
+++ b/test/gmock_leak_test_.cc
@@ -0,0 +1,95 @@
+// Copyright 2009, 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.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may 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.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+// Google Mock - a framework for writing C++ mock classes.
+//
+// This program is for verifying that a leaked mock object can be
+// caught by Google Mock's leak detector.
+
+#include <gmock/gmock.h>
+
+namespace {
+
+using ::testing::Return;
+
+class FooInterface {
+ public:
+  virtual ~FooInterface() {}
+  virtual void DoThis() = 0;
+};
+
+class MockFoo : public FooInterface {
+ public:
+  MOCK_METHOD0(DoThis, void());
+};
+
+TEST(LeakTest, LeakedMockWithExpectCallCausesFailureWhenLeakCheckingIsEnabled) {
+  MockFoo* foo = new MockFoo;
+
+  EXPECT_CALL(*foo, DoThis());
+  foo->DoThis();
+
+  // In order to test the leak detector, we deliberately leak foo.
+
+  // Makes sure Google Mock's leak detector can change the exit code
+  // to 1 even when the code is already exiting with 0.
+  exit(0);
+}
+
+TEST(LeakTest, LeakedMockWithOnCallCausesFailureWhenLeakCheckingIsEnabled) {
+  MockFoo* foo = new MockFoo;
+
+  ON_CALL(*foo, DoThis()).WillByDefault(Return());
+
+  // In order to test the leak detector, we deliberately leak foo.
+
+  // Makes sure Google Mock's leak detector can change the exit code
+  // to 1 even when the code is already exiting with 0.
+  exit(0);
+}
+
+TEST(LeakTest, CatchesMultipleLeakedMockObjects) {
+  MockFoo* foo1 = new MockFoo;
+  MockFoo* foo2 = new MockFoo;
+
+  ON_CALL(*foo1, DoThis()).WillByDefault(Return());
+  EXPECT_CALL(*foo2, DoThis());
+  foo2->DoThis();
+
+  // In order to test the leak detector, we deliberately leak foo1 and
+  // foo2.
+
+  // Makes sure Google Mock's leak detector can change the exit code
+  // to 1 even when the code is already exiting with 0.
+  exit(0);
+}
+
+}  // namespace
diff --git a/test/gmock_output_test.py b/test/gmock_output_test.py
index f7f37ab..2e99219 100755
--- a/test/gmock_output_test.py
+++ b/test/gmock_output_test.py
@@ -59,7 +59,7 @@
   PROGRAM = 'gmock_output_test_'
 
 PROGRAM_PATH = os.path.join(gmock_test_utils.GetBuildDir(), PROGRAM)
-COMMAND = PROGRAM_PATH + ' --gtest_stack_trace_depth=0'
+COMMAND = PROGRAM_PATH + ' --gtest_stack_trace_depth=0 --gtest_print_time=0'
 GOLDEN_NAME = 'gmock_output_test_golden.txt'
 GOLDEN_PATH = os.path.join(gmock_test_utils.GetSourceDir(),
                            GOLDEN_NAME)
diff --git a/test/gmock_output_test_.cc b/test/gmock_output_test_.cc
index bb56b7c..c97bc78 100644
--- a/test/gmock_output_test_.cc
+++ b/test/gmock_output_test_.cc
@@ -40,6 +40,7 @@
 #include <gtest/gtest.h>
 
 using testing::_;
+using testing::AnyNumber;
 using testing::Ge;
 using testing::InSequence;
 using testing::Ref;
@@ -239,3 +240,31 @@
   foo_.Bar2(2, 2);
   foo_.Bar2(1, 1);  // Explicit actions in EXPECT_CALL run out.
 }
+
+TEST_F(GMockOutputTest, CatchesLeakedMocks) {
+  MockFoo* foo1 = new MockFoo;
+  MockFoo* foo2 = new MockFoo;
+
+  // Invokes ON_CALL on foo1.
+  ON_CALL(*foo1, Bar(_, _, _)).WillByDefault(Return('a'));
+
+  // Invokes EXPECT_CALL on foo2.
+  EXPECT_CALL(*foo2, Bar2(_, _));
+  EXPECT_CALL(*foo2, Bar2(1, _));
+  EXPECT_CALL(*foo2, Bar3(_, _)).Times(AnyNumber());
+  foo2->Bar2(2, 1);
+  foo2->Bar2(1, 1);
+
+  // Both foo1 and foo2 are deliberately leaked.
+}
+
+int main(int argc, char **argv) {
+  testing::InitGoogleMock(&argc, argv);
+
+  // Ensures that the tests pass no matter what value of
+  // --gmock_catch_leaked_mocks and --gmock_verbose the user specifies.
+  testing::GMOCK_FLAG(catch_leaked_mocks) = true;
+  testing::GMOCK_FLAG(verbose) = "warning";
+
+  return RUN_ALL_TESTS();
+}
diff --git a/test/gmock_output_test_golden.txt b/test/gmock_output_test_golden.txt
index 374e665..50ef7b7 100644
--- a/test/gmock_output_test_golden.txt
+++ b/test/gmock_output_test_golden.txt
@@ -1,4 +1,3 @@
-Running main() from gmock_main.cc
 [ RUN      ] GMockOutputTest.ExpectedCall
 
 FILE:#: EXPECT_CALL(foo_, Bar2(0, _)) invoked
@@ -280,6 +279,8 @@
 FILE:#:
 Stack trace:
 [       OK ] GMockOutputTest.ExplicitActionsRunOutWithDefaultAction
+[ RUN      ] GMockOutputTest.CatchesLeakedMocks
+[       OK ] GMockOutputTest.CatchesLeakedMocks
 [  FAILED  ] GMockOutputTest.UnexpectedCall
 [  FAILED  ] GMockOutputTest.UnexpectedCallToVoidFunction
 [  FAILED  ] GMockOutputTest.ExcessiveCall
@@ -294,3 +295,7 @@
 [  FAILED  ] GMockOutputTest.UnexpectedCallWithDefaultAction
 [  FAILED  ] GMockOutputTest.ExcessiveCallWithDefaultAction
 
+
+FILE:#: ERROR: this mock object should be deleted but never is. Its address is @0x#.
+FILE:#: ERROR: this mock object should be deleted but never is. Its address is @0x#.
+ERROR: 2 leaked mock objects found at program exit.
diff --git a/test/gmock_test.cc b/test/gmock_test.cc
index 63c3fe8..0c83260 100644
--- a/test/gmock_test.cc
+++ b/test/gmock_test.cc
@@ -246,3 +246,10 @@
   TestInitGoogleMock(argv, new_argv, "error");
   EXPECT_EQ(old_init_gtest_count + 1, g_init_gtest_count);
 }
+
+// Makes sure Google Mock flags can be accessed in code.
+TEST(FlagTest, IsAccessibleInCode) {
+  bool dummy = testing::GMOCK_FLAG(catch_leaked_mocks) &&
+      testing::GMOCK_FLAG(verbose) == "";
+  dummy = dummy;  // Avoids the "unused local variable" warning.
+}