Callback API Change: Reimplement Bind(); support IgnoreResult, full currying, and use less types.

The main API change IgnoreResult() and fully currying.  See unittest for what the new API looks like.  The rest of the changes are done to support that.

Previously, IgnoreReturn could not be used with WeakPtr<> Bind()s as it was applied after the fact to the Callback object.  Now, IgnoreResult() wraps the function like Unretained().

As an incidental benefit, the new implementation gave us fully currying for free.

Also, the new implementation scales better when supporting higher arities of functions.  The new type growth is:

  (n^2 + 20n) / 2

as opposed to

  (3n^2 + 17n) / 2

where n == arity.

For n = 6 and n=10, the new implementation has 81 and 155 templates respectively.

The old implementation had 105 and 235 templates respectively.

BUG=35233,98919,98542
TEST=existing unittests

Review URL: http://codereview.chromium.org/8483003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@110975 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/base/bind_internal.h b/base/bind_internal.h
index 7beba51..6c76d80 100644
--- a/base/bind_internal.h
+++ b/base/bind_internal.h
@@ -4,6 +4,12 @@
 
 
 
+// TODO(ajwong): If you create an fully unbound method, is there a way to
+// enforce the first argument must be refcounted?  Or do we just say
+// "oh well"?
+//
+// Do we want to allow creating a fully unbound method??
+
 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
@@ -26,2167 +32,2114 @@
 namespace base {
 namespace internal {
 
-// The method by which a function is invoked is determined by 3 different
-// dimensions:
+// CONCEPTS:
+//  Runnable -- A type (really a type class) that has a single Run() method
+//              and a RunType typedef that corresponds to the type of Run().
+//              A Runnable can declare that it should treated like a method
+//              call by including a typedef named IsMethod.  The value of
+//              this typedef is NOT inspected, only the existence.  When a
+//              Runnable declares itself a method, Bind() will enforce special
+//              refcounting + WeakPtr handling semantics for the first
+//              parameter which is expected to be an object.
+//  Functor -- A copyable type representing something that should be called.
+//             All function pointers, Callback<>, and Runnables are functors
+//             even if the invocation syntax differs.
+//  RunType -- A function type (as opposed to function _pointer_ type) for
+//             a Run() function.  Usually just a convenience typedef.
+//  (Bound)ArgsType -- A function type that is being (ab)used to store the
+//                     types of set of arguments.  The "return" type is always
+//                     void here.  We use this hack so that we do not need
+//                     a new type name for each arity of type. (eg.,
+//                     BindState1, BindState2).  This makes forward
+//                     declarations and friending much much easier.
 //
-//   1) The type of function (normal or method).
-//   2) The arity of the function.
-//   3) The number of bound parameters.
-//
-// The templates below handle the determination of each of these dimensions.
-// In brief:
-//
-//   FunctionTraits<> -- Provides a normalied signature, and other traits.
-//   InvokerN<> -- Provides a DoInvoke() function that actually executes
-//                 a calback.
-//   InvokerStorageN<> -- Provides storage for the bound parameters, and
-//                        typedefs to the above.
-//   IsWeakMethod<> -- Determines if we are binding a method to a WeakPtr<>.
-//
-// More details about the design of each class is included in a comment closer
-// to their defition.
+// Types:
+//  RunnableAdapter<> -- Wraps the various "function" pointer types into an
+//                       object that adheres to the Runnable interface.
+//                       There are |3*ARITY| RunnableAdapter types.
+//  FunctionTraits<> -- Type traits that unwrap a function signature into a
+//                      a set of easier to use typedefs.  Used mainly for
+//                      compile time asserts.
+//                      There are |ARITY| FunctionTraits types.
+//  ForceVoidReturn<> -- Helper class for translating function signatures to
+//                       equivalent forms with a "void" return type.
+//                    There are |ARITY| ForceVoidReturn types.
+//  FunctorTraits<> -- Type traits used determine the correct RunType and
+//                     RunnableType for a Functor.  This is where function
+//                     signature adapters are applied.
+//                    There are |ARITY| ForceVoidReturn types.
+//  MakeRunnable<> -- Takes a Functor and returns an object in the Runnable
+//                    type class that represents the underlying Functor.
+//                    There are |O(1)| MakeRunnable types.
+//  InvokeHelper<> -- Take a Runnable + arguments and actully invokes it.
+// Handle the differing syntaxes needed for WeakPtr<> support,
+//                    and for ignoring return values.  This is separate from
+//                    Invoker to avoid creating multiple version of Invoker<>
+//                    which grows at O(n^2) with the arity.
+//                    There are |k*ARITY| InvokeHelper types.
+//  Invoker<> -- Unwraps the curried parameters and executes the Runnable.
+//               There are |(ARITY^2 + ARITY)/2| Invoketypes.
+//  BindState<> -- Stores the curried parameters, and is the main entry point
+//                 into the Bind() system, doing most of the type resolution.
+//                 There are ARITY BindState types.
 
 
-// IsWeakMethod determines if we are binding a method to a WeakPtr<> for an
-// object.  It is used to select an InvokerN that will no-op itself in the
-// event the WeakPtr<> for the target object is invalidated.
-template <bool IsMethod, typename T>
-struct IsWeakMethod : public false_type {};
+// RunnableAdapter<>
+//
+// The RunnableAdapter<> templates provide a uniform interface for invoking
+// a function pointer, method pointer, or const method pointer. The adapter
+// exposes a Run() method with an appropriate signature. Using this wrapper
+// allows for writing code that supports all three pointer types without
+// undue repetition.  Without it, a lot of code would need to be repeated 3
+// times.
+//
+// For method pointers and const method pointers the first argument to Run()
+// is considered to be the received of the method.  This is similar to STL's
+// mem_fun().
+//
+// This class also exposes a RunType typedef that is the function type of the
+// Run() function.
+//
+// If and only if the wrapper contains a method or const method pointer, an
+// IsMethod typedef is exposed.  The existence of this typedef (NOT the value)
+// marks that the wrapper should be considered a method wrapper.
 
-template <typename T>
-struct IsWeakMethod<true, WeakPtr<T> > : public true_type {};
-
-// FunctionTraits<>
-//
-// The FunctionTraits<> template determines the type of function, and also
-// creates a NormalizedType used to select the InvokerN classes.  It turns out
-// that syntactically, you only really have 2 variations when invoking a
-// funciton pointer: normal, and method.  One is invoked func_ptr(arg1). The
-// other is invoked (*obj_->method_ptr(arg1)).
-//
-// However, in the type system, there are many more distinctions. In standard
-// C++, there's all variations of const, and volatile on the function pointer.
-// In Windows, there are additional calling conventions (eg., __stdcall,
-// __fastcall, etc.). FunctionTraits<> handles categorizing each of these into
-// a normalized signature.
-//
-// Having a NormalizedSignature signature, reduces the combinatoric
-// complexity of defintions for the InvokerN<> later.  Even though there are
-// only 2 syntactic variations on invoking a function, without normalizing the
-// signature, there would need to be one specialization of InvokerN for each
-// unique (function_type, bound_arg, unbound_args) tuple in order to match all
-// function signatures.
-//
-// By normalizing the function signature, we reduce function_type to exactly 2.
-
-template <typename Sig>
-struct FunctionTraits;
+template <typename Functor>
+class RunnableAdapter;
 
 // Function: Arity 0.
 template <typename R>
-struct FunctionTraits<R(*)()> {
-  typedef R (*NormalizedSig)();
-  typedef false_type IsMethod;
+class RunnableAdapter<R(*)()> {
+ public:
+  typedef R (RunType)();
 
-  typedef R Return;
+  explicit RunnableAdapter(R(*function)())
+      : function_(function) {
+  }
 
+  R Run() {
+    return function_();
+  }
+
+ private:
+  R (*function_)();
 };
 
 // Method: Arity 0.
 template <typename R, typename T>
-struct FunctionTraits<R(T::*)()> {
-  typedef R (T::*NormalizedSig)();
+class RunnableAdapter<R(T::*)()> {
+ public:
+  typedef R (RunType)(T*);
   typedef true_type IsMethod;
 
-  typedef R Return;
+  explicit RunnableAdapter(R(T::*method)())
+      : method_(method) {
+  }
 
-  // Target type for each bound parameter.
-  typedef T B1;
+  R Run(T* object) {
+    return (object->*method_)();
+  }
 
+ private:
+  R (T::*method_)();
 };
 
 // Const Method: Arity 0.
 template <typename R, typename T>
-struct FunctionTraits<R(T::*)() const> {
-  typedef R (T::*NormalizedSig)();
+class RunnableAdapter<R(T::*)() const> {
+ public:
+  typedef R (RunType)(const T*);
   typedef true_type IsMethod;
 
-  typedef R Return;
+  explicit RunnableAdapter(R(T::*method)() const)
+      : method_(method) {
+  }
 
-  // Target type for each bound parameter.
-  typedef T B1;
+  R Run(const T* object) {
+    return (object->*method_)();
+  }
 
+ private:
+  R (T::*method_)() const;
 };
 
 // Function: Arity 1.
-template <typename R, typename X1>
-struct FunctionTraits<R(*)(X1)> {
-  typedef R (*NormalizedSig)(X1);
-  typedef false_type IsMethod;
+template <typename R, typename A1>
+class RunnableAdapter<R(*)(A1)> {
+ public:
+  typedef R (RunType)(A1);
 
-  typedef R Return;
+  explicit RunnableAdapter(R(*function)(A1))
+      : function_(function) {
+  }
 
-  // Target type for each bound parameter.
-  typedef X1 B1;
+  R Run(typename CallbackParamTraits<A1>::ForwardType a1) {
+    return function_(a1);
+  }
 
+ private:
+  R (*function_)(A1);
 };
 
 // Method: Arity 1.
-template <typename R, typename T, typename X1>
-struct FunctionTraits<R(T::*)(X1)> {
-  typedef R (T::*NormalizedSig)(X1);
+template <typename R, typename T, typename A1>
+class RunnableAdapter<R(T::*)(A1)> {
+ public:
+  typedef R (RunType)(T*, A1);
   typedef true_type IsMethod;
 
-  typedef R Return;
+  explicit RunnableAdapter(R(T::*method)(A1))
+      : method_(method) {
+  }
 
-  // Target type for each bound parameter.
-  typedef T B1;
-  typedef X1 B2;
+  R Run(T* object, typename CallbackParamTraits<A1>::ForwardType a1) {
+    return (object->*method_)(a1);
+  }
 
+ private:
+  R (T::*method_)(A1);
 };
 
 // Const Method: Arity 1.
-template <typename R, typename T, typename X1>
-struct FunctionTraits<R(T::*)(X1) const> {
-  typedef R (T::*NormalizedSig)(X1);
+template <typename R, typename T, typename A1>
+class RunnableAdapter<R(T::*)(A1) const> {
+ public:
+  typedef R (RunType)(const T*, A1);
   typedef true_type IsMethod;
 
-  typedef R Return;
+  explicit RunnableAdapter(R(T::*method)(A1) const)
+      : method_(method) {
+  }
 
-  // Target type for each bound parameter.
-  typedef T B1;
-  typedef X1 B2;
+  R Run(const T* object, typename CallbackParamTraits<A1>::ForwardType a1) {
+    return (object->*method_)(a1);
+  }
 
+ private:
+  R (T::*method_)(A1) const;
 };
 
 // Function: Arity 2.
-template <typename R, typename X1, typename X2>
-struct FunctionTraits<R(*)(X1, X2)> {
-  typedef R (*NormalizedSig)(X1, X2);
-  typedef false_type IsMethod;
+template <typename R, typename A1, typename A2>
+class RunnableAdapter<R(*)(A1, A2)> {
+ public:
+  typedef R (RunType)(A1, A2);
 
-  typedef R Return;
+  explicit RunnableAdapter(R(*function)(A1, A2))
+      : function_(function) {
+  }
 
-  // Target type for each bound parameter.
-  typedef X1 B1;
-  typedef X2 B2;
+  R Run(typename CallbackParamTraits<A1>::ForwardType a1,
+      typename CallbackParamTraits<A2>::ForwardType a2) {
+    return function_(a1, a2);
+  }
 
+ private:
+  R (*function_)(A1, A2);
 };
 
 // Method: Arity 2.
-template <typename R, typename T, typename X1, typename X2>
-struct FunctionTraits<R(T::*)(X1, X2)> {
-  typedef R (T::*NormalizedSig)(X1, X2);
+template <typename R, typename T, typename A1, typename A2>
+class RunnableAdapter<R(T::*)(A1, A2)> {
+ public:
+  typedef R (RunType)(T*, A1, A2);
   typedef true_type IsMethod;
 
-  typedef R Return;
+  explicit RunnableAdapter(R(T::*method)(A1, A2))
+      : method_(method) {
+  }
 
-  // Target type for each bound parameter.
-  typedef T B1;
-  typedef X1 B2;
-  typedef X2 B3;
+  R Run(T* object, typename CallbackParamTraits<A1>::ForwardType a1,
+      typename CallbackParamTraits<A2>::ForwardType a2) {
+    return (object->*method_)(a1, a2);
+  }
 
+ private:
+  R (T::*method_)(A1, A2);
 };
 
 // Const Method: Arity 2.
-template <typename R, typename T, typename X1, typename X2>
-struct FunctionTraits<R(T::*)(X1, X2) const> {
-  typedef R (T::*NormalizedSig)(X1, X2);
+template <typename R, typename T, typename A1, typename A2>
+class RunnableAdapter<R(T::*)(A1, A2) const> {
+ public:
+  typedef R (RunType)(const T*, A1, A2);
   typedef true_type IsMethod;
 
-  typedef R Return;
+  explicit RunnableAdapter(R(T::*method)(A1, A2) const)
+      : method_(method) {
+  }
 
-  // Target type for each bound parameter.
-  typedef T B1;
-  typedef X1 B2;
-  typedef X2 B3;
+  R Run(const T* object, typename CallbackParamTraits<A1>::ForwardType a1,
+      typename CallbackParamTraits<A2>::ForwardType a2) {
+    return (object->*method_)(a1, a2);
+  }
 
+ private:
+  R (T::*method_)(A1, A2) const;
 };
 
 // Function: Arity 3.
-template <typename R, typename X1, typename X2, typename X3>
-struct FunctionTraits<R(*)(X1, X2, X3)> {
-  typedef R (*NormalizedSig)(X1, X2, X3);
-  typedef false_type IsMethod;
+template <typename R, typename A1, typename A2, typename A3>
+class RunnableAdapter<R(*)(A1, A2, A3)> {
+ public:
+  typedef R (RunType)(A1, A2, A3);
 
-  typedef R Return;
+  explicit RunnableAdapter(R(*function)(A1, A2, A3))
+      : function_(function) {
+  }
 
-  // Target type for each bound parameter.
-  typedef X1 B1;
-  typedef X2 B2;
-  typedef X3 B3;
+  R Run(typename CallbackParamTraits<A1>::ForwardType a1,
+      typename CallbackParamTraits<A2>::ForwardType a2,
+      typename CallbackParamTraits<A3>::ForwardType a3) {
+    return function_(a1, a2, a3);
+  }
 
+ private:
+  R (*function_)(A1, A2, A3);
 };
 
 // Method: Arity 3.
-template <typename R, typename T, typename X1, typename X2, typename X3>
-struct FunctionTraits<R(T::*)(X1, X2, X3)> {
-  typedef R (T::*NormalizedSig)(X1, X2, X3);
+template <typename R, typename T, typename A1, typename A2, typename A3>
+class RunnableAdapter<R(T::*)(A1, A2, A3)> {
+ public:
+  typedef R (RunType)(T*, A1, A2, A3);
   typedef true_type IsMethod;
 
-  typedef R Return;
+  explicit RunnableAdapter(R(T::*method)(A1, A2, A3))
+      : method_(method) {
+  }
 
-  // Target type for each bound parameter.
-  typedef T B1;
-  typedef X1 B2;
-  typedef X2 B3;
-  typedef X3 B4;
+  R Run(T* object, typename CallbackParamTraits<A1>::ForwardType a1,
+      typename CallbackParamTraits<A2>::ForwardType a2,
+      typename CallbackParamTraits<A3>::ForwardType a3) {
+    return (object->*method_)(a1, a2, a3);
+  }
 
+ private:
+  R (T::*method_)(A1, A2, A3);
 };
 
 // Const Method: Arity 3.
-template <typename R, typename T, typename X1, typename X2, typename X3>
-struct FunctionTraits<R(T::*)(X1, X2, X3) const> {
-  typedef R (T::*NormalizedSig)(X1, X2, X3);
+template <typename R, typename T, typename A1, typename A2, typename A3>
+class RunnableAdapter<R(T::*)(A1, A2, A3) const> {
+ public:
+  typedef R (RunType)(const T*, A1, A2, A3);
   typedef true_type IsMethod;
 
-  typedef R Return;
+  explicit RunnableAdapter(R(T::*method)(A1, A2, A3) const)
+      : method_(method) {
+  }
 
-  // Target type for each bound parameter.
-  typedef T B1;
-  typedef X1 B2;
-  typedef X2 B3;
-  typedef X3 B4;
+  R Run(const T* object, typename CallbackParamTraits<A1>::ForwardType a1,
+      typename CallbackParamTraits<A2>::ForwardType a2,
+      typename CallbackParamTraits<A3>::ForwardType a3) {
+    return (object->*method_)(a1, a2, a3);
+  }
 
+ private:
+  R (T::*method_)(A1, A2, A3) const;
 };
 
 // Function: Arity 4.
-template <typename R, typename X1, typename X2, typename X3, typename X4>
-struct FunctionTraits<R(*)(X1, X2, X3, X4)> {
-  typedef R (*NormalizedSig)(X1, X2, X3, X4);
-  typedef false_type IsMethod;
+template <typename R, typename A1, typename A2, typename A3, typename A4>
+class RunnableAdapter<R(*)(A1, A2, A3, A4)> {
+ public:
+  typedef R (RunType)(A1, A2, A3, A4);
 
-  typedef R Return;
+  explicit RunnableAdapter(R(*function)(A1, A2, A3, A4))
+      : function_(function) {
+  }
 
-  // Target type for each bound parameter.
-  typedef X1 B1;
-  typedef X2 B2;
-  typedef X3 B3;
-  typedef X4 B4;
+  R Run(typename CallbackParamTraits<A1>::ForwardType a1,
+      typename CallbackParamTraits<A2>::ForwardType a2,
+      typename CallbackParamTraits<A3>::ForwardType a3,
+      typename CallbackParamTraits<A4>::ForwardType a4) {
+    return function_(a1, a2, a3, a4);
+  }
 
+ private:
+  R (*function_)(A1, A2, A3, A4);
 };
 
 // Method: Arity 4.
-template <typename R, typename T, typename X1, typename X2, typename X3,
-    typename X4>
-struct FunctionTraits<R(T::*)(X1, X2, X3, X4)> {
-  typedef R (T::*NormalizedSig)(X1, X2, X3, X4);
+template <typename R, typename T, typename A1, typename A2, typename A3,
+    typename A4>
+class RunnableAdapter<R(T::*)(A1, A2, A3, A4)> {
+ public:
+  typedef R (RunType)(T*, A1, A2, A3, A4);
   typedef true_type IsMethod;
 
-  typedef R Return;
+  explicit RunnableAdapter(R(T::*method)(A1, A2, A3, A4))
+      : method_(method) {
+  }
 
-  // Target type for each bound parameter.
-  typedef T B1;
-  typedef X1 B2;
-  typedef X2 B3;
-  typedef X3 B4;
-  typedef X4 B5;
+  R Run(T* object, typename CallbackParamTraits<A1>::ForwardType a1,
+      typename CallbackParamTraits<A2>::ForwardType a2,
+      typename CallbackParamTraits<A3>::ForwardType a3,
+      typename CallbackParamTraits<A4>::ForwardType a4) {
+    return (object->*method_)(a1, a2, a3, a4);
+  }
 
+ private:
+  R (T::*method_)(A1, A2, A3, A4);
 };
 
 // Const Method: Arity 4.
-template <typename R, typename T, typename X1, typename X2, typename X3,
-    typename X4>
-struct FunctionTraits<R(T::*)(X1, X2, X3, X4) const> {
-  typedef R (T::*NormalizedSig)(X1, X2, X3, X4);
+template <typename R, typename T, typename A1, typename A2, typename A3,
+    typename A4>
+class RunnableAdapter<R(T::*)(A1, A2, A3, A4) const> {
+ public:
+  typedef R (RunType)(const T*, A1, A2, A3, A4);
   typedef true_type IsMethod;
 
-  typedef R Return;
+  explicit RunnableAdapter(R(T::*method)(A1, A2, A3, A4) const)
+      : method_(method) {
+  }
 
-  // Target type for each bound parameter.
-  typedef T B1;
-  typedef X1 B2;
-  typedef X2 B3;
-  typedef X3 B4;
-  typedef X4 B5;
+  R Run(const T* object, typename CallbackParamTraits<A1>::ForwardType a1,
+      typename CallbackParamTraits<A2>::ForwardType a2,
+      typename CallbackParamTraits<A3>::ForwardType a3,
+      typename CallbackParamTraits<A4>::ForwardType a4) {
+    return (object->*method_)(a1, a2, a3, a4);
+  }
 
+ private:
+  R (T::*method_)(A1, A2, A3, A4) const;
 };
 
 // Function: Arity 5.
-template <typename R, typename X1, typename X2, typename X3, typename X4,
-    typename X5>
-struct FunctionTraits<R(*)(X1, X2, X3, X4, X5)> {
-  typedef R (*NormalizedSig)(X1, X2, X3, X4, X5);
-  typedef false_type IsMethod;
+template <typename R, typename A1, typename A2, typename A3, typename A4,
+    typename A5>
+class RunnableAdapter<R(*)(A1, A2, A3, A4, A5)> {
+ public:
+  typedef R (RunType)(A1, A2, A3, A4, A5);
 
-  typedef R Return;
+  explicit RunnableAdapter(R(*function)(A1, A2, A3, A4, A5))
+      : function_(function) {
+  }
 
-  // Target type for each bound parameter.
-  typedef X1 B1;
-  typedef X2 B2;
-  typedef X3 B3;
-  typedef X4 B4;
-  typedef X5 B5;
+  R Run(typename CallbackParamTraits<A1>::ForwardType a1,
+      typename CallbackParamTraits<A2>::ForwardType a2,
+      typename CallbackParamTraits<A3>::ForwardType a3,
+      typename CallbackParamTraits<A4>::ForwardType a4,
+      typename CallbackParamTraits<A5>::ForwardType a5) {
+    return function_(a1, a2, a3, a4, a5);
+  }
 
+ private:
+  R (*function_)(A1, A2, A3, A4, A5);
 };
 
 // Method: Arity 5.
-template <typename R, typename T, typename X1, typename X2, typename X3,
-    typename X4, typename X5>
-struct FunctionTraits<R(T::*)(X1, X2, X3, X4, X5)> {
-  typedef R (T::*NormalizedSig)(X1, X2, X3, X4, X5);
+template <typename R, typename T, typename A1, typename A2, typename A3,
+    typename A4, typename A5>
+class RunnableAdapter<R(T::*)(A1, A2, A3, A4, A5)> {
+ public:
+  typedef R (RunType)(T*, A1, A2, A3, A4, A5);
   typedef true_type IsMethod;
 
-  typedef R Return;
+  explicit RunnableAdapter(R(T::*method)(A1, A2, A3, A4, A5))
+      : method_(method) {
+  }
 
-  // Target type for each bound parameter.
-  typedef T B1;
-  typedef X1 B2;
-  typedef X2 B3;
-  typedef X3 B4;
-  typedef X4 B5;
-  typedef X5 B6;
+  R Run(T* object, typename CallbackParamTraits<A1>::ForwardType a1,
+      typename CallbackParamTraits<A2>::ForwardType a2,
+      typename CallbackParamTraits<A3>::ForwardType a3,
+      typename CallbackParamTraits<A4>::ForwardType a4,
+      typename CallbackParamTraits<A5>::ForwardType a5) {
+    return (object->*method_)(a1, a2, a3, a4, a5);
+  }
 
+ private:
+  R (T::*method_)(A1, A2, A3, A4, A5);
 };
 
 // Const Method: Arity 5.
-template <typename R, typename T, typename X1, typename X2, typename X3,
-    typename X4, typename X5>
-struct FunctionTraits<R(T::*)(X1, X2, X3, X4, X5) const> {
-  typedef R (T::*NormalizedSig)(X1, X2, X3, X4, X5);
+template <typename R, typename T, typename A1, typename A2, typename A3,
+    typename A4, typename A5>
+class RunnableAdapter<R(T::*)(A1, A2, A3, A4, A5) const> {
+ public:
+  typedef R (RunType)(const T*, A1, A2, A3, A4, A5);
   typedef true_type IsMethod;
 
-  typedef R Return;
+  explicit RunnableAdapter(R(T::*method)(A1, A2, A3, A4, A5) const)
+      : method_(method) {
+  }
 
-  // Target type for each bound parameter.
-  typedef T B1;
-  typedef X1 B2;
-  typedef X2 B3;
-  typedef X3 B4;
-  typedef X4 B5;
-  typedef X5 B6;
+  R Run(const T* object, typename CallbackParamTraits<A1>::ForwardType a1,
+      typename CallbackParamTraits<A2>::ForwardType a2,
+      typename CallbackParamTraits<A3>::ForwardType a3,
+      typename CallbackParamTraits<A4>::ForwardType a4,
+      typename CallbackParamTraits<A5>::ForwardType a5) {
+    return (object->*method_)(a1, a2, a3, a4, a5);
+  }
 
+ private:
+  R (T::*method_)(A1, A2, A3, A4, A5) const;
 };
 
 // Function: Arity 6.
-template <typename R, typename X1, typename X2, typename X3, typename X4,
-    typename X5, typename X6>
-struct FunctionTraits<R(*)(X1, X2, X3, X4, X5, X6)> {
-  typedef R (*NormalizedSig)(X1, X2, X3, X4, X5, X6);
-  typedef false_type IsMethod;
+template <typename R, typename A1, typename A2, typename A3, typename A4,
+    typename A5, typename A6>
+class RunnableAdapter<R(*)(A1, A2, A3, A4, A5, A6)> {
+ public:
+  typedef R (RunType)(A1, A2, A3, A4, A5, A6);
 
-  typedef R Return;
+  explicit RunnableAdapter(R(*function)(A1, A2, A3, A4, A5, A6))
+      : function_(function) {
+  }
 
-  // Target type for each bound parameter.
-  typedef X1 B1;
-  typedef X2 B2;
-  typedef X3 B3;
-  typedef X4 B4;
-  typedef X5 B5;
-  typedef X6 B6;
+  R Run(typename CallbackParamTraits<A1>::ForwardType a1,
+      typename CallbackParamTraits<A2>::ForwardType a2,
+      typename CallbackParamTraits<A3>::ForwardType a3,
+      typename CallbackParamTraits<A4>::ForwardType a4,
+      typename CallbackParamTraits<A5>::ForwardType a5,
+      typename CallbackParamTraits<A6>::ForwardType a6) {
+    return function_(a1, a2, a3, a4, a5, a6);
+  }
 
+ private:
+  R (*function_)(A1, A2, A3, A4, A5, A6);
 };
 
 // Method: Arity 6.
-template <typename R, typename T, typename X1, typename X2, typename X3,
-    typename X4, typename X5, typename X6>
-struct FunctionTraits<R(T::*)(X1, X2, X3, X4, X5, X6)> {
-  typedef R (T::*NormalizedSig)(X1, X2, X3, X4, X5, X6);
+template <typename R, typename T, typename A1, typename A2, typename A3,
+    typename A4, typename A5, typename A6>
+class RunnableAdapter<R(T::*)(A1, A2, A3, A4, A5, A6)> {
+ public:
+  typedef R (RunType)(T*, A1, A2, A3, A4, A5, A6);
   typedef true_type IsMethod;
 
-  typedef R Return;
+  explicit RunnableAdapter(R(T::*method)(A1, A2, A3, A4, A5, A6))
+      : method_(method) {
+  }
 
-  // Target type for each bound parameter.
-  typedef T B1;
-  typedef X1 B2;
-  typedef X2 B3;
-  typedef X3 B4;
-  typedef X4 B5;
-  typedef X5 B6;
-  typedef X6 B7;
+  R Run(T* object, typename CallbackParamTraits<A1>::ForwardType a1,
+      typename CallbackParamTraits<A2>::ForwardType a2,
+      typename CallbackParamTraits<A3>::ForwardType a3,
+      typename CallbackParamTraits<A4>::ForwardType a4,
+      typename CallbackParamTraits<A5>::ForwardType a5,
+      typename CallbackParamTraits<A6>::ForwardType a6) {
+    return (object->*method_)(a1, a2, a3, a4, a5, a6);
+  }
 
+ private:
+  R (T::*method_)(A1, A2, A3, A4, A5, A6);
 };
 
 // Const Method: Arity 6.
-template <typename R, typename T, typename X1, typename X2, typename X3,
-    typename X4, typename X5, typename X6>
-struct FunctionTraits<R(T::*)(X1, X2, X3, X4, X5, X6) const> {
-  typedef R (T::*NormalizedSig)(X1, X2, X3, X4, X5, X6);
+template <typename R, typename T, typename A1, typename A2, typename A3,
+    typename A4, typename A5, typename A6>
+class RunnableAdapter<R(T::*)(A1, A2, A3, A4, A5, A6) const> {
+ public:
+  typedef R (RunType)(const T*, A1, A2, A3, A4, A5, A6);
   typedef true_type IsMethod;
 
-  typedef R Return;
+  explicit RunnableAdapter(R(T::*method)(A1, A2, A3, A4, A5, A6) const)
+      : method_(method) {
+  }
 
-  // Target type for each bound parameter.
-  typedef T B1;
-  typedef X1 B2;
-  typedef X2 B3;
-  typedef X3 B4;
-  typedef X4 B5;
-  typedef X5 B6;
-  typedef X6 B7;
+  R Run(const T* object, typename CallbackParamTraits<A1>::ForwardType a1,
+      typename CallbackParamTraits<A2>::ForwardType a2,
+      typename CallbackParamTraits<A3>::ForwardType a3,
+      typename CallbackParamTraits<A4>::ForwardType a4,
+      typename CallbackParamTraits<A5>::ForwardType a5,
+      typename CallbackParamTraits<A6>::ForwardType a6) {
+    return (object->*method_)(a1, a2, a3, a4, a5, a6);
+  }
 
+ private:
+  R (T::*method_)(A1, A2, A3, A4, A5, A6) const;
 };
 
-// InvokerN<>
+
+// FunctionTraits<>
 //
-// The InvokerN templates contain a static DoInvoke() function that is the key
-// to implementing type erasure in the Callback() classes.
-//
-// DoInvoke() is a static function with a fixed signature that is independent
-// of StorageType; its first argument is a pointer to the non-templated common
-// baseclass of StorageType. This lets us store pointer to DoInvoke() in a
-// function pointer that has knowledge of the specific StorageType, and thus
-// no knowledge of the bound function and bound parameter types.
-//
-// As long as we ensure that DoInvoke() is only used with pointers there were
-// upcasted from the correct StorageType, we can be sure that execution is
-// safe.
-//
-// The InvokerN templates are the only point that knows the number of bound
-// and unbound arguments.  This is intentional because it allows the other
-// templates classes in the system to only have as many specializations as
-// the max arity of function we wish to support.
-
-template <bool IsWeak, typename StorageType, typename NormalizedSig>
-struct Invoker0;
-
-// Function: Arity 0 -> 0.
-template <typename StorageType, typename R>
-struct Invoker0<false, StorageType, R(*)()> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*);
-
-  static R DoInvoke(InvokerStorageBase* base) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return invoker->f_();
-  }
-};
-
-// Function: Arity 1 -> 1.
-template <typename StorageType, typename R,typename X1>
-struct Invoker0<false, StorageType, R(*)(X1)> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X1>::ForwardType);
-
-  static R DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X1>::ForwardType x1) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return invoker->f_(x1);
-  }
-};
-
-// Function: Arity 2 -> 2.
-template <typename StorageType, typename R,typename X1, typename X2>
-struct Invoker0<false, StorageType, R(*)(X1, X2)> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X1>::ForwardType,
-          typename internal::ParamTraits<X2>::ForwardType);
-
-  static R DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X1>::ForwardType x1,
-      typename internal::ParamTraits<X2>::ForwardType x2) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return invoker->f_(x1, x2);
-  }
-};
-
-// Function: Arity 3 -> 3.
-template <typename StorageType, typename R,typename X1, typename X2,
-    typename X3>
-struct Invoker0<false, StorageType, R(*)(X1, X2, X3)> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X1>::ForwardType,
-          typename internal::ParamTraits<X2>::ForwardType,
-          typename internal::ParamTraits<X3>::ForwardType);
-
-  static R DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X1>::ForwardType x1,
-      typename internal::ParamTraits<X2>::ForwardType x2,
-      typename internal::ParamTraits<X3>::ForwardType x3) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return invoker->f_(x1, x2, x3);
-  }
-};
-
-// Function: Arity 4 -> 4.
-template <typename StorageType, typename R,typename X1, typename X2,
-    typename X3, typename X4>
-struct Invoker0<false, StorageType, R(*)(X1, X2, X3, X4)> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X1>::ForwardType,
-          typename internal::ParamTraits<X2>::ForwardType,
-          typename internal::ParamTraits<X3>::ForwardType,
-          typename internal::ParamTraits<X4>::ForwardType);
-
-  static R DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X1>::ForwardType x1,
-      typename internal::ParamTraits<X2>::ForwardType x2,
-      typename internal::ParamTraits<X3>::ForwardType x3,
-      typename internal::ParamTraits<X4>::ForwardType x4) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return invoker->f_(x1, x2, x3, x4);
-  }
-};
-
-// Function: Arity 5 -> 5.
-template <typename StorageType, typename R,typename X1, typename X2,
-    typename X3, typename X4, typename X5>
-struct Invoker0<false, StorageType, R(*)(X1, X2, X3, X4, X5)> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X1>::ForwardType,
-          typename internal::ParamTraits<X2>::ForwardType,
-          typename internal::ParamTraits<X3>::ForwardType,
-          typename internal::ParamTraits<X4>::ForwardType,
-          typename internal::ParamTraits<X5>::ForwardType);
-
-  static R DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X1>::ForwardType x1,
-      typename internal::ParamTraits<X2>::ForwardType x2,
-      typename internal::ParamTraits<X3>::ForwardType x3,
-      typename internal::ParamTraits<X4>::ForwardType x4,
-      typename internal::ParamTraits<X5>::ForwardType x5) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return invoker->f_(x1, x2, x3, x4, x5);
-  }
-};
-
-// Function: Arity 6 -> 6.
-template <typename StorageType, typename R,typename X1, typename X2,
-    typename X3, typename X4, typename X5, typename X6>
-struct Invoker0<false, StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X1>::ForwardType,
-          typename internal::ParamTraits<X2>::ForwardType,
-          typename internal::ParamTraits<X3>::ForwardType,
-          typename internal::ParamTraits<X4>::ForwardType,
-          typename internal::ParamTraits<X5>::ForwardType,
-          typename internal::ParamTraits<X6>::ForwardType);
-
-  static R DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X1>::ForwardType x1,
-      typename internal::ParamTraits<X2>::ForwardType x2,
-      typename internal::ParamTraits<X3>::ForwardType x3,
-      typename internal::ParamTraits<X4>::ForwardType x4,
-      typename internal::ParamTraits<X5>::ForwardType x5,
-      typename internal::ParamTraits<X6>::ForwardType x6) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return invoker->f_(x1, x2, x3, x4, x5, x6);
-  }
-};
-
-template <bool IsWeak, typename StorageType, typename NormalizedSig>
-struct Invoker1;
-
-// Function: Arity 1 -> 0.
-template <typename StorageType, typename R,typename X1>
-struct Invoker1<false, StorageType, R(*)(X1)> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*);
-
-  static R DoInvoke(InvokerStorageBase* base) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return invoker->f_(Unwrap(invoker->p1_));
-  }
-};
-
-// Method: Arity 0 -> 0.
-template <typename StorageType, typename R, typename T>
-struct Invoker1<false, StorageType, R(T::*)()> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*);
-
-  static R DoInvoke(InvokerStorageBase* base) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return (Unwrap(invoker->p1_)->*invoker->f_)();
-  }
-};
-
-// WeakPtr Method: Arity 0 -> 0.
-template <typename StorageType, typename T>
-struct Invoker1<true, StorageType, void(T::*)()> {
-  typedef void(*DoInvokeType)(
-      internal::InvokerStorageBase*);
-
-  static void DoInvoke(InvokerStorageBase* base) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_;
-    if (!weak_ptr.get()) {
-      return;
-    }
-    (weak_ptr->*invoker->f_)();
-  }
-};
-
-// Function: Arity 2 -> 1.
-template <typename StorageType, typename R,typename X1, typename X2>
-struct Invoker1<false, StorageType, R(*)(X1, X2)> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X2>::ForwardType);
-
-  static R DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X2>::ForwardType x2) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return invoker->f_(Unwrap(invoker->p1_), x2);
-  }
-};
-
-// Method: Arity 1 -> 1.
-template <typename StorageType, typename R, typename T, typename X1>
-struct Invoker1<false, StorageType, R(T::*)(X1)> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X1>::ForwardType);
-
-  static R DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X1>::ForwardType x1) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return (Unwrap(invoker->p1_)->*invoker->f_)(x1);
-  }
-};
-
-// WeakPtr Method: Arity 1 -> 1.
-template <typename StorageType, typename T, typename X1>
-struct Invoker1<true, StorageType, void(T::*)(X1)> {
-  typedef void(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X1>::ForwardType);
-
-  static void DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X1>::ForwardType x1) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_;
-    if (!weak_ptr.get()) {
-      return;
-    }
-    (weak_ptr->*invoker->f_)(x1);
-  }
-};
-
-// Function: Arity 3 -> 2.
-template <typename StorageType, typename R,typename X1, typename X2,
-    typename X3>
-struct Invoker1<false, StorageType, R(*)(X1, X2, X3)> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X2>::ForwardType,
-          typename internal::ParamTraits<X3>::ForwardType);
-
-  static R DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X2>::ForwardType x2,
-      typename internal::ParamTraits<X3>::ForwardType x3) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return invoker->f_(Unwrap(invoker->p1_), x2, x3);
-  }
-};
-
-// Method: Arity 2 -> 2.
-template <typename StorageType, typename R, typename T, typename X1,
-    typename X2>
-struct Invoker1<false, StorageType, R(T::*)(X1, X2)> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X1>::ForwardType,
-          typename internal::ParamTraits<X2>::ForwardType);
-
-  static R DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X1>::ForwardType x1,
-      typename internal::ParamTraits<X2>::ForwardType x2) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return (Unwrap(invoker->p1_)->*invoker->f_)(x1, x2);
-  }
-};
-
-// WeakPtr Method: Arity 2 -> 2.
-template <typename StorageType, typename T, typename X1, typename X2>
-struct Invoker1<true, StorageType, void(T::*)(X1, X2)> {
-  typedef void(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X1>::ForwardType,
-          typename internal::ParamTraits<X2>::ForwardType);
-
-  static void DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X1>::ForwardType x1,
-      typename internal::ParamTraits<X2>::ForwardType x2) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_;
-    if (!weak_ptr.get()) {
-      return;
-    }
-    (weak_ptr->*invoker->f_)(x1, x2);
-  }
-};
-
-// Function: Arity 4 -> 3.
-template <typename StorageType, typename R,typename X1, typename X2,
-    typename X3, typename X4>
-struct Invoker1<false, StorageType, R(*)(X1, X2, X3, X4)> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X2>::ForwardType,
-          typename internal::ParamTraits<X3>::ForwardType,
-          typename internal::ParamTraits<X4>::ForwardType);
-
-  static R DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X2>::ForwardType x2,
-      typename internal::ParamTraits<X3>::ForwardType x3,
-      typename internal::ParamTraits<X4>::ForwardType x4) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return invoker->f_(Unwrap(invoker->p1_), x2, x3, x4);
-  }
-};
-
-// Method: Arity 3 -> 3.
-template <typename StorageType, typename R, typename T, typename X1,
-    typename X2, typename X3>
-struct Invoker1<false, StorageType, R(T::*)(X1, X2, X3)> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X1>::ForwardType,
-          typename internal::ParamTraits<X2>::ForwardType,
-          typename internal::ParamTraits<X3>::ForwardType);
-
-  static R DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X1>::ForwardType x1,
-      typename internal::ParamTraits<X2>::ForwardType x2,
-      typename internal::ParamTraits<X3>::ForwardType x3) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return (Unwrap(invoker->p1_)->*invoker->f_)(x1, x2, x3);
-  }
-};
-
-// WeakPtr Method: Arity 3 -> 3.
-template <typename StorageType, typename T, typename X1, typename X2,
-    typename X3>
-struct Invoker1<true, StorageType, void(T::*)(X1, X2, X3)> {
-  typedef void(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X1>::ForwardType,
-          typename internal::ParamTraits<X2>::ForwardType,
-          typename internal::ParamTraits<X3>::ForwardType);
-
-  static void DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X1>::ForwardType x1,
-      typename internal::ParamTraits<X2>::ForwardType x2,
-      typename internal::ParamTraits<X3>::ForwardType x3) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_;
-    if (!weak_ptr.get()) {
-      return;
-    }
-    (weak_ptr->*invoker->f_)(x1, x2, x3);
-  }
-};
-
-// Function: Arity 5 -> 4.
-template <typename StorageType, typename R,typename X1, typename X2,
-    typename X3, typename X4, typename X5>
-struct Invoker1<false, StorageType, R(*)(X1, X2, X3, X4, X5)> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X2>::ForwardType,
-          typename internal::ParamTraits<X3>::ForwardType,
-          typename internal::ParamTraits<X4>::ForwardType,
-          typename internal::ParamTraits<X5>::ForwardType);
-
-  static R DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X2>::ForwardType x2,
-      typename internal::ParamTraits<X3>::ForwardType x3,
-      typename internal::ParamTraits<X4>::ForwardType x4,
-      typename internal::ParamTraits<X5>::ForwardType x5) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return invoker->f_(Unwrap(invoker->p1_), x2, x3, x4, x5);
-  }
-};
-
-// Method: Arity 4 -> 4.
-template <typename StorageType, typename R, typename T, typename X1,
-    typename X2, typename X3, typename X4>
-struct Invoker1<false, StorageType, R(T::*)(X1, X2, X3, X4)> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X1>::ForwardType,
-          typename internal::ParamTraits<X2>::ForwardType,
-          typename internal::ParamTraits<X3>::ForwardType,
-          typename internal::ParamTraits<X4>::ForwardType);
-
-  static R DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X1>::ForwardType x1,
-      typename internal::ParamTraits<X2>::ForwardType x2,
-      typename internal::ParamTraits<X3>::ForwardType x3,
-      typename internal::ParamTraits<X4>::ForwardType x4) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return (Unwrap(invoker->p1_)->*invoker->f_)(x1, x2, x3, x4);
-  }
-};
-
-// WeakPtr Method: Arity 4 -> 4.
-template <typename StorageType, typename T, typename X1, typename X2,
-    typename X3, typename X4>
-struct Invoker1<true, StorageType, void(T::*)(X1, X2, X3, X4)> {
-  typedef void(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X1>::ForwardType,
-          typename internal::ParamTraits<X2>::ForwardType,
-          typename internal::ParamTraits<X3>::ForwardType,
-          typename internal::ParamTraits<X4>::ForwardType);
-
-  static void DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X1>::ForwardType x1,
-      typename internal::ParamTraits<X2>::ForwardType x2,
-      typename internal::ParamTraits<X3>::ForwardType x3,
-      typename internal::ParamTraits<X4>::ForwardType x4) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_;
-    if (!weak_ptr.get()) {
-      return;
-    }
-    (weak_ptr->*invoker->f_)(x1, x2, x3, x4);
-  }
-};
-
-// Function: Arity 6 -> 5.
-template <typename StorageType, typename R,typename X1, typename X2,
-    typename X3, typename X4, typename X5, typename X6>
-struct Invoker1<false, StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X2>::ForwardType,
-          typename internal::ParamTraits<X3>::ForwardType,
-          typename internal::ParamTraits<X4>::ForwardType,
-          typename internal::ParamTraits<X5>::ForwardType,
-          typename internal::ParamTraits<X6>::ForwardType);
-
-  static R DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X2>::ForwardType x2,
-      typename internal::ParamTraits<X3>::ForwardType x3,
-      typename internal::ParamTraits<X4>::ForwardType x4,
-      typename internal::ParamTraits<X5>::ForwardType x5,
-      typename internal::ParamTraits<X6>::ForwardType x6) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return invoker->f_(Unwrap(invoker->p1_), x2, x3, x4, x5, x6);
-  }
-};
-
-// Method: Arity 5 -> 5.
-template <typename StorageType, typename R, typename T, typename X1,
-    typename X2, typename X3, typename X4, typename X5>
-struct Invoker1<false, StorageType, R(T::*)(X1, X2, X3, X4, X5)> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X1>::ForwardType,
-          typename internal::ParamTraits<X2>::ForwardType,
-          typename internal::ParamTraits<X3>::ForwardType,
-          typename internal::ParamTraits<X4>::ForwardType,
-          typename internal::ParamTraits<X5>::ForwardType);
-
-  static R DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X1>::ForwardType x1,
-      typename internal::ParamTraits<X2>::ForwardType x2,
-      typename internal::ParamTraits<X3>::ForwardType x3,
-      typename internal::ParamTraits<X4>::ForwardType x4,
-      typename internal::ParamTraits<X5>::ForwardType x5) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return (Unwrap(invoker->p1_)->*invoker->f_)(x1, x2, x3, x4, x5);
-  }
-};
-
-// WeakPtr Method: Arity 5 -> 5.
-template <typename StorageType, typename T, typename X1, typename X2,
-    typename X3, typename X4, typename X5>
-struct Invoker1<true, StorageType, void(T::*)(X1, X2, X3, X4, X5)> {
-  typedef void(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X1>::ForwardType,
-          typename internal::ParamTraits<X2>::ForwardType,
-          typename internal::ParamTraits<X3>::ForwardType,
-          typename internal::ParamTraits<X4>::ForwardType,
-          typename internal::ParamTraits<X5>::ForwardType);
-
-  static void DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X1>::ForwardType x1,
-      typename internal::ParamTraits<X2>::ForwardType x2,
-      typename internal::ParamTraits<X3>::ForwardType x3,
-      typename internal::ParamTraits<X4>::ForwardType x4,
-      typename internal::ParamTraits<X5>::ForwardType x5) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_;
-    if (!weak_ptr.get()) {
-      return;
-    }
-    (weak_ptr->*invoker->f_)(x1, x2, x3, x4, x5);
-  }
-};
-
-template <bool IsWeak, typename StorageType, typename NormalizedSig>
-struct Invoker2;
-
-// Function: Arity 2 -> 0.
-template <typename StorageType, typename R,typename X1, typename X2>
-struct Invoker2<false, StorageType, R(*)(X1, X2)> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*);
-
-  static R DoInvoke(InvokerStorageBase* base) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_));
-  }
-};
-
-// Method: Arity 1 -> 0.
-template <typename StorageType, typename R, typename T, typename X1>
-struct Invoker2<false, StorageType, R(T::*)(X1)> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*);
-
-  static R DoInvoke(InvokerStorageBase* base) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_));
-  }
-};
-
-// WeakPtr Method: Arity 1 -> 0.
-template <typename StorageType, typename T, typename X1>
-struct Invoker2<true, StorageType, void(T::*)(X1)> {
-  typedef void(*DoInvokeType)(
-      internal::InvokerStorageBase*);
-
-  static void DoInvoke(InvokerStorageBase* base) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_;
-    if (!weak_ptr.get()) {
-      return;
-    }
-    (weak_ptr->*invoker->f_)(Unwrap(invoker->p2_));
-  }
-};
-
-// Function: Arity 3 -> 1.
-template <typename StorageType, typename R,typename X1, typename X2,
-    typename X3>
-struct Invoker2<false, StorageType, R(*)(X1, X2, X3)> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X3>::ForwardType);
-
-  static R DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X3>::ForwardType x3) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_), x3);
-  }
-};
-
-// Method: Arity 2 -> 1.
-template <typename StorageType, typename R, typename T, typename X1,
-    typename X2>
-struct Invoker2<false, StorageType, R(T::*)(X1, X2)> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X2>::ForwardType);
-
-  static R DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X2>::ForwardType x2) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_), x2);
-  }
-};
-
-// WeakPtr Method: Arity 2 -> 1.
-template <typename StorageType, typename T, typename X1, typename X2>
-struct Invoker2<true, StorageType, void(T::*)(X1, X2)> {
-  typedef void(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X2>::ForwardType);
-
-  static void DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X2>::ForwardType x2) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_;
-    if (!weak_ptr.get()) {
-      return;
-    }
-    (weak_ptr->*invoker->f_)(Unwrap(invoker->p2_), x2);
-  }
-};
-
-// Function: Arity 4 -> 2.
-template <typename StorageType, typename R,typename X1, typename X2,
-    typename X3, typename X4>
-struct Invoker2<false, StorageType, R(*)(X1, X2, X3, X4)> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X3>::ForwardType,
-          typename internal::ParamTraits<X4>::ForwardType);
-
-  static R DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X3>::ForwardType x3,
-      typename internal::ParamTraits<X4>::ForwardType x4) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_), x3, x4);
-  }
-};
-
-// Method: Arity 3 -> 2.
-template <typename StorageType, typename R, typename T, typename X1,
-    typename X2, typename X3>
-struct Invoker2<false, StorageType, R(T::*)(X1, X2, X3)> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X2>::ForwardType,
-          typename internal::ParamTraits<X3>::ForwardType);
-
-  static R DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X2>::ForwardType x2,
-      typename internal::ParamTraits<X3>::ForwardType x3) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_), x2, x3);
-  }
-};
-
-// WeakPtr Method: Arity 3 -> 2.
-template <typename StorageType, typename T, typename X1, typename X2,
-    typename X3>
-struct Invoker2<true, StorageType, void(T::*)(X1, X2, X3)> {
-  typedef void(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X2>::ForwardType,
-          typename internal::ParamTraits<X3>::ForwardType);
-
-  static void DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X2>::ForwardType x2,
-      typename internal::ParamTraits<X3>::ForwardType x3) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_;
-    if (!weak_ptr.get()) {
-      return;
-    }
-    (weak_ptr->*invoker->f_)(Unwrap(invoker->p2_), x2, x3);
-  }
-};
-
-// Function: Arity 5 -> 3.
-template <typename StorageType, typename R,typename X1, typename X2,
-    typename X3, typename X4, typename X5>
-struct Invoker2<false, StorageType, R(*)(X1, X2, X3, X4, X5)> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X3>::ForwardType,
-          typename internal::ParamTraits<X4>::ForwardType,
-          typename internal::ParamTraits<X5>::ForwardType);
-
-  static R DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X3>::ForwardType x3,
-      typename internal::ParamTraits<X4>::ForwardType x4,
-      typename internal::ParamTraits<X5>::ForwardType x5) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_), x3, x4, x5);
-  }
-};
-
-// Method: Arity 4 -> 3.
-template <typename StorageType, typename R, typename T, typename X1,
-    typename X2, typename X3, typename X4>
-struct Invoker2<false, StorageType, R(T::*)(X1, X2, X3, X4)> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X2>::ForwardType,
-          typename internal::ParamTraits<X3>::ForwardType,
-          typename internal::ParamTraits<X4>::ForwardType);
-
-  static R DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X2>::ForwardType x2,
-      typename internal::ParamTraits<X3>::ForwardType x3,
-      typename internal::ParamTraits<X4>::ForwardType x4) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_), x2, x3,
-        x4);
-  }
-};
-
-// WeakPtr Method: Arity 4 -> 3.
-template <typename StorageType, typename T, typename X1, typename X2,
-    typename X3, typename X4>
-struct Invoker2<true, StorageType, void(T::*)(X1, X2, X3, X4)> {
-  typedef void(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X2>::ForwardType,
-          typename internal::ParamTraits<X3>::ForwardType,
-          typename internal::ParamTraits<X4>::ForwardType);
-
-  static void DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X2>::ForwardType x2,
-      typename internal::ParamTraits<X3>::ForwardType x3,
-      typename internal::ParamTraits<X4>::ForwardType x4) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_;
-    if (!weak_ptr.get()) {
-      return;
-    }
-    (weak_ptr->*invoker->f_)(Unwrap(invoker->p2_), x2, x3, x4);
-  }
-};
-
-// Function: Arity 6 -> 4.
-template <typename StorageType, typename R,typename X1, typename X2,
-    typename X3, typename X4, typename X5, typename X6>
-struct Invoker2<false, StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X3>::ForwardType,
-          typename internal::ParamTraits<X4>::ForwardType,
-          typename internal::ParamTraits<X5>::ForwardType,
-          typename internal::ParamTraits<X6>::ForwardType);
-
-  static R DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X3>::ForwardType x3,
-      typename internal::ParamTraits<X4>::ForwardType x4,
-      typename internal::ParamTraits<X5>::ForwardType x5,
-      typename internal::ParamTraits<X6>::ForwardType x6) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_), x3, x4, x5,
-        x6);
-  }
-};
-
-// Method: Arity 5 -> 4.
-template <typename StorageType, typename R, typename T, typename X1,
-    typename X2, typename X3, typename X4, typename X5>
-struct Invoker2<false, StorageType, R(T::*)(X1, X2, X3, X4, X5)> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X2>::ForwardType,
-          typename internal::ParamTraits<X3>::ForwardType,
-          typename internal::ParamTraits<X4>::ForwardType,
-          typename internal::ParamTraits<X5>::ForwardType);
-
-  static R DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X2>::ForwardType x2,
-      typename internal::ParamTraits<X3>::ForwardType x3,
-      typename internal::ParamTraits<X4>::ForwardType x4,
-      typename internal::ParamTraits<X5>::ForwardType x5) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_), x2, x3,
-        x4, x5);
-  }
-};
-
-// WeakPtr Method: Arity 5 -> 4.
-template <typename StorageType, typename T, typename X1, typename X2,
-    typename X3, typename X4, typename X5>
-struct Invoker2<true, StorageType, void(T::*)(X1, X2, X3, X4, X5)> {
-  typedef void(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X2>::ForwardType,
-          typename internal::ParamTraits<X3>::ForwardType,
-          typename internal::ParamTraits<X4>::ForwardType,
-          typename internal::ParamTraits<X5>::ForwardType);
-
-  static void DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X2>::ForwardType x2,
-      typename internal::ParamTraits<X3>::ForwardType x3,
-      typename internal::ParamTraits<X4>::ForwardType x4,
-      typename internal::ParamTraits<X5>::ForwardType x5) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_;
-    if (!weak_ptr.get()) {
-      return;
-    }
-    (weak_ptr->*invoker->f_)(Unwrap(invoker->p2_), x2, x3, x4, x5);
-  }
-};
-
-template <bool IsWeak, typename StorageType, typename NormalizedSig>
-struct Invoker3;
-
-// Function: Arity 3 -> 0.
-template <typename StorageType, typename R,typename X1, typename X2,
-    typename X3>
-struct Invoker3<false, StorageType, R(*)(X1, X2, X3)> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*);
-
-  static R DoInvoke(InvokerStorageBase* base) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
-        Unwrap(invoker->p3_));
-  }
-};
-
-// Method: Arity 2 -> 0.
-template <typename StorageType, typename R, typename T, typename X1,
-    typename X2>
-struct Invoker3<false, StorageType, R(T::*)(X1, X2)> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*);
-
-  static R DoInvoke(InvokerStorageBase* base) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
-        Unwrap(invoker->p3_));
-  }
-};
-
-// WeakPtr Method: Arity 2 -> 0.
-template <typename StorageType, typename T, typename X1, typename X2>
-struct Invoker3<true, StorageType, void(T::*)(X1, X2)> {
-  typedef void(*DoInvokeType)(
-      internal::InvokerStorageBase*);
-
-  static void DoInvoke(InvokerStorageBase* base) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_;
-    if (!weak_ptr.get()) {
-      return;
-    }
-    (weak_ptr->*invoker->f_)(Unwrap(invoker->p2_), Unwrap(invoker->p3_));
-  }
-};
-
-// Function: Arity 4 -> 1.
-template <typename StorageType, typename R,typename X1, typename X2,
-    typename X3, typename X4>
-struct Invoker3<false, StorageType, R(*)(X1, X2, X3, X4)> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X4>::ForwardType);
-
-  static R DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X4>::ForwardType x4) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
-        Unwrap(invoker->p3_), x4);
-  }
-};
-
-// Method: Arity 3 -> 1.
-template <typename StorageType, typename R, typename T, typename X1,
-    typename X2, typename X3>
-struct Invoker3<false, StorageType, R(T::*)(X1, X2, X3)> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X3>::ForwardType);
-
-  static R DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X3>::ForwardType x3) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
-        Unwrap(invoker->p3_), x3);
-  }
-};
-
-// WeakPtr Method: Arity 3 -> 1.
-template <typename StorageType, typename T, typename X1, typename X2,
-    typename X3>
-struct Invoker3<true, StorageType, void(T::*)(X1, X2, X3)> {
-  typedef void(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X3>::ForwardType);
-
-  static void DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X3>::ForwardType x3) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_;
-    if (!weak_ptr.get()) {
-      return;
-    }
-    (weak_ptr->*invoker->f_)(Unwrap(invoker->p2_), Unwrap(invoker->p3_), x3);
-  }
-};
-
-// Function: Arity 5 -> 2.
-template <typename StorageType, typename R,typename X1, typename X2,
-    typename X3, typename X4, typename X5>
-struct Invoker3<false, StorageType, R(*)(X1, X2, X3, X4, X5)> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X4>::ForwardType,
-          typename internal::ParamTraits<X5>::ForwardType);
-
-  static R DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X4>::ForwardType x4,
-      typename internal::ParamTraits<X5>::ForwardType x5) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
-        Unwrap(invoker->p3_), x4, x5);
-  }
-};
-
-// Method: Arity 4 -> 2.
-template <typename StorageType, typename R, typename T, typename X1,
-    typename X2, typename X3, typename X4>
-struct Invoker3<false, StorageType, R(T::*)(X1, X2, X3, X4)> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X3>::ForwardType,
-          typename internal::ParamTraits<X4>::ForwardType);
-
-  static R DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X3>::ForwardType x3,
-      typename internal::ParamTraits<X4>::ForwardType x4) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
-        Unwrap(invoker->p3_), x3, x4);
-  }
-};
-
-// WeakPtr Method: Arity 4 -> 2.
-template <typename StorageType, typename T, typename X1, typename X2,
-    typename X3, typename X4>
-struct Invoker3<true, StorageType, void(T::*)(X1, X2, X3, X4)> {
-  typedef void(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X3>::ForwardType,
-          typename internal::ParamTraits<X4>::ForwardType);
-
-  static void DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X3>::ForwardType x3,
-      typename internal::ParamTraits<X4>::ForwardType x4) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_;
-    if (!weak_ptr.get()) {
-      return;
-    }
-    (weak_ptr->*invoker->f_)(Unwrap(invoker->p2_), Unwrap(invoker->p3_), x3,
-        x4);
-  }
-};
-
-// Function: Arity 6 -> 3.
-template <typename StorageType, typename R,typename X1, typename X2,
-    typename X3, typename X4, typename X5, typename X6>
-struct Invoker3<false, StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X4>::ForwardType,
-          typename internal::ParamTraits<X5>::ForwardType,
-          typename internal::ParamTraits<X6>::ForwardType);
-
-  static R DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X4>::ForwardType x4,
-      typename internal::ParamTraits<X5>::ForwardType x5,
-      typename internal::ParamTraits<X6>::ForwardType x6) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
-        Unwrap(invoker->p3_), x4, x5, x6);
-  }
-};
-
-// Method: Arity 5 -> 3.
-template <typename StorageType, typename R, typename T, typename X1,
-    typename X2, typename X3, typename X4, typename X5>
-struct Invoker3<false, StorageType, R(T::*)(X1, X2, X3, X4, X5)> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X3>::ForwardType,
-          typename internal::ParamTraits<X4>::ForwardType,
-          typename internal::ParamTraits<X5>::ForwardType);
-
-  static R DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X3>::ForwardType x3,
-      typename internal::ParamTraits<X4>::ForwardType x4,
-      typename internal::ParamTraits<X5>::ForwardType x5) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
-        Unwrap(invoker->p3_), x3, x4, x5);
-  }
-};
-
-// WeakPtr Method: Arity 5 -> 3.
-template <typename StorageType, typename T, typename X1, typename X2,
-    typename X3, typename X4, typename X5>
-struct Invoker3<true, StorageType, void(T::*)(X1, X2, X3, X4, X5)> {
-  typedef void(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X3>::ForwardType,
-          typename internal::ParamTraits<X4>::ForwardType,
-          typename internal::ParamTraits<X5>::ForwardType);
-
-  static void DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X3>::ForwardType x3,
-      typename internal::ParamTraits<X4>::ForwardType x4,
-      typename internal::ParamTraits<X5>::ForwardType x5) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_;
-    if (!weak_ptr.get()) {
-      return;
-    }
-    (weak_ptr->*invoker->f_)(Unwrap(invoker->p2_), Unwrap(invoker->p3_), x3,
-        x4, x5);
-  }
-};
-
-template <bool IsWeak, typename StorageType, typename NormalizedSig>
-struct Invoker4;
-
-// Function: Arity 4 -> 0.
-template <typename StorageType, typename R,typename X1, typename X2,
-    typename X3, typename X4>
-struct Invoker4<false, StorageType, R(*)(X1, X2, X3, X4)> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*);
-
-  static R DoInvoke(InvokerStorageBase* base) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
-        Unwrap(invoker->p3_), Unwrap(invoker->p4_));
-  }
-};
-
-// Method: Arity 3 -> 0.
-template <typename StorageType, typename R, typename T, typename X1,
-    typename X2, typename X3>
-struct Invoker4<false, StorageType, R(T::*)(X1, X2, X3)> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*);
-
-  static R DoInvoke(InvokerStorageBase* base) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
-        Unwrap(invoker->p3_), Unwrap(invoker->p4_));
-  }
-};
-
-// WeakPtr Method: Arity 3 -> 0.
-template <typename StorageType, typename T, typename X1, typename X2,
-    typename X3>
-struct Invoker4<true, StorageType, void(T::*)(X1, X2, X3)> {
-  typedef void(*DoInvokeType)(
-      internal::InvokerStorageBase*);
-
-  static void DoInvoke(InvokerStorageBase* base) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_;
-    if (!weak_ptr.get()) {
-      return;
-    }
-    (weak_ptr->*invoker->f_)(Unwrap(invoker->p2_), Unwrap(invoker->p3_),
-        Unwrap(invoker->p4_));
-  }
-};
-
-// Function: Arity 5 -> 1.
-template <typename StorageType, typename R,typename X1, typename X2,
-    typename X3, typename X4, typename X5>
-struct Invoker4<false, StorageType, R(*)(X1, X2, X3, X4, X5)> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X5>::ForwardType);
-
-  static R DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X5>::ForwardType x5) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
-        Unwrap(invoker->p3_), Unwrap(invoker->p4_), x5);
-  }
-};
-
-// Method: Arity 4 -> 1.
-template <typename StorageType, typename R, typename T, typename X1,
-    typename X2, typename X3, typename X4>
-struct Invoker4<false, StorageType, R(T::*)(X1, X2, X3, X4)> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X4>::ForwardType);
-
-  static R DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X4>::ForwardType x4) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
-        Unwrap(invoker->p3_), Unwrap(invoker->p4_), x4);
-  }
-};
-
-// WeakPtr Method: Arity 4 -> 1.
-template <typename StorageType, typename T, typename X1, typename X2,
-    typename X3, typename X4>
-struct Invoker4<true, StorageType, void(T::*)(X1, X2, X3, X4)> {
-  typedef void(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X4>::ForwardType);
-
-  static void DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X4>::ForwardType x4) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_;
-    if (!weak_ptr.get()) {
-      return;
-    }
-    (weak_ptr->*invoker->f_)(Unwrap(invoker->p2_), Unwrap(invoker->p3_),
-        Unwrap(invoker->p4_), x4);
-  }
-};
-
-// Function: Arity 6 -> 2.
-template <typename StorageType, typename R,typename X1, typename X2,
-    typename X3, typename X4, typename X5, typename X6>
-struct Invoker4<false, StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X5>::ForwardType,
-          typename internal::ParamTraits<X6>::ForwardType);
-
-  static R DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X5>::ForwardType x5,
-      typename internal::ParamTraits<X6>::ForwardType x6) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
-        Unwrap(invoker->p3_), Unwrap(invoker->p4_), x5, x6);
-  }
-};
-
-// Method: Arity 5 -> 2.
-template <typename StorageType, typename R, typename T, typename X1,
-    typename X2, typename X3, typename X4, typename X5>
-struct Invoker4<false, StorageType, R(T::*)(X1, X2, X3, X4, X5)> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X4>::ForwardType,
-          typename internal::ParamTraits<X5>::ForwardType);
-
-  static R DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X4>::ForwardType x4,
-      typename internal::ParamTraits<X5>::ForwardType x5) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
-        Unwrap(invoker->p3_), Unwrap(invoker->p4_), x4, x5);
-  }
-};
-
-// WeakPtr Method: Arity 5 -> 2.
-template <typename StorageType, typename T, typename X1, typename X2,
-    typename X3, typename X4, typename X5>
-struct Invoker4<true, StorageType, void(T::*)(X1, X2, X3, X4, X5)> {
-  typedef void(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X4>::ForwardType,
-          typename internal::ParamTraits<X5>::ForwardType);
-
-  static void DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X4>::ForwardType x4,
-      typename internal::ParamTraits<X5>::ForwardType x5) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_;
-    if (!weak_ptr.get()) {
-      return;
-    }
-    (weak_ptr->*invoker->f_)(Unwrap(invoker->p2_), Unwrap(invoker->p3_),
-        Unwrap(invoker->p4_), x4, x5);
-  }
-};
-
-template <bool IsWeak, typename StorageType, typename NormalizedSig>
-struct Invoker5;
-
-// Function: Arity 5 -> 0.
-template <typename StorageType, typename R,typename X1, typename X2,
-    typename X3, typename X4, typename X5>
-struct Invoker5<false, StorageType, R(*)(X1, X2, X3, X4, X5)> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*);
-
-  static R DoInvoke(InvokerStorageBase* base) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
-        Unwrap(invoker->p3_), Unwrap(invoker->p4_), Unwrap(invoker->p5_));
-  }
-};
-
-// Method: Arity 4 -> 0.
-template <typename StorageType, typename R, typename T, typename X1,
-    typename X2, typename X3, typename X4>
-struct Invoker5<false, StorageType, R(T::*)(X1, X2, X3, X4)> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*);
-
-  static R DoInvoke(InvokerStorageBase* base) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
-        Unwrap(invoker->p3_), Unwrap(invoker->p4_), Unwrap(invoker->p5_));
-  }
-};
-
-// WeakPtr Method: Arity 4 -> 0.
-template <typename StorageType, typename T, typename X1, typename X2,
-    typename X3, typename X4>
-struct Invoker5<true, StorageType, void(T::*)(X1, X2, X3, X4)> {
-  typedef void(*DoInvokeType)(
-      internal::InvokerStorageBase*);
-
-  static void DoInvoke(InvokerStorageBase* base) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_;
-    if (!weak_ptr.get()) {
-      return;
-    }
-    (weak_ptr->*invoker->f_)(Unwrap(invoker->p2_), Unwrap(invoker->p3_),
-        Unwrap(invoker->p4_), Unwrap(invoker->p5_));
-  }
-};
-
-// Function: Arity 6 -> 1.
-template <typename StorageType, typename R,typename X1, typename X2,
-    typename X3, typename X4, typename X5, typename X6>
-struct Invoker5<false, StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X6>::ForwardType);
-
-  static R DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X6>::ForwardType x6) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
-        Unwrap(invoker->p3_), Unwrap(invoker->p4_), Unwrap(invoker->p5_), x6);
-  }
-};
-
-// Method: Arity 5 -> 1.
-template <typename StorageType, typename R, typename T, typename X1,
-    typename X2, typename X3, typename X4, typename X5>
-struct Invoker5<false, StorageType, R(T::*)(X1, X2, X3, X4, X5)> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X5>::ForwardType);
-
-  static R DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X5>::ForwardType x5) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
-        Unwrap(invoker->p3_), Unwrap(invoker->p4_), Unwrap(invoker->p5_), x5);
-  }
-};
-
-// WeakPtr Method: Arity 5 -> 1.
-template <typename StorageType, typename T, typename X1, typename X2,
-    typename X3, typename X4, typename X5>
-struct Invoker5<true, StorageType, void(T::*)(X1, X2, X3, X4, X5)> {
-  typedef void(*DoInvokeType)(
-      internal::InvokerStorageBase*,
-          typename internal::ParamTraits<X5>::ForwardType);
-
-  static void DoInvoke(InvokerStorageBase* base,
-      typename internal::ParamTraits<X5>::ForwardType x5) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_;
-    if (!weak_ptr.get()) {
-      return;
-    }
-    (weak_ptr->*invoker->f_)(Unwrap(invoker->p2_), Unwrap(invoker->p3_),
-        Unwrap(invoker->p4_), Unwrap(invoker->p5_), x5);
-  }
-};
-
-template <bool IsWeak, typename StorageType, typename NormalizedSig>
-struct Invoker6;
-
-// Function: Arity 6 -> 0.
-template <typename StorageType, typename R,typename X1, typename X2,
-    typename X3, typename X4, typename X5, typename X6>
-struct Invoker6<false, StorageType, R(*)(X1, X2, X3, X4, X5, X6)> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*);
-
-  static R DoInvoke(InvokerStorageBase* base) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return invoker->f_(Unwrap(invoker->p1_), Unwrap(invoker->p2_),
-        Unwrap(invoker->p3_), Unwrap(invoker->p4_), Unwrap(invoker->p5_),
-        Unwrap(invoker->p6_));
-  }
-};
-
-// Method: Arity 5 -> 0.
-template <typename StorageType, typename R, typename T, typename X1,
-    typename X2, typename X3, typename X4, typename X5>
-struct Invoker6<false, StorageType, R(T::*)(X1, X2, X3, X4, X5)> {
-  typedef R(*DoInvokeType)(
-      internal::InvokerStorageBase*);
-
-  static R DoInvoke(InvokerStorageBase* base) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    return (Unwrap(invoker->p1_)->*invoker->f_)(Unwrap(invoker->p2_),
-        Unwrap(invoker->p3_), Unwrap(invoker->p4_), Unwrap(invoker->p5_),
-        Unwrap(invoker->p6_));
-  }
-};
-
-// WeakPtr Method: Arity 5 -> 0.
-template <typename StorageType, typename T, typename X1, typename X2,
-    typename X3, typename X4, typename X5>
-struct Invoker6<true, StorageType, void(T::*)(X1, X2, X3, X4, X5)> {
-  typedef void(*DoInvokeType)(
-      internal::InvokerStorageBase*);
-
-  static void DoInvoke(InvokerStorageBase* base) {
-    StorageType* invoker = static_cast<StorageType*>(base);
-    typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_;
-    if (!weak_ptr.get()) {
-      return;
-    }
-    (weak_ptr->*invoker->f_)(Unwrap(invoker->p2_), Unwrap(invoker->p3_),
-        Unwrap(invoker->p4_), Unwrap(invoker->p5_), Unwrap(invoker->p6_));
-  }
-};
-
-// BindMoreFuncN<>
-//
-// This set of functions help in fully binding the free parameters in a
-// Callback<>.
-template <typename Sig, typename P1>
-void BindMoreFunc1(const base::Callback<Sig>& callback, const P1& p1) {
-  callback.Run(p1);
-}
-
-template <typename Sig, typename P1, typename P2>
-void BindMoreFunc2(const base::Callback<Sig>& callback, const P1& p1,
-    const P2& p2) {
-  callback.Run(p1, p2);
-}
-
-template <typename Sig, typename P1, typename P2, typename P3>
-void BindMoreFunc3(const base::Callback<Sig>& callback, const P1& p1,
-    const P2& p2, const P3& p3) {
-  callback.Run(p1, p2, p3);
-}
-
-template <typename Sig, typename P1, typename P2, typename P3, typename P4>
-void BindMoreFunc4(const base::Callback<Sig>& callback, const P1& p1,
-    const P2& p2, const P3& p3, const P4& p4) {
-  callback.Run(p1, p2, p3, p4);
-}
-
-template <typename Sig, typename P1, typename P2, typename P3, typename P4,
-    typename P5>
-void BindMoreFunc5(const base::Callback<Sig>& callback, const P1& p1,
-    const P2& p2, const P3& p3, const P4& p4, const P5& p5) {
-  callback.Run(p1, p2, p3, p4, p5);
-}
-
-template <typename Sig, typename P1, typename P2, typename P3, typename P4,
-    typename P5, typename P6>
-void BindMoreFunc6(const base::Callback<Sig>& callback, const P1& p1,
-    const P2& p2, const P3& p3, const P4& p4, const P5& p5, const P6& p6) {
-  callback.Run(p1, p2, p3, p4, p5, p6);
-}
-
-// InvokerStorageN<>
-//
-// These are the actual storage classes for the Invokers.
-//
-// Though these types are "classes", they are being used as structs with
-// all member variable public.  We cannot make it a struct because it inherits
-// from a class which causes a compiler warning.  We cannot add a "Run()" method
-// that forwards the unbound arguments because that would require we unwrap the
-// Sig type like in InvokerN above to know the return type, and the arity
-// of Run().
-//
-// An alternate solution would be to merge InvokerN and InvokerStorageN,
-// but the generated code seemed harder to read.
-
+// Breaks a function signature apart into typedefs for easier introspection.
 template <typename Sig>
-class InvokerStorage0 : public InvokerStorageBase {
- public:
-  typedef InvokerStorage0 StorageType;
-  typedef FunctionTraits<Sig> TargetTraits;
-  typedef typename TargetTraits::IsMethod IsMethod;
-  typedef Sig Signature;
-  typedef Invoker0<false, StorageType,
-                   typename TargetTraits::NormalizedSig> Invoker;
+struct FunctionTraits;
 
-
-
-  InvokerStorage0(Sig f)
-      : f_(f) {
-  }
-
-  virtual ~InvokerStorage0() {  }
-
-  Sig f_;
+template <typename R>
+struct FunctionTraits<R()> {
+  typedef R ReturnType;
 };
 
-template <typename Sig, typename P1>
-class InvokerStorage1 : public InvokerStorageBase {
- public:
-  typedef InvokerStorage1 StorageType;
-  typedef FunctionTraits<Sig> TargetTraits;
-  typedef typename TargetTraits::IsMethod IsMethod;
-  typedef Sig Signature;
-  typedef ParamTraits<P1> P1Traits;
-  typedef Invoker1<IsWeakMethod<IsMethod::value, P1>::value, StorageType,
-                   typename TargetTraits::NormalizedSig> Invoker;
-  COMPILE_ASSERT(!(IsWeakMethod<IsMethod::value, P1>::value) ||
-                 is_void<typename TargetTraits::Return>::value,
-                 weak_ptrs_can_only_bind_to_methods_without_return_values);
-
-  // For methods, we need to be careful for parameter 1.  We skip the
-  // scoped_refptr check because the binder itself takes care of this. We also
-  // disallow binding of an array as the method's target object.
-  COMPILE_ASSERT(IsMethod::value ||
-                 internal::NeedsScopedRefptrButGetsRawPtr<
-                     typename ParamTraits<P1>::StorageType>::value == 0,
-                 p1_is_refcounted_type_and_needs_scoped_refptr);
-  COMPILE_ASSERT(!IsMethod::value || !is_array<P1>::value,
-                 first_bound_argument_to_method_cannot_be_array);
-
-  // Do not allow binding a non-const reference parameter. Non-const reference
-  // parameters are disallowed by the Google style guide.  Also, binding a
-  // non-const reference parameter can make for subtle bugs because the
-  // invoked function will receive a reference to the stored copy of the
-  // argument and not the original.
-  COMPILE_ASSERT(
-      !( is_non_const_reference<typename TargetTraits::B1>::value ),
-      do_not_bind_functions_with_nonconst_ref);
-
-
-  InvokerStorage1(Sig f, const P1& p1)
-      : f_(f), p1_(static_cast<typename ParamTraits<P1>::StorageType>(p1)) {
-    MaybeRefcount<IsMethod, P1>::AddRef(p1_);
-  }
-
-  virtual ~InvokerStorage1() {
-    MaybeRefcount<IsMethod, P1>::Release(p1_);
-  }
-
-  Sig f_;
-  typename ParamTraits<P1>::StorageType p1_;
+template <typename R, typename A1>
+struct FunctionTraits<R(A1)> {
+  typedef R ReturnType;
+  typedef A1 A1Type;
 };
 
-template <typename Sig, typename P1, typename P2>
-class InvokerStorage2 : public InvokerStorageBase {
- public:
-  typedef InvokerStorage2 StorageType;
-  typedef FunctionTraits<Sig> TargetTraits;
-  typedef typename TargetTraits::IsMethod IsMethod;
-  typedef Sig Signature;
-  typedef ParamTraits<P1> P1Traits;
-  typedef ParamTraits<P2> P2Traits;
-  typedef Invoker2<IsWeakMethod<IsMethod::value, P1>::value, StorageType,
-                   typename TargetTraits::NormalizedSig> Invoker;
-  COMPILE_ASSERT(!(IsWeakMethod<IsMethod::value, P1>::value) ||
-                 is_void<typename TargetTraits::Return>::value,
-                 weak_ptrs_can_only_bind_to_methods_without_return_values);
-
-  // For methods, we need to be careful for parameter 1.  We skip the
-  // scoped_refptr check because the binder itself takes care of this. We also
-  // disallow binding of an array as the method's target object.
-  COMPILE_ASSERT(IsMethod::value ||
-                 internal::NeedsScopedRefptrButGetsRawPtr<
-                     typename ParamTraits<P1>::StorageType>::value == 0,
-                 p1_is_refcounted_type_and_needs_scoped_refptr);
-  COMPILE_ASSERT(!IsMethod::value || !is_array<P1>::value,
-                 first_bound_argument_to_method_cannot_be_array);
-  COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr<
-          typename ParamTraits<P2>::StorageType>::value == 0,
-      p2_is_refcounted_type_and_needs_scoped_refptr);
-
-  // Do not allow binding a non-const reference parameter. Non-const reference
-  // parameters are disallowed by the Google style guide.  Also, binding a
-  // non-const reference parameter can make for subtle bugs because the
-  // invoked function will receive a reference to the stored copy of the
-  // argument and not the original.
-  COMPILE_ASSERT(
-      !( is_non_const_reference<typename TargetTraits::B1>::value ||
-          is_non_const_reference<typename TargetTraits::B2>::value ),
-      do_not_bind_functions_with_nonconst_ref);
-
-
-  InvokerStorage2(Sig f, const P1& p1, const P2& p2)
-      : f_(f), p1_(static_cast<typename ParamTraits<P1>::StorageType>(p1)),
-          p2_(static_cast<typename ParamTraits<P2>::StorageType>(p2)) {
-    MaybeRefcount<IsMethod, P1>::AddRef(p1_);
-  }
-
-  virtual ~InvokerStorage2() {
-    MaybeRefcount<IsMethod, P1>::Release(p1_);
-  }
-
-  Sig f_;
-  typename ParamTraits<P1>::StorageType p1_;
-  typename ParamTraits<P2>::StorageType p2_;
+template <typename R, typename A1, typename A2>
+struct FunctionTraits<R(A1, A2)> {
+  typedef R ReturnType;
+  typedef A1 A1Type;
+  typedef A2 A2Type;
 };
 
-template <typename Sig, typename P1, typename P2, typename P3>
-class InvokerStorage3 : public InvokerStorageBase {
- public:
-  typedef InvokerStorage3 StorageType;
-  typedef FunctionTraits<Sig> TargetTraits;
-  typedef typename TargetTraits::IsMethod IsMethod;
-  typedef Sig Signature;
-  typedef ParamTraits<P1> P1Traits;
-  typedef ParamTraits<P2> P2Traits;
-  typedef ParamTraits<P3> P3Traits;
-  typedef Invoker3<IsWeakMethod<IsMethod::value, P1>::value, StorageType,
-                   typename TargetTraits::NormalizedSig> Invoker;
-  COMPILE_ASSERT(!(IsWeakMethod<IsMethod::value, P1>::value) ||
-                 is_void<typename TargetTraits::Return>::value,
-                 weak_ptrs_can_only_bind_to_methods_without_return_values);
-
-  // For methods, we need to be careful for parameter 1.  We skip the
-  // scoped_refptr check because the binder itself takes care of this. We also
-  // disallow binding of an array as the method's target object.
-  COMPILE_ASSERT(IsMethod::value ||
-                 internal::NeedsScopedRefptrButGetsRawPtr<
-                     typename ParamTraits<P1>::StorageType>::value == 0,
-                 p1_is_refcounted_type_and_needs_scoped_refptr);
-  COMPILE_ASSERT(!IsMethod::value || !is_array<P1>::value,
-                 first_bound_argument_to_method_cannot_be_array);
-  COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr<
-          typename ParamTraits<P2>::StorageType>::value == 0,
-      p2_is_refcounted_type_and_needs_scoped_refptr);
-  COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr<
-          typename ParamTraits<P3>::StorageType>::value == 0,
-      p3_is_refcounted_type_and_needs_scoped_refptr);
-
-  // Do not allow binding a non-const reference parameter. Non-const reference
-  // parameters are disallowed by the Google style guide.  Also, binding a
-  // non-const reference parameter can make for subtle bugs because the
-  // invoked function will receive a reference to the stored copy of the
-  // argument and not the original.
-  COMPILE_ASSERT(
-      !( is_non_const_reference<typename TargetTraits::B1>::value ||
-          is_non_const_reference<typename TargetTraits::B2>::value ||
-          is_non_const_reference<typename TargetTraits::B3>::value ),
-      do_not_bind_functions_with_nonconst_ref);
-
-
-  InvokerStorage3(Sig f, const P1& p1, const P2& p2, const P3& p3)
-      : f_(f), p1_(static_cast<typename ParamTraits<P1>::StorageType>(p1)),
-          p2_(static_cast<typename ParamTraits<P2>::StorageType>(p2)),
-          p3_(static_cast<typename ParamTraits<P3>::StorageType>(p3)) {
-    MaybeRefcount<IsMethod, P1>::AddRef(p1_);
-  }
-
-  virtual ~InvokerStorage3() {
-    MaybeRefcount<IsMethod, P1>::Release(p1_);
-  }
-
-  Sig f_;
-  typename ParamTraits<P1>::StorageType p1_;
-  typename ParamTraits<P2>::StorageType p2_;
-  typename ParamTraits<P3>::StorageType p3_;
+template <typename R, typename A1, typename A2, typename A3>
+struct FunctionTraits<R(A1, A2, A3)> {
+  typedef R ReturnType;
+  typedef A1 A1Type;
+  typedef A2 A2Type;
+  typedef A3 A3Type;
 };
 
-template <typename Sig, typename P1, typename P2, typename P3, typename P4>
-class InvokerStorage4 : public InvokerStorageBase {
- public:
-  typedef InvokerStorage4 StorageType;
-  typedef FunctionTraits<Sig> TargetTraits;
-  typedef typename TargetTraits::IsMethod IsMethod;
-  typedef Sig Signature;
-  typedef ParamTraits<P1> P1Traits;
-  typedef ParamTraits<P2> P2Traits;
-  typedef ParamTraits<P3> P3Traits;
-  typedef ParamTraits<P4> P4Traits;
-  typedef Invoker4<IsWeakMethod<IsMethod::value, P1>::value, StorageType,
-                   typename TargetTraits::NormalizedSig> Invoker;
-  COMPILE_ASSERT(!(IsWeakMethod<IsMethod::value, P1>::value) ||
-                 is_void<typename TargetTraits::Return>::value,
-                 weak_ptrs_can_only_bind_to_methods_without_return_values);
-
-  // For methods, we need to be careful for parameter 1.  We skip the
-  // scoped_refptr check because the binder itself takes care of this. We also
-  // disallow binding of an array as the method's target object.
-  COMPILE_ASSERT(IsMethod::value ||
-                 internal::NeedsScopedRefptrButGetsRawPtr<
-                     typename ParamTraits<P1>::StorageType>::value == 0,
-                 p1_is_refcounted_type_and_needs_scoped_refptr);
-  COMPILE_ASSERT(!IsMethod::value || !is_array<P1>::value,
-                 first_bound_argument_to_method_cannot_be_array);
-  COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr<
-          typename ParamTraits<P2>::StorageType>::value == 0,
-      p2_is_refcounted_type_and_needs_scoped_refptr);
-  COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr<
-          typename ParamTraits<P3>::StorageType>::value == 0,
-      p3_is_refcounted_type_and_needs_scoped_refptr);
-  COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr<
-          typename ParamTraits<P4>::StorageType>::value == 0,
-      p4_is_refcounted_type_and_needs_scoped_refptr);
-
-  // Do not allow binding a non-const reference parameter. Non-const reference
-  // parameters are disallowed by the Google style guide.  Also, binding a
-  // non-const reference parameter can make for subtle bugs because the
-  // invoked function will receive a reference to the stored copy of the
-  // argument and not the original.
-  COMPILE_ASSERT(
-      !( is_non_const_reference<typename TargetTraits::B1>::value ||
-          is_non_const_reference<typename TargetTraits::B2>::value ||
-          is_non_const_reference<typename TargetTraits::B3>::value ||
-          is_non_const_reference<typename TargetTraits::B4>::value ),
-      do_not_bind_functions_with_nonconst_ref);
-
-
-  InvokerStorage4(Sig f, const P1& p1, const P2& p2, const P3& p3, const P4& p4)
-      : f_(f), p1_(static_cast<typename ParamTraits<P1>::StorageType>(p1)),
-          p2_(static_cast<typename ParamTraits<P2>::StorageType>(p2)),
-          p3_(static_cast<typename ParamTraits<P3>::StorageType>(p3)),
-          p4_(static_cast<typename ParamTraits<P4>::StorageType>(p4)) {
-    MaybeRefcount<IsMethod, P1>::AddRef(p1_);
-  }
-
-  virtual ~InvokerStorage4() {
-    MaybeRefcount<IsMethod, P1>::Release(p1_);
-  }
-
-  Sig f_;
-  typename ParamTraits<P1>::StorageType p1_;
-  typename ParamTraits<P2>::StorageType p2_;
-  typename ParamTraits<P3>::StorageType p3_;
-  typename ParamTraits<P4>::StorageType p4_;
+template <typename R, typename A1, typename A2, typename A3, typename A4>
+struct FunctionTraits<R(A1, A2, A3, A4)> {
+  typedef R ReturnType;
+  typedef A1 A1Type;
+  typedef A2 A2Type;
+  typedef A3 A3Type;
+  typedef A4 A4Type;
 };
 
-template <typename Sig, typename P1, typename P2, typename P3, typename P4,
-    typename P5>
-class InvokerStorage5 : public InvokerStorageBase {
- public:
-  typedef InvokerStorage5 StorageType;
-  typedef FunctionTraits<Sig> TargetTraits;
-  typedef typename TargetTraits::IsMethod IsMethod;
-  typedef Sig Signature;
-  typedef ParamTraits<P1> P1Traits;
-  typedef ParamTraits<P2> P2Traits;
-  typedef ParamTraits<P3> P3Traits;
-  typedef ParamTraits<P4> P4Traits;
-  typedef ParamTraits<P5> P5Traits;
-  typedef Invoker5<IsWeakMethod<IsMethod::value, P1>::value, StorageType,
-                   typename TargetTraits::NormalizedSig> Invoker;
-  COMPILE_ASSERT(!(IsWeakMethod<IsMethod::value, P1>::value) ||
-                 is_void<typename TargetTraits::Return>::value,
+template <typename R, typename A1, typename A2, typename A3, typename A4,
+    typename A5>
+struct FunctionTraits<R(A1, A2, A3, A4, A5)> {
+  typedef R ReturnType;
+  typedef A1 A1Type;
+  typedef A2 A2Type;
+  typedef A3 A3Type;
+  typedef A4 A4Type;
+  typedef A5 A5Type;
+};
+
+template <typename R, typename A1, typename A2, typename A3, typename A4,
+    typename A5, typename A6>
+struct FunctionTraits<R(A1, A2, A3, A4, A5, A6)> {
+  typedef R ReturnType;
+  typedef A1 A1Type;
+  typedef A2 A2Type;
+  typedef A3 A3Type;
+  typedef A4 A4Type;
+  typedef A5 A5Type;
+  typedef A6 A6Type;
+};
+
+
+// ForceVoidReturn<>
+//
+// Set of templates that support forcing the function return type to void.
+template <typename Sig>
+struct ForceVoidReturn;
+
+template <typename R>
+struct ForceVoidReturn<R()> {
+  typedef void(RunType)();
+};
+
+template <typename R, typename A1>
+struct ForceVoidReturn<R(A1)> {
+  typedef void(RunType)(A1);
+};
+
+template <typename R, typename A1, typename A2>
+struct ForceVoidReturn<R(A1, A2)> {
+  typedef void(RunType)(A1, A2);
+};
+
+template <typename R, typename A1, typename A2, typename A3>
+struct ForceVoidReturn<R(A1, A2, A3)> {
+  typedef void(RunType)(A1, A2, A3);
+};
+
+template <typename R, typename A1, typename A2, typename A3, typename A4>
+struct ForceVoidReturn<R(A1, A2, A3, A4)> {
+  typedef void(RunType)(A1, A2, A3, A4);
+};
+
+template <typename R, typename A1, typename A2, typename A3, typename A4,
+    typename A5>
+struct ForceVoidReturn<R(A1, A2, A3, A4, A5)> {
+  typedef void(RunType)(A1, A2, A3, A4, A5);
+};
+
+template <typename R, typename A1, typename A2, typename A3, typename A4,
+    typename A5, typename A6>
+struct ForceVoidReturn<R(A1, A2, A3, A4, A5, A6)> {
+  typedef void(RunType)(A1, A2, A3, A4, A5, A6);
+};
+
+
+// FunctorTraits<>
+//
+// See description at top of file.
+template <typename T>
+struct FunctorTraits {
+  typedef RunnableAdapter<T> RunnableType;
+  typedef typename RunnableType::RunType RunType;
+};
+
+template <typename T>
+struct FunctorTraits<IgnoreResultHelper<T> > {
+  typedef typename FunctorTraits<T>::RunnableType RunnableType;
+  typedef typename ForceVoidReturn<
+      typename RunnableType::RunType>::RunType RunType;
+};
+
+template <typename T>
+struct FunctorTraits<Callback<T> > {
+  typedef Callback<T> RunnableType;
+  typedef typename Callback<T>::RunType RunType;
+};
+
+
+// MakeRunnable<>
+//
+// Converts a passed in functor to a RunnableType using type inference.
+
+template <typename T>
+typename FunctorTraits<T>::RunnableType MakeRunnable(const T& t) {
+  return RunnableAdapter<T>(t);
+}
+
+template <typename T>
+typename FunctorTraits<T>::RunnableType
+MakeRunnable(const IgnoreResultHelper<T>& t) {
+  return MakeRunnable(t.functor_);
+}
+
+template <typename T>
+const typename FunctorTraits<Callback<T> >::RunnableType&
+MakeRunnable(const Callback<T>& t) {
+  return t;
+}
+
+
+// InvokeHelper<>
+//
+// There are 3 logical InvokeHelper<> specializations: normal, void-return,
+// WeakCalls.
+//
+// The normal type just calls the underlying runnable.
+//
+// We need a InvokeHelper to handle void return types in order to support
+// IgnoreResult().  Normally, if the Runnable's RunType had a void return,
+// the template system would just accept "return functor.Run()" ignoring
+// the fact that a void function is being used with return. This piece of
+// sugar breaks though when the Runnable's RunType is not void.  Thus, we
+// need a partial specialization to change the syntax to drop the "return"
+// from the invocation call.
+//
+// WeakCalls similarly need special syntax that is applied to the first
+// argument to check if they should no-op themselves.
+template <bool IsWeakCall, typename ReturnType, typename Runnable,
+          typename ArgsType>
+struct InvokeHelper;
+
+template <typename ReturnType, typename Runnable>
+struct InvokeHelper<false, ReturnType, Runnable,
+    void()>  {
+  static ReturnType MakeItSo(Runnable runnable) {
+    return runnable.Run();
+  }
+};
+
+template <typename Runnable>
+struct InvokeHelper<false, void, Runnable,
+    void()>  {
+  static void MakeItSo(Runnable runnable) {
+    runnable.Run();
+  }
+};
+
+template <typename ReturnType, typename Runnable,typename A1>
+struct InvokeHelper<false, ReturnType, Runnable,
+    void(A1)>  {
+  static ReturnType MakeItSo(Runnable runnable, A1 a1) {
+    return runnable.Run(a1);
+  }
+};
+
+template <typename Runnable,typename A1>
+struct InvokeHelper<false, void, Runnable,
+    void(A1)>  {
+  static void MakeItSo(Runnable runnable, A1 a1) {
+    runnable.Run(a1);
+  }
+};
+
+template <typename Runnable, typename A1>
+struct InvokeHelper<true, void, Runnable,
+    void(A1)>  {
+  static void MakeItSo(Runnable runnable, A1 a1) {
+    if (!a1.get()) {
+      return;
+    }
+
+    runnable.Run(a1);
+  }
+};
+
+template <typename ReturnType, typename Runnable,typename A1, typename A2>
+struct InvokeHelper<false, ReturnType, Runnable,
+    void(A1, A2)>  {
+  static ReturnType MakeItSo(Runnable runnable, A1 a1, A2 a2) {
+    return runnable.Run(a1, a2);
+  }
+};
+
+template <typename Runnable,typename A1, typename A2>
+struct InvokeHelper<false, void, Runnable,
+    void(A1, A2)>  {
+  static void MakeItSo(Runnable runnable, A1 a1, A2 a2) {
+    runnable.Run(a1, a2);
+  }
+};
+
+template <typename Runnable, typename A1, typename A2>
+struct InvokeHelper<true, void, Runnable,
+    void(A1, A2)>  {
+  static void MakeItSo(Runnable runnable, A1 a1, A2 a2) {
+    if (!a1.get()) {
+      return;
+    }
+
+    runnable.Run(a1, a2);
+  }
+};
+
+template <typename ReturnType, typename Runnable,typename A1, typename A2,
+    typename A3>
+struct InvokeHelper<false, ReturnType, Runnable,
+    void(A1, A2, A3)>  {
+  static ReturnType MakeItSo(Runnable runnable, A1 a1, A2 a2, A3 a3) {
+    return runnable.Run(a1, a2, a3);
+  }
+};
+
+template <typename Runnable,typename A1, typename A2, typename A3>
+struct InvokeHelper<false, void, Runnable,
+    void(A1, A2, A3)>  {
+  static void MakeItSo(Runnable runnable, A1 a1, A2 a2, A3 a3) {
+    runnable.Run(a1, a2, a3);
+  }
+};
+
+template <typename Runnable, typename A1, typename A2, typename A3>
+struct InvokeHelper<true, void, Runnable,
+    void(A1, A2, A3)>  {
+  static void MakeItSo(Runnable runnable, A1 a1, A2 a2, A3 a3) {
+    if (!a1.get()) {
+      return;
+    }
+
+    runnable.Run(a1, a2, a3);
+  }
+};
+
+template <typename ReturnType, typename Runnable,typename A1, typename A2,
+    typename A3, typename A4>
+struct InvokeHelper<false, ReturnType, Runnable,
+    void(A1, A2, A3, A4)>  {
+  static ReturnType MakeItSo(Runnable runnable, A1 a1, A2 a2, A3 a3, A4 a4) {
+    return runnable.Run(a1, a2, a3, a4);
+  }
+};
+
+template <typename Runnable,typename A1, typename A2, typename A3, typename A4>
+struct InvokeHelper<false, void, Runnable,
+    void(A1, A2, A3, A4)>  {
+  static void MakeItSo(Runnable runnable, A1 a1, A2 a2, A3 a3, A4 a4) {
+    runnable.Run(a1, a2, a3, a4);
+  }
+};
+
+template <typename Runnable, typename A1, typename A2, typename A3, typename A4>
+struct InvokeHelper<true, void, Runnable,
+    void(A1, A2, A3, A4)>  {
+  static void MakeItSo(Runnable runnable, A1 a1, A2 a2, A3 a3, A4 a4) {
+    if (!a1.get()) {
+      return;
+    }
+
+    runnable.Run(a1, a2, a3, a4);
+  }
+};
+
+template <typename ReturnType, typename Runnable,typename A1, typename A2,
+    typename A3, typename A4, typename A5>
+struct InvokeHelper<false, ReturnType, Runnable,
+    void(A1, A2, A3, A4, A5)>  {
+  static ReturnType MakeItSo(Runnable runnable, A1 a1, A2 a2, A3 a3, A4 a4,
+      A5 a5) {
+    return runnable.Run(a1, a2, a3, a4, a5);
+  }
+};
+
+template <typename Runnable,typename A1, typename A2, typename A3, typename A4,
+    typename A5>
+struct InvokeHelper<false, void, Runnable,
+    void(A1, A2, A3, A4, A5)>  {
+  static void MakeItSo(Runnable runnable, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) {
+    runnable.Run(a1, a2, a3, a4, a5);
+  }
+};
+
+template <typename Runnable, typename A1, typename A2, typename A3,
+    typename A4, typename A5>
+struct InvokeHelper<true, void, Runnable,
+    void(A1, A2, A3, A4, A5)>  {
+  static void MakeItSo(Runnable runnable, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) {
+    if (!a1.get()) {
+      return;
+    }
+
+    runnable.Run(a1, a2, a3, a4, a5);
+  }
+};
+
+template <typename ReturnType, typename Runnable,typename A1, typename A2,
+    typename A3, typename A4, typename A5, typename A6>
+struct InvokeHelper<false, ReturnType, Runnable,
+    void(A1, A2, A3, A4, A5, A6)>  {
+  static ReturnType MakeItSo(Runnable runnable, A1 a1, A2 a2, A3 a3, A4 a4,
+      A5 a5, A6 a6) {
+    return runnable.Run(a1, a2, a3, a4, a5, a6);
+  }
+};
+
+template <typename Runnable,typename A1, typename A2, typename A3, typename A4,
+    typename A5, typename A6>
+struct InvokeHelper<false, void, Runnable,
+    void(A1, A2, A3, A4, A5, A6)>  {
+  static void MakeItSo(Runnable runnable, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5,
+      A6 a6) {
+    runnable.Run(a1, a2, a3, a4, a5, a6);
+  }
+};
+
+template <typename Runnable, typename A1, typename A2, typename A3,
+    typename A4, typename A5, typename A6>
+struct InvokeHelper<true, void, Runnable,
+    void(A1, A2, A3, A4, A5, A6)>  {
+  static void MakeItSo(Runnable runnable, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5,
+      A6 a6) {
+    if (!a1.get()) {
+      return;
+    }
+
+    runnable.Run(a1, a2, a3, a4, a5, a6);
+  }
+};
+
+#if !defined(_MSC_VER)
+
+template <typename ReturnType, typename Runnable, typename ArgsType>
+struct InvokeHelper<true, ReturnType, Runnable, ArgsType> {
+  // WeakCalls are only supported for functions with a void return type.
+  // Otherwise, the function result would be undefined if the the WeakPtr<>
+  // is invalidated.
+  COMPILE_ASSERT(is_void<ReturnType>::value,
                  weak_ptrs_can_only_bind_to_methods_without_return_values);
+};
 
-  // For methods, we need to be careful for parameter 1.  We skip the
-  // scoped_refptr check because the binder itself takes care of this. We also
-  // disallow binding of an array as the method's target object.
-  COMPILE_ASSERT(IsMethod::value ||
-                 internal::NeedsScopedRefptrButGetsRawPtr<
-                     typename ParamTraits<P1>::StorageType>::value == 0,
-                 p1_is_refcounted_type_and_needs_scoped_refptr);
-  COMPILE_ASSERT(!IsMethod::value || !is_array<P1>::value,
-                 first_bound_argument_to_method_cannot_be_array);
-  COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr<
-          typename ParamTraits<P2>::StorageType>::value == 0,
-      p2_is_refcounted_type_and_needs_scoped_refptr);
-  COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr<
-          typename ParamTraits<P3>::StorageType>::value == 0,
-      p3_is_refcounted_type_and_needs_scoped_refptr);
-  COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr<
-          typename ParamTraits<P4>::StorageType>::value == 0,
-      p4_is_refcounted_type_and_needs_scoped_refptr);
-  COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr<
-          typename ParamTraits<P5>::StorageType>::value == 0,
-      p5_is_refcounted_type_and_needs_scoped_refptr);
+#endif
 
-  // Do not allow binding a non-const reference parameter. Non-const reference
-  // parameters are disallowed by the Google style guide.  Also, binding a
-  // non-const reference parameter can make for subtle bugs because the
-  // invoked function will receive a reference to the stored copy of the
-  // argument and not the original.
-  COMPILE_ASSERT(
-      !( is_non_const_reference<typename TargetTraits::B1>::value ||
-          is_non_const_reference<typename TargetTraits::B2>::value ||
-          is_non_const_reference<typename TargetTraits::B3>::value ||
-          is_non_const_reference<typename TargetTraits::B4>::value ||
-          is_non_const_reference<typename TargetTraits::B5>::value ),
-      do_not_bind_functions_with_nonconst_ref);
+// Invoker<>
+//
+// See description at the top of the file.
+template <int NumBound, typename Storage, typename RunType>
+struct Invoker;
+
+// Arity 0 -> 0.
+template <typename StorageType, typename R>
+struct Invoker<0, StorageType, R()> {
+  typedef R(RunType)(BindStateBase*);
+
+  typedef R(UnboundRunType)();
+
+  static R Run(BindStateBase* base) {
+    StorageType* storage = static_cast<StorageType*>(base);
+
+    // Local references to make debugger stepping easier. If in a debugger,
+    // you really want to warp ahead and step through the
+    // InvokeHelper<>::MakeItSo() call below.
+
+    return InvokeHelper<StorageType::IsWeakCall::value, R,
+           typename StorageType::RunnableType,
+           void()>
+               ::MakeItSo(storage->runnable_);
+  }
+};
+
+// Arity 1 -> 1.
+template <typename StorageType, typename R,typename X1>
+struct Invoker<0, StorageType, R(X1)> {
+  typedef R(RunType)(BindStateBase*,
+      typename CallbackParamTraits<X1>::ForwardType);
+
+  typedef R(UnboundRunType)(X1);
+
+  static R Run(BindStateBase* base,
+      typename CallbackParamTraits<X1>::ForwardType x1) {
+    StorageType* storage = static_cast<StorageType*>(base);
+
+    // Local references to make debugger stepping easier. If in a debugger,
+    // you really want to warp ahead and step through the
+    // InvokeHelper<>::MakeItSo() call below.
+
+    return InvokeHelper<StorageType::IsWeakCall::value, R,
+           typename StorageType::RunnableType,
+           void(typename CallbackParamTraits<X1>::ForwardType x1)>
+               ::MakeItSo(storage->runnable_, x1);
+  }
+};
+
+// Arity 1 -> 0.
+template <typename StorageType, typename R,typename X1>
+struct Invoker<1, StorageType, R(X1)> {
+  typedef R(RunType)(BindStateBase*);
+
+  typedef R(UnboundRunType)();
+
+  static R Run(BindStateBase* base) {
+    StorageType* storage = static_cast<StorageType*>(base);
+
+    // Local references to make debugger stepping easier. If in a debugger,
+    // you really want to warp ahead and step through the
+    // InvokeHelper<>::MakeItSo() call below.
+    typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits;
+
+    typename Bound1UnwrapTraits::ForwardType x1 =
+        Bound1UnwrapTraits::Unwrap(storage->p1_);
+    return InvokeHelper<StorageType::IsWeakCall::value, R,
+           typename StorageType::RunnableType,
+           void(typename Bound1UnwrapTraits::ForwardType)>
+               ::MakeItSo(storage->runnable_, x1);
+  }
+};
+
+// Arity 2 -> 2.
+template <typename StorageType, typename R,typename X1, typename X2>
+struct Invoker<0, StorageType, R(X1, X2)> {
+  typedef R(RunType)(BindStateBase*,
+      typename CallbackParamTraits<X1>::ForwardType,
+      typename CallbackParamTraits<X2>::ForwardType);
+
+  typedef R(UnboundRunType)(X1, X2);
+
+  static R Run(BindStateBase* base,
+      typename CallbackParamTraits<X1>::ForwardType x1,
+      typename CallbackParamTraits<X2>::ForwardType x2) {
+    StorageType* storage = static_cast<StorageType*>(base);
+
+    // Local references to make debugger stepping easier. If in a debugger,
+    // you really want to warp ahead and step through the
+    // InvokeHelper<>::MakeItSo() call below.
+
+    return InvokeHelper<StorageType::IsWeakCall::value, R,
+           typename StorageType::RunnableType,
+           void(typename CallbackParamTraits<X1>::ForwardType x1,
+               typename CallbackParamTraits<X2>::ForwardType x2)>
+               ::MakeItSo(storage->runnable_, x1, x2);
+  }
+};
+
+// Arity 2 -> 1.
+template <typename StorageType, typename R,typename X1, typename X2>
+struct Invoker<1, StorageType, R(X1, X2)> {
+  typedef R(RunType)(BindStateBase*,
+      typename CallbackParamTraits<X2>::ForwardType);
+
+  typedef R(UnboundRunType)(X2);
+
+  static R Run(BindStateBase* base,
+      typename CallbackParamTraits<X2>::ForwardType x2) {
+    StorageType* storage = static_cast<StorageType*>(base);
+
+    // Local references to make debugger stepping easier. If in a debugger,
+    // you really want to warp ahead and step through the
+    // InvokeHelper<>::MakeItSo() call below.
+    typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits;
+
+    typename Bound1UnwrapTraits::ForwardType x1 =
+        Bound1UnwrapTraits::Unwrap(storage->p1_);
+    return InvokeHelper<StorageType::IsWeakCall::value, R,
+           typename StorageType::RunnableType,
+           void(typename Bound1UnwrapTraits::ForwardType,
+               typename CallbackParamTraits<X2>::ForwardType x2)>
+               ::MakeItSo(storage->runnable_, x1, x2);
+  }
+};
+
+// Arity 2 -> 0.
+template <typename StorageType, typename R,typename X1, typename X2>
+struct Invoker<2, StorageType, R(X1, X2)> {
+  typedef R(RunType)(BindStateBase*);
+
+  typedef R(UnboundRunType)();
+
+  static R Run(BindStateBase* base) {
+    StorageType* storage = static_cast<StorageType*>(base);
+
+    // Local references to make debugger stepping easier. If in a debugger,
+    // you really want to warp ahead and step through the
+    // InvokeHelper<>::MakeItSo() call below.
+    typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits;
+    typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits;
+
+    typename Bound1UnwrapTraits::ForwardType x1 =
+        Bound1UnwrapTraits::Unwrap(storage->p1_);
+    typename Bound2UnwrapTraits::ForwardType x2 =
+        Bound2UnwrapTraits::Unwrap(storage->p2_);
+    return InvokeHelper<StorageType::IsWeakCall::value, R,
+           typename StorageType::RunnableType,
+           void(typename Bound1UnwrapTraits::ForwardType,
+               typename Bound2UnwrapTraits::ForwardType)>
+               ::MakeItSo(storage->runnable_, x1, x2);
+  }
+};
+
+// Arity 3 -> 3.
+template <typename StorageType, typename R,typename X1, typename X2,
+    typename X3>
+struct Invoker<0, StorageType, R(X1, X2, X3)> {
+  typedef R(RunType)(BindStateBase*,
+      typename CallbackParamTraits<X1>::ForwardType,
+      typename CallbackParamTraits<X2>::ForwardType,
+      typename CallbackParamTraits<X3>::ForwardType);
+
+  typedef R(UnboundRunType)(X1, X2, X3);
+
+  static R Run(BindStateBase* base,
+      typename CallbackParamTraits<X1>::ForwardType x1,
+      typename CallbackParamTraits<X2>::ForwardType x2,
+      typename CallbackParamTraits<X3>::ForwardType x3) {
+    StorageType* storage = static_cast<StorageType*>(base);
+
+    // Local references to make debugger stepping easier. If in a debugger,
+    // you really want to warp ahead and step through the
+    // InvokeHelper<>::MakeItSo() call below.
+
+    return InvokeHelper<StorageType::IsWeakCall::value, R,
+           typename StorageType::RunnableType,
+           void(typename CallbackParamTraits<X1>::ForwardType x1,
+               typename CallbackParamTraits<X2>::ForwardType x2,
+               typename CallbackParamTraits<X3>::ForwardType x3)>
+               ::MakeItSo(storage->runnable_, x1, x2, x3);
+  }
+};
+
+// Arity 3 -> 2.
+template <typename StorageType, typename R,typename X1, typename X2,
+    typename X3>
+struct Invoker<1, StorageType, R(X1, X2, X3)> {
+  typedef R(RunType)(BindStateBase*,
+      typename CallbackParamTraits<X2>::ForwardType,
+      typename CallbackParamTraits<X3>::ForwardType);
+
+  typedef R(UnboundRunType)(X2, X3);
+
+  static R Run(BindStateBase* base,
+      typename CallbackParamTraits<X2>::ForwardType x2,
+      typename CallbackParamTraits<X3>::ForwardType x3) {
+    StorageType* storage = static_cast<StorageType*>(base);
+
+    // Local references to make debugger stepping easier. If in a debugger,
+    // you really want to warp ahead and step through the
+    // InvokeHelper<>::MakeItSo() call below.
+    typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits;
+
+    typename Bound1UnwrapTraits::ForwardType x1 =
+        Bound1UnwrapTraits::Unwrap(storage->p1_);
+    return InvokeHelper<StorageType::IsWeakCall::value, R,
+           typename StorageType::RunnableType,
+           void(typename Bound1UnwrapTraits::ForwardType,
+               typename CallbackParamTraits<X2>::ForwardType x2,
+               typename CallbackParamTraits<X3>::ForwardType x3)>
+               ::MakeItSo(storage->runnable_, x1, x2, x3);
+  }
+};
+
+// Arity 3 -> 1.
+template <typename StorageType, typename R,typename X1, typename X2,
+    typename X3>
+struct Invoker<2, StorageType, R(X1, X2, X3)> {
+  typedef R(RunType)(BindStateBase*,
+      typename CallbackParamTraits<X3>::ForwardType);
+
+  typedef R(UnboundRunType)(X3);
+
+  static R Run(BindStateBase* base,
+      typename CallbackParamTraits<X3>::ForwardType x3) {
+    StorageType* storage = static_cast<StorageType*>(base);
+
+    // Local references to make debugger stepping easier. If in a debugger,
+    // you really want to warp ahead and step through the
+    // InvokeHelper<>::MakeItSo() call below.
+    typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits;
+    typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits;
+
+    typename Bound1UnwrapTraits::ForwardType x1 =
+        Bound1UnwrapTraits::Unwrap(storage->p1_);
+    typename Bound2UnwrapTraits::ForwardType x2 =
+        Bound2UnwrapTraits::Unwrap(storage->p2_);
+    return InvokeHelper<StorageType::IsWeakCall::value, R,
+           typename StorageType::RunnableType,
+           void(typename Bound1UnwrapTraits::ForwardType,
+               typename Bound2UnwrapTraits::ForwardType,
+               typename CallbackParamTraits<X3>::ForwardType x3)>
+               ::MakeItSo(storage->runnable_, x1, x2, x3);
+  }
+};
+
+// Arity 3 -> 0.
+template <typename StorageType, typename R,typename X1, typename X2,
+    typename X3>
+struct Invoker<3, StorageType, R(X1, X2, X3)> {
+  typedef R(RunType)(BindStateBase*);
+
+  typedef R(UnboundRunType)();
+
+  static R Run(BindStateBase* base) {
+    StorageType* storage = static_cast<StorageType*>(base);
+
+    // Local references to make debugger stepping easier. If in a debugger,
+    // you really want to warp ahead and step through the
+    // InvokeHelper<>::MakeItSo() call below.
+    typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits;
+    typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits;
+    typedef typename StorageType::Bound3UnwrapTraits Bound3UnwrapTraits;
+
+    typename Bound1UnwrapTraits::ForwardType x1 =
+        Bound1UnwrapTraits::Unwrap(storage->p1_);
+    typename Bound2UnwrapTraits::ForwardType x2 =
+        Bound2UnwrapTraits::Unwrap(storage->p2_);
+    typename Bound3UnwrapTraits::ForwardType x3 =
+        Bound3UnwrapTraits::Unwrap(storage->p3_);
+    return InvokeHelper<StorageType::IsWeakCall::value, R,
+           typename StorageType::RunnableType,
+           void(typename Bound1UnwrapTraits::ForwardType,
+               typename Bound2UnwrapTraits::ForwardType,
+               typename Bound3UnwrapTraits::ForwardType)>
+               ::MakeItSo(storage->runnable_, x1, x2, x3);
+  }
+};
+
+// Arity 4 -> 4.
+template <typename StorageType, typename R,typename X1, typename X2,
+    typename X3, typename X4>
+struct Invoker<0, StorageType, R(X1, X2, X3, X4)> {
+  typedef R(RunType)(BindStateBase*,
+      typename CallbackParamTraits<X1>::ForwardType,
+      typename CallbackParamTraits<X2>::ForwardType,
+      typename CallbackParamTraits<X3>::ForwardType,
+      typename CallbackParamTraits<X4>::ForwardType);
+
+  typedef R(UnboundRunType)(X1, X2, X3, X4);
+
+  static R Run(BindStateBase* base,
+      typename CallbackParamTraits<X1>::ForwardType x1,
+      typename CallbackParamTraits<X2>::ForwardType x2,
+      typename CallbackParamTraits<X3>::ForwardType x3,
+      typename CallbackParamTraits<X4>::ForwardType x4) {
+    StorageType* storage = static_cast<StorageType*>(base);
+
+    // Local references to make debugger stepping easier. If in a debugger,
+    // you really want to warp ahead and step through the
+    // InvokeHelper<>::MakeItSo() call below.
+
+    return InvokeHelper<StorageType::IsWeakCall::value, R,
+           typename StorageType::RunnableType,
+           void(typename CallbackParamTraits<X1>::ForwardType x1,
+               typename CallbackParamTraits<X2>::ForwardType x2,
+               typename CallbackParamTraits<X3>::ForwardType x3,
+               typename CallbackParamTraits<X4>::ForwardType x4)>
+               ::MakeItSo(storage->runnable_, x1, x2, x3, x4);
+  }
+};
+
+// Arity 4 -> 3.
+template <typename StorageType, typename R,typename X1, typename X2,
+    typename X3, typename X4>
+struct Invoker<1, StorageType, R(X1, X2, X3, X4)> {
+  typedef R(RunType)(BindStateBase*,
+      typename CallbackParamTraits<X2>::ForwardType,
+      typename CallbackParamTraits<X3>::ForwardType,
+      typename CallbackParamTraits<X4>::ForwardType);
+
+  typedef R(UnboundRunType)(X2, X3, X4);
+
+  static R Run(BindStateBase* base,
+      typename CallbackParamTraits<X2>::ForwardType x2,
+      typename CallbackParamTraits<X3>::ForwardType x3,
+      typename CallbackParamTraits<X4>::ForwardType x4) {
+    StorageType* storage = static_cast<StorageType*>(base);
+
+    // Local references to make debugger stepping easier. If in a debugger,
+    // you really want to warp ahead and step through the
+    // InvokeHelper<>::MakeItSo() call below.
+    typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits;
+
+    typename Bound1UnwrapTraits::ForwardType x1 =
+        Bound1UnwrapTraits::Unwrap(storage->p1_);
+    return InvokeHelper<StorageType::IsWeakCall::value, R,
+           typename StorageType::RunnableType,
+           void(typename Bound1UnwrapTraits::ForwardType,
+               typename CallbackParamTraits<X2>::ForwardType x2,
+               typename CallbackParamTraits<X3>::ForwardType x3,
+               typename CallbackParamTraits<X4>::ForwardType x4)>
+               ::MakeItSo(storage->runnable_, x1, x2, x3, x4);
+  }
+};
+
+// Arity 4 -> 2.
+template <typename StorageType, typename R,typename X1, typename X2,
+    typename X3, typename X4>
+struct Invoker<2, StorageType, R(X1, X2, X3, X4)> {
+  typedef R(RunType)(BindStateBase*,
+      typename CallbackParamTraits<X3>::ForwardType,
+      typename CallbackParamTraits<X4>::ForwardType);
+
+  typedef R(UnboundRunType)(X3, X4);
+
+  static R Run(BindStateBase* base,
+      typename CallbackParamTraits<X3>::ForwardType x3,
+      typename CallbackParamTraits<X4>::ForwardType x4) {
+    StorageType* storage = static_cast<StorageType*>(base);
+
+    // Local references to make debugger stepping easier. If in a debugger,
+    // you really want to warp ahead and step through the
+    // InvokeHelper<>::MakeItSo() call below.
+    typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits;
+    typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits;
+
+    typename Bound1UnwrapTraits::ForwardType x1 =
+        Bound1UnwrapTraits::Unwrap(storage->p1_);
+    typename Bound2UnwrapTraits::ForwardType x2 =
+        Bound2UnwrapTraits::Unwrap(storage->p2_);
+    return InvokeHelper<StorageType::IsWeakCall::value, R,
+           typename StorageType::RunnableType,
+           void(typename Bound1UnwrapTraits::ForwardType,
+               typename Bound2UnwrapTraits::ForwardType,
+               typename CallbackParamTraits<X3>::ForwardType x3,
+               typename CallbackParamTraits<X4>::ForwardType x4)>
+               ::MakeItSo(storage->runnable_, x1, x2, x3, x4);
+  }
+};
+
+// Arity 4 -> 1.
+template <typename StorageType, typename R,typename X1, typename X2,
+    typename X3, typename X4>
+struct Invoker<3, StorageType, R(X1, X2, X3, X4)> {
+  typedef R(RunType)(BindStateBase*,
+      typename CallbackParamTraits<X4>::ForwardType);
+
+  typedef R(UnboundRunType)(X4);
+
+  static R Run(BindStateBase* base,
+      typename CallbackParamTraits<X4>::ForwardType x4) {
+    StorageType* storage = static_cast<StorageType*>(base);
+
+    // Local references to make debugger stepping easier. If in a debugger,
+    // you really want to warp ahead and step through the
+    // InvokeHelper<>::MakeItSo() call below.
+    typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits;
+    typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits;
+    typedef typename StorageType::Bound3UnwrapTraits Bound3UnwrapTraits;
+
+    typename Bound1UnwrapTraits::ForwardType x1 =
+        Bound1UnwrapTraits::Unwrap(storage->p1_);
+    typename Bound2UnwrapTraits::ForwardType x2 =
+        Bound2UnwrapTraits::Unwrap(storage->p2_);
+    typename Bound3UnwrapTraits::ForwardType x3 =
+        Bound3UnwrapTraits::Unwrap(storage->p3_);
+    return InvokeHelper<StorageType::IsWeakCall::value, R,
+           typename StorageType::RunnableType,
+           void(typename Bound1UnwrapTraits::ForwardType,
+               typename Bound2UnwrapTraits::ForwardType,
+               typename Bound3UnwrapTraits::ForwardType,
+               typename CallbackParamTraits<X4>::ForwardType x4)>
+               ::MakeItSo(storage->runnable_, x1, x2, x3, x4);
+  }
+};
+
+// Arity 4 -> 0.
+template <typename StorageType, typename R,typename X1, typename X2,
+    typename X3, typename X4>
+struct Invoker<4, StorageType, R(X1, X2, X3, X4)> {
+  typedef R(RunType)(BindStateBase*);
+
+  typedef R(UnboundRunType)();
+
+  static R Run(BindStateBase* base) {
+    StorageType* storage = static_cast<StorageType*>(base);
+
+    // Local references to make debugger stepping easier. If in a debugger,
+    // you really want to warp ahead and step through the
+    // InvokeHelper<>::MakeItSo() call below.
+    typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits;
+    typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits;
+    typedef typename StorageType::Bound3UnwrapTraits Bound3UnwrapTraits;
+    typedef typename StorageType::Bound4UnwrapTraits Bound4UnwrapTraits;
+
+    typename Bound1UnwrapTraits::ForwardType x1 =
+        Bound1UnwrapTraits::Unwrap(storage->p1_);
+    typename Bound2UnwrapTraits::ForwardType x2 =
+        Bound2UnwrapTraits::Unwrap(storage->p2_);
+    typename Bound3UnwrapTraits::ForwardType x3 =
+        Bound3UnwrapTraits::Unwrap(storage->p3_);
+    typename Bound4UnwrapTraits::ForwardType x4 =
+        Bound4UnwrapTraits::Unwrap(storage->p4_);
+    return InvokeHelper<StorageType::IsWeakCall::value, R,
+           typename StorageType::RunnableType,
+           void(typename Bound1UnwrapTraits::ForwardType,
+               typename Bound2UnwrapTraits::ForwardType,
+               typename Bound3UnwrapTraits::ForwardType,
+               typename Bound4UnwrapTraits::ForwardType)>
+               ::MakeItSo(storage->runnable_, x1, x2, x3, x4);
+  }
+};
+
+// Arity 5 -> 5.
+template <typename StorageType, typename R,typename X1, typename X2,
+    typename X3, typename X4, typename X5>
+struct Invoker<0, StorageType, R(X1, X2, X3, X4, X5)> {
+  typedef R(RunType)(BindStateBase*,
+      typename CallbackParamTraits<X1>::ForwardType,
+      typename CallbackParamTraits<X2>::ForwardType,
+      typename CallbackParamTraits<X3>::ForwardType,
+      typename CallbackParamTraits<X4>::ForwardType,
+      typename CallbackParamTraits<X5>::ForwardType);
+
+  typedef R(UnboundRunType)(X1, X2, X3, X4, X5);
+
+  static R Run(BindStateBase* base,
+      typename CallbackParamTraits<X1>::ForwardType x1,
+      typename CallbackParamTraits<X2>::ForwardType x2,
+      typename CallbackParamTraits<X3>::ForwardType x3,
+      typename CallbackParamTraits<X4>::ForwardType x4,
+      typename CallbackParamTraits<X5>::ForwardType x5) {
+    StorageType* storage = static_cast<StorageType*>(base);
+
+    // Local references to make debugger stepping easier. If in a debugger,
+    // you really want to warp ahead and step through the
+    // InvokeHelper<>::MakeItSo() call below.
+
+    return InvokeHelper<StorageType::IsWeakCall::value, R,
+           typename StorageType::RunnableType,
+           void(typename CallbackParamTraits<X1>::ForwardType x1,
+               typename CallbackParamTraits<X2>::ForwardType x2,
+               typename CallbackParamTraits<X3>::ForwardType x3,
+               typename CallbackParamTraits<X4>::ForwardType x4,
+               typename CallbackParamTraits<X5>::ForwardType x5)>
+               ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5);
+  }
+};
+
+// Arity 5 -> 4.
+template <typename StorageType, typename R,typename X1, typename X2,
+    typename X3, typename X4, typename X5>
+struct Invoker<1, StorageType, R(X1, X2, X3, X4, X5)> {
+  typedef R(RunType)(BindStateBase*,
+      typename CallbackParamTraits<X2>::ForwardType,
+      typename CallbackParamTraits<X3>::ForwardType,
+      typename CallbackParamTraits<X4>::ForwardType,
+      typename CallbackParamTraits<X5>::ForwardType);
+
+  typedef R(UnboundRunType)(X2, X3, X4, X5);
+
+  static R Run(BindStateBase* base,
+      typename CallbackParamTraits<X2>::ForwardType x2,
+      typename CallbackParamTraits<X3>::ForwardType x3,
+      typename CallbackParamTraits<X4>::ForwardType x4,
+      typename CallbackParamTraits<X5>::ForwardType x5) {
+    StorageType* storage = static_cast<StorageType*>(base);
+
+    // Local references to make debugger stepping easier. If in a debugger,
+    // you really want to warp ahead and step through the
+    // InvokeHelper<>::MakeItSo() call below.
+    typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits;
+
+    typename Bound1UnwrapTraits::ForwardType x1 =
+        Bound1UnwrapTraits::Unwrap(storage->p1_);
+    return InvokeHelper<StorageType::IsWeakCall::value, R,
+           typename StorageType::RunnableType,
+           void(typename Bound1UnwrapTraits::ForwardType,
+               typename CallbackParamTraits<X2>::ForwardType x2,
+               typename CallbackParamTraits<X3>::ForwardType x3,
+               typename CallbackParamTraits<X4>::ForwardType x4,
+               typename CallbackParamTraits<X5>::ForwardType x5)>
+               ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5);
+  }
+};
+
+// Arity 5 -> 3.
+template <typename StorageType, typename R,typename X1, typename X2,
+    typename X3, typename X4, typename X5>
+struct Invoker<2, StorageType, R(X1, X2, X3, X4, X5)> {
+  typedef R(RunType)(BindStateBase*,
+      typename CallbackParamTraits<X3>::ForwardType,
+      typename CallbackParamTraits<X4>::ForwardType,
+      typename CallbackParamTraits<X5>::ForwardType);
+
+  typedef R(UnboundRunType)(X3, X4, X5);
+
+  static R Run(BindStateBase* base,
+      typename CallbackParamTraits<X3>::ForwardType x3,
+      typename CallbackParamTraits<X4>::ForwardType x4,
+      typename CallbackParamTraits<X5>::ForwardType x5) {
+    StorageType* storage = static_cast<StorageType*>(base);
+
+    // Local references to make debugger stepping easier. If in a debugger,
+    // you really want to warp ahead and step through the
+    // InvokeHelper<>::MakeItSo() call below.
+    typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits;
+    typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits;
+
+    typename Bound1UnwrapTraits::ForwardType x1 =
+        Bound1UnwrapTraits::Unwrap(storage->p1_);
+    typename Bound2UnwrapTraits::ForwardType x2 =
+        Bound2UnwrapTraits::Unwrap(storage->p2_);
+    return InvokeHelper<StorageType::IsWeakCall::value, R,
+           typename StorageType::RunnableType,
+           void(typename Bound1UnwrapTraits::ForwardType,
+               typename Bound2UnwrapTraits::ForwardType,
+               typename CallbackParamTraits<X3>::ForwardType x3,
+               typename CallbackParamTraits<X4>::ForwardType x4,
+               typename CallbackParamTraits<X5>::ForwardType x5)>
+               ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5);
+  }
+};
+
+// Arity 5 -> 2.
+template <typename StorageType, typename R,typename X1, typename X2,
+    typename X3, typename X4, typename X5>
+struct Invoker<3, StorageType, R(X1, X2, X3, X4, X5)> {
+  typedef R(RunType)(BindStateBase*,
+      typename CallbackParamTraits<X4>::ForwardType,
+      typename CallbackParamTraits<X5>::ForwardType);
+
+  typedef R(UnboundRunType)(X4, X5);
+
+  static R Run(BindStateBase* base,
+      typename CallbackParamTraits<X4>::ForwardType x4,
+      typename CallbackParamTraits<X5>::ForwardType x5) {
+    StorageType* storage = static_cast<StorageType*>(base);
+
+    // Local references to make debugger stepping easier. If in a debugger,
+    // you really want to warp ahead and step through the
+    // InvokeHelper<>::MakeItSo() call below.
+    typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits;
+    typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits;
+    typedef typename StorageType::Bound3UnwrapTraits Bound3UnwrapTraits;
+
+    typename Bound1UnwrapTraits::ForwardType x1 =
+        Bound1UnwrapTraits::Unwrap(storage->p1_);
+    typename Bound2UnwrapTraits::ForwardType x2 =
+        Bound2UnwrapTraits::Unwrap(storage->p2_);
+    typename Bound3UnwrapTraits::ForwardType x3 =
+        Bound3UnwrapTraits::Unwrap(storage->p3_);
+    return InvokeHelper<StorageType::IsWeakCall::value, R,
+           typename StorageType::RunnableType,
+           void(typename Bound1UnwrapTraits::ForwardType,
+               typename Bound2UnwrapTraits::ForwardType,
+               typename Bound3UnwrapTraits::ForwardType,
+               typename CallbackParamTraits<X4>::ForwardType x4,
+               typename CallbackParamTraits<X5>::ForwardType x5)>
+               ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5);
+  }
+};
+
+// Arity 5 -> 1.
+template <typename StorageType, typename R,typename X1, typename X2,
+    typename X3, typename X4, typename X5>
+struct Invoker<4, StorageType, R(X1, X2, X3, X4, X5)> {
+  typedef R(RunType)(BindStateBase*,
+      typename CallbackParamTraits<X5>::ForwardType);
+
+  typedef R(UnboundRunType)(X5);
+
+  static R Run(BindStateBase* base,
+      typename CallbackParamTraits<X5>::ForwardType x5) {
+    StorageType* storage = static_cast<StorageType*>(base);
+
+    // Local references to make debugger stepping easier. If in a debugger,
+    // you really want to warp ahead and step through the
+    // InvokeHelper<>::MakeItSo() call below.
+    typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits;
+    typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits;
+    typedef typename StorageType::Bound3UnwrapTraits Bound3UnwrapTraits;
+    typedef typename StorageType::Bound4UnwrapTraits Bound4UnwrapTraits;
+
+    typename Bound1UnwrapTraits::ForwardType x1 =
+        Bound1UnwrapTraits::Unwrap(storage->p1_);
+    typename Bound2UnwrapTraits::ForwardType x2 =
+        Bound2UnwrapTraits::Unwrap(storage->p2_);
+    typename Bound3UnwrapTraits::ForwardType x3 =
+        Bound3UnwrapTraits::Unwrap(storage->p3_);
+    typename Bound4UnwrapTraits::ForwardType x4 =
+        Bound4UnwrapTraits::Unwrap(storage->p4_);
+    return InvokeHelper<StorageType::IsWeakCall::value, R,
+           typename StorageType::RunnableType,
+           void(typename Bound1UnwrapTraits::ForwardType,
+               typename Bound2UnwrapTraits::ForwardType,
+               typename Bound3UnwrapTraits::ForwardType,
+               typename Bound4UnwrapTraits::ForwardType,
+               typename CallbackParamTraits<X5>::ForwardType x5)>
+               ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5);
+  }
+};
+
+// Arity 5 -> 0.
+template <typename StorageType, typename R,typename X1, typename X2,
+    typename X3, typename X4, typename X5>
+struct Invoker<5, StorageType, R(X1, X2, X3, X4, X5)> {
+  typedef R(RunType)(BindStateBase*);
+
+  typedef R(UnboundRunType)();
+
+  static R Run(BindStateBase* base) {
+    StorageType* storage = static_cast<StorageType*>(base);
+
+    // Local references to make debugger stepping easier. If in a debugger,
+    // you really want to warp ahead and step through the
+    // InvokeHelper<>::MakeItSo() call below.
+    typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits;
+    typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits;
+    typedef typename StorageType::Bound3UnwrapTraits Bound3UnwrapTraits;
+    typedef typename StorageType::Bound4UnwrapTraits Bound4UnwrapTraits;
+    typedef typename StorageType::Bound5UnwrapTraits Bound5UnwrapTraits;
+
+    typename Bound1UnwrapTraits::ForwardType x1 =
+        Bound1UnwrapTraits::Unwrap(storage->p1_);
+    typename Bound2UnwrapTraits::ForwardType x2 =
+        Bound2UnwrapTraits::Unwrap(storage->p2_);
+    typename Bound3UnwrapTraits::ForwardType x3 =
+        Bound3UnwrapTraits::Unwrap(storage->p3_);
+    typename Bound4UnwrapTraits::ForwardType x4 =
+        Bound4UnwrapTraits::Unwrap(storage->p4_);
+    typename Bound5UnwrapTraits::ForwardType x5 =
+        Bound5UnwrapTraits::Unwrap(storage->p5_);
+    return InvokeHelper<StorageType::IsWeakCall::value, R,
+           typename StorageType::RunnableType,
+           void(typename Bound1UnwrapTraits::ForwardType,
+               typename Bound2UnwrapTraits::ForwardType,
+               typename Bound3UnwrapTraits::ForwardType,
+               typename Bound4UnwrapTraits::ForwardType,
+               typename Bound5UnwrapTraits::ForwardType)>
+               ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5);
+  }
+};
+
+// Arity 6 -> 6.
+template <typename StorageType, typename R,typename X1, typename X2,
+    typename X3, typename X4, typename X5, typename X6>
+struct Invoker<0, StorageType, R(X1, X2, X3, X4, X5, X6)> {
+  typedef R(RunType)(BindStateBase*,
+      typename CallbackParamTraits<X1>::ForwardType,
+      typename CallbackParamTraits<X2>::ForwardType,
+      typename CallbackParamTraits<X3>::ForwardType,
+      typename CallbackParamTraits<X4>::ForwardType,
+      typename CallbackParamTraits<X5>::ForwardType,
+      typename CallbackParamTraits<X6>::ForwardType);
+
+  typedef R(UnboundRunType)(X1, X2, X3, X4, X5, X6);
+
+  static R Run(BindStateBase* base,
+      typename CallbackParamTraits<X1>::ForwardType x1,
+      typename CallbackParamTraits<X2>::ForwardType x2,
+      typename CallbackParamTraits<X3>::ForwardType x3,
+      typename CallbackParamTraits<X4>::ForwardType x4,
+      typename CallbackParamTraits<X5>::ForwardType x5,
+      typename CallbackParamTraits<X6>::ForwardType x6) {
+    StorageType* storage = static_cast<StorageType*>(base);
+
+    // Local references to make debugger stepping easier. If in a debugger,
+    // you really want to warp ahead and step through the
+    // InvokeHelper<>::MakeItSo() call below.
+
+    return InvokeHelper<StorageType::IsWeakCall::value, R,
+           typename StorageType::RunnableType,
+           void(typename CallbackParamTraits<X1>::ForwardType x1,
+               typename CallbackParamTraits<X2>::ForwardType x2,
+               typename CallbackParamTraits<X3>::ForwardType x3,
+               typename CallbackParamTraits<X4>::ForwardType x4,
+               typename CallbackParamTraits<X5>::ForwardType x5,
+               typename CallbackParamTraits<X6>::ForwardType x6)>
+               ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5, x6);
+  }
+};
+
+// Arity 6 -> 5.
+template <typename StorageType, typename R,typename X1, typename X2,
+    typename X3, typename X4, typename X5, typename X6>
+struct Invoker<1, StorageType, R(X1, X2, X3, X4, X5, X6)> {
+  typedef R(RunType)(BindStateBase*,
+      typename CallbackParamTraits<X2>::ForwardType,
+      typename CallbackParamTraits<X3>::ForwardType,
+      typename CallbackParamTraits<X4>::ForwardType,
+      typename CallbackParamTraits<X5>::ForwardType,
+      typename CallbackParamTraits<X6>::ForwardType);
+
+  typedef R(UnboundRunType)(X2, X3, X4, X5, X6);
+
+  static R Run(BindStateBase* base,
+      typename CallbackParamTraits<X2>::ForwardType x2,
+      typename CallbackParamTraits<X3>::ForwardType x3,
+      typename CallbackParamTraits<X4>::ForwardType x4,
+      typename CallbackParamTraits<X5>::ForwardType x5,
+      typename CallbackParamTraits<X6>::ForwardType x6) {
+    StorageType* storage = static_cast<StorageType*>(base);
+
+    // Local references to make debugger stepping easier. If in a debugger,
+    // you really want to warp ahead and step through the
+    // InvokeHelper<>::MakeItSo() call below.
+    typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits;
+
+    typename Bound1UnwrapTraits::ForwardType x1 =
+        Bound1UnwrapTraits::Unwrap(storage->p1_);
+    return InvokeHelper<StorageType::IsWeakCall::value, R,
+           typename StorageType::RunnableType,
+           void(typename Bound1UnwrapTraits::ForwardType,
+               typename CallbackParamTraits<X2>::ForwardType x2,
+               typename CallbackParamTraits<X3>::ForwardType x3,
+               typename CallbackParamTraits<X4>::ForwardType x4,
+               typename CallbackParamTraits<X5>::ForwardType x5,
+               typename CallbackParamTraits<X6>::ForwardType x6)>
+               ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5, x6);
+  }
+};
+
+// Arity 6 -> 4.
+template <typename StorageType, typename R,typename X1, typename X2,
+    typename X3, typename X4, typename X5, typename X6>
+struct Invoker<2, StorageType, R(X1, X2, X3, X4, X5, X6)> {
+  typedef R(RunType)(BindStateBase*,
+      typename CallbackParamTraits<X3>::ForwardType,
+      typename CallbackParamTraits<X4>::ForwardType,
+      typename CallbackParamTraits<X5>::ForwardType,
+      typename CallbackParamTraits<X6>::ForwardType);
+
+  typedef R(UnboundRunType)(X3, X4, X5, X6);
+
+  static R Run(BindStateBase* base,
+      typename CallbackParamTraits<X3>::ForwardType x3,
+      typename CallbackParamTraits<X4>::ForwardType x4,
+      typename CallbackParamTraits<X5>::ForwardType x5,
+      typename CallbackParamTraits<X6>::ForwardType x6) {
+    StorageType* storage = static_cast<StorageType*>(base);
+
+    // Local references to make debugger stepping easier. If in a debugger,
+    // you really want to warp ahead and step through the
+    // InvokeHelper<>::MakeItSo() call below.
+    typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits;
+    typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits;
+
+    typename Bound1UnwrapTraits::ForwardType x1 =
+        Bound1UnwrapTraits::Unwrap(storage->p1_);
+    typename Bound2UnwrapTraits::ForwardType x2 =
+        Bound2UnwrapTraits::Unwrap(storage->p2_);
+    return InvokeHelper<StorageType::IsWeakCall::value, R,
+           typename StorageType::RunnableType,
+           void(typename Bound1UnwrapTraits::ForwardType,
+               typename Bound2UnwrapTraits::ForwardType,
+               typename CallbackParamTraits<X3>::ForwardType x3,
+               typename CallbackParamTraits<X4>::ForwardType x4,
+               typename CallbackParamTraits<X5>::ForwardType x5,
+               typename CallbackParamTraits<X6>::ForwardType x6)>
+               ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5, x6);
+  }
+};
+
+// Arity 6 -> 3.
+template <typename StorageType, typename R,typename X1, typename X2,
+    typename X3, typename X4, typename X5, typename X6>
+struct Invoker<3, StorageType, R(X1, X2, X3, X4, X5, X6)> {
+  typedef R(RunType)(BindStateBase*,
+      typename CallbackParamTraits<X4>::ForwardType,
+      typename CallbackParamTraits<X5>::ForwardType,
+      typename CallbackParamTraits<X6>::ForwardType);
+
+  typedef R(UnboundRunType)(X4, X5, X6);
+
+  static R Run(BindStateBase* base,
+      typename CallbackParamTraits<X4>::ForwardType x4,
+      typename CallbackParamTraits<X5>::ForwardType x5,
+      typename CallbackParamTraits<X6>::ForwardType x6) {
+    StorageType* storage = static_cast<StorageType*>(base);
+
+    // Local references to make debugger stepping easier. If in a debugger,
+    // you really want to warp ahead and step through the
+    // InvokeHelper<>::MakeItSo() call below.
+    typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits;
+    typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits;
+    typedef typename StorageType::Bound3UnwrapTraits Bound3UnwrapTraits;
+
+    typename Bound1UnwrapTraits::ForwardType x1 =
+        Bound1UnwrapTraits::Unwrap(storage->p1_);
+    typename Bound2UnwrapTraits::ForwardType x2 =
+        Bound2UnwrapTraits::Unwrap(storage->p2_);
+    typename Bound3UnwrapTraits::ForwardType x3 =
+        Bound3UnwrapTraits::Unwrap(storage->p3_);
+    return InvokeHelper<StorageType::IsWeakCall::value, R,
+           typename StorageType::RunnableType,
+           void(typename Bound1UnwrapTraits::ForwardType,
+               typename Bound2UnwrapTraits::ForwardType,
+               typename Bound3UnwrapTraits::ForwardType,
+               typename CallbackParamTraits<X4>::ForwardType x4,
+               typename CallbackParamTraits<X5>::ForwardType x5,
+               typename CallbackParamTraits<X6>::ForwardType x6)>
+               ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5, x6);
+  }
+};
+
+// Arity 6 -> 2.
+template <typename StorageType, typename R,typename X1, typename X2,
+    typename X3, typename X4, typename X5, typename X6>
+struct Invoker<4, StorageType, R(X1, X2, X3, X4, X5, X6)> {
+  typedef R(RunType)(BindStateBase*,
+      typename CallbackParamTraits<X5>::ForwardType,
+      typename CallbackParamTraits<X6>::ForwardType);
+
+  typedef R(UnboundRunType)(X5, X6);
+
+  static R Run(BindStateBase* base,
+      typename CallbackParamTraits<X5>::ForwardType x5,
+      typename CallbackParamTraits<X6>::ForwardType x6) {
+    StorageType* storage = static_cast<StorageType*>(base);
+
+    // Local references to make debugger stepping easier. If in a debugger,
+    // you really want to warp ahead and step through the
+    // InvokeHelper<>::MakeItSo() call below.
+    typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits;
+    typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits;
+    typedef typename StorageType::Bound3UnwrapTraits Bound3UnwrapTraits;
+    typedef typename StorageType::Bound4UnwrapTraits Bound4UnwrapTraits;
+
+    typename Bound1UnwrapTraits::ForwardType x1 =
+        Bound1UnwrapTraits::Unwrap(storage->p1_);
+    typename Bound2UnwrapTraits::ForwardType x2 =
+        Bound2UnwrapTraits::Unwrap(storage->p2_);
+    typename Bound3UnwrapTraits::ForwardType x3 =
+        Bound3UnwrapTraits::Unwrap(storage->p3_);
+    typename Bound4UnwrapTraits::ForwardType x4 =
+        Bound4UnwrapTraits::Unwrap(storage->p4_);
+    return InvokeHelper<StorageType::IsWeakCall::value, R,
+           typename StorageType::RunnableType,
+           void(typename Bound1UnwrapTraits::ForwardType,
+               typename Bound2UnwrapTraits::ForwardType,
+               typename Bound3UnwrapTraits::ForwardType,
+               typename Bound4UnwrapTraits::ForwardType,
+               typename CallbackParamTraits<X5>::ForwardType x5,
+               typename CallbackParamTraits<X6>::ForwardType x6)>
+               ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5, x6);
+  }
+};
+
+// Arity 6 -> 1.
+template <typename StorageType, typename R,typename X1, typename X2,
+    typename X3, typename X4, typename X5, typename X6>
+struct Invoker<5, StorageType, R(X1, X2, X3, X4, X5, X6)> {
+  typedef R(RunType)(BindStateBase*,
+      typename CallbackParamTraits<X6>::ForwardType);
+
+  typedef R(UnboundRunType)(X6);
+
+  static R Run(BindStateBase* base,
+      typename CallbackParamTraits<X6>::ForwardType x6) {
+    StorageType* storage = static_cast<StorageType*>(base);
+
+    // Local references to make debugger stepping easier. If in a debugger,
+    // you really want to warp ahead and step through the
+    // InvokeHelper<>::MakeItSo() call below.
+    typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits;
+    typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits;
+    typedef typename StorageType::Bound3UnwrapTraits Bound3UnwrapTraits;
+    typedef typename StorageType::Bound4UnwrapTraits Bound4UnwrapTraits;
+    typedef typename StorageType::Bound5UnwrapTraits Bound5UnwrapTraits;
+
+    typename Bound1UnwrapTraits::ForwardType x1 =
+        Bound1UnwrapTraits::Unwrap(storage->p1_);
+    typename Bound2UnwrapTraits::ForwardType x2 =
+        Bound2UnwrapTraits::Unwrap(storage->p2_);
+    typename Bound3UnwrapTraits::ForwardType x3 =
+        Bound3UnwrapTraits::Unwrap(storage->p3_);
+    typename Bound4UnwrapTraits::ForwardType x4 =
+        Bound4UnwrapTraits::Unwrap(storage->p4_);
+    typename Bound5UnwrapTraits::ForwardType x5 =
+        Bound5UnwrapTraits::Unwrap(storage->p5_);
+    return InvokeHelper<StorageType::IsWeakCall::value, R,
+           typename StorageType::RunnableType,
+           void(typename Bound1UnwrapTraits::ForwardType,
+               typename Bound2UnwrapTraits::ForwardType,
+               typename Bound3UnwrapTraits::ForwardType,
+               typename Bound4UnwrapTraits::ForwardType,
+               typename Bound5UnwrapTraits::ForwardType,
+               typename CallbackParamTraits<X6>::ForwardType x6)>
+               ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5, x6);
+  }
+};
+
+// Arity 6 -> 0.
+template <typename StorageType, typename R,typename X1, typename X2,
+    typename X3, typename X4, typename X5, typename X6>
+struct Invoker<6, StorageType, R(X1, X2, X3, X4, X5, X6)> {
+  typedef R(RunType)(BindStateBase*);
+
+  typedef R(UnboundRunType)();
+
+  static R Run(BindStateBase* base) {
+    StorageType* storage = static_cast<StorageType*>(base);
+
+    // Local references to make debugger stepping easier. If in a debugger,
+    // you really want to warp ahead and step through the
+    // InvokeHelper<>::MakeItSo() call below.
+    typedef typename StorageType::Bound1UnwrapTraits Bound1UnwrapTraits;
+    typedef typename StorageType::Bound2UnwrapTraits Bound2UnwrapTraits;
+    typedef typename StorageType::Bound3UnwrapTraits Bound3UnwrapTraits;
+    typedef typename StorageType::Bound4UnwrapTraits Bound4UnwrapTraits;
+    typedef typename StorageType::Bound5UnwrapTraits Bound5UnwrapTraits;
+    typedef typename StorageType::Bound6UnwrapTraits Bound6UnwrapTraits;
+
+    typename Bound1UnwrapTraits::ForwardType x1 =
+        Bound1UnwrapTraits::Unwrap(storage->p1_);
+    typename Bound2UnwrapTraits::ForwardType x2 =
+        Bound2UnwrapTraits::Unwrap(storage->p2_);
+    typename Bound3UnwrapTraits::ForwardType x3 =
+        Bound3UnwrapTraits::Unwrap(storage->p3_);
+    typename Bound4UnwrapTraits::ForwardType x4 =
+        Bound4UnwrapTraits::Unwrap(storage->p4_);
+    typename Bound5UnwrapTraits::ForwardType x5 =
+        Bound5UnwrapTraits::Unwrap(storage->p5_);
+    typename Bound6UnwrapTraits::ForwardType x6 =
+        Bound6UnwrapTraits::Unwrap(storage->p6_);
+    return InvokeHelper<StorageType::IsWeakCall::value, R,
+           typename StorageType::RunnableType,
+           void(typename Bound1UnwrapTraits::ForwardType,
+               typename Bound2UnwrapTraits::ForwardType,
+               typename Bound3UnwrapTraits::ForwardType,
+               typename Bound4UnwrapTraits::ForwardType,
+               typename Bound5UnwrapTraits::ForwardType,
+               typename Bound6UnwrapTraits::ForwardType)>
+               ::MakeItSo(storage->runnable_, x1, x2, x3, x4, x5, x6);
+  }
+};
 
 
-  InvokerStorage5(Sig f, const P1& p1, const P2& p2, const P3& p3,
+// BindState<>
+//
+// This stores all the state passed into Bind() and is also where most
+// of the template resolution magic occurs.
+//
+// Runnable is the functor we are binding arguments to.
+// RunType is type of the Run() function that the Invoker<> should use.
+// Normally, this is the same as the RunType of the Runnable, but it can
+// be different if an adapter like IgnoreResult() has been used.
+//
+// BoundArgsType contains the storage type for all the bound arguments by
+// (ab)using a function type.
+template <typename Runnable, typename RunType, typename BoundArgsType>
+struct BindState;
+
+template <typename Runnable, typename RunType>
+struct BindState<Runnable, RunType, void()> : public BindStateBase {
+  typedef Runnable RunnableType;
+  typedef false_type IsWeakCall;
+  typedef Invoker<0, BindState, RunType> InvokerType;
+  typedef typename InvokerType::UnboundRunType UnboundRunType;
+  explicit BindState(const Runnable& runnable)
+      : runnable_(runnable) {
+  }
+
+  virtual ~BindState() {  }
+
+  RunnableType runnable_;
+};
+
+template <typename Runnable, typename RunType, typename P1>
+struct BindState<Runnable, RunType, void(P1)> : public BindStateBase {
+  typedef Runnable RunnableType;
+  typedef IsWeakMethod<HasIsMethodTag<Runnable>::value, P1> IsWeakCall;
+  typedef Invoker<1, BindState, RunType> InvokerType;
+  typedef typename InvokerType::UnboundRunType UnboundRunType;
+
+  // Convenience typedefs for bound argument types.
+  typedef UnwrapTraits<P1> Bound1UnwrapTraits;
+
+  BindState(const Runnable& runnable, const P1& p1)
+      : runnable_(runnable),
+        p1_(p1) {
+    MaybeRefcount<HasIsMethodTag<Runnable>::value, P1>::AddRef(p1_);
+  }
+
+  virtual ~BindState() {    MaybeRefcount<HasIsMethodTag<Runnable>::value,
+      P1>::Release(p1_);  }
+
+  RunnableType runnable_;
+  P1 p1_;
+};
+
+template <typename Runnable, typename RunType, typename P1, typename P2>
+struct BindState<Runnable, RunType, void(P1, P2)> : public BindStateBase {
+  typedef Runnable RunnableType;
+  typedef IsWeakMethod<HasIsMethodTag<Runnable>::value, P1> IsWeakCall;
+  typedef Invoker<2, BindState, RunType> InvokerType;
+  typedef typename InvokerType::UnboundRunType UnboundRunType;
+
+  // Convenience typedefs for bound argument types.
+  typedef UnwrapTraits<P1> Bound1UnwrapTraits;
+  typedef UnwrapTraits<P2> Bound2UnwrapTraits;
+
+  BindState(const Runnable& runnable, const P1& p1, const P2& p2)
+      : runnable_(runnable),
+        p1_(p1),
+        p2_(p2) {
+    MaybeRefcount<HasIsMethodTag<Runnable>::value, P1>::AddRef(p1_);
+  }
+
+  virtual ~BindState() {    MaybeRefcount<HasIsMethodTag<Runnable>::value,
+      P1>::Release(p1_);  }
+
+  RunnableType runnable_;
+  P1 p1_;
+  P2 p2_;
+};
+
+template <typename Runnable, typename RunType, typename P1, typename P2,
+    typename P3>
+struct BindState<Runnable, RunType, void(P1, P2, P3)> : public BindStateBase {
+  typedef Runnable RunnableType;
+  typedef IsWeakMethod<HasIsMethodTag<Runnable>::value, P1> IsWeakCall;
+  typedef Invoker<3, BindState, RunType> InvokerType;
+  typedef typename InvokerType::UnboundRunType UnboundRunType;
+
+  // Convenience typedefs for bound argument types.
+  typedef UnwrapTraits<P1> Bound1UnwrapTraits;
+  typedef UnwrapTraits<P2> Bound2UnwrapTraits;
+  typedef UnwrapTraits<P3> Bound3UnwrapTraits;
+
+  BindState(const Runnable& runnable, const P1& p1, const P2& p2, const P3& p3)
+      : runnable_(runnable),
+        p1_(p1),
+        p2_(p2),
+        p3_(p3) {
+    MaybeRefcount<HasIsMethodTag<Runnable>::value, P1>::AddRef(p1_);
+  }
+
+  virtual ~BindState() {    MaybeRefcount<HasIsMethodTag<Runnable>::value,
+      P1>::Release(p1_);  }
+
+  RunnableType runnable_;
+  P1 p1_;
+  P2 p2_;
+  P3 p3_;
+};
+
+template <typename Runnable, typename RunType, typename P1, typename P2,
+    typename P3, typename P4>
+struct BindState<Runnable, RunType, void(P1, P2, P3,
+    P4)> : public BindStateBase {
+  typedef Runnable RunnableType;
+  typedef IsWeakMethod<HasIsMethodTag<Runnable>::value, P1> IsWeakCall;
+  typedef Invoker<4, BindState, RunType> InvokerType;
+  typedef typename InvokerType::UnboundRunType UnboundRunType;
+
+  // Convenience typedefs for bound argument types.
+  typedef UnwrapTraits<P1> Bound1UnwrapTraits;
+  typedef UnwrapTraits<P2> Bound2UnwrapTraits;
+  typedef UnwrapTraits<P3> Bound3UnwrapTraits;
+  typedef UnwrapTraits<P4> Bound4UnwrapTraits;
+
+  BindState(const Runnable& runnable, const P1& p1, const P2& p2, const P3& p3,
+      const P4& p4)
+      : runnable_(runnable),
+        p1_(p1),
+        p2_(p2),
+        p3_(p3),
+        p4_(p4) {
+    MaybeRefcount<HasIsMethodTag<Runnable>::value, P1>::AddRef(p1_);
+  }
+
+  virtual ~BindState() {    MaybeRefcount<HasIsMethodTag<Runnable>::value,
+      P1>::Release(p1_);  }
+
+  RunnableType runnable_;
+  P1 p1_;
+  P2 p2_;
+  P3 p3_;
+  P4 p4_;
+};
+
+template <typename Runnable, typename RunType, typename P1, typename P2,
+    typename P3, typename P4, typename P5>
+struct BindState<Runnable, RunType, void(P1, P2, P3, P4,
+    P5)> : public BindStateBase {
+  typedef Runnable RunnableType;
+  typedef IsWeakMethod<HasIsMethodTag<Runnable>::value, P1> IsWeakCall;
+  typedef Invoker<5, BindState, RunType> InvokerType;
+  typedef typename InvokerType::UnboundRunType UnboundRunType;
+
+  // Convenience typedefs for bound argument types.
+  typedef UnwrapTraits<P1> Bound1UnwrapTraits;
+  typedef UnwrapTraits<P2> Bound2UnwrapTraits;
+  typedef UnwrapTraits<P3> Bound3UnwrapTraits;
+  typedef UnwrapTraits<P4> Bound4UnwrapTraits;
+  typedef UnwrapTraits<P5> Bound5UnwrapTraits;
+
+  BindState(const Runnable& runnable, const P1& p1, const P2& p2, const P3& p3,
       const P4& p4, const P5& p5)
-      : f_(f), p1_(static_cast<typename ParamTraits<P1>::StorageType>(p1)),
-          p2_(static_cast<typename ParamTraits<P2>::StorageType>(p2)),
-          p3_(static_cast<typename ParamTraits<P3>::StorageType>(p3)),
-          p4_(static_cast<typename ParamTraits<P4>::StorageType>(p4)),
-          p5_(static_cast<typename ParamTraits<P5>::StorageType>(p5)) {
-    MaybeRefcount<IsMethod, P1>::AddRef(p1_);
+      : runnable_(runnable),
+        p1_(p1),
+        p2_(p2),
+        p3_(p3),
+        p4_(p4),
+        p5_(p5) {
+    MaybeRefcount<HasIsMethodTag<Runnable>::value, P1>::AddRef(p1_);
   }
 
-  virtual ~InvokerStorage5() {
-    MaybeRefcount<IsMethod, P1>::Release(p1_);
-  }
+  virtual ~BindState() {    MaybeRefcount<HasIsMethodTag<Runnable>::value,
+      P1>::Release(p1_);  }
 
-  Sig f_;
-  typename ParamTraits<P1>::StorageType p1_;
-  typename ParamTraits<P2>::StorageType p2_;
-  typename ParamTraits<P3>::StorageType p3_;
-  typename ParamTraits<P4>::StorageType p4_;
-  typename ParamTraits<P5>::StorageType p5_;
+  RunnableType runnable_;
+  P1 p1_;
+  P2 p2_;
+  P3 p3_;
+  P4 p4_;
+  P5 p5_;
 };
 
-template <typename Sig, typename P1, typename P2, typename P3, typename P4,
-    typename P5, typename P6>
-class InvokerStorage6 : public InvokerStorageBase {
- public:
-  typedef InvokerStorage6 StorageType;
-  typedef FunctionTraits<Sig> TargetTraits;
-  typedef typename TargetTraits::IsMethod IsMethod;
-  typedef Sig Signature;
-  typedef ParamTraits<P1> P1Traits;
-  typedef ParamTraits<P2> P2Traits;
-  typedef ParamTraits<P3> P3Traits;
-  typedef ParamTraits<P4> P4Traits;
-  typedef ParamTraits<P5> P5Traits;
-  typedef ParamTraits<P6> P6Traits;
-  typedef Invoker6<IsWeakMethod<IsMethod::value, P1>::value, StorageType,
-                   typename TargetTraits::NormalizedSig> Invoker;
-  COMPILE_ASSERT(!(IsWeakMethod<IsMethod::value, P1>::value) ||
-                 is_void<typename TargetTraits::Return>::value,
-                 weak_ptrs_can_only_bind_to_methods_without_return_values);
+template <typename Runnable, typename RunType, typename P1, typename P2,
+    typename P3, typename P4, typename P5, typename P6>
+struct BindState<Runnable, RunType, void(P1, P2, P3, P4, P5,
+    P6)> : public BindStateBase {
+  typedef Runnable RunnableType;
+  typedef IsWeakMethod<HasIsMethodTag<Runnable>::value, P1> IsWeakCall;
+  typedef Invoker<6, BindState, RunType> InvokerType;
+  typedef typename InvokerType::UnboundRunType UnboundRunType;
 
-  // For methods, we need to be careful for parameter 1.  We skip the
-  // scoped_refptr check because the binder itself takes care of this. We also
-  // disallow binding of an array as the method's target object.
-  COMPILE_ASSERT(IsMethod::value ||
-                 internal::NeedsScopedRefptrButGetsRawPtr<
-                     typename ParamTraits<P1>::StorageType>::value == 0,
-                 p1_is_refcounted_type_and_needs_scoped_refptr);
-  COMPILE_ASSERT(!IsMethod::value || !is_array<P1>::value,
-                 first_bound_argument_to_method_cannot_be_array);
-  COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr<
-          typename ParamTraits<P2>::StorageType>::value == 0,
-      p2_is_refcounted_type_and_needs_scoped_refptr);
-  COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr<
-          typename ParamTraits<P3>::StorageType>::value == 0,
-      p3_is_refcounted_type_and_needs_scoped_refptr);
-  COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr<
-          typename ParamTraits<P4>::StorageType>::value == 0,
-      p4_is_refcounted_type_and_needs_scoped_refptr);
-  COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr<
-          typename ParamTraits<P5>::StorageType>::value == 0,
-      p5_is_refcounted_type_and_needs_scoped_refptr);
-  COMPILE_ASSERT(internal::NeedsScopedRefptrButGetsRawPtr<
-          typename ParamTraits<P6>::StorageType>::value == 0,
-      p6_is_refcounted_type_and_needs_scoped_refptr);
+  // Convenience typedefs for bound argument types.
+  typedef UnwrapTraits<P1> Bound1UnwrapTraits;
+  typedef UnwrapTraits<P2> Bound2UnwrapTraits;
+  typedef UnwrapTraits<P3> Bound3UnwrapTraits;
+  typedef UnwrapTraits<P4> Bound4UnwrapTraits;
+  typedef UnwrapTraits<P5> Bound5UnwrapTraits;
+  typedef UnwrapTraits<P6> Bound6UnwrapTraits;
 
-  // Do not allow binding a non-const reference parameter. Non-const reference
-  // parameters are disallowed by the Google style guide.  Also, binding a
-  // non-const reference parameter can make for subtle bugs because the
-  // invoked function will receive a reference to the stored copy of the
-  // argument and not the original.
-  COMPILE_ASSERT(
-      !( is_non_const_reference<typename TargetTraits::B1>::value ||
-          is_non_const_reference<typename TargetTraits::B2>::value ||
-          is_non_const_reference<typename TargetTraits::B3>::value ||
-          is_non_const_reference<typename TargetTraits::B4>::value ||
-          is_non_const_reference<typename TargetTraits::B5>::value ||
-          is_non_const_reference<typename TargetTraits::B6>::value ),
-      do_not_bind_functions_with_nonconst_ref);
-
-
-  InvokerStorage6(Sig f, const P1& p1, const P2& p2, const P3& p3,
+  BindState(const Runnable& runnable, const P1& p1, const P2& p2, const P3& p3,
       const P4& p4, const P5& p5, const P6& p6)
-      : f_(f), p1_(static_cast<typename ParamTraits<P1>::StorageType>(p1)),
-          p2_(static_cast<typename ParamTraits<P2>::StorageType>(p2)),
-          p3_(static_cast<typename ParamTraits<P3>::StorageType>(p3)),
-          p4_(static_cast<typename ParamTraits<P4>::StorageType>(p4)),
-          p5_(static_cast<typename ParamTraits<P5>::StorageType>(p5)),
-          p6_(static_cast<typename ParamTraits<P6>::StorageType>(p6)) {
-    MaybeRefcount<IsMethod, P1>::AddRef(p1_);
+      : runnable_(runnable),
+        p1_(p1),
+        p2_(p2),
+        p3_(p3),
+        p4_(p4),
+        p5_(p5),
+        p6_(p6) {
+    MaybeRefcount<HasIsMethodTag<Runnable>::value, P1>::AddRef(p1_);
   }
 
-  virtual ~InvokerStorage6() {
-    MaybeRefcount<IsMethod, P1>::Release(p1_);
-  }
+  virtual ~BindState() {    MaybeRefcount<HasIsMethodTag<Runnable>::value,
+      P1>::Release(p1_);  }
 
-  Sig f_;
-  typename ParamTraits<P1>::StorageType p1_;
-  typename ParamTraits<P2>::StorageType p2_;
-  typename ParamTraits<P3>::StorageType p3_;
-  typename ParamTraits<P4>::StorageType p4_;
-  typename ParamTraits<P5>::StorageType p5_;
-  typename ParamTraits<P6>::StorageType p6_;
+  RunnableType runnable_;
+  P1 p1_;
+  P2 p2_;
+  P3 p3_;
+  P4 p4_;
+  P5 p5_;
+  P6 p6_;
 };
 
 }  // namespace internal