Re-organizes the file structure for actions.
diff --git a/Makefile.am b/Makefile.am
index 196b927..1ce29ba 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -110,6 +110,11 @@
 test_gmock_matchers_test_SOURCES = test/gmock-matchers_test.cc
 test_gmock_matchers_test_LDADD = $(GTEST_LIBS) lib/libgmock_main.la
 
+TESTS += test/gmock-more-actions_test
+check_PROGRAMS += test/gmock-more-actions_test
+test_gmock_more_actions_test_SOURCES = test/gmock-more-actions_test.cc
+test_gmock_more_actions_test_LDADD = $(GTEST_LIBS) lib/libgmock_main.la
+
 TESTS += test/gmock-nice-strict_test
 check_PROGRAMS += test/gmock-nice-strict_test
 test_gmock_nice_strict_test_SOURCES = test/gmock-nice-strict_test.cc
diff --git a/include/gmock/gmock-actions.h b/include/gmock/gmock-actions.h
index a283ed7..49d5532 100644
--- a/include/gmock/gmock-actions.h
+++ b/include/gmock/gmock-actions.h
@@ -43,6 +43,7 @@
 #include <errno.h>
 #endif
 
+#include <gmock/gmock-printers.h>
 #include <gmock/internal/gmock-internal-utils.h>
 #include <gmock/internal/gmock-port.h>
 
@@ -787,6 +788,74 @@
   const A action_;
 };
 
+// A ReferenceWrapper<T> object represents a reference to type T,
+// which can be either const or not.  It can be explicitly converted
+// from, and implicitly converted to, a T&.  Unlike a reference,
+// ReferenceWrapper<T> can be copied and can survive template type
+// inference.  This is used to support by-reference arguments in the
+// InvokeArgument<N>(...) action.  The idea was from "reference
+// wrappers" in tr1, which we don't have in our source tree yet.
+template <typename T>
+class ReferenceWrapper {
+ public:
+  // Constructs a ReferenceWrapper<T> object from a T&.
+  explicit ReferenceWrapper(T& l_value) : pointer_(&l_value) {}  // NOLINT
+
+  // Allows a ReferenceWrapper<T> object to be implicitly converted to
+  // a T&.
+  operator T&() const { return *pointer_; }
+ private:
+  T* pointer_;
+};
+
+// Allows the expression ByRef(x) to be printed as a reference to x.
+template <typename T>
+void PrintTo(const ReferenceWrapper<T>& ref, ::std::ostream* os) {
+  T& value = ref;
+  UniversalPrinter<T&>::Print(value, os);
+}
+
+// Does two actions sequentially.  Used for implementing the DoAll(a1,
+// a2, ...) action.
+template <typename Action1, typename Action2>
+class DoBothAction {
+ public:
+  DoBothAction(Action1 action1, Action2 action2)
+      : action1_(action1), action2_(action2) {}
+
+  // This template type conversion operator allows DoAll(a1, ..., a_n)
+  // to be used in ANY function of compatible type.
+  template <typename F>
+  operator Action<F>() const {
+    return Action<F>(new Impl<F>(action1_, action2_));
+  }
+
+ private:
+  // Implements the DoAll(...) action for a particular function type F.
+  template <typename F>
+  class Impl : public ActionInterface<F> {
+   public:
+    typedef typename Function<F>::Result Result;
+    typedef typename Function<F>::ArgumentTuple ArgumentTuple;
+    typedef typename Function<F>::MakeResultVoid VoidResult;
+
+    Impl(const Action<VoidResult>& action1, const Action<F>& action2)
+        : action1_(action1), action2_(action2) {}
+
+    virtual Result Perform(const ArgumentTuple& args) {
+      action1_.Perform(args);
+      return action2_.Perform(args);
+    }
+
+   private:
+    const Action<VoidResult> action1_;
+    const Action<F> action2_;
+  };
+
+  Action1 action1_;
+  Action2 action2_;
+};
+
 }  // namespace internal
 
 // An Unused object can be implicitly constructed from ANY value.
@@ -926,6 +995,18 @@
   return internal::IgnoreResultAction<A>(an_action);
 }
 
+// Creates a reference wrapper for the given L-value.  If necessary,
+// you can explicitly specify the type of the reference.  For example,
+// suppose 'derived' is an object of type Derived, ByRef(derived)
+// would wrap a Derived&.  If you want to wrap a const Base& instead,
+// where Base is a base class of Derived, just write:
+//
+//   ByRef<const Base>(derived)
+template <typename T>
+inline internal::ReferenceWrapper<T> ByRef(T& l_value) {  // NOLINT
+  return internal::ReferenceWrapper<T>(l_value);
+}
+
 }  // namespace testing
 
 #endif  // GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
diff --git a/include/gmock/gmock-generated-actions.h b/include/gmock/gmock-generated-actions.h
index 06d9449..143a99b 100644
--- a/include/gmock/gmock-generated-actions.h
+++ b/include/gmock/gmock-generated-actions.h
@@ -39,7 +39,6 @@
 #define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
 
 #include <gmock/gmock-actions.h>
-#include <gmock/gmock-printers.h>
 #include <gmock/internal/gmock-port.h>
 
 namespace testing {
@@ -283,75 +282,6 @@
   }
 };
 
-
-// Implements the Invoke(f) action.  The template argument
-// FunctionImpl is the implementation type of f, which can be either a
-// function pointer or a functor.  Invoke(f) can be used as an
-// Action<F> as long as f's type is compatible with F (i.e. f can be
-// assigned to a tr1::function<F>).
-template <typename FunctionImpl>
-class InvokeAction {
- public:
-  // The c'tor makes a copy of function_impl (either a function
-  // pointer or a functor).
-  explicit InvokeAction(FunctionImpl function_impl)
-      : function_impl_(function_impl) {}
-
-  template <typename Result, typename ArgumentTuple>
-  Result Perform(const ArgumentTuple& args) {
-    return InvokeHelper<Result, ArgumentTuple>::Invoke(function_impl_, args);
-  }
- private:
-  FunctionImpl function_impl_;
-};
-
-// Implements the Invoke(object_ptr, &Class::Method) action.
-template <class Class, typename MethodPtr>
-class InvokeMethodAction {
- public:
-  InvokeMethodAction(Class* obj_ptr, MethodPtr method_ptr)
-      : obj_ptr_(obj_ptr), method_ptr_(method_ptr) {}
-
-  template <typename Result, typename ArgumentTuple>
-  Result Perform(const ArgumentTuple& args) const {
-    return InvokeHelper<Result, ArgumentTuple>::InvokeMethod(
-        obj_ptr_, method_ptr_, args);
-  }
- private:
-  Class* const obj_ptr_;
-  const MethodPtr method_ptr_;
-};
-
-// TODO(wan@google.com): ReferenceWrapper and ByRef() are neither
-// action-specific nor variadic.  Move them to a better place.
-
-// A ReferenceWrapper<T> object represents a reference to type T,
-// which can be either const or not.  It can be explicitly converted
-// from, and implicitly converted to, a T&.  Unlike a reference,
-// ReferenceWrapper<T> can be copied and can survive template type
-// inference.  This is used to support by-reference arguments in the
-// InvokeArgument<N>(...) action.  The idea was from "reference
-// wrappers" in tr1, which we don't have in our source tree yet.
-template <typename T>
-class ReferenceWrapper {
- public:
-  // Constructs a ReferenceWrapper<T> object from a T&.
-  explicit ReferenceWrapper(T& l_value) : pointer_(&l_value) {}  // NOLINT
-
-  // Allows a ReferenceWrapper<T> object to be implicitly converted to
-  // a T&.
-  operator T&() const { return *pointer_; }
- private:
-  T* pointer_;
-};
-
-// Allows the expression ByRef(x) to be printed as a reference to x.
-template <typename T>
-void PrintTo(const ReferenceWrapper<T>& ref, ::std::ostream* os) {
-  T& value = ref;
-  UniversalPrinter<T&>::Print(value, os);
-}
-
 // CallableHelper has static methods for invoking "callables",
 // i.e. function pointers and functors.  It uses overloading to
 // provide a uniform interface for invoking different kinds of
@@ -687,47 +617,6 @@
   const InnerAction action_;
 };
 
-// Does two actions sequentially.  Used for implementing the DoAll(a1,
-// a2, ...) action.
-template <typename Action1, typename Action2>
-class DoBothAction {
- public:
-  DoBothAction(Action1 action1, Action2 action2)
-      : action1_(action1), action2_(action2) {}
-
-  // This template type conversion operator allows DoAll(a1, ..., a_n)
-  // to be used in ANY function of compatible type.
-  template <typename F>
-  operator Action<F>() const {
-    return Action<F>(new Impl<F>(action1_, action2_));
-  }
-
- private:
-  // Implements the DoAll(...) action for a particular function type F.
-  template <typename F>
-  class Impl : public ActionInterface<F> {
-   public:
-    typedef typename Function<F>::Result Result;
-    typedef typename Function<F>::ArgumentTuple ArgumentTuple;
-    typedef typename Function<F>::MakeResultVoid VoidResult;
-
-    Impl(const Action<VoidResult>& action1, const Action<F>& action2)
-        : action1_(action1), action2_(action2) {}
-
-    virtual Result Perform(const ArgumentTuple& args) {
-      action1_.Perform(args);
-      return action2_.Perform(args);
-    }
-
-   private:
-    const Action<VoidResult> action1_;
-    const Action<F> action2_;
-  };
-
-  Action1 action1_;
-  Action2 action2_;
-};
-
 // A macro from the ACTION* family (defined later in this file)
 // defines an action that can be used in a mock function.  Typically,
 // these actions only care about a subset of the arguments of the mock
@@ -863,57 +752,6 @@
 
 // Various overloads for Invoke().
 
-// Creates an action that invokes 'function_impl' with the mock
-// function's arguments.
-template <typename FunctionImpl>
-PolymorphicAction<internal::InvokeAction<FunctionImpl> > Invoke(
-    FunctionImpl function_impl) {
-  return MakePolymorphicAction(
-      internal::InvokeAction<FunctionImpl>(function_impl));
-}
-
-// Creates an action that invokes the given method on the given object
-// with the mock function's arguments.
-template <class Class, typename MethodPtr>
-PolymorphicAction<internal::InvokeMethodAction<Class, MethodPtr> > Invoke(
-    Class* obj_ptr, MethodPtr method_ptr) {
-  return MakePolymorphicAction(
-      internal::InvokeMethodAction<Class, MethodPtr>(obj_ptr, method_ptr));
-}
-
-// Creates a reference wrapper for the given L-value.  If necessary,
-// you can explicitly specify the type of the reference.  For example,
-// suppose 'derived' is an object of type Derived, ByRef(derived)
-// would wrap a Derived&.  If you want to wrap a const Base& instead,
-// where Base is a base class of Derived, just write:
-//
-//   ByRef<const Base>(derived)
-template <typename T>
-inline internal::ReferenceWrapper<T> ByRef(T& l_value) {  // NOLINT
-  return internal::ReferenceWrapper<T>(l_value);
-}
-
-// WithoutArgs(inner_action) can be used in a mock function with a
-// non-empty argument list to perform inner_action, which takes no
-// argument.  In other words, it adapts an action accepting no
-// argument to one that accepts (and ignores) arguments.
-template <typename InnerAction>
-inline internal::WithArgsAction<InnerAction>
-WithoutArgs(const InnerAction& action) {
-  return internal::WithArgsAction<InnerAction>(action);
-}
-
-// WithArg<k>(an_action) creates an action that passes the k-th
-// (0-based) argument of the mock function to an_action and performs
-// it.  It adapts an action accepting one argument to one that accepts
-// multiple arguments.  For convenience, we also provide
-// WithArgs<k>(an_action) (defined below) as a synonym.
-template <int k, typename InnerAction>
-inline internal::WithArgsAction<InnerAction, k>
-WithArg(const InnerAction& action) {
-  return internal::WithArgsAction<InnerAction, k>(action);
-}
-
 // WithArgs<N1, N2, ..., Nk>(an_action) creates an action that passes
 // the selected arguments of the mock function to an_action and
 // performs it.  It serves as an adaptor between actions with
@@ -2441,55 +2279,6 @@
       ::std::tr1::get<k>(args), p0, p1, p2, p3, p4, p5, p6, p7, p8, p9);
 }
 
-// Action ReturnArg<k>() returns the k-th argument of the mock function.
-ACTION_TEMPLATE(ReturnArg,
-                HAS_1_TEMPLATE_PARAMS(int, k),
-                AND_0_VALUE_PARAMS()) {
-  return std::tr1::get<k>(args);
-}
-
-// Action SaveArg<k>(pointer) saves the k-th (0-based) argument of the
-// mock function to *pointer.
-ACTION_TEMPLATE(SaveArg,
-                HAS_1_TEMPLATE_PARAMS(int, k),
-                AND_1_VALUE_PARAMS(pointer)) {
-  *pointer = ::std::tr1::get<k>(args);
-}
-
-// Action SetArgReferee<k>(value) assigns 'value' to the variable
-// referenced by the k-th (0-based) argument of the mock function.
-ACTION_TEMPLATE(SetArgReferee,
-                HAS_1_TEMPLATE_PARAMS(int, k),
-                AND_1_VALUE_PARAMS(value)) {
-  typedef typename ::std::tr1::tuple_element<k, args_type>::type argk_type;
-  // Ensures that argument #k is a reference.  If you get a compiler
-  // error on the next line, you are using SetArgReferee<k>(value) in
-  // a mock function whose k-th (0-based) argument is not a reference.
-  GMOCK_COMPILE_ASSERT_(internal::is_reference<argk_type>::value,
-                        SetArgReferee_must_be_used_with_a_reference_argument);
-  ::std::tr1::get<k>(args) = value;
-}
-
-// Action SetArrayArgument<k>(first, last) copies the elements in
-// source range [first, last) to the array pointed to by the k-th
-// (0-based) argument, which can be either a pointer or an
-// iterator. The action does not take ownership of the elements in the
-// source range.
-ACTION_TEMPLATE(SetArrayArgument,
-                HAS_1_TEMPLATE_PARAMS(int, k),
-                AND_2_VALUE_PARAMS(first, last)) {
-  // Microsoft compiler deprecates ::std::copy, so we want to suppress warning
-  // 4996 (Function call with parameters that may be unsafe) there.
-#ifdef _MSC_VER
-#pragma warning(push)          // Saves the current warning state.
-#pragma warning(disable:4996)  // Temporarily disables warning 4996.
-#endif
-  ::std::copy(first, last, ::std::tr1::get<k>(args));
-#ifdef _MSC_VER
-#pragma warning(pop)           // Restores the warning state.
-#endif
-}
-
 // Various overloads for ReturnNew<T>().
 //
 // The ReturnNew<T>(a1, a2, ..., a_k) action returns a pointer to a new
@@ -2561,20 +2350,6 @@
   return new T(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9);
 }
 
-// Action DeleteArg<k>() deletes the k-th (0-based) argument of the mock
-// function.
-ACTION_TEMPLATE(DeleteArg,
-                HAS_1_TEMPLATE_PARAMS(int, k),
-                AND_0_VALUE_PARAMS()) {
-  delete ::std::tr1::get<k>(args);
-}
-
-// Action Throw(exception) can be used in a mock function of any type
-// to throw the given exception.  Any copyable value can be thrown.
-#if GTEST_HAS_EXCEPTIONS
-ACTION_P(Throw, exception) { throw exception; }
-#endif  // GTEST_HAS_EXCEPTIONS
-
 }  // namespace testing
 
 #endif  // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
diff --git a/include/gmock/gmock-generated-actions.h.pump b/include/gmock/gmock-generated-actions.h.pump
index cc11769..05bf3db 100644
--- a/include/gmock/gmock-generated-actions.h.pump
+++ b/include/gmock/gmock-generated-actions.h.pump
@@ -43,7 +43,6 @@
 #define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
 
 #include <gmock/gmock-actions.h>
-#include <gmock/gmock-printers.h>
 #include <gmock/internal/gmock-port.h>
 
 namespace testing {
@@ -85,75 +84,6 @@
 
 
 ]]
-
-// Implements the Invoke(f) action.  The template argument
-// FunctionImpl is the implementation type of f, which can be either a
-// function pointer or a functor.  Invoke(f) can be used as an
-// Action<F> as long as f's type is compatible with F (i.e. f can be
-// assigned to a tr1::function<F>).
-template <typename FunctionImpl>
-class InvokeAction {
- public:
-  // The c'tor makes a copy of function_impl (either a function
-  // pointer or a functor).
-  explicit InvokeAction(FunctionImpl function_impl)
-      : function_impl_(function_impl) {}
-
-  template <typename Result, typename ArgumentTuple>
-  Result Perform(const ArgumentTuple& args) {
-    return InvokeHelper<Result, ArgumentTuple>::Invoke(function_impl_, args);
-  }
- private:
-  FunctionImpl function_impl_;
-};
-
-// Implements the Invoke(object_ptr, &Class::Method) action.
-template <class Class, typename MethodPtr>
-class InvokeMethodAction {
- public:
-  InvokeMethodAction(Class* obj_ptr, MethodPtr method_ptr)
-      : obj_ptr_(obj_ptr), method_ptr_(method_ptr) {}
-
-  template <typename Result, typename ArgumentTuple>
-  Result Perform(const ArgumentTuple& args) const {
-    return InvokeHelper<Result, ArgumentTuple>::InvokeMethod(
-        obj_ptr_, method_ptr_, args);
-  }
- private:
-  Class* const obj_ptr_;
-  const MethodPtr method_ptr_;
-};
-
-// TODO(wan@google.com): ReferenceWrapper and ByRef() are neither
-// action-specific nor variadic.  Move them to a better place.
-
-// A ReferenceWrapper<T> object represents a reference to type T,
-// which can be either const or not.  It can be explicitly converted
-// from, and implicitly converted to, a T&.  Unlike a reference,
-// ReferenceWrapper<T> can be copied and can survive template type
-// inference.  This is used to support by-reference arguments in the
-// InvokeArgument<N>(...) action.  The idea was from "reference
-// wrappers" in tr1, which we don't have in our source tree yet.
-template <typename T>
-class ReferenceWrapper {
- public:
-  // Constructs a ReferenceWrapper<T> object from a T&.
-  explicit ReferenceWrapper(T& l_value) : pointer_(&l_value) {}  // NOLINT
-
-  // Allows a ReferenceWrapper<T> object to be implicitly converted to
-  // a T&.
-  operator T&() const { return *pointer_; }
- private:
-  T* pointer_;
-};
-
-// Allows the expression ByRef(x) to be printed as a reference to x.
-template <typename T>
-void PrintTo(const ReferenceWrapper<T>& ref, ::std::ostream* os) {
-  T& value = ref;
-  UniversalPrinter<T&>::Print(value, os);
-}
-
 // CallableHelper has static methods for invoking "callables",
 // i.e. function pointers and functors.  It uses overloading to
 // provide a uniform interface for invoking different kinds of
@@ -300,47 +230,6 @@
   const InnerAction action_;
 };
 
-// Does two actions sequentially.  Used for implementing the DoAll(a1,
-// a2, ...) action.
-template <typename Action1, typename Action2>
-class DoBothAction {
- public:
-  DoBothAction(Action1 action1, Action2 action2)
-      : action1_(action1), action2_(action2) {}
-
-  // This template type conversion operator allows DoAll(a1, ..., a_n)
-  // to be used in ANY function of compatible type.
-  template <typename F>
-  operator Action<F>() const {
-    return Action<F>(new Impl<F>(action1_, action2_));
-  }
-
- private:
-  // Implements the DoAll(...) action for a particular function type F.
-  template <typename F>
-  class Impl : public ActionInterface<F> {
-   public:
-    typedef typename Function<F>::Result Result;
-    typedef typename Function<F>::ArgumentTuple ArgumentTuple;
-    typedef typename Function<F>::MakeResultVoid VoidResult;
-
-    Impl(const Action<VoidResult>& action1, const Action<F>& action2)
-        : action1_(action1), action2_(action2) {}
-
-    virtual Result Perform(const ArgumentTuple& args) {
-      action1_.Perform(args);
-      return action2_.Perform(args);
-    }
-
-   private:
-    const Action<VoidResult> action1_;
-    const Action<F> action2_;
-  };
-
-  Action1 action1_;
-  Action2 action2_;
-};
-
 // A macro from the ACTION* family (defined later in this file)
 // defines an action that can be used in a mock function.  Typically,
 // these actions only care about a subset of the arguments of the mock
@@ -388,57 +277,6 @@
 
 // Various overloads for Invoke().
 
-// Creates an action that invokes 'function_impl' with the mock
-// function's arguments.
-template <typename FunctionImpl>
-PolymorphicAction<internal::InvokeAction<FunctionImpl> > Invoke(
-    FunctionImpl function_impl) {
-  return MakePolymorphicAction(
-      internal::InvokeAction<FunctionImpl>(function_impl));
-}
-
-// Creates an action that invokes the given method on the given object
-// with the mock function's arguments.
-template <class Class, typename MethodPtr>
-PolymorphicAction<internal::InvokeMethodAction<Class, MethodPtr> > Invoke(
-    Class* obj_ptr, MethodPtr method_ptr) {
-  return MakePolymorphicAction(
-      internal::InvokeMethodAction<Class, MethodPtr>(obj_ptr, method_ptr));
-}
-
-// Creates a reference wrapper for the given L-value.  If necessary,
-// you can explicitly specify the type of the reference.  For example,
-// suppose 'derived' is an object of type Derived, ByRef(derived)
-// would wrap a Derived&.  If you want to wrap a const Base& instead,
-// where Base is a base class of Derived, just write:
-//
-//   ByRef<const Base>(derived)
-template <typename T>
-inline internal::ReferenceWrapper<T> ByRef(T& l_value) {  // NOLINT
-  return internal::ReferenceWrapper<T>(l_value);
-}
-
-// WithoutArgs(inner_action) can be used in a mock function with a
-// non-empty argument list to perform inner_action, which takes no
-// argument.  In other words, it adapts an action accepting no
-// argument to one that accepts (and ignores) arguments.
-template <typename InnerAction>
-inline internal::WithArgsAction<InnerAction>
-WithoutArgs(const InnerAction& action) {
-  return internal::WithArgsAction<InnerAction>(action);
-}
-
-// WithArg<k>(an_action) creates an action that passes the k-th
-// (0-based) argument of the mock function to an_action and performs
-// it.  It adapts an action accepting one argument to one that accepts
-// multiple arguments.  For convenience, we also provide
-// WithArgs<k>(an_action) (defined below) as a synonym.
-template <int k, typename InnerAction>
-inline internal::WithArgsAction<InnerAction, k>
-WithArg(const InnerAction& action) {
-  return internal::WithArgsAction<InnerAction, k>(action);
-}
-
 // WithArgs<N1, N2, ..., Nk>(an_action) creates an action that passes
 // the selected arguments of the mock function to an_action and
 // performs it.  It serves as an adaptor between actions with
@@ -940,55 +778,6 @@
 
 ]]
 
-// Action ReturnArg<k>() returns the k-th argument of the mock function.
-ACTION_TEMPLATE(ReturnArg,
-                HAS_1_TEMPLATE_PARAMS(int, k),
-                AND_0_VALUE_PARAMS()) {
-  return std::tr1::get<k>(args);
-}
-
-// Action SaveArg<k>(pointer) saves the k-th (0-based) argument of the
-// mock function to *pointer.
-ACTION_TEMPLATE(SaveArg,
-                HAS_1_TEMPLATE_PARAMS(int, k),
-                AND_1_VALUE_PARAMS(pointer)) {
-  *pointer = ::std::tr1::get<k>(args);
-}
-
-// Action SetArgReferee<k>(value) assigns 'value' to the variable
-// referenced by the k-th (0-based) argument of the mock function.
-ACTION_TEMPLATE(SetArgReferee,
-                HAS_1_TEMPLATE_PARAMS(int, k),
-                AND_1_VALUE_PARAMS(value)) {
-  typedef typename ::std::tr1::tuple_element<k, args_type>::type argk_type;
-  // Ensures that argument #k is a reference.  If you get a compiler
-  // error on the next line, you are using SetArgReferee<k>(value) in
-  // a mock function whose k-th (0-based) argument is not a reference.
-  GMOCK_COMPILE_ASSERT_(internal::is_reference<argk_type>::value,
-                        SetArgReferee_must_be_used_with_a_reference_argument);
-  ::std::tr1::get<k>(args) = value;
-}
-
-// Action SetArrayArgument<k>(first, last) copies the elements in
-// source range [first, last) to the array pointed to by the k-th
-// (0-based) argument, which can be either a pointer or an
-// iterator. The action does not take ownership of the elements in the
-// source range.
-ACTION_TEMPLATE(SetArrayArgument,
-                HAS_1_TEMPLATE_PARAMS(int, k),
-                AND_2_VALUE_PARAMS(first, last)) {
-  // Microsoft compiler deprecates ::std::copy, so we want to suppress warning
-  // 4996 (Function call with parameters that may be unsafe) there.
-#ifdef _MSC_VER
-#pragma warning(push)          // Saves the current warning state.
-#pragma warning(disable:4996)  // Temporarily disables warning 4996.
-#endif
-  ::std::copy(first, last, ::std::tr1::get<k>(args));
-#ifdef _MSC_VER
-#pragma warning(pop)           // Restores the warning state.
-#endif
-}
-
 // Various overloads for ReturnNew<T>().
 //
 // The ReturnNew<T>(a1, a2, ..., a_k) action returns a pointer to a new
@@ -1007,20 +796,6 @@
 
 ]]
 
-// Action DeleteArg<k>() deletes the k-th (0-based) argument of the mock
-// function.
-ACTION_TEMPLATE(DeleteArg,
-                HAS_1_TEMPLATE_PARAMS(int, k),
-                AND_0_VALUE_PARAMS()) {
-  delete ::std::tr1::get<k>(args);
-}
-
-// Action Throw(exception) can be used in a mock function of any type
-// to throw the given exception.  Any copyable value can be thrown.
-#if GTEST_HAS_EXCEPTIONS
-ACTION_P(Throw, exception) { throw exception; }
-#endif  // GTEST_HAS_EXCEPTIONS
-
 }  // namespace testing
 
 #endif  // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
diff --git a/include/gmock/gmock-more-actions.h b/include/gmock/gmock-more-actions.h
new file mode 100644
index 0000000..c6fa6bb
--- /dev/null
+++ b/include/gmock/gmock-more-actions.h
@@ -0,0 +1,190 @@
+// Copyright 2007, 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 file implements some actions that depend on gmock-generated-actions.h.
+
+#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
+#define GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
+
+#include <gmock/gmock-generated-actions.h>
+
+namespace testing {
+namespace internal {
+
+// Implements the Invoke(f) action.  The template argument
+// FunctionImpl is the implementation type of f, which can be either a
+// function pointer or a functor.  Invoke(f) can be used as an
+// Action<F> as long as f's type is compatible with F (i.e. f can be
+// assigned to a tr1::function<F>).
+template <typename FunctionImpl>
+class InvokeAction {
+ public:
+  // The c'tor makes a copy of function_impl (either a function
+  // pointer or a functor).
+  explicit InvokeAction(FunctionImpl function_impl)
+      : function_impl_(function_impl) {}
+
+  template <typename Result, typename ArgumentTuple>
+  Result Perform(const ArgumentTuple& args) {
+    return InvokeHelper<Result, ArgumentTuple>::Invoke(function_impl_, args);
+  }
+ private:
+  FunctionImpl function_impl_;
+};
+
+// Implements the Invoke(object_ptr, &Class::Method) action.
+template <class Class, typename MethodPtr>
+class InvokeMethodAction {
+ public:
+  InvokeMethodAction(Class* obj_ptr, MethodPtr method_ptr)
+      : obj_ptr_(obj_ptr), method_ptr_(method_ptr) {}
+
+  template <typename Result, typename ArgumentTuple>
+  Result Perform(const ArgumentTuple& args) const {
+    return InvokeHelper<Result, ArgumentTuple>::InvokeMethod(
+        obj_ptr_, method_ptr_, args);
+  }
+ private:
+  Class* const obj_ptr_;
+  const MethodPtr method_ptr_;
+};
+
+}  // namespace internal
+
+// Various overloads for Invoke().
+
+// Creates an action that invokes 'function_impl' with the mock
+// function's arguments.
+template <typename FunctionImpl>
+PolymorphicAction<internal::InvokeAction<FunctionImpl> > Invoke(
+    FunctionImpl function_impl) {
+  return MakePolymorphicAction(
+      internal::InvokeAction<FunctionImpl>(function_impl));
+}
+
+// Creates an action that invokes the given method on the given object
+// with the mock function's arguments.
+template <class Class, typename MethodPtr>
+PolymorphicAction<internal::InvokeMethodAction<Class, MethodPtr> > Invoke(
+    Class* obj_ptr, MethodPtr method_ptr) {
+  return MakePolymorphicAction(
+      internal::InvokeMethodAction<Class, MethodPtr>(obj_ptr, method_ptr));
+}
+
+// WithoutArgs(inner_action) can be used in a mock function with a
+// non-empty argument list to perform inner_action, which takes no
+// argument.  In other words, it adapts an action accepting no
+// argument to one that accepts (and ignores) arguments.
+template <typename InnerAction>
+inline internal::WithArgsAction<InnerAction>
+WithoutArgs(const InnerAction& action) {
+  return internal::WithArgsAction<InnerAction>(action);
+}
+
+// WithArg<k>(an_action) creates an action that passes the k-th
+// (0-based) argument of the mock function to an_action and performs
+// it.  It adapts an action accepting one argument to one that accepts
+// multiple arguments.  For convenience, we also provide
+// WithArgs<k>(an_action) (defined below) as a synonym.
+template <int k, typename InnerAction>
+inline internal::WithArgsAction<InnerAction, k>
+WithArg(const InnerAction& action) {
+  return internal::WithArgsAction<InnerAction, k>(action);
+}
+
+// Action ReturnArg<k>() returns the k-th argument of the mock function.
+ACTION_TEMPLATE(ReturnArg,
+                HAS_1_TEMPLATE_PARAMS(int, k),
+                AND_0_VALUE_PARAMS()) {
+  return std::tr1::get<k>(args);
+}
+
+// Action SaveArg<k>(pointer) saves the k-th (0-based) argument of the
+// mock function to *pointer.
+ACTION_TEMPLATE(SaveArg,
+                HAS_1_TEMPLATE_PARAMS(int, k),
+                AND_1_VALUE_PARAMS(pointer)) {
+  *pointer = ::std::tr1::get<k>(args);
+}
+
+// Action SetArgReferee<k>(value) assigns 'value' to the variable
+// referenced by the k-th (0-based) argument of the mock function.
+ACTION_TEMPLATE(SetArgReferee,
+                HAS_1_TEMPLATE_PARAMS(int, k),
+                AND_1_VALUE_PARAMS(value)) {
+  typedef typename ::std::tr1::tuple_element<k, args_type>::type argk_type;
+  // Ensures that argument #k is a reference.  If you get a compiler
+  // error on the next line, you are using SetArgReferee<k>(value) in
+  // a mock function whose k-th (0-based) argument is not a reference.
+  GMOCK_COMPILE_ASSERT_(internal::is_reference<argk_type>::value,
+                        SetArgReferee_must_be_used_with_a_reference_argument);
+  ::std::tr1::get<k>(args) = value;
+}
+
+// Action SetArrayArgument<k>(first, last) copies the elements in
+// source range [first, last) to the array pointed to by the k-th
+// (0-based) argument, which can be either a pointer or an
+// iterator. The action does not take ownership of the elements in the
+// source range.
+ACTION_TEMPLATE(SetArrayArgument,
+                HAS_1_TEMPLATE_PARAMS(int, k),
+                AND_2_VALUE_PARAMS(first, last)) {
+  // Microsoft compiler deprecates ::std::copy, so we want to suppress warning
+  // 4996 (Function call with parameters that may be unsafe) there.
+#ifdef _MSC_VER
+#pragma warning(push)          // Saves the current warning state.
+#pragma warning(disable:4996)  // Temporarily disables warning 4996.
+#endif
+  ::std::copy(first, last, ::std::tr1::get<k>(args));
+#ifdef _MSC_VER
+#pragma warning(pop)           // Restores the warning state.
+#endif
+}
+
+// Action DeleteArg<k>() deletes the k-th (0-based) argument of the mock
+// function.
+ACTION_TEMPLATE(DeleteArg,
+                HAS_1_TEMPLATE_PARAMS(int, k),
+                AND_0_VALUE_PARAMS()) {
+  delete ::std::tr1::get<k>(args);
+}
+
+// Action Throw(exception) can be used in a mock function of any type
+// to throw the given exception.  Any copyable value can be thrown.
+#if GTEST_HAS_EXCEPTIONS
+ACTION_P(Throw, exception) { throw exception; }
+#endif  // GTEST_HAS_EXCEPTIONS
+
+}  // namespace testing
+
+#endif  // GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
diff --git a/include/gmock/gmock.h b/include/gmock/gmock.h
index 29d9727..daf5288 100644
--- a/include/gmock/gmock.h
+++ b/include/gmock/gmock.h
@@ -60,6 +60,7 @@
 #include <gmock/gmock-generated-actions.h>
 #include <gmock/gmock-generated-function-mockers.h>
 #include <gmock/gmock-generated-matchers.h>
+#include <gmock/gmock-more-actions.h>
 #include <gmock/gmock-generated-nice-strict.h>
 #include <gmock/gmock-matchers.h>
 #include <gmock/gmock-printers.h>
diff --git a/test/gmock-actions_test.cc b/test/gmock-actions_test.cc
index 2446260..9bf4c32 100644
--- a/test/gmock-actions_test.cc
+++ b/test/gmock-actions_test.cc
@@ -56,6 +56,7 @@
 using testing::Action;
 using testing::ActionInterface;
 using testing::Assign;
+using testing::ByRef;
 using testing::DefaultValue;
 using testing::DoDefault;
 using testing::IgnoreResult;
@@ -68,7 +69,6 @@
 using testing::ReturnNull;
 using testing::ReturnRef;
 using testing::SetArgumentPointee;
-using testing::SetArrayArgument;
 
 #ifndef _WIN32_WCE
 using testing::SetErrnoAndReturn;
@@ -743,85 +743,6 @@
 
 #endif  // GMOCK_HAS_PROTOBUF_
 
-// Tests that SetArrayArgument<N>(first, last) sets the elements of the array
-// pointed to by the N-th (0-based) argument to values in range [first, last).
-TEST(SetArrayArgumentTest, SetsTheNthArray) {
-  typedef void MyFunction(bool, int*, char*);
-  int numbers[] = { 1, 2, 3 };
-  Action<MyFunction> a = SetArrayArgument<1>(numbers, numbers + 3);
-
-  int n[4] = {};
-  int* pn = n;
-  char ch[4] = {};
-  char* pch = ch;
-  a.Perform(make_tuple(true, pn, pch));
-  EXPECT_EQ(1, n[0]);
-  EXPECT_EQ(2, n[1]);
-  EXPECT_EQ(3, n[2]);
-  EXPECT_EQ(0, n[3]);
-  EXPECT_EQ('\0', ch[0]);
-  EXPECT_EQ('\0', ch[1]);
-  EXPECT_EQ('\0', ch[2]);
-  EXPECT_EQ('\0', ch[3]);
-
-  // Tests first and last are iterators.
-  std::string letters = "abc";
-  a = SetArrayArgument<2>(letters.begin(), letters.end());
-  std::fill_n(n, 4, 0);
-  std::fill_n(ch, 4, '\0');
-  a.Perform(make_tuple(true, pn, pch));
-  EXPECT_EQ(0, n[0]);
-  EXPECT_EQ(0, n[1]);
-  EXPECT_EQ(0, n[2]);
-  EXPECT_EQ(0, n[3]);
-  EXPECT_EQ('a', ch[0]);
-  EXPECT_EQ('b', ch[1]);
-  EXPECT_EQ('c', ch[2]);
-  EXPECT_EQ('\0', ch[3]);
-}
-
-// Tests SetArrayArgument<N>(first, last) where first == last.
-TEST(SetArrayArgumentTest, SetsTheNthArrayWithEmptyRange) {
-  typedef void MyFunction(bool, int*);
-  int numbers[] = { 1, 2, 3 };
-  Action<MyFunction> a = SetArrayArgument<1>(numbers, numbers);
-
-  int n[4] = {};
-  int* pn = n;
-  a.Perform(make_tuple(true, pn));
-  EXPECT_EQ(0, n[0]);
-  EXPECT_EQ(0, n[1]);
-  EXPECT_EQ(0, n[2]);
-  EXPECT_EQ(0, n[3]);
-}
-
-// Tests SetArrayArgument<N>(first, last) where *first is convertible
-// (but not equal) to the argument type.
-TEST(SetArrayArgumentTest, SetsTheNthArrayWithConvertibleType) {
-  typedef void MyFunction(bool, char*);
-  int codes[] = { 97, 98, 99 };
-  Action<MyFunction> a = SetArrayArgument<1>(codes, codes + 3);
-
-  char ch[4] = {};
-  char* pch = ch;
-  a.Perform(make_tuple(true, pch));
-  EXPECT_EQ('a', ch[0]);
-  EXPECT_EQ('b', ch[1]);
-  EXPECT_EQ('c', ch[2]);
-  EXPECT_EQ('\0', ch[3]);
-}
-
-// Test SetArrayArgument<N>(first, last) with iterator as argument.
-TEST(SetArrayArgumentTest, SetsTheNthArrayWithIteratorArgument) {
-  typedef void MyFunction(bool, std::back_insert_iterator<std::string>);
-  std::string letters = "abc";
-  Action<MyFunction> a = SetArrayArgument<1>(letters.begin(), letters.end());
-
-  std::string s;
-  a.Perform(make_tuple(true, back_inserter(s)));
-  EXPECT_EQ(letters, s);
-}
-
 // Sample functions and functors for testing Invoke() and etc.
 int Nullary() { return 1; }
 
@@ -1031,4 +952,87 @@
 
 #endif  // _WIN32_WCE
 
+// Tests ByRef().
+
+// Tests that ReferenceWrapper<T> is copyable.
+TEST(ByRefTest, IsCopyable) {
+  const std::string s1 = "Hi";
+  const std::string s2 = "Hello";
+
+  ::testing::internal::ReferenceWrapper<const std::string> ref_wrapper = ByRef(s1);
+  const std::string& r1 = ref_wrapper;
+  EXPECT_EQ(&s1, &r1);
+
+  // Assigns a new value to ref_wrapper.
+  ref_wrapper = ByRef(s2);
+  const std::string& r2 = ref_wrapper;
+  EXPECT_EQ(&s2, &r2);
+
+  ::testing::internal::ReferenceWrapper<const std::string> ref_wrapper1 = ByRef(s1);
+  // Copies ref_wrapper1 to ref_wrapper.
+  ref_wrapper = ref_wrapper1;
+  const std::string& r3 = ref_wrapper;
+  EXPECT_EQ(&s1, &r3);
+}
+
+// Tests using ByRef() on a const value.
+TEST(ByRefTest, ConstValue) {
+  const int n = 0;
+  // int& ref = ByRef(n);  // This shouldn't compile - we have a
+                           // negative compilation test to catch it.
+  const int& const_ref = ByRef(n);
+  EXPECT_EQ(&n, &const_ref);
+}
+
+// Tests using ByRef() on a non-const value.
+TEST(ByRefTest, NonConstValue) {
+  int n = 0;
+
+  // ByRef(n) can be used as either an int&,
+  int& ref = ByRef(n);
+  EXPECT_EQ(&n, &ref);
+
+  // or a const int&.
+  const int& const_ref = ByRef(n);
+  EXPECT_EQ(&n, &const_ref);
+}
+
+// Tests explicitly specifying the type when using ByRef().
+TEST(ByRefTest, ExplicitType) {
+  int n = 0;
+  const int& r1 = ByRef<const int>(n);
+  EXPECT_EQ(&n, &r1);
+
+  // ByRef<char>(n);  // This shouldn't compile - we have a negative
+                      // compilation test to catch it.
+
+  Derived d;
+  Derived& r2 = ByRef<Derived>(d);
+  EXPECT_EQ(&d, &r2);
+
+  const Derived& r3 = ByRef<const Derived>(d);
+  EXPECT_EQ(&d, &r3);
+
+  Base& r4 = ByRef<Base>(d);
+  EXPECT_EQ(&d, &r4);
+
+  const Base& r5 = ByRef<const Base>(d);
+  EXPECT_EQ(&d, &r5);
+
+  // The following shouldn't compile - we have a negative compilation
+  // test for it.
+  //
+  // Base b;
+  // ByRef<Derived>(b);
+}
+
+// Tests that Google Mock prints expression ByRef(x) as a reference to x.
+TEST(ByRefTest, PrintsCorrectly) {
+  int n = 42;
+  ::std::stringstream expected, actual;
+  testing::internal::UniversalPrinter<const int&>::Print(n, &expected);
+  testing::internal::UniversalPrint(ByRef(n), &actual);
+  EXPECT_EQ(expected.str(), actual.str());
+}
+
 }  // Unnamed namespace
diff --git a/test/gmock-generated-actions_test.cc b/test/gmock-generated-actions_test.cc
index 885097c..2e6fa0b 100644
--- a/test/gmock-generated-actions_test.cc
+++ b/test/gmock-generated-actions_test.cc
@@ -54,23 +54,16 @@
 using testing::Action;
 using testing::ActionInterface;
 using testing::ByRef;
-using testing::DeleteArg;
 using testing::DoAll;
 using testing::Invoke;
-using testing::InvokeArgument;
 using testing::Return;
-using testing::ReturnArg;
 using testing::ReturnNew;
-using testing::SaveArg;
-using testing::SetArgReferee;
 using testing::SetArgumentPointee;
 using testing::StaticAssertTypeEq;
 using testing::Unused;
-using testing::WithArg;
 using testing::WithArgs;
-using testing::WithoutArgs;
 
-// Sample functions and functors for testing Invoke() and etc.
+// Sample functions and functors for testing various actions.
 int Nullary() { return 1; }
 
 class NullaryFunctor {
@@ -79,19 +72,11 @@
 };
 
 bool g_done = false;
-void VoidNullary() { g_done = true; }
-
-class VoidNullaryFunctor {
- public:
-  void operator()() { g_done = true; }
-};
 
 bool Unary(int x) { return x < 0; }
 
 const char* Plus1(const char* s) { return s + 1; }
 
-void VoidUnary(int n) { g_done = true; }
-
 bool ByConstRef(const string& s) { return s == "Hi"; }
 
 const double g_double = 0;
@@ -113,10 +98,6 @@
 
 int SumOf4(int a, int b, int c, int d) { return a + b + c + d; }
 
-int SumOfFirst2(int a, int b, Unused, Unused) { return a + b; }
-
-void VoidFunctionWithFourArguments(char, int, float, double) { g_done = true; }
-
 string Concat4(const char* s1, const char* s2, const char* s3,
                const char* s4) {
   return string(s1) + s2 + s3 + s4;
@@ -175,388 +156,10 @@
   return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10;
 }
 
-class Foo {
- public:
-  Foo() : value_(123) {}
-
-  int Nullary() const { return value_; }
-
-  short Unary(long x) { return static_cast<short>(value_ + x); }  // NOLINT
-
-  string Binary(const string& str, char c) const { return str + c; }
-
-  int Ternary(int x, bool y, char z) { return value_ + x + y*z; }
-
-  int SumOf4(int a, int b, int c, int d) const {
-    return a + b + c + d + value_;
-  }
-
-  int SumOfLast2(Unused, Unused, int a, int b) const { return a + b; }
-
-  int SumOf5(int a, int b, int c, int d, int e) { return a + b + c + d + e; }
-
-  int SumOf6(int a, int b, int c, int d, int e, int f) {
-    return a + b + c + d + e + f;
-  }
-
-  string Concat7(const char* s1, const char* s2, const char* s3,
-                 const char* s4, const char* s5, const char* s6,
-                 const char* s7) {
-    return string(s1) + s2 + s3 + s4 + s5 + s6 + s7;
-  }
-
-  string Concat8(const char* s1, const char* s2, const char* s3,
-                 const char* s4, const char* s5, const char* s6,
-                 const char* s7, const char* s8) {
-    return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8;
-  }
-
-  string Concat9(const char* s1, const char* s2, const char* s3,
-                 const char* s4, const char* s5, const char* s6,
-                 const char* s7, const char* s8, const char* s9) {
-    return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9;
-  }
-
-  string Concat10(const char* s1, const char* s2, const char* s3,
-                  const char* s4, const char* s5, const char* s6,
-                  const char* s7, const char* s8, const char* s9,
-                  const char* s10) {
-    return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10;
-  }
- private:
-  int value_;
-};
-
-// Tests using Invoke() with a nullary function.
-TEST(InvokeTest, Nullary) {
-  Action<int()> a = Invoke(Nullary);  // NOLINT
-  EXPECT_EQ(1, a.Perform(make_tuple()));
-}
-
-// Tests using Invoke() with a unary function.
-TEST(InvokeTest, Unary) {
-  Action<bool(int)> a = Invoke(Unary);  // NOLINT
-  EXPECT_FALSE(a.Perform(make_tuple(1)));
-  EXPECT_TRUE(a.Perform(make_tuple(-1)));
-}
-
-// Tests using Invoke() with a binary function.
-TEST(InvokeTest, Binary) {
-  Action<const char*(const char*, short)> a = Invoke(Binary);  // NOLINT
-  const char* p = "Hello";
-  EXPECT_EQ(p + 2, a.Perform(make_tuple(p, 2)));
-}
-
-// Tests using Invoke() with a ternary function.
-TEST(InvokeTest, Ternary) {
-  Action<int(int, char, short)> a = Invoke(Ternary);  // NOLINT
-  EXPECT_EQ(6, a.Perform(make_tuple(1, '\2', 3)));
-}
-
-// Tests using Invoke() with a 4-argument function.
-TEST(InvokeTest, FunctionThatTakes4Arguments) {
-  Action<int(int, int, int, int)> a = Invoke(SumOf4);  // NOLINT
-  EXPECT_EQ(1234, a.Perform(make_tuple(1000, 200, 30, 4)));
-}
-
-// Tests using Invoke() with a 5-argument function.
-TEST(InvokeTest, FunctionThatTakes5Arguments) {
-  Action<int(int, int, int, int, int)> a = Invoke(SumOf5);  // NOLINT
-  EXPECT_EQ(12345, a.Perform(make_tuple(10000, 2000, 300, 40, 5)));
-}
-
-// Tests using Invoke() with a 6-argument function.
-TEST(InvokeTest, FunctionThatTakes6Arguments) {
-  Action<int(int, int, int, int, int, int)> a = Invoke(SumOf6);  // NOLINT
-  EXPECT_EQ(123456, a.Perform(make_tuple(100000, 20000, 3000, 400, 50, 6)));
-}
-
 // A helper that turns the type of a C-string literal from const
 // char[N] to const char*.
 inline const char* CharPtr(const char* s) { return s; }
 
-// Tests using Invoke() with a 7-argument function.
-TEST(InvokeTest, FunctionThatTakes7Arguments) {
-  Action<string(const char*, const char*, const char*, const char*,
-                const char*, const char*, const char*)> a =
-      Invoke(Concat7);
-  EXPECT_EQ("1234567",
-            a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
-                                 CharPtr("4"), CharPtr("5"), CharPtr("6"),
-                                 CharPtr("7"))));
-}
-
-// Tests using Invoke() with a 8-argument function.
-TEST(InvokeTest, FunctionThatTakes8Arguments) {
-  Action<string(const char*, const char*, const char*, const char*,
-                const char*, const char*, const char*, const char*)> a =
-      Invoke(Concat8);
-  EXPECT_EQ("12345678",
-            a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
-                                 CharPtr("4"), CharPtr("5"), CharPtr("6"),
-                                 CharPtr("7"), CharPtr("8"))));
-}
-
-// Tests using Invoke() with a 9-argument function.
-TEST(InvokeTest, FunctionThatTakes9Arguments) {
-  Action<string(const char*, const char*, const char*, const char*,
-                const char*, const char*, const char*, const char*,
-                const char*)> a = Invoke(Concat9);
-  EXPECT_EQ("123456789",
-            a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
-                                 CharPtr("4"), CharPtr("5"), CharPtr("6"),
-                                 CharPtr("7"), CharPtr("8"), CharPtr("9"))));
-}
-
-// Tests using Invoke() with a 10-argument function.
-TEST(InvokeTest, FunctionThatTakes10Arguments) {
-  Action<string(const char*, const char*, const char*, const char*,
-                const char*, const char*, const char*, const char*,
-                const char*, const char*)> a = Invoke(Concat10);
-  EXPECT_EQ("1234567890",
-            a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
-                                 CharPtr("4"), CharPtr("5"), CharPtr("6"),
-                                 CharPtr("7"), CharPtr("8"), CharPtr("9"),
-                                 CharPtr("0"))));
-}
-
-// Tests using Invoke() with functions with parameters declared as Unused.
-TEST(InvokeTest, FunctionWithUnusedParameters) {
-  Action<int(int, int, double, const string&)> a1 =
-      Invoke(SumOfFirst2);
-  EXPECT_EQ(12, a1.Perform(make_tuple(10, 2, 5.6, CharPtr("hi"))));
-
-  Action<int(int, int, bool, int*)> a2 =
-      Invoke(SumOfFirst2);
-  EXPECT_EQ(23, a2.Perform(make_tuple(20, 3, true, static_cast<int*>(NULL))));
-}
-
-// Tests using Invoke() with methods with parameters declared as Unused.
-TEST(InvokeTest, MethodWithUnusedParameters) {
-  Foo foo;
-  Action<int(string, bool, int, int)> a1 =
-      Invoke(&foo, &Foo::SumOfLast2);
-  EXPECT_EQ(12, a1.Perform(make_tuple(CharPtr("hi"), true, 10, 2)));
-
-  Action<int(char, double, int, int)> a2 =
-      Invoke(&foo, &Foo::SumOfLast2);
-  EXPECT_EQ(23, a2.Perform(make_tuple('a', 2.5, 20, 3)));
-}
-
-// Tests using Invoke() with a functor.
-TEST(InvokeTest, Functor) {
-  Action<int(short, char)> a = Invoke(plus<short>());  // NOLINT
-  EXPECT_EQ(3, a.Perform(make_tuple(1, 2)));
-}
-
-// Tests using Invoke(f) as an action of a compatible type.
-TEST(InvokeTest, FunctionWithCompatibleType) {
-  Action<long(int, short, char, bool)> a = Invoke(SumOf4);  // NOLINT
-  EXPECT_EQ(4321, a.Perform(make_tuple(4000, 300, 20, true)));
-}
-
-// Tests using Invoke() with an object pointer and a method pointer.
-
-// Tests using Invoke() with a nullary method.
-TEST(InvokeMethodTest, Nullary) {
-  Foo foo;
-  Action<int()> a = Invoke(&foo, &Foo::Nullary);  // NOLINT
-  EXPECT_EQ(123, a.Perform(make_tuple()));
-}
-
-// Tests using Invoke() with a unary method.
-TEST(InvokeMethodTest, Unary) {
-  Foo foo;
-  Action<short(long)> a = Invoke(&foo, &Foo::Unary);  // NOLINT
-  EXPECT_EQ(4123, a.Perform(make_tuple(4000)));
-}
-
-// Tests using Invoke() with a binary method.
-TEST(InvokeMethodTest, Binary) {
-  Foo foo;
-  Action<string(const string&, char)> a = Invoke(&foo, &Foo::Binary);
-  string s("Hell");
-  EXPECT_EQ("Hello", a.Perform(make_tuple(s, 'o')));
-}
-
-// Tests using Invoke() with a ternary method.
-TEST(InvokeMethodTest, Ternary) {
-  Foo foo;
-  Action<int(int, bool, char)> a = Invoke(&foo, &Foo::Ternary);  // NOLINT
-  EXPECT_EQ(1124, a.Perform(make_tuple(1000, true, 1)));
-}
-
-// Tests using Invoke() with a 4-argument method.
-TEST(InvokeMethodTest, MethodThatTakes4Arguments) {
-  Foo foo;
-  Action<int(int, int, int, int)> a = Invoke(&foo, &Foo::SumOf4);  // NOLINT
-  EXPECT_EQ(1357, a.Perform(make_tuple(1000, 200, 30, 4)));
-}
-
-// Tests using Invoke() with a 5-argument method.
-TEST(InvokeMethodTest, MethodThatTakes5Arguments) {
-  Foo foo;
-  Action<int(int, int, int, int, int)> a = Invoke(&foo, &Foo::SumOf5);  // NOLINT
-  EXPECT_EQ(12345, a.Perform(make_tuple(10000, 2000, 300, 40, 5)));
-}
-
-// Tests using Invoke() with a 6-argument method.
-TEST(InvokeMethodTest, MethodThatTakes6Arguments) {
-  Foo foo;
-  Action<int(int, int, int, int, int, int)> a =  // NOLINT
-      Invoke(&foo, &Foo::SumOf6);
-  EXPECT_EQ(123456, a.Perform(make_tuple(100000, 20000, 3000, 400, 50, 6)));
-}
-
-// Tests using Invoke() with a 7-argument method.
-TEST(InvokeMethodTest, MethodThatTakes7Arguments) {
-  Foo foo;
-  Action<string(const char*, const char*, const char*, const char*,
-                const char*, const char*, const char*)> a =
-      Invoke(&foo, &Foo::Concat7);
-  EXPECT_EQ("1234567",
-            a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
-                                 CharPtr("4"), CharPtr("5"), CharPtr("6"),
-                                 CharPtr("7"))));
-}
-
-// Tests using Invoke() with a 8-argument method.
-TEST(InvokeMethodTest, MethodThatTakes8Arguments) {
-  Foo foo;
-  Action<string(const char*, const char*, const char*, const char*,
-                const char*, const char*, const char*, const char*)> a =
-      Invoke(&foo, &Foo::Concat8);
-  EXPECT_EQ("12345678",
-            a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
-                                 CharPtr("4"), CharPtr("5"), CharPtr("6"),
-                                 CharPtr("7"), CharPtr("8"))));
-}
-
-// Tests using Invoke() with a 9-argument method.
-TEST(InvokeMethodTest, MethodThatTakes9Arguments) {
-  Foo foo;
-  Action<string(const char*, const char*, const char*, const char*,
-                const char*, const char*, const char*, const char*,
-                const char*)> a = Invoke(&foo, &Foo::Concat9);
-  EXPECT_EQ("123456789",
-            a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
-                                 CharPtr("4"), CharPtr("5"), CharPtr("6"),
-                                 CharPtr("7"), CharPtr("8"), CharPtr("9"))));
-}
-
-// Tests using Invoke() with a 10-argument method.
-TEST(InvokeMethodTest, MethodThatTakes10Arguments) {
-  Foo foo;
-  Action<string(const char*, const char*, const char*, const char*,
-                const char*, const char*, const char*, const char*,
-                const char*, const char*)> a = Invoke(&foo, &Foo::Concat10);
-  EXPECT_EQ("1234567890",
-            a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
-                                 CharPtr("4"), CharPtr("5"), CharPtr("6"),
-                                 CharPtr("7"), CharPtr("8"), CharPtr("9"),
-                                 CharPtr("0"))));
-}
-
-// Tests using Invoke(f) as an action of a compatible type.
-TEST(InvokeMethodTest, MethodWithCompatibleType) {
-  Foo foo;
-  Action<long(int, short, char, bool)> a =  // NOLINT
-      Invoke(&foo, &Foo::SumOf4);
-  EXPECT_EQ(4444, a.Perform(make_tuple(4000, 300, 20, true)));
-}
-
-// Tests ByRef().
-
-// Tests that ReferenceWrapper<T> is copyable.
-TEST(ByRefTest, IsCopyable) {
-  const string s1 = "Hi";
-  const string s2 = "Hello";
-
-  ::testing::internal::ReferenceWrapper<const string> ref_wrapper = ByRef(s1);
-  const string& r1 = ref_wrapper;
-  EXPECT_EQ(&s1, &r1);
-
-  // Assigns a new value to ref_wrapper.
-  ref_wrapper = ByRef(s2);
-  const string& r2 = ref_wrapper;
-  EXPECT_EQ(&s2, &r2);
-
-  ::testing::internal::ReferenceWrapper<const string> ref_wrapper1 = ByRef(s1);
-  // Copies ref_wrapper1 to ref_wrapper.
-  ref_wrapper = ref_wrapper1;
-  const string& r3 = ref_wrapper;
-  EXPECT_EQ(&s1, &r3);
-}
-
-// Tests using ByRef() on a const value.
-TEST(ByRefTest, ConstValue) {
-  const int n = 0;
-  // int& ref = ByRef(n);  // This shouldn't compile - we have a
-                           // negative compilation test to catch it.
-  const int& const_ref = ByRef(n);
-  EXPECT_EQ(&n, &const_ref);
-}
-
-// Tests using ByRef() on a non-const value.
-TEST(ByRefTest, NonConstValue) {
-  int n = 0;
-
-  // ByRef(n) can be used as either an int&,
-  int& ref = ByRef(n);
-  EXPECT_EQ(&n, &ref);
-
-  // or a const int&.
-  const int& const_ref = ByRef(n);
-  EXPECT_EQ(&n, &const_ref);
-}
-
-struct Base {
-  bool operator==(const Base&) { return true; }
-};
-
-struct Derived : public Base {
-  bool operator==(const Derived&) { return true; }
-};
-
-// Tests explicitly specifying the type when using ByRef().
-TEST(ByRefTest, ExplicitType) {
-  int n = 0;
-  const int& r1 = ByRef<const int>(n);
-  EXPECT_EQ(&n, &r1);
-
-  // ByRef<char>(n);  // This shouldn't compile - we have a negative
-                      // compilation test to catch it.
-
-
-  Derived d;
-  Derived& r2 = ByRef<Derived>(d);
-  EXPECT_EQ(&d, &r2);
-
-  const Derived& r3 = ByRef<const Derived>(d);
-  EXPECT_EQ(&d, &r3);
-
-  Base& r4 = ByRef<Base>(d);
-  EXPECT_EQ(&d, &r4);
-
-  const Base& r5 = ByRef<const Base>(d);
-  EXPECT_EQ(&d, &r5);
-
-  // The following shouldn't compile - we have a negative compilation
-  // test for it.
-  //
-  // Base b;
-  // ByRef<Derived>(b);
-}
-
-// Tests that Google Mock prints expression ByRef(x) as a reference to x.
-TEST(ByRefTest, PrintsCorrectly) {
-  int n = 42;
-  ::std::stringstream expected, actual;
-  testing::internal::UniversalPrinter<const int&>::Print(n, &expected);
-  testing::internal::UniversalPrint(ByRef(n), &actual);
-  EXPECT_EQ(expected.str(), actual.str());
-}
-
 // Tests InvokeArgument<N>(...).
 
 // Tests using InvokeArgument with a nullary function.
@@ -674,23 +277,11 @@
   EXPECT_FALSE(a.Perform(make_tuple(&ReferencesGlobalDouble)));
 }
 
-// Tests using WithoutArgs with an action that takes no argument.
-TEST(WithoutArgsTest, NoArg) {
-  Action<int(int n)> a = WithoutArgs(Invoke(Nullary));  // NOLINT
-  EXPECT_EQ(1, a.Perform(make_tuple(2)));
-}
-
-// Tests using WithArgs and WithArg with an action that takes 1 argument.
+// Tests using WithArgs and with an action that takes 1 argument.
 TEST(WithArgsTest, OneArg) {
   Action<bool(double x, int n)> a = WithArgs<1>(Invoke(Unary));  // NOLINT
   EXPECT_TRUE(a.Perform(make_tuple(1.5, -1)));
   EXPECT_FALSE(a.Perform(make_tuple(1.5, 1)));
-
-  // Also tests the synonym WithArg.
-  Action<bool(double x, int n)> b = WithArg<1>(Invoke(Unary));  // NOLINT
-  EXPECT_TRUE(a.Perform(make_tuple(1.5, -1)));
-  EXPECT_FALSE(a.Perform(make_tuple(1.5, 1)));
-
 }
 
 // Tests using WithArgs with an action that takes 2 arguments.
@@ -1383,56 +974,6 @@
   EXPECT_EQ(55, a.Perform(empty));
 }
 
-TEST(ReturnArgActionTest, WorksForOneArgIntArg0) {
-  const Action<int(int)> a = ReturnArg<0>();
-  EXPECT_EQ(5, a.Perform(make_tuple(5)));
-}
-
-TEST(ReturnArgActionTest, WorksForMultiArgBoolArg0) {
-  const Action<bool(bool, bool, bool)> a = ReturnArg<0>();
-  EXPECT_TRUE(a.Perform(make_tuple(true, false, false)));
-}
-
-TEST(ReturnArgActionTest, WorksForMultiArgStringArg2) {
-  const Action<string(int, int, string, int)> a = ReturnArg<2>();
-  EXPECT_EQ("seven", a.Perform(make_tuple(5, 6, string("seven"), 8)));
-}
-
-TEST(SaveArgActionTest, WorksForSameType) {
-  int result = 0;
-  const Action<void(int n)> a1 = SaveArg<0>(&result);
-  a1.Perform(make_tuple(5));
-  EXPECT_EQ(5, result);
-}
-
-TEST(SaveArgActionTest, WorksForCompatibleType) {
-  int result = 0;
-  const Action<void(bool, char)> a1 = SaveArg<1>(&result);
-  a1.Perform(make_tuple(true, 'a'));
-  EXPECT_EQ('a', result);
-}
-
-TEST(SetArgRefereeActionTest, WorksForSameType) {
-  int value = 0;
-  const Action<void(int&)> a1 = SetArgReferee<0>(1);
-  a1.Perform(tuple<int&>(value));
-  EXPECT_EQ(1, value);
-}
-
-TEST(SetArgRefereeActionTest, WorksForCompatibleType) {
-  int value = 0;
-  const Action<void(int, int&)> a1 = SetArgReferee<1>('a');
-  a1.Perform(tuple<int, int&>(0, value));
-  EXPECT_EQ('a', value);
-}
-
-TEST(SetArgRefereeActionTest, WorksWithExtraArguments) {
-  int value = 0;
-  const Action<void(bool, int, int&, const char*)> a1 = SetArgReferee<2>('a');
-  a1.Perform(tuple<bool, int, int&, const char*>(true, 0, value, "hi"));
-  EXPECT_EQ('a', value);
-}
-
 class NullaryConstructorClass {
  public:
   NullaryConstructorClass() : value_(123) {}
@@ -1497,64 +1038,6 @@
   delete c;
 }
 
-// A class that can be used to verify that its destructor is called: it will set
-// the bool provided to the constructor to true when destroyed.
-class DeletionTester {
- public:
-  explicit DeletionTester(bool* is_deleted)
-    : is_deleted_(is_deleted) {
-    // Make sure the bit is set to false.
-    *is_deleted_ = false;
-  }
-
-  ~DeletionTester() {
-    *is_deleted_ = true;
-  }
-
- private:
-  bool* is_deleted_;
-};
-
-TEST(DeleteArgActionTest, OneArg) {
-  bool is_deleted = false;
-  DeletionTester* t = new DeletionTester(&is_deleted);
-  const Action<void(DeletionTester*)> a1 = DeleteArg<0>();      // NOLINT
-  EXPECT_FALSE(is_deleted);
-  a1.Perform(make_tuple(t));
-  EXPECT_TRUE(is_deleted);
-}
-
-TEST(DeleteArgActionTest, TenArgs) {
-  bool is_deleted = false;
-  DeletionTester* t = new DeletionTester(&is_deleted);
-  const Action<void(bool, int, int, const char*, bool,
-                    int, int, int, int, DeletionTester*)> a1 = DeleteArg<9>();
-  EXPECT_FALSE(is_deleted);
-  a1.Perform(make_tuple(true, 5, 6, CharPtr("hi"), false, 7, 8, 9, 10, t));
-  EXPECT_TRUE(is_deleted);
-}
-
-#if GTEST_HAS_EXCEPTIONS
-
-TEST(ThrowActionTest, ThrowsGivenExceptionInVoidFunction) {
-  const Action<void(int n)> a = Throw('a');
-  EXPECT_THROW(a.Perform(make_tuple(0)), char);
-}
-
-class MyException {};
-
-TEST(ThrowActionTest, ThrowsGivenExceptionInNonVoidFunction) {
-  const Action<double(char ch)> a = Throw(MyException());
-  EXPECT_THROW(a.Perform(make_tuple('0')), MyException);
-}
-
-TEST(ThrowActionTest, ThrowsGivenExceptionInNullaryFunction) {
-  const Action<double()> a = Throw(MyException());
-  EXPECT_THROW(a.Perform(make_tuple()), MyException);
-}
-
-#endif  // GTEST_HAS_EXCEPTIONS
-
 // Tests that ACTION_TEMPLATE works when there is no value parameter.
 ACTION_TEMPLATE(CreateNew,
                 HAS_1_TEMPLATE_PARAMS(typename, T),
diff --git a/test/gmock-more-actions_test.cc b/test/gmock-more-actions_test.cc
new file mode 100644
index 0000000..9507776
--- /dev/null
+++ b/test/gmock-more-actions_test.cc
@@ -0,0 +1,796 @@
+// Copyright 2007, 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 file tests the built-in actions in gmock-more-actions.h.
+
+#include <gmock/gmock-more-actions.h>
+
+#include <functional>
+#include <sstream>
+#include <string>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+namespace testing {
+namespace gmock_more_actions_test {
+
+using ::std::plus;
+using ::std::string;
+using ::std::tr1::get;
+using ::std::tr1::make_tuple;
+using ::std::tr1::tuple;
+using ::std::tr1::tuple_element;
+using testing::_;
+using testing::Action;
+using testing::ActionInterface;
+using testing::DeleteArg;
+using testing::Invoke;
+using testing::Return;
+using testing::ReturnArg;
+using testing::SaveArg;
+using testing::SetArgReferee;
+using testing::SetArgumentPointee;
+using testing::StaticAssertTypeEq;
+using testing::Unused;
+using testing::WithArg;
+using testing::WithoutArgs;
+
+// Sample functions and functors for testing Invoke() and etc.
+int Nullary() { return 1; }
+
+class NullaryFunctor {
+ public:
+  int operator()() { return 2; }
+};
+
+bool g_done = false;
+void VoidNullary() { g_done = true; }
+
+class VoidNullaryFunctor {
+ public:
+  void operator()() { g_done = true; }
+};
+
+bool Unary(int x) { return x < 0; }
+
+const char* Plus1(const char* s) { return s + 1; }
+
+void VoidUnary(int n) { g_done = true; }
+
+bool ByConstRef(const string& s) { return s == "Hi"; }
+
+const double g_double = 0;
+bool ReferencesGlobalDouble(const double& x) { return &x == &g_double; }
+
+string ByNonConstRef(string& s) { return s += "+"; }  // NOLINT
+
+struct UnaryFunctor {
+  int operator()(bool x) { return x ? 1 : -1; }
+};
+
+const char* Binary(const char* input, short n) { return input + n; }  // NOLINT
+
+void VoidBinary(int, char) { g_done = true; }
+
+int Ternary(int x, char y, short z) { return x + y + z; }  // NOLINT
+
+void VoidTernary(int, char, bool) { g_done = true; }
+
+int SumOf4(int a, int b, int c, int d) { return a + b + c + d; }
+
+int SumOfFirst2(int a, int b, Unused, Unused) { return a + b; }
+
+void VoidFunctionWithFourArguments(char, int, float, double) { g_done = true; }
+
+string Concat4(const char* s1, const char* s2, const char* s3,
+               const char* s4) {
+  return string(s1) + s2 + s3 + s4;
+}
+
+int SumOf5(int a, int b, int c, int d, int e) { return a + b + c + d + e; }
+
+struct SumOf5Functor {
+  int operator()(int a, int b, int c, int d, int e) {
+    return a + b + c + d + e;
+  }
+};
+
+string Concat5(const char* s1, const char* s2, const char* s3,
+               const char* s4, const char* s5) {
+  return string(s1) + s2 + s3 + s4 + s5;
+}
+
+int SumOf6(int a, int b, int c, int d, int e, int f) {
+  return a + b + c + d + e + f;
+}
+
+struct SumOf6Functor {
+  int operator()(int a, int b, int c, int d, int e, int f) {
+    return a + b + c + d + e + f;
+  }
+};
+
+string Concat6(const char* s1, const char* s2, const char* s3,
+               const char* s4, const char* s5, const char* s6) {
+  return string(s1) + s2 + s3 + s4 + s5 + s6;
+}
+
+string Concat7(const char* s1, const char* s2, const char* s3,
+               const char* s4, const char* s5, const char* s6,
+               const char* s7) {
+  return string(s1) + s2 + s3 + s4 + s5 + s6 + s7;
+}
+
+string Concat8(const char* s1, const char* s2, const char* s3,
+               const char* s4, const char* s5, const char* s6,
+               const char* s7, const char* s8) {
+  return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8;
+}
+
+string Concat9(const char* s1, const char* s2, const char* s3,
+               const char* s4, const char* s5, const char* s6,
+               const char* s7, const char* s8, const char* s9) {
+  return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9;
+}
+
+string Concat10(const char* s1, const char* s2, const char* s3,
+                const char* s4, const char* s5, const char* s6,
+                const char* s7, const char* s8, const char* s9,
+                const char* s10) {
+  return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10;
+}
+
+class Foo {
+ public:
+  Foo() : value_(123) {}
+
+  int Nullary() const { return value_; }
+
+  short Unary(long x) { return static_cast<short>(value_ + x); }  // NOLINT
+
+  string Binary(const string& str, char c) const { return str + c; }
+
+  int Ternary(int x, bool y, char z) { return value_ + x + y*z; }
+
+  int SumOf4(int a, int b, int c, int d) const {
+    return a + b + c + d + value_;
+  }
+
+  int SumOfLast2(Unused, Unused, int a, int b) const { return a + b; }
+
+  int SumOf5(int a, int b, int c, int d, int e) { return a + b + c + d + e; }
+
+  int SumOf6(int a, int b, int c, int d, int e, int f) {
+    return a + b + c + d + e + f;
+  }
+
+  string Concat7(const char* s1, const char* s2, const char* s3,
+                 const char* s4, const char* s5, const char* s6,
+                 const char* s7) {
+    return string(s1) + s2 + s3 + s4 + s5 + s6 + s7;
+  }
+
+  string Concat8(const char* s1, const char* s2, const char* s3,
+                 const char* s4, const char* s5, const char* s6,
+                 const char* s7, const char* s8) {
+    return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8;
+  }
+
+  string Concat9(const char* s1, const char* s2, const char* s3,
+                 const char* s4, const char* s5, const char* s6,
+                 const char* s7, const char* s8, const char* s9) {
+    return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9;
+  }
+
+  string Concat10(const char* s1, const char* s2, const char* s3,
+                  const char* s4, const char* s5, const char* s6,
+                  const char* s7, const char* s8, const char* s9,
+                  const char* s10) {
+    return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10;
+  }
+ private:
+  int value_;
+};
+
+// Tests using Invoke() with a nullary function.
+TEST(InvokeTest, Nullary) {
+  Action<int()> a = Invoke(Nullary);  // NOLINT
+  EXPECT_EQ(1, a.Perform(make_tuple()));
+}
+
+// Tests using Invoke() with a unary function.
+TEST(InvokeTest, Unary) {
+  Action<bool(int)> a = Invoke(Unary);  // NOLINT
+  EXPECT_FALSE(a.Perform(make_tuple(1)));
+  EXPECT_TRUE(a.Perform(make_tuple(-1)));
+}
+
+// Tests using Invoke() with a binary function.
+TEST(InvokeTest, Binary) {
+  Action<const char*(const char*, short)> a = Invoke(Binary);  // NOLINT
+  const char* p = "Hello";
+  EXPECT_EQ(p + 2, a.Perform(make_tuple(p, 2)));
+}
+
+// Tests using Invoke() with a ternary function.
+TEST(InvokeTest, Ternary) {
+  Action<int(int, char, short)> a = Invoke(Ternary);  // NOLINT
+  EXPECT_EQ(6, a.Perform(make_tuple(1, '\2', 3)));
+}
+
+// Tests using Invoke() with a 4-argument function.
+TEST(InvokeTest, FunctionThatTakes4Arguments) {
+  Action<int(int, int, int, int)> a = Invoke(SumOf4);  // NOLINT
+  EXPECT_EQ(1234, a.Perform(make_tuple(1000, 200, 30, 4)));
+}
+
+// Tests using Invoke() with a 5-argument function.
+TEST(InvokeTest, FunctionThatTakes5Arguments) {
+  Action<int(int, int, int, int, int)> a = Invoke(SumOf5);  // NOLINT
+  EXPECT_EQ(12345, a.Perform(make_tuple(10000, 2000, 300, 40, 5)));
+}
+
+// Tests using Invoke() with a 6-argument function.
+TEST(InvokeTest, FunctionThatTakes6Arguments) {
+  Action<int(int, int, int, int, int, int)> a = Invoke(SumOf6);  // NOLINT
+  EXPECT_EQ(123456, a.Perform(make_tuple(100000, 20000, 3000, 400, 50, 6)));
+}
+
+// A helper that turns the type of a C-string literal from const
+// char[N] to const char*.
+inline const char* CharPtr(const char* s) { return s; }
+
+// Tests using Invoke() with a 7-argument function.
+TEST(InvokeTest, FunctionThatTakes7Arguments) {
+  Action<string(const char*, const char*, const char*, const char*,
+                const char*, const char*, const char*)> a =
+      Invoke(Concat7);
+  EXPECT_EQ("1234567",
+            a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
+                                 CharPtr("4"), CharPtr("5"), CharPtr("6"),
+                                 CharPtr("7"))));
+}
+
+// Tests using Invoke() with a 8-argument function.
+TEST(InvokeTest, FunctionThatTakes8Arguments) {
+  Action<string(const char*, const char*, const char*, const char*,
+                const char*, const char*, const char*, const char*)> a =
+      Invoke(Concat8);
+  EXPECT_EQ("12345678",
+            a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
+                                 CharPtr("4"), CharPtr("5"), CharPtr("6"),
+                                 CharPtr("7"), CharPtr("8"))));
+}
+
+// Tests using Invoke() with a 9-argument function.
+TEST(InvokeTest, FunctionThatTakes9Arguments) {
+  Action<string(const char*, const char*, const char*, const char*,
+                const char*, const char*, const char*, const char*,
+                const char*)> a = Invoke(Concat9);
+  EXPECT_EQ("123456789",
+            a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
+                                 CharPtr("4"), CharPtr("5"), CharPtr("6"),
+                                 CharPtr("7"), CharPtr("8"), CharPtr("9"))));
+}
+
+// Tests using Invoke() with a 10-argument function.
+TEST(InvokeTest, FunctionThatTakes10Arguments) {
+  Action<string(const char*, const char*, const char*, const char*,
+                const char*, const char*, const char*, const char*,
+                const char*, const char*)> a = Invoke(Concat10);
+  EXPECT_EQ("1234567890",
+            a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
+                                 CharPtr("4"), CharPtr("5"), CharPtr("6"),
+                                 CharPtr("7"), CharPtr("8"), CharPtr("9"),
+                                 CharPtr("0"))));
+}
+
+// Tests using Invoke() with functions with parameters declared as Unused.
+TEST(InvokeTest, FunctionWithUnusedParameters) {
+  Action<int(int, int, double, const string&)> a1 =
+      Invoke(SumOfFirst2);
+  EXPECT_EQ(12, a1.Perform(make_tuple(10, 2, 5.6, CharPtr("hi"))));
+
+  Action<int(int, int, bool, int*)> a2 =
+      Invoke(SumOfFirst2);
+  EXPECT_EQ(23, a2.Perform(make_tuple(20, 3, true, static_cast<int*>(NULL))));
+}
+
+// Tests using Invoke() with methods with parameters declared as Unused.
+TEST(InvokeTest, MethodWithUnusedParameters) {
+  Foo foo;
+  Action<int(string, bool, int, int)> a1 =
+      Invoke(&foo, &Foo::SumOfLast2);
+  EXPECT_EQ(12, a1.Perform(make_tuple(CharPtr("hi"), true, 10, 2)));
+
+  Action<int(char, double, int, int)> a2 =
+      Invoke(&foo, &Foo::SumOfLast2);
+  EXPECT_EQ(23, a2.Perform(make_tuple('a', 2.5, 20, 3)));
+}
+
+// Tests using Invoke() with a functor.
+TEST(InvokeTest, Functor) {
+  Action<int(short, char)> a = Invoke(plus<short>());  // NOLINT
+  EXPECT_EQ(3, a.Perform(make_tuple(1, 2)));
+}
+
+// Tests using Invoke(f) as an action of a compatible type.
+TEST(InvokeTest, FunctionWithCompatibleType) {
+  Action<long(int, short, char, bool)> a = Invoke(SumOf4);  // NOLINT
+  EXPECT_EQ(4321, a.Perform(make_tuple(4000, 300, 20, true)));
+}
+
+#if GMOCK_HAS_GOOGLE3_CALLBACK_
+
+// Tests IgnoreResult(Invoke(result_callback)).
+TEST(InvokeTest, IgnoreResultOfResultCallback) {
+  ResultCallback<int>* c = NewPermanentCallback(Nullary);
+  Action<void()> a = IgnoreResult(Invoke(c));
+  a.Perform(make_tuple());
+}
+
+// Tests IgnoreResult(Invoke(result_callback4)).
+TEST(InvokeTest, IgnoreResultOfResultCallback4) {
+  ResultCallback4<int, int, int, int, int>* c =
+      NewPermanentCallback(SumOf4);
+  Action<void(int, int, int, int)> a = IgnoreResult(Invoke(c));
+  a.Perform(make_tuple(1, 2, 3, 4));
+}
+
+#endif  // GMOCK_HAS_GOOGLE3_CALLBACK_
+
+// Tests using Invoke() with an object pointer and a method pointer.
+
+// Tests using Invoke() with a nullary method.
+TEST(InvokeMethodTest, Nullary) {
+  Foo foo;
+  Action<int()> a = Invoke(&foo, &Foo::Nullary);  // NOLINT
+  EXPECT_EQ(123, a.Perform(make_tuple()));
+}
+
+// Tests using Invoke() with a unary method.
+TEST(InvokeMethodTest, Unary) {
+  Foo foo;
+  Action<short(long)> a = Invoke(&foo, &Foo::Unary);  // NOLINT
+  EXPECT_EQ(4123, a.Perform(make_tuple(4000)));
+}
+
+// Tests using Invoke() with a binary method.
+TEST(InvokeMethodTest, Binary) {
+  Foo foo;
+  Action<string(const string&, char)> a = Invoke(&foo, &Foo::Binary);
+  string s("Hell");
+  EXPECT_EQ("Hello", a.Perform(make_tuple(s, 'o')));
+}
+
+// Tests using Invoke() with a ternary method.
+TEST(InvokeMethodTest, Ternary) {
+  Foo foo;
+  Action<int(int, bool, char)> a = Invoke(&foo, &Foo::Ternary);  // NOLINT
+  EXPECT_EQ(1124, a.Perform(make_tuple(1000, true, 1)));
+}
+
+// Tests using Invoke() with a 4-argument method.
+TEST(InvokeMethodTest, MethodThatTakes4Arguments) {
+  Foo foo;
+  Action<int(int, int, int, int)> a = Invoke(&foo, &Foo::SumOf4);  // NOLINT
+  EXPECT_EQ(1357, a.Perform(make_tuple(1000, 200, 30, 4)));
+}
+
+// Tests using Invoke() with a 5-argument method.
+TEST(InvokeMethodTest, MethodThatTakes5Arguments) {
+  Foo foo;
+  Action<int(int, int, int, int, int)> a = Invoke(&foo, &Foo::SumOf5);  // NOLINT
+  EXPECT_EQ(12345, a.Perform(make_tuple(10000, 2000, 300, 40, 5)));
+}
+
+// Tests using Invoke() with a 6-argument method.
+TEST(InvokeMethodTest, MethodThatTakes6Arguments) {
+  Foo foo;
+  Action<int(int, int, int, int, int, int)> a =  // NOLINT
+      Invoke(&foo, &Foo::SumOf6);
+  EXPECT_EQ(123456, a.Perform(make_tuple(100000, 20000, 3000, 400, 50, 6)));
+}
+
+// Tests using Invoke() with a 7-argument method.
+TEST(InvokeMethodTest, MethodThatTakes7Arguments) {
+  Foo foo;
+  Action<string(const char*, const char*, const char*, const char*,
+                const char*, const char*, const char*)> a =
+      Invoke(&foo, &Foo::Concat7);
+  EXPECT_EQ("1234567",
+            a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
+                                 CharPtr("4"), CharPtr("5"), CharPtr("6"),
+                                 CharPtr("7"))));
+}
+
+// Tests using Invoke() with a 8-argument method.
+TEST(InvokeMethodTest, MethodThatTakes8Arguments) {
+  Foo foo;
+  Action<string(const char*, const char*, const char*, const char*,
+                const char*, const char*, const char*, const char*)> a =
+      Invoke(&foo, &Foo::Concat8);
+  EXPECT_EQ("12345678",
+            a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
+                                 CharPtr("4"), CharPtr("5"), CharPtr("6"),
+                                 CharPtr("7"), CharPtr("8"))));
+}
+
+// Tests using Invoke() with a 9-argument method.
+TEST(InvokeMethodTest, MethodThatTakes9Arguments) {
+  Foo foo;
+  Action<string(const char*, const char*, const char*, const char*,
+                const char*, const char*, const char*, const char*,
+                const char*)> a = Invoke(&foo, &Foo::Concat9);
+  EXPECT_EQ("123456789",
+            a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
+                                 CharPtr("4"), CharPtr("5"), CharPtr("6"),
+                                 CharPtr("7"), CharPtr("8"), CharPtr("9"))));
+}
+
+// Tests using Invoke() with a 10-argument method.
+TEST(InvokeMethodTest, MethodThatTakes10Arguments) {
+  Foo foo;
+  Action<string(const char*, const char*, const char*, const char*,
+                const char*, const char*, const char*, const char*,
+                const char*, const char*)> a = Invoke(&foo, &Foo::Concat10);
+  EXPECT_EQ("1234567890",
+            a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
+                                 CharPtr("4"), CharPtr("5"), CharPtr("6"),
+                                 CharPtr("7"), CharPtr("8"), CharPtr("9"),
+                                 CharPtr("0"))));
+}
+
+// Tests using Invoke(f) as an action of a compatible type.
+TEST(InvokeMethodTest, MethodWithCompatibleType) {
+  Foo foo;
+  Action<long(int, short, char, bool)> a =  // NOLINT
+      Invoke(&foo, &Foo::SumOf4);
+  EXPECT_EQ(4444, a.Perform(make_tuple(4000, 300, 20, true)));
+}
+
+#if GMOCK_HAS_GOOGLE3_CALLBACK_
+
+// We don't have dedicated tests to verify that Invoke(callback) and
+// InvokeWithoutArgs(callback) delete the callback argument.  Instead,
+// we rely on the heap checker linked in this test program to do that.
+
+// Tests that Invoke(non-permanent-callback) kills the process.
+TEST(InvokeCallbackDeathTest, RejectsNonPermanentCallback) {
+  EXPECT_DEATH({
+    Action<int()> a = Invoke(NewCallback(Nullary));  // NOLINT
+  }, "");
+}
+
+// Tests using Invoke() with a nullary callback.
+TEST(InvokeCallbackTest, Nullary) {
+  // Tests using Invoke(callback) as an action of the exact type.
+  Action<int()> a = Invoke(NewPermanentCallback(Nullary));  // NOLINT
+  EXPECT_EQ(1, a.Perform(make_tuple()));
+
+  // Tests using Invoke(callback) as an action of a compatible type.
+  Action<bool()> a2 = Invoke(NewPermanentCallback(Nullary));  // NOLINT
+  EXPECT_TRUE(a2.Perform(make_tuple()));
+
+  // Tests using Invoke() on a callback that returns void.
+  Action<void()> a3 = Invoke(NewPermanentCallback(VoidNullary));  // NOLINT
+  g_done = false;
+  a3.Perform(make_tuple());
+  EXPECT_TRUE(g_done);
+}
+
+// Tests using Invoke() with a unary callback.
+TEST(InvokeCallbackTest, Unary) {
+  // Tests using Invoke(callback1) as an action of the exact type.
+  Action<bool(int)> a = Invoke(NewPermanentCallback(Unary));  // NOLINT
+  EXPECT_FALSE(a.Perform(make_tuple(1)));
+  EXPECT_TRUE(a.Perform(make_tuple(-1)));
+
+  // Tests using Invoke(callback1) as an action of a compatible type.
+  Action<int(long)> a2 = Invoke(NewPermanentCallback(Unary));  // NOLINT
+  EXPECT_EQ(0, a2.Perform(make_tuple(1L)));
+  EXPECT_EQ(1, a2.Perform(make_tuple(-1L)));
+
+  // Tests using Invoke() on a callback that returns void.
+  Action<void(char)> a3 = Invoke(NewPermanentCallback(VoidUnary));  // NOLINT
+  g_done = false;
+  a3.Perform(make_tuple('a'));
+  EXPECT_TRUE(g_done);
+}
+
+// Tests using Invoke() with a binary callback.
+TEST(InvokeCallbackTest, Binary) {
+  // Tests using Invoke(callback2) as an action of the exact type.
+  Action<const char*(const char*, short)> a =  // NOLINT
+      Invoke(NewPermanentCallback(Binary));
+  const char* p = "Hello";
+  EXPECT_EQ(p + 2, a.Perform(make_tuple(p, 2)));
+
+  // Tests using Invoke(callback2) as an action of a compatible type.
+  Action<bool(char*, int)> a2 =  // NOLINT
+      Invoke(NewPermanentCallback(Binary));
+  char str[] = "Hello";
+  EXPECT_TRUE(a2.Perform(make_tuple(str, 2)));
+
+  // Tests using Invoke() on a callback that returns void.
+  Action<void(char, char)> a3 =
+      Invoke(NewPermanentCallback(VoidBinary));  // NOLINT
+  g_done = false;
+  a3.Perform(make_tuple('a', 'b'));
+  EXPECT_TRUE(g_done);
+}
+
+// Tests using Invoke() with a ternary callback.
+TEST(InvokeCallbackTest, Ternary) {
+  // Tests using Invoke(callback3) as an action of the exact type.
+  Action<int(int, char, short)> a =  // NOLINT
+      Invoke(NewPermanentCallback(Ternary));
+  EXPECT_EQ(6, a.Perform(make_tuple(1, '\2', 3)));
+
+  // Tests using Invoke(callback3) as an action of a compatible type.
+  Action<long(char, int, int)> a2 =  // NOLINT
+      Invoke(NewPermanentCallback(Ternary));
+  EXPECT_EQ(6, a2.Perform(make_tuple('\1', 2, 3)));
+
+  // Tests using Invoke() on a callback that returns void.
+  Action<void(char, char, bool)> a3 =
+      Invoke(NewPermanentCallback(VoidTernary));  // NOLINT
+  g_done = false;
+  a3.Perform(make_tuple('a', 'b', true));
+  EXPECT_TRUE(g_done);
+}
+
+// Tests using Invoke() with a 4-argument callback.
+TEST(InvokeCallbackTest, CallbackThatTakes4Arguments) {
+  // Tests using Invoke(callback4) as an action of the exact type.
+  Action<int(int, int, int, int)> a =  // NOLINT
+      Invoke(NewPermanentCallback(SumOf4));
+  EXPECT_EQ(1234, a.Perform(make_tuple(1000, 200, 30, 4)));
+
+  // Tests using Invoke(callback4) as an action of a compatible type.
+  Action<long(int, short, char, bool)> a2 =  // NOLINT
+      Invoke(NewPermanentCallback(SumOf4));
+  EXPECT_EQ(4321, a2.Perform(make_tuple(4000, 300, 20, true)));
+
+  // Tests using Invoke() on a callback that returns void.
+  Action<void(char, char, double, double)> a3 =
+      Invoke(NewPermanentCallback(VoidFunctionWithFourArguments));  // NOLINT
+  g_done = false;
+  a3.Perform(make_tuple('a', 'b', 0, 1));
+  EXPECT_TRUE(g_done);
+}
+
+#endif  // GMOCK_HAS_GOOGLE3_CALLBACK_
+
+// Tests using WithoutArgs with an action that takes no argument.
+TEST(WithoutArgsTest, NoArg) {
+  Action<int(int n)> a = WithoutArgs(Invoke(Nullary));  // NOLINT
+  EXPECT_EQ(1, a.Perform(make_tuple(2)));
+}
+
+// Tests using WithArg with an action that takes 1 argument.
+TEST(WithArgTest, OneArg) {
+  Action<bool(double x, int n)> b = WithArg<1>(Invoke(Unary));  // NOLINT
+  EXPECT_TRUE(b.Perform(make_tuple(1.5, -1)));
+  EXPECT_FALSE(b.Perform(make_tuple(1.5, 1)));
+}
+
+TEST(ReturnArgActionTest, WorksForOneArgIntArg0) {
+  const Action<int(int)> a = ReturnArg<0>();
+  EXPECT_EQ(5, a.Perform(make_tuple(5)));
+}
+
+TEST(ReturnArgActionTest, WorksForMultiArgBoolArg0) {
+  const Action<bool(bool, bool, bool)> a = ReturnArg<0>();
+  EXPECT_TRUE(a.Perform(make_tuple(true, false, false)));
+}
+
+TEST(ReturnArgActionTest, WorksForMultiArgStringArg2) {
+  const Action<string(int, int, string, int)> a = ReturnArg<2>();
+  EXPECT_EQ("seven", a.Perform(make_tuple(5, 6, string("seven"), 8)));
+}
+
+TEST(SaveArgActionTest, WorksForSameType) {
+  int result = 0;
+  const Action<void(int n)> a1 = SaveArg<0>(&result);
+  a1.Perform(make_tuple(5));
+  EXPECT_EQ(5, result);
+}
+
+TEST(SaveArgActionTest, WorksForCompatibleType) {
+  int result = 0;
+  const Action<void(bool, char)> a1 = SaveArg<1>(&result);
+  a1.Perform(make_tuple(true, 'a'));
+  EXPECT_EQ('a', result);
+}
+
+TEST(SetArgRefereeActionTest, WorksForSameType) {
+  int value = 0;
+  const Action<void(int&)> a1 = SetArgReferee<0>(1);
+  a1.Perform(tuple<int&>(value));
+  EXPECT_EQ(1, value);
+}
+
+TEST(SetArgRefereeActionTest, WorksForCompatibleType) {
+  int value = 0;
+  const Action<void(int, int&)> a1 = SetArgReferee<1>('a');
+  a1.Perform(tuple<int, int&>(0, value));
+  EXPECT_EQ('a', value);
+}
+
+TEST(SetArgRefereeActionTest, WorksWithExtraArguments) {
+  int value = 0;
+  const Action<void(bool, int, int&, const char*)> a1 = SetArgReferee<2>('a');
+  a1.Perform(tuple<bool, int, int&, const char*>(true, 0, value, "hi"));
+  EXPECT_EQ('a', value);
+}
+
+// A class that can be used to verify that its destructor is called: it will set
+// the bool provided to the constructor to true when destroyed.
+class DeletionTester {
+ public:
+  explicit DeletionTester(bool* is_deleted)
+    : is_deleted_(is_deleted) {
+    // Make sure the bit is set to false.
+    *is_deleted_ = false;
+  }
+
+  ~DeletionTester() {
+    *is_deleted_ = true;
+  }
+
+ private:
+  bool* is_deleted_;
+};
+
+TEST(DeleteArgActionTest, OneArg) {
+  bool is_deleted = false;
+  DeletionTester* t = new DeletionTester(&is_deleted);
+  const Action<void(DeletionTester*)> a1 = DeleteArg<0>();      // NOLINT
+  EXPECT_FALSE(is_deleted);
+  a1.Perform(make_tuple(t));
+  EXPECT_TRUE(is_deleted);
+}
+
+TEST(DeleteArgActionTest, TenArgs) {
+  bool is_deleted = false;
+  DeletionTester* t = new DeletionTester(&is_deleted);
+  const Action<void(bool, int, int, const char*, bool,
+                    int, int, int, int, DeletionTester*)> a1 = DeleteArg<9>();
+  EXPECT_FALSE(is_deleted);
+  a1.Perform(make_tuple(true, 5, 6, CharPtr("hi"), false, 7, 8, 9, 10, t));
+  EXPECT_TRUE(is_deleted);
+}
+
+#if GTEST_HAS_EXCEPTIONS
+
+TEST(ThrowActionTest, ThrowsGivenExceptionInVoidFunction) {
+  const Action<void(int n)> a = Throw('a');
+  EXPECT_THROW(a.Perform(make_tuple(0)), char);
+}
+
+class MyException {};
+
+TEST(ThrowActionTest, ThrowsGivenExceptionInNonVoidFunction) {
+  const Action<double(char ch)> a = Throw(MyException());
+  EXPECT_THROW(a.Perform(make_tuple('0')), MyException);
+}
+
+TEST(ThrowActionTest, ThrowsGivenExceptionInNullaryFunction) {
+  const Action<double()> a = Throw(MyException());
+  EXPECT_THROW(a.Perform(make_tuple()), MyException);
+}
+
+#endif  // GTEST_HAS_EXCEPTIONS
+
+// Tests that SetArrayArgument<N>(first, last) sets the elements of the array
+// pointed to by the N-th (0-based) argument to values in range [first, last).
+TEST(SetArrayArgumentTest, SetsTheNthArray) {
+  typedef void MyFunction(bool, int*, char*);
+  int numbers[] = { 1, 2, 3 };
+  Action<MyFunction> a = SetArrayArgument<1>(numbers, numbers + 3);
+
+  int n[4] = {};
+  int* pn = n;
+  char ch[4] = {};
+  char* pch = ch;
+  a.Perform(make_tuple(true, pn, pch));
+  EXPECT_EQ(1, n[0]);
+  EXPECT_EQ(2, n[1]);
+  EXPECT_EQ(3, n[2]);
+  EXPECT_EQ(0, n[3]);
+  EXPECT_EQ('\0', ch[0]);
+  EXPECT_EQ('\0', ch[1]);
+  EXPECT_EQ('\0', ch[2]);
+  EXPECT_EQ('\0', ch[3]);
+
+  // Tests first and last are iterators.
+  std::string letters = "abc";
+  a = SetArrayArgument<2>(letters.begin(), letters.end());
+  std::fill_n(n, 4, 0);
+  std::fill_n(ch, 4, '\0');
+  a.Perform(make_tuple(true, pn, pch));
+  EXPECT_EQ(0, n[0]);
+  EXPECT_EQ(0, n[1]);
+  EXPECT_EQ(0, n[2]);
+  EXPECT_EQ(0, n[3]);
+  EXPECT_EQ('a', ch[0]);
+  EXPECT_EQ('b', ch[1]);
+  EXPECT_EQ('c', ch[2]);
+  EXPECT_EQ('\0', ch[3]);
+}
+
+// Tests SetArrayArgument<N>(first, last) where first == last.
+TEST(SetArrayArgumentTest, SetsTheNthArrayWithEmptyRange) {
+  typedef void MyFunction(bool, int*);
+  int numbers[] = { 1, 2, 3 };
+  Action<MyFunction> a = SetArrayArgument<1>(numbers, numbers);
+
+  int n[4] = {};
+  int* pn = n;
+  a.Perform(make_tuple(true, pn));
+  EXPECT_EQ(0, n[0]);
+  EXPECT_EQ(0, n[1]);
+  EXPECT_EQ(0, n[2]);
+  EXPECT_EQ(0, n[3]);
+}
+
+// Tests SetArrayArgument<N>(first, last) where *first is convertible
+// (but not equal) to the argument type.
+TEST(SetArrayArgumentTest, SetsTheNthArrayWithConvertibleType) {
+  typedef void MyFunction(bool, char*);
+  int codes[] = { 97, 98, 99 };
+  Action<MyFunction> a = SetArrayArgument<1>(codes, codes + 3);
+
+  char ch[4] = {};
+  char* pch = ch;
+  a.Perform(make_tuple(true, pch));
+  EXPECT_EQ('a', ch[0]);
+  EXPECT_EQ('b', ch[1]);
+  EXPECT_EQ('c', ch[2]);
+  EXPECT_EQ('\0', ch[3]);
+}
+
+// Test SetArrayArgument<N>(first, last) with iterator as argument.
+TEST(SetArrayArgumentTest, SetsTheNthArrayWithIteratorArgument) {
+  typedef void MyFunction(bool, std::back_insert_iterator<std::string>);
+  std::string letters = "abc";
+  Action<MyFunction> a = SetArrayArgument<1>(letters.begin(), letters.end());
+
+  std::string s;
+  a.Perform(make_tuple(true, back_inserter(s)));
+  EXPECT_EQ(letters, s);
+}
+
+}  // namespace gmock_generated_actions_test
+}  // namespace testing