Update from https://crrev.com/307664

This includes changes to the following:

mojo/tools/roll/cc_strip_video.patch due to
https://codereview.chromium.org/786583002 (renaming files)

ui/compositor/compositor.h due to https://codereview.chromium.org/783373002
(adding a parameter to ApplyViewportDeltas)

services/surfaces/surfaces_scheduler due to
https://codereview.chromium.org/767083005 (renaming a method)

TBR=jamesr@chromium.org

Review URL: https://codereview.chromium.org/787803004
diff --git a/android/java/src/org/chromium/base/TraceEvent.java b/android/java/src/org/chromium/base/TraceEvent.java
index 1c7e534..164ccf8 100644
--- a/android/java/src/org/chromium/base/TraceEvent.java
+++ b/android/java/src/org/chromium/base/TraceEvent.java
@@ -221,15 +221,6 @@
     }
 
     /**
-     * Convenience wrapper around the versions of startAsync() that take string parameters.
-     * @param id The id of the asynchronous event.
-     * @see #begin()
-     */
-    public static void startAsync(long id) {
-        if (sEnabled) nativeStartAsync(getCallerName(), id, null);
-    }
-
-    /**
      * Triggers the 'start' native trace event with no arguments.
      * @param name The name of the event.
      * @param id   The id of the asynchronous event.
@@ -249,15 +240,6 @@
     }
 
     /**
-     * Convenience wrapper around the versions of finishAsync() that take string parameters.
-     * @param id The id of the asynchronous event.
-     * @see #begin()
-     */
-    public static void finishAsync(long id) {
-        if (sEnabled) nativeFinishAsync(getCallerName(), id, null);
-    }
-
-    /**
      * Triggers the 'finish' native trace event with no arguments.
      * @param name The name of the event.
      * @param id   The id of the asynchronous event.
diff --git a/id_map.h b/id_map.h
index 9cbc1f8..852c138 100644
--- a/id_map.h
+++ b/id_map.h
@@ -53,13 +53,14 @@
     Releaser<OS, 0>::release_all(&data_);
   }
 
-  // Sets whether Add should CHECK if passed in NULL data. Default is false.
+  // Sets whether Add and Replace should DCHECK if passed in NULL data.
+  // Default is false.
   void set_check_on_null_data(bool value) { check_on_null_data_ = value; }
 
   // Adds a view with an automatically generated unique ID. See AddWithID.
   KeyType Add(T* data) {
     DCHECK(CalledOnValidThread());
-    CHECK(!check_on_null_data_ || data);
+    DCHECK(!check_on_null_data_ || data);
     KeyType this_id = next_id_;
     DCHECK(data_.find(this_id) == data_.end()) << "Inserting duplicate item";
     data_[this_id] = data;
@@ -73,7 +74,7 @@
   // two methods may not be mixed, or duplicate IDs may be generated
   void AddWithID(T* data, KeyType id) {
     DCHECK(CalledOnValidThread());
-    CHECK(!check_on_null_data_ || data);
+    DCHECK(!check_on_null_data_ || data);
     DCHECK(data_.find(id) == data_.end()) << "Inserting duplicate item";
     data_[id] = data;
   }
@@ -94,6 +95,25 @@
     }
   }
 
+  // Replaces the value for |id| with |new_data| and returns a pointer to the
+  // existing value. If there is no entry for |id|, the map is not altered and
+  // nullptr is returned. The OwnershipSemantics of the map have no effect on
+  // how the existing value is treated, the IDMap does not delete the existing
+  // value being replaced.
+  T* Replace(KeyType id, T* new_data) {
+    DCHECK(CalledOnValidThread());
+    DCHECK(!check_on_null_data_ || new_data);
+    typename HashTable::iterator i = data_.find(id);
+    if (i == data_.end()) {
+      NOTREACHED() << "Attempting to replace an item not in the list";
+      return nullptr;
+    }
+
+    T* temp = i->second;
+    i->second = new_data;
+    return temp;
+  }
+
   void Clear() {
     DCHECK(CalledOnValidThread());
     if (iteration_depth_ == 0) {
diff --git a/id_map_unittest.cc b/id_map_unittest.cc
index c005a69..a9fb2b9 100644
--- a/id_map_unittest.cc
+++ b/id_map_unittest.cc
@@ -53,6 +53,9 @@
   EXPECT_EQ(&obj1, map.Lookup(1));
   EXPECT_EQ(&obj2, map.Lookup(2));
 
+  EXPECT_EQ(&obj2, map.Replace(2, &obj1));
+  EXPECT_EQ(&obj1, map.Lookup(2));
+
   EXPECT_EQ(0, map.iteration_depth());
 }
 
diff --git a/strings/string_util_unittest.cc b/strings/string_util_unittest.cc
index f29baac..923116d 100644
--- a/strings/string_util_unittest.cc
+++ b/strings/string_util_unittest.cc
@@ -494,10 +494,10 @@
   const char chars_with_nul[] = "test\0string";
   const int length_with_nul = arraysize(chars_with_nul) - 1;
   std::string string_with_nul(chars_with_nul, length_with_nul);
-  std::wstring wide_with_nul = ASCIIToWide(string_with_nul);
-  EXPECT_EQ(static_cast<std::wstring::size_type>(length_with_nul),
-            wide_with_nul.length());
-  std::string narrow_with_nul = UTF16ToASCII(WideToUTF16(wide_with_nul));
+  base::string16 string16_with_nul = ASCIIToUTF16(string_with_nul);
+  EXPECT_EQ(static_cast<base::string16::size_type>(length_with_nul),
+            string16_with_nul.length());
+  std::string narrow_with_nul = UTF16ToASCII(string16_with_nul);
   EXPECT_EQ(static_cast<std::string::size_type>(length_with_nul),
             narrow_with_nul.length());
   EXPECT_EQ(0, string_with_nul.compare(narrow_with_nul));
diff --git a/strings/utf_string_conversions.cc b/strings/utf_string_conversions.cc
index 9796eec..1480d48 100644
--- a/strings/utf_string_conversions.cc
+++ b/strings/utf_string_conversions.cc
@@ -209,11 +209,6 @@
 
 #endif
 
-std::wstring ASCIIToWide(const StringPiece& ascii) {
-  DCHECK(IsStringASCII(ascii)) << ascii;
-  return std::wstring(ascii.begin(), ascii.end());
-}
-
 string16 ASCIIToUTF16(const StringPiece& ascii) {
   DCHECK(IsStringASCII(ascii)) << ascii;
   return string16(ascii.begin(), ascii.end());
diff --git a/strings/utf_string_conversions.h b/strings/utf_string_conversions.h
index 13e0b71..06a3bc6 100644
--- a/strings/utf_string_conversions.h
+++ b/strings/utf_string_conversions.h
@@ -39,9 +39,8 @@
                              std::string* output);
 BASE_EXPORT std::string UTF16ToUTF8(const string16& utf16);
 
-// These convert an ASCII string, typically a hardcoded constant, to a
-// UTF16/Wide string.
-BASE_EXPORT std::wstring ASCIIToWide(const StringPiece& ascii);
+// This converts an ASCII string, typically a hardcoded constant, to a UTF16
+// string.
 BASE_EXPORT string16 ASCIIToUTF16(const StringPiece& ascii);
 
 // Converts to 7-bit ASCII by truncating. The result must be known to be ASCII
diff --git a/tuple.h b/tuple.h
index 12f7f84..16f5124 100644
--- a/tuple.h
+++ b/tuple.h
@@ -31,6 +31,29 @@
 
 #include "base/bind_helpers.h"
 
+// Index sequences
+//
+// Minimal clone of the similarly-named C++14 functionality.
+
+template <size_t...>
+struct IndexSequence {};
+
+template <size_t... Ns>
+struct MakeIndexSequenceImpl;
+
+template <size_t... Ns>
+struct MakeIndexSequenceImpl<0, Ns...> {
+  using Type = IndexSequence<Ns...>;
+};
+
+template <size_t N, size_t... Ns>
+struct MakeIndexSequenceImpl<N, Ns...> {
+  using Type = typename MakeIndexSequenceImpl<N - 1, N - 1, Ns...>::Type;
+};
+
+template <size_t N>
+using MakeIndexSequence = typename MakeIndexSequenceImpl<N>::Type;
+
 // Traits ----------------------------------------------------------------------
 //
 // A simple traits class for tuple arguments.
@@ -53,9 +76,6 @@
   typedef P& ParamType;
 };
 
-template <class P>
-struct TupleTypes { };
-
 // Tuple -----------------------------------------------------------------------
 //
 // This set of classes is useful for bundling 0 or more heterogeneous data types
@@ -70,73 +90,70 @@
 // want filled by the dispatchee, and the tuple is merely a container for that
 // output (a "tier").  See MakeRefTuple and its usages.
 
-struct Tuple0 {
-  typedef Tuple0 ValueTuple;
-  typedef Tuple0 RefTuple;
-  typedef Tuple0 ParamTuple;
-};
+template <typename... Ts>
+struct Tuple;
 
-template <class A>
-struct Tuple1 {
+template <>
+struct Tuple<> {};
+
+template <typename A>
+struct Tuple<A> {
  public:
   typedef A TypeA;
 
-  Tuple1() {}
-  explicit Tuple1(typename TupleTraits<A>::ParamType a) : a(a) {}
+  Tuple() {}
+  explicit Tuple(typename TupleTraits<A>::ParamType a) : a(a) {}
 
   A a;
 };
 
-template <class A, class B>
-struct Tuple2 {
+template <typename A, typename B>
+struct Tuple<A, B> {
  public:
   typedef A TypeA;
   typedef B TypeB;
 
-  Tuple2() {}
-  Tuple2(typename TupleTraits<A>::ParamType a,
-         typename TupleTraits<B>::ParamType b)
-      : a(a), b(b) {
-  }
+  Tuple() {}
+  Tuple(typename TupleTraits<A>::ParamType a,
+        typename TupleTraits<B>::ParamType b)
+      : a(a), b(b) {}
 
   A a;
   B b;
 };
 
-template <class A, class B, class C>
-struct Tuple3 {
+template <typename A, typename B, typename C>
+struct Tuple<A, B, C> {
  public:
   typedef A TypeA;
   typedef B TypeB;
   typedef C TypeC;
 
-  Tuple3() {}
-  Tuple3(typename TupleTraits<A>::ParamType a,
-         typename TupleTraits<B>::ParamType b,
-         typename TupleTraits<C>::ParamType c)
-      : a(a), b(b), c(c){
-  }
+  Tuple() {}
+  Tuple(typename TupleTraits<A>::ParamType a,
+        typename TupleTraits<B>::ParamType b,
+        typename TupleTraits<C>::ParamType c)
+      : a(a), b(b), c(c) {}
 
   A a;
   B b;
   C c;
 };
 
-template <class A, class B, class C, class D>
-struct Tuple4 {
+template <typename A, typename B, typename C, typename D>
+struct Tuple<A, B, C, D> {
  public:
   typedef A TypeA;
   typedef B TypeB;
   typedef C TypeC;
   typedef D TypeD;
 
-  Tuple4() {}
-  Tuple4(typename TupleTraits<A>::ParamType a,
-         typename TupleTraits<B>::ParamType b,
-         typename TupleTraits<C>::ParamType c,
-         typename TupleTraits<D>::ParamType d)
-      : a(a), b(b), c(c), d(d) {
-  }
+  Tuple() {}
+  Tuple(typename TupleTraits<A>::ParamType a,
+        typename TupleTraits<B>::ParamType b,
+        typename TupleTraits<C>::ParamType c,
+        typename TupleTraits<D>::ParamType d)
+      : a(a), b(b), c(c), d(d) {}
 
   A a;
   B b;
@@ -144,8 +161,8 @@
   D d;
 };
 
-template <class A, class B, class C, class D, class E>
-struct Tuple5 {
+template <typename A, typename B, typename C, typename D, typename E>
+struct Tuple<A, B, C, D, E> {
  public:
   typedef A TypeA;
   typedef B TypeB;
@@ -153,14 +170,13 @@
   typedef D TypeD;
   typedef E TypeE;
 
-  Tuple5() {}
-  Tuple5(typename TupleTraits<A>::ParamType a,
-    typename TupleTraits<B>::ParamType b,
-    typename TupleTraits<C>::ParamType c,
-    typename TupleTraits<D>::ParamType d,
-    typename TupleTraits<E>::ParamType e)
-    : a(a), b(b), c(c), d(d), e(e) {
-  }
+  Tuple() {}
+  Tuple(typename TupleTraits<A>::ParamType a,
+        typename TupleTraits<B>::ParamType b,
+        typename TupleTraits<C>::ParamType c,
+        typename TupleTraits<D>::ParamType d,
+        typename TupleTraits<E>::ParamType e)
+      : a(a), b(b), c(c), d(d), e(e) {}
 
   A a;
   B b;
@@ -169,8 +185,13 @@
   E e;
 };
 
-template <class A, class B, class C, class D, class E, class F>
-struct Tuple6 {
+template <typename A,
+          typename B,
+          typename C,
+          typename D,
+          typename E,
+          typename F>
+struct Tuple<A, B, C, D, E, F> {
  public:
   typedef A TypeA;
   typedef B TypeB;
@@ -179,15 +200,14 @@
   typedef E TypeE;
   typedef F TypeF;
 
-  Tuple6() {}
-  Tuple6(typename TupleTraits<A>::ParamType a,
-    typename TupleTraits<B>::ParamType b,
-    typename TupleTraits<C>::ParamType c,
-    typename TupleTraits<D>::ParamType d,
-    typename TupleTraits<E>::ParamType e,
-    typename TupleTraits<F>::ParamType f)
-    : a(a), b(b), c(c), d(d), e(e), f(f) {
-  }
+  Tuple() {}
+  Tuple(typename TupleTraits<A>::ParamType a,
+        typename TupleTraits<B>::ParamType b,
+        typename TupleTraits<C>::ParamType c,
+        typename TupleTraits<D>::ParamType d,
+        typename TupleTraits<E>::ParamType e,
+        typename TupleTraits<F>::ParamType f)
+      : a(a), b(b), c(c), d(d), e(e), f(f) {}
 
   A a;
   B b;
@@ -197,8 +217,14 @@
   F f;
 };
 
-template <class A, class B, class C, class D, class E, class F, class G>
-struct Tuple7 {
+template <typename A,
+          typename B,
+          typename C,
+          typename D,
+          typename E,
+          typename F,
+          typename G>
+struct Tuple<A, B, C, D, E, F, G> {
  public:
   typedef A TypeA;
   typedef B TypeB;
@@ -208,16 +234,15 @@
   typedef F TypeF;
   typedef G TypeG;
 
-  Tuple7() {}
-  Tuple7(typename TupleTraits<A>::ParamType a,
-    typename TupleTraits<B>::ParamType b,
-    typename TupleTraits<C>::ParamType c,
-    typename TupleTraits<D>::ParamType d,
-    typename TupleTraits<E>::ParamType e,
-    typename TupleTraits<F>::ParamType f,
-    typename TupleTraits<G>::ParamType g)
-    : a(a), b(b), c(c), d(d), e(e), f(f), g(g) {
-  }
+  Tuple() {}
+  Tuple(typename TupleTraits<A>::ParamType a,
+        typename TupleTraits<B>::ParamType b,
+        typename TupleTraits<C>::ParamType c,
+        typename TupleTraits<D>::ParamType d,
+        typename TupleTraits<E>::ParamType e,
+        typename TupleTraits<F>::ParamType f,
+        typename TupleTraits<G>::ParamType g)
+      : a(a), b(b), c(c), d(d), e(e), f(f), g(g) {}
 
   A a;
   B b;
@@ -228,9 +253,15 @@
   G g;
 };
 
-template <class A, class B, class C, class D, class E, class F, class G,
-          class H>
-struct Tuple8 {
+template <typename A,
+          typename B,
+          typename C,
+          typename D,
+          typename E,
+          typename F,
+          typename G,
+          typename H>
+struct Tuple<A, B, C, D, E, F, G, H> {
  public:
   typedef A TypeA;
   typedef B TypeB;
@@ -241,17 +272,16 @@
   typedef G TypeG;
   typedef H TypeH;
 
-  Tuple8() {}
-  Tuple8(typename TupleTraits<A>::ParamType a,
-    typename TupleTraits<B>::ParamType b,
-    typename TupleTraits<C>::ParamType c,
-    typename TupleTraits<D>::ParamType d,
-    typename TupleTraits<E>::ParamType e,
-    typename TupleTraits<F>::ParamType f,
-    typename TupleTraits<G>::ParamType g,
-    typename TupleTraits<H>::ParamType h)
-    : a(a), b(b), c(c), d(d), e(e), f(f), g(g), h(h) {
-  }
+  Tuple() {}
+  Tuple(typename TupleTraits<A>::ParamType a,
+        typename TupleTraits<B>::ParamType b,
+        typename TupleTraits<C>::ParamType c,
+        typename TupleTraits<D>::ParamType d,
+        typename TupleTraits<E>::ParamType e,
+        typename TupleTraits<F>::ParamType f,
+        typename TupleTraits<G>::ParamType g,
+        typename TupleTraits<H>::ParamType h)
+      : a(a), b(b), c(c), d(d), e(e), f(f), g(g), h(h) {}
 
   A a;
   B b;
@@ -263,157 +293,144 @@
   H h;
 };
 
+// Deprecated compat aliases
+
+using Tuple0 = Tuple<>;
+template <typename A>
+using Tuple1 = Tuple<A>;
+template <typename A, typename B>
+using Tuple2 = Tuple<A, B>;
+template <typename A, typename B, typename C>
+using Tuple3 = Tuple<A, B, C>;
+template <typename A, typename B, typename C, typename D>
+using Tuple4 = Tuple<A, B, C, D>;
+template <typename A, typename B, typename C, typename D, typename E>
+using Tuple5 = Tuple<A, B, C, D, E>;
+template <typename A,
+          typename B,
+          typename C,
+          typename D,
+          typename E,
+          typename F>
+using Tuple6 = Tuple<A, B, C, D, E, F>;
+template <typename A,
+          typename B,
+          typename C,
+          typename D,
+          typename E,
+          typename F,
+          typename G>
+using Tuple7 = Tuple<A, B, C, D, E, F, G>;
+template <typename A,
+          typename B,
+          typename C,
+          typename D,
+          typename E,
+          typename F,
+          typename G,
+          typename H>
+using Tuple8 = Tuple<A, B, C, D, E, F, G, H>;
+
+// Tuple element --------------------------------------------------------------
+
+template <size_t N, typename T>
+struct TupleElement;
+
+template <typename T, typename... Ts>
+struct TupleElement<0, Tuple<T, Ts...>> {
+  using Type = T;
+};
+
+template <size_t N, typename T, typename... Ts>
+struct TupleElement<N, Tuple<T, Ts...>> {
+  using Type = typename TupleElement<N - 1, Tuple<Ts...>>::Type;
+};
+
+// Tuple getters --------------------------------------------------------------
+
+template <size_t, typename T>
+struct TupleGetter;
+
+template <typename... Ts>
+struct TupleGetter<0, Tuple<Ts...>> {
+  using Elem = typename TupleElement<0, Tuple<Ts...>>::Type;
+  static Elem& Get(Tuple<Ts...>& t) { return t.a; }
+  static const Elem& Get(const Tuple<Ts...>& t) { return t.a; }
+};
+
+template <typename... Ts>
+struct TupleGetter<1, Tuple<Ts...>> {
+  using Elem = typename TupleElement<1, Tuple<Ts...>>::Type;
+  static Elem& Get(Tuple<Ts...>& t) { return t.b; }
+  static const Elem& Get(const Tuple<Ts...>& t) { return t.b; }
+};
+
+template <typename... Ts>
+struct TupleGetter<2, Tuple<Ts...>> {
+  using Elem = typename TupleElement<2, Tuple<Ts...>>::Type;
+  static Elem& Get(Tuple<Ts...>& t) { return t.c; }
+  static const Elem& Get(const Tuple<Ts...>& t) { return t.c; }
+};
+
+template <typename... Ts>
+struct TupleGetter<3, Tuple<Ts...>> {
+  using Elem = typename TupleElement<3, Tuple<Ts...>>::Type;
+  static Elem& Get(Tuple<Ts...>& t) { return t.d; }
+  static const Elem& Get(const Tuple<Ts...>& t) { return t.d; }
+};
+
+template <typename... Ts>
+struct TupleGetter<4, Tuple<Ts...>> {
+  using Elem = typename TupleElement<4, Tuple<Ts...>>::Type;
+  static Elem& Get(Tuple<Ts...>& t) { return t.e; }
+  static const Elem& Get(const Tuple<Ts...>& t) { return t.e; }
+};
+
+template <typename... Ts>
+struct TupleGetter<5, Tuple<Ts...>> {
+  using Elem = typename TupleElement<5, Tuple<Ts...>>::Type;
+  static Elem& Get(Tuple<Ts...>& t) { return t.f; }
+  static const Elem& Get(const Tuple<Ts...>& t) { return t.f; }
+};
+
+template <typename... Ts>
+struct TupleGetter<6, Tuple<Ts...>> {
+  using Elem = typename TupleElement<6, Tuple<Ts...>>::Type;
+  static Elem& Get(Tuple<Ts...>& t) { return t.g; }
+  static const Elem& Get(const Tuple<Ts...>& t) { return t.g; }
+};
+
+template <typename... Ts>
+struct TupleGetter<7, Tuple<Ts...>> {
+  using Elem = typename TupleElement<7, Tuple<Ts...>>::Type;
+  static Elem& Get(Tuple<Ts...>& t) { return t.h; }
+  static const Elem& Get(const Tuple<Ts...>& t) { return t.h; }
+};
+
+template <size_t I, typename... Ts>
+typename TupleElement<I, Tuple<Ts...>>::Type& get(Tuple<Ts...>& tuple) {
+  return TupleGetter<I, Tuple<Ts...>>::Get(tuple);
+}
+
+template <size_t I, typename... Ts>
+const typename TupleElement<I, Tuple<Ts...>>::Type& get(
+    const Tuple<Ts...>& tuple) {
+  return TupleGetter<I, Tuple<Ts...>>::Get(tuple);
+}
+
 // Tuple types ----------------------------------------------------------------
 //
 // Allows for selection of ValueTuple/RefTuple/ParamTuple without needing the
 // definitions of class types the tuple takes as parameters.
 
-template <>
-struct TupleTypes< Tuple0 > {
-  typedef Tuple0 ValueTuple;
-  typedef Tuple0 RefTuple;
-  typedef Tuple0 ParamTuple;
-};
+template <typename T>
+struct TupleTypes;
 
-template <class A>
-struct TupleTypes< Tuple1<A> > {
-  typedef Tuple1<typename TupleTraits<A>::ValueType> ValueTuple;
-  typedef Tuple1<typename TupleTraits<A>::RefType> RefTuple;
-  typedef Tuple1<typename TupleTraits<A>::ParamType> ParamTuple;
-};
-
-template <class A, class B>
-struct TupleTypes< Tuple2<A, B> > {
-  typedef Tuple2<typename TupleTraits<A>::ValueType,
-                 typename TupleTraits<B>::ValueType> ValueTuple;
-typedef Tuple2<typename TupleTraits<A>::RefType,
-               typename TupleTraits<B>::RefType> RefTuple;
-  typedef Tuple2<typename TupleTraits<A>::ParamType,
-                 typename TupleTraits<B>::ParamType> ParamTuple;
-};
-
-template <class A, class B, class C>
-struct TupleTypes< Tuple3<A, B, C> > {
-  typedef Tuple3<typename TupleTraits<A>::ValueType,
-                 typename TupleTraits<B>::ValueType,
-                 typename TupleTraits<C>::ValueType> ValueTuple;
-typedef Tuple3<typename TupleTraits<A>::RefType,
-               typename TupleTraits<B>::RefType,
-               typename TupleTraits<C>::RefType> RefTuple;
-  typedef Tuple3<typename TupleTraits<A>::ParamType,
-                 typename TupleTraits<B>::ParamType,
-                 typename TupleTraits<C>::ParamType> ParamTuple;
-};
-
-template <class A, class B, class C, class D>
-struct TupleTypes< Tuple4<A, B, C, D> > {
-  typedef Tuple4<typename TupleTraits<A>::ValueType,
-                 typename TupleTraits<B>::ValueType,
-                 typename TupleTraits<C>::ValueType,
-                 typename TupleTraits<D>::ValueType> ValueTuple;
-typedef Tuple4<typename TupleTraits<A>::RefType,
-               typename TupleTraits<B>::RefType,
-               typename TupleTraits<C>::RefType,
-               typename TupleTraits<D>::RefType> RefTuple;
-  typedef Tuple4<typename TupleTraits<A>::ParamType,
-                 typename TupleTraits<B>::ParamType,
-                 typename TupleTraits<C>::ParamType,
-                 typename TupleTraits<D>::ParamType> ParamTuple;
-};
-
-template <class A, class B, class C, class D, class E>
-struct TupleTypes< Tuple5<A, B, C, D, E> > {
-  typedef Tuple5<typename TupleTraits<A>::ValueType,
-                 typename TupleTraits<B>::ValueType,
-                 typename TupleTraits<C>::ValueType,
-                 typename TupleTraits<D>::ValueType,
-                 typename TupleTraits<E>::ValueType> ValueTuple;
-typedef Tuple5<typename TupleTraits<A>::RefType,
-               typename TupleTraits<B>::RefType,
-               typename TupleTraits<C>::RefType,
-               typename TupleTraits<D>::RefType,
-               typename TupleTraits<E>::RefType> RefTuple;
-  typedef Tuple5<typename TupleTraits<A>::ParamType,
-                 typename TupleTraits<B>::ParamType,
-                 typename TupleTraits<C>::ParamType,
-                 typename TupleTraits<D>::ParamType,
-                 typename TupleTraits<E>::ParamType> ParamTuple;
-};
-
-template <class A, class B, class C, class D, class E, class F>
-struct TupleTypes< Tuple6<A, B, C, D, E, F> > {
-  typedef Tuple6<typename TupleTraits<A>::ValueType,
-                 typename TupleTraits<B>::ValueType,
-                 typename TupleTraits<C>::ValueType,
-                 typename TupleTraits<D>::ValueType,
-                 typename TupleTraits<E>::ValueType,
-                 typename TupleTraits<F>::ValueType> ValueTuple;
-typedef Tuple6<typename TupleTraits<A>::RefType,
-               typename TupleTraits<B>::RefType,
-               typename TupleTraits<C>::RefType,
-               typename TupleTraits<D>::RefType,
-               typename TupleTraits<E>::RefType,
-               typename TupleTraits<F>::RefType> RefTuple;
-  typedef Tuple6<typename TupleTraits<A>::ParamType,
-                 typename TupleTraits<B>::ParamType,
-                 typename TupleTraits<C>::ParamType,
-                 typename TupleTraits<D>::ParamType,
-                 typename TupleTraits<E>::ParamType,
-                 typename TupleTraits<F>::ParamType> ParamTuple;
-};
-
-template <class A, class B, class C, class D, class E, class F, class G>
-struct TupleTypes< Tuple7<A, B, C, D, E, F, G> > {
-  typedef Tuple7<typename TupleTraits<A>::ValueType,
-                 typename TupleTraits<B>::ValueType,
-                 typename TupleTraits<C>::ValueType,
-                 typename TupleTraits<D>::ValueType,
-                 typename TupleTraits<E>::ValueType,
-                 typename TupleTraits<F>::ValueType,
-                 typename TupleTraits<G>::ValueType> ValueTuple;
-typedef Tuple7<typename TupleTraits<A>::RefType,
-               typename TupleTraits<B>::RefType,
-               typename TupleTraits<C>::RefType,
-               typename TupleTraits<D>::RefType,
-               typename TupleTraits<E>::RefType,
-               typename TupleTraits<F>::RefType,
-               typename TupleTraits<G>::RefType> RefTuple;
-  typedef Tuple7<typename TupleTraits<A>::ParamType,
-                 typename TupleTraits<B>::ParamType,
-                 typename TupleTraits<C>::ParamType,
-                 typename TupleTraits<D>::ParamType,
-                 typename TupleTraits<E>::ParamType,
-                 typename TupleTraits<F>::ParamType,
-                 typename TupleTraits<G>::ParamType> ParamTuple;
-};
-
-template <class A, class B, class C, class D, class E, class F, class G,
-          class H>
-struct TupleTypes< Tuple8<A, B, C, D, E, F, G, H> > {
-  typedef Tuple8<typename TupleTraits<A>::ValueType,
-                 typename TupleTraits<B>::ValueType,
-                 typename TupleTraits<C>::ValueType,
-                 typename TupleTraits<D>::ValueType,
-                 typename TupleTraits<E>::ValueType,
-                 typename TupleTraits<F>::ValueType,
-                 typename TupleTraits<G>::ValueType,
-                 typename TupleTraits<H>::ValueType> ValueTuple;
-typedef Tuple8<typename TupleTraits<A>::RefType,
-               typename TupleTraits<B>::RefType,
-               typename TupleTraits<C>::RefType,
-               typename TupleTraits<D>::RefType,
-               typename TupleTraits<E>::RefType,
-               typename TupleTraits<F>::RefType,
-               typename TupleTraits<G>::RefType,
-               typename TupleTraits<H>::RefType> RefTuple;
-  typedef Tuple8<typename TupleTraits<A>::ParamType,
-                 typename TupleTraits<B>::ParamType,
-                 typename TupleTraits<C>::ParamType,
-                 typename TupleTraits<D>::ParamType,
-                 typename TupleTraits<E>::ParamType,
-                 typename TupleTraits<F>::ParamType,
-                 typename TupleTraits<G>::ParamType,
-                 typename TupleTraits<H>::ParamType> ParamTuple;
+template <typename... Ts>
+struct TupleTypes<Tuple<Ts...>> {
+  using ValueTuple = Tuple<typename TupleTraits<Ts>::ValueType...>;
+  using RefTuple = Tuple<typename TupleTraits<Ts>::RefType...>;
+  using ParamTuple = Tuple<typename TupleTraits<Ts>::ParamType...>;
 };
 
 // Tuple creators -------------------------------------------------------------
@@ -421,105 +438,17 @@
 // Helper functions for constructing tuples while inferring the template
 // argument types.
 
-inline Tuple0 MakeTuple() {
-  return Tuple0();
-}
-
-template <class A>
-inline Tuple1<A> MakeTuple(const A& a) {
-  return Tuple1<A>(a);
-}
-
-template <class A, class B>
-inline Tuple2<A, B> MakeTuple(const A& a, const B& b) {
-  return Tuple2<A, B>(a, b);
-}
-
-template <class A, class B, class C>
-inline Tuple3<A, B, C> MakeTuple(const A& a, const B& b, const C& c) {
-  return Tuple3<A, B, C>(a, b, c);
-}
-
-template <class A, class B, class C, class D>
-inline Tuple4<A, B, C, D> MakeTuple(const A& a, const B& b, const C& c,
-                                    const D& d) {
-  return Tuple4<A, B, C, D>(a, b, c, d);
-}
-
-template <class A, class B, class C, class D, class E>
-inline Tuple5<A, B, C, D, E> MakeTuple(const A& a, const B& b, const C& c,
-                                       const D& d, const E& e) {
-  return Tuple5<A, B, C, D, E>(a, b, c, d, e);
-}
-
-template <class A, class B, class C, class D, class E, class F>
-inline Tuple6<A, B, C, D, E, F> MakeTuple(const A& a, const B& b, const C& c,
-                                          const D& d, const E& e, const F& f) {
-  return Tuple6<A, B, C, D, E, F>(a, b, c, d, e, f);
-}
-
-template <class A, class B, class C, class D, class E, class F, class G>
-inline Tuple7<A, B, C, D, E, F, G> MakeTuple(const A& a, const B& b, const C& c,
-                                             const D& d, const E& e, const F& f,
-                                             const G& g) {
-  return Tuple7<A, B, C, D, E, F, G>(a, b, c, d, e, f, g);
-}
-
-template <class A, class B, class C, class D, class E, class F, class G,
-          class H>
-inline Tuple8<A, B, C, D, E, F, G, H> MakeTuple(const A& a, const B& b,
-                                                const C& c, const D& d,
-                                                const E& e, const F& f,
-                                                const G& g, const H& h) {
-  return Tuple8<A, B, C, D, E, F, G, H>(a, b, c, d, e, f, g, h);
+template <typename... Ts>
+inline Tuple<Ts...> MakeTuple(const Ts&... arg) {
+  return Tuple<Ts...>(arg...);
 }
 
 // The following set of helpers make what Boost refers to as "Tiers" - a tuple
 // of references.
 
-template <class A>
-inline Tuple1<A&> MakeRefTuple(A& a) {
-  return Tuple1<A&>(a);
-}
-
-template <class A, class B>
-inline Tuple2<A&, B&> MakeRefTuple(A& a, B& b) {
-  return Tuple2<A&, B&>(a, b);
-}
-
-template <class A, class B, class C>
-inline Tuple3<A&, B&, C&> MakeRefTuple(A& a, B& b, C& c) {
-  return Tuple3<A&, B&, C&>(a, b, c);
-}
-
-template <class A, class B, class C, class D>
-inline Tuple4<A&, B&, C&, D&> MakeRefTuple(A& a, B& b, C& c, D& d) {
-  return Tuple4<A&, B&, C&, D&>(a, b, c, d);
-}
-
-template <class A, class B, class C, class D, class E>
-inline Tuple5<A&, B&, C&, D&, E&> MakeRefTuple(A& a, B& b, C& c, D& d, E& e) {
-  return Tuple5<A&, B&, C&, D&, E&>(a, b, c, d, e);
-}
-
-template <class A, class B, class C, class D, class E, class F>
-inline Tuple6<A&, B&, C&, D&, E&, F&> MakeRefTuple(A& a, B& b, C& c, D& d, E& e,
-                                                   F& f) {
-  return Tuple6<A&, B&, C&, D&, E&, F&>(a, b, c, d, e, f);
-}
-
-template <class A, class B, class C, class D, class E, class F, class G>
-inline Tuple7<A&, B&, C&, D&, E&, F&, G&> MakeRefTuple(A& a, B& b, C& c, D& d,
-                                                       E& e, F& f, G& g) {
-  return Tuple7<A&, B&, C&, D&, E&, F&, G&>(a, b, c, d, e, f, g);
-}
-
-template <class A, class B, class C, class D, class E, class F, class G,
-          class H>
-inline Tuple8<A&, B&, C&, D&, E&, F&, G&, H&> MakeRefTuple(A& a, B& b, C& c,
-                                                           D& d, E& e, F& f,
-                                                           G& g, H& h) {
-  return Tuple8<A&, B&, C&, D&, E&, F&, G&, H&>(a, b, c, d, e, f, g, h);
+template <typename... Ts>
+inline Tuple<Ts&...> MakeRefTuple(Ts&... arg) {
+  return Tuple<Ts&...>(arg...);
 }
 
 // Dispatchers ----------------------------------------------------------------
@@ -533,759 +462,94 @@
 
 // Non-Static Dispatchers with no out params.
 
-template <class ObjT, class Method>
-inline void DispatchToMethod(ObjT* obj, Method method, const Tuple0& arg) {
-  (obj->*method)();
-}
-
-template <class ObjT, class Method, class A>
+template <typename ObjT, typename Method, typename A>
 inline void DispatchToMethod(ObjT* obj, Method method, const A& arg) {
   (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg));
 }
 
-template <class ObjT, class Method, class A>
-inline void DispatchToMethod(ObjT* obj, Method method, const Tuple1<A>& arg) {
-  (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg.a));
+template <typename ObjT, typename Method, typename... Ts, size_t... Ns>
+inline void DispatchToMethodImpl(ObjT* obj,
+                                 Method method,
+                                 const Tuple<Ts...>& arg,
+                                 IndexSequence<Ns...>) {
+  (obj->*method)(base::internal::UnwrapTraits<Ts>::Unwrap(get<Ns>(arg))...);
 }
 
-template<class ObjT, class Method, class A, class B>
+template <typename ObjT, typename Method, typename... Ts>
 inline void DispatchToMethod(ObjT* obj,
                              Method method,
-                             const Tuple2<A, B>& arg) {
-  (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg.a),
-                 base::internal::UnwrapTraits<B>::Unwrap(arg.b));
-}
-
-template<class ObjT, class Method, class A, class B, class C>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const Tuple3<A, B, C>& arg) {
-  (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg.a),
-                 base::internal::UnwrapTraits<B>::Unwrap(arg.b),
-                 base::internal::UnwrapTraits<C>::Unwrap(arg.c));
-}
-
-template<class ObjT, class Method, class A, class B, class C, class D>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const Tuple4<A, B, C, D>& arg) {
-  (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg.a),
-                 base::internal::UnwrapTraits<B>::Unwrap(arg.b),
-                 base::internal::UnwrapTraits<C>::Unwrap(arg.c),
-                 base::internal::UnwrapTraits<D>::Unwrap(arg.d));
-}
-
-template<class ObjT, class Method, class A, class B, class C, class D, class E>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const Tuple5<A, B, C, D, E>& arg) {
-  (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg.a),
-                 base::internal::UnwrapTraits<B>::Unwrap(arg.b),
-                 base::internal::UnwrapTraits<C>::Unwrap(arg.c),
-                 base::internal::UnwrapTraits<D>::Unwrap(arg.d),
-                 base::internal::UnwrapTraits<E>::Unwrap(arg.e));
-}
-
-template<class ObjT, class Method, class A, class B, class C, class D, class E,
-         class F>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const Tuple6<A, B, C, D, E, F>& arg) {
-  (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg.a),
-                 base::internal::UnwrapTraits<B>::Unwrap(arg.b),
-                 base::internal::UnwrapTraits<C>::Unwrap(arg.c),
-                 base::internal::UnwrapTraits<D>::Unwrap(arg.d),
-                 base::internal::UnwrapTraits<E>::Unwrap(arg.e),
-                 base::internal::UnwrapTraits<F>::Unwrap(arg.f));
-}
-
-template<class ObjT, class Method, class A, class B, class C, class D, class E,
-         class F, class G>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const Tuple7<A, B, C, D, E, F, G>& arg) {
-  (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg.a),
-                 base::internal::UnwrapTraits<B>::Unwrap(arg.b),
-                 base::internal::UnwrapTraits<C>::Unwrap(arg.c),
-                 base::internal::UnwrapTraits<D>::Unwrap(arg.d),
-                 base::internal::UnwrapTraits<E>::Unwrap(arg.e),
-                 base::internal::UnwrapTraits<F>::Unwrap(arg.f),
-                 base::internal::UnwrapTraits<G>::Unwrap(arg.g));
-}
-
-template<class ObjT, class Method, class A, class B, class C, class D, class E,
-         class F, class G, class H>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const Tuple8<A, B, C, D, E, F, G, H>& arg) {
-  (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg.a),
-                 base::internal::UnwrapTraits<B>::Unwrap(arg.b),
-                 base::internal::UnwrapTraits<C>::Unwrap(arg.c),
-                 base::internal::UnwrapTraits<D>::Unwrap(arg.d),
-                 base::internal::UnwrapTraits<E>::Unwrap(arg.e),
-                 base::internal::UnwrapTraits<F>::Unwrap(arg.f),
-                 base::internal::UnwrapTraits<G>::Unwrap(arg.g),
-                 base::internal::UnwrapTraits<H>::Unwrap(arg.h));
+                             const Tuple<Ts...>& arg) {
+  DispatchToMethodImpl(obj, method, arg, MakeIndexSequence<sizeof...(Ts)>());
 }
 
 // Static Dispatchers with no out params.
 
-template <class Function>
-inline void DispatchToFunction(Function function, const Tuple0& arg) {
-  (*function)();
+template <typename Function, typename A>
+inline void DispatchToMethod(Function function, const A& arg) {
+  (*function)(base::internal::UnwrapTraits<A>::Unwrap(arg));
 }
 
-template <class Function, class A>
-inline void DispatchToFunction(Function function, const A& arg) {
-  (*function)(arg);
+template <typename Function, typename... Ts, size_t... Ns>
+inline void DispatchToFunctionImpl(Function function,
+                                   const Tuple<Ts...>& arg,
+                                   IndexSequence<Ns...>) {
+  (*function)(base::internal::UnwrapTraits<Ts>::Unwrap(get<Ns>(arg))...);
 }
 
-template <class Function, class A>
-inline void DispatchToFunction(Function function, const Tuple1<A>& arg) {
-  (*function)(base::internal::UnwrapTraits<A>::Unwrap(arg.a));
+template <typename Function, typename... Ts>
+inline void DispatchToFunction(Function function, const Tuple<Ts...>& arg) {
+  DispatchToFunctionImpl(function, arg, MakeIndexSequence<sizeof...(Ts)>());
 }
 
-template<class Function, class A, class B>
-inline void DispatchToFunction(Function function, const Tuple2<A, B>& arg) {
-  (*function)(base::internal::UnwrapTraits<A>::Unwrap(arg.a),
-              base::internal::UnwrapTraits<B>::Unwrap(arg.b));
+// Dispatchers with out parameters.
+
+template <typename ObjT,
+          typename Method,
+          typename In,
+          typename... OutTs,
+          size_t... OutNs>
+inline void DispatchToMethodImpl(ObjT* obj,
+                                 Method method,
+                                 const In& in,
+                                 Tuple<OutTs...>* out,
+                                 IndexSequence<OutNs...>) {
+  (obj->*method)(base::internal::UnwrapTraits<In>::Unwrap(in),
+                 &get<OutNs>(*out)...);
 }
 
-template<class Function, class A, class B, class C>
-inline void DispatchToFunction(Function function, const Tuple3<A, B, C>& arg) {
-  (*function)(base::internal::UnwrapTraits<A>::Unwrap(arg.a),
-              base::internal::UnwrapTraits<B>::Unwrap(arg.b),
-              base::internal::UnwrapTraits<C>::Unwrap(arg.c));
-}
-
-template<class Function, class A, class B, class C, class D>
-inline void DispatchToFunction(Function function,
-                               const Tuple4<A, B, C, D>& arg) {
-  (*function)(base::internal::UnwrapTraits<A>::Unwrap(arg.a),
-              base::internal::UnwrapTraits<B>::Unwrap(arg.b),
-              base::internal::UnwrapTraits<C>::Unwrap(arg.c),
-              base::internal::UnwrapTraits<D>::Unwrap(arg.d));
-}
-
-template<class Function, class A, class B, class C, class D, class E>
-inline void DispatchToFunction(Function function,
-                               const Tuple5<A, B, C, D, E>& arg) {
-  (*function)(base::internal::UnwrapTraits<A>::Unwrap(arg.a),
-              base::internal::UnwrapTraits<B>::Unwrap(arg.b),
-              base::internal::UnwrapTraits<C>::Unwrap(arg.c),
-              base::internal::UnwrapTraits<D>::Unwrap(arg.d),
-              base::internal::UnwrapTraits<E>::Unwrap(arg.e));
-}
-
-template<class Function, class A, class B, class C, class D, class E, class F>
-inline void DispatchToFunction(Function function,
-                               const Tuple6<A, B, C, D, E, F>& arg) {
-  (*function)(base::internal::UnwrapTraits<A>::Unwrap(arg.a),
-              base::internal::UnwrapTraits<B>::Unwrap(arg.b),
-              base::internal::UnwrapTraits<C>::Unwrap(arg.c),
-              base::internal::UnwrapTraits<D>::Unwrap(arg.d),
-              base::internal::UnwrapTraits<E>::Unwrap(arg.e),
-              base::internal::UnwrapTraits<F>::Unwrap(arg.f));
-}
-
-template<class Function, class A, class B, class C, class D, class E, class F,
-         class G>
-inline void DispatchToFunction(Function function,
-                               const Tuple7<A, B, C, D, E, F, G>& arg) {
-  (*function)(base::internal::UnwrapTraits<A>::Unwrap(arg.a),
-              base::internal::UnwrapTraits<B>::Unwrap(arg.b),
-              base::internal::UnwrapTraits<C>::Unwrap(arg.c),
-              base::internal::UnwrapTraits<D>::Unwrap(arg.d),
-              base::internal::UnwrapTraits<E>::Unwrap(arg.e),
-              base::internal::UnwrapTraits<F>::Unwrap(arg.f),
-              base::internal::UnwrapTraits<G>::Unwrap(arg.g));
-}
-
-template<class Function, class A, class B, class C, class D, class E, class F,
-         class G, class H>
-inline void DispatchToFunction(Function function,
-                               const Tuple8<A, B, C, D, E, F, G, H>& arg) {
-  (*function)(base::internal::UnwrapTraits<A>::Unwrap(arg.a),
-              base::internal::UnwrapTraits<B>::Unwrap(arg.b),
-              base::internal::UnwrapTraits<C>::Unwrap(arg.c),
-              base::internal::UnwrapTraits<D>::Unwrap(arg.d),
-              base::internal::UnwrapTraits<E>::Unwrap(arg.e),
-              base::internal::UnwrapTraits<F>::Unwrap(arg.f),
-              base::internal::UnwrapTraits<G>::Unwrap(arg.g),
-              base::internal::UnwrapTraits<H>::Unwrap(arg.h));
-}
-
-// Dispatchers with 0 out param (as a Tuple0).
-
-template <class ObjT, class Method>
+template <typename ObjT, typename Method, typename In, typename... OutTs>
 inline void DispatchToMethod(ObjT* obj,
                              Method method,
-                             const Tuple0& arg, Tuple0*) {
-  (obj->*method)();
+                             const In& in,
+                             Tuple<OutTs...>* out) {
+  DispatchToMethodImpl(obj, method, in, out,
+                       MakeIndexSequence<sizeof...(OutTs)>());
 }
 
-template <class ObjT, class Method, class A>
-inline void DispatchToMethod(ObjT* obj, Method method, const A& arg, Tuple0*) {
-  (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg));
+template <typename ObjT,
+          typename Method,
+          typename... InTs,
+          typename... OutTs,
+          size_t... InNs,
+          size_t... OutNs>
+inline void DispatchToMethodImpl(ObjT* obj,
+                                 Method method,
+                                 const Tuple<InTs...>& in,
+                                 Tuple<OutTs...>* out,
+                                 IndexSequence<InNs...>,
+                                 IndexSequence<OutNs...>) {
+  (obj->*method)(base::internal::UnwrapTraits<InTs>::Unwrap(get<InNs>(in))...,
+                 &get<OutNs>(*out)...);
 }
 
-template <class ObjT, class Method, class A>
+template <typename ObjT, typename Method, typename... InTs, typename... OutTs>
 inline void DispatchToMethod(ObjT* obj,
                              Method method,
-                             const Tuple1<A>& arg, Tuple0*) {
-  (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg.a));
-}
-
-template<class ObjT, class Method, class A, class B>
-inline void DispatchToMethod(ObjT* obj,
-                             Method method,
-                             const Tuple2<A, B>& arg, Tuple0*) {
-  (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg.a),
-                 base::internal::UnwrapTraits<B>::Unwrap(arg.b));
-}
-
-template<class ObjT, class Method, class A, class B, class C>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const Tuple3<A, B, C>& arg, Tuple0*) {
-  (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg.a),
-                 base::internal::UnwrapTraits<B>::Unwrap(arg.b),
-                 base::internal::UnwrapTraits<C>::Unwrap(arg.c));
-}
-
-template<class ObjT, class Method, class A, class B, class C, class D>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const Tuple4<A, B, C, D>& arg, Tuple0*) {
-  (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg.a),
-                 base::internal::UnwrapTraits<B>::Unwrap(arg.b),
-                 base::internal::UnwrapTraits<C>::Unwrap(arg.c),
-                 base::internal::UnwrapTraits<D>::Unwrap(arg.d));
-}
-
-template<class ObjT, class Method, class A, class B, class C, class D, class E>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const Tuple5<A, B, C, D, E>& arg, Tuple0*) {
-  (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg.a),
-                 base::internal::UnwrapTraits<B>::Unwrap(arg.b),
-                 base::internal::UnwrapTraits<C>::Unwrap(arg.c),
-                 base::internal::UnwrapTraits<D>::Unwrap(arg.d),
-                 base::internal::UnwrapTraits<E>::Unwrap(arg.e));
-}
-
-template<class ObjT, class Method, class A, class B, class C, class D, class E,
-         class F>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const Tuple6<A, B, C, D, E, F>& arg, Tuple0*) {
-  (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg.a),
-                 base::internal::UnwrapTraits<B>::Unwrap(arg.b),
-                 base::internal::UnwrapTraits<C>::Unwrap(arg.c),
-                 base::internal::UnwrapTraits<D>::Unwrap(arg.d),
-                 base::internal::UnwrapTraits<E>::Unwrap(arg.e),
-                 base::internal::UnwrapTraits<F>::Unwrap(arg.f));
-}
-
-// Dispatchers with 1 out param.
-
-template<class ObjT, class Method,
-         class OutA>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const Tuple0& in,
-                             Tuple1<OutA>* out) {
-  (obj->*method)(&out->a);
-}
-
-template<class ObjT, class Method, class InA,
-         class OutA>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const InA& in,
-                             Tuple1<OutA>* out) {
-  (obj->*method)(in, &out->a);
-}
-
-template<class ObjT, class Method, class InA,
-         class OutA>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const Tuple1<InA>& in,
-                             Tuple1<OutA>* out) {
-  (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a), &out->a);
-}
-
-template<class ObjT, class Method, class InA, class InB,
-         class OutA>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const Tuple2<InA, InB>& in,
-                             Tuple1<OutA>* out) {
-  (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
-                 base::internal::UnwrapTraits<InB>::Unwrap(in.b),
-                 &out->a);
-}
-
-template<class ObjT, class Method, class InA, class InB, class InC,
-         class OutA>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const Tuple3<InA, InB, InC>& in,
-                             Tuple1<OutA>* out) {
-  (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
-                 base::internal::UnwrapTraits<InB>::Unwrap(in.b),
-                 base::internal::UnwrapTraits<InC>::Unwrap(in.c),
-                 &out->a);
-}
-
-template<class ObjT, class Method, class InA, class InB, class InC, class InD,
-         class OutA>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const Tuple4<InA, InB, InC, InD>& in,
-                             Tuple1<OutA>* out) {
-  (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
-                 base::internal::UnwrapTraits<InB>::Unwrap(in.b),
-                 base::internal::UnwrapTraits<InC>::Unwrap(in.c),
-                 base::internal::UnwrapTraits<InD>::Unwrap(in.d),
-                 &out->a);
-}
-
-template<class ObjT, class Method, class InA, class InB, class InC, class InD,
-         class InE, class OutA>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const Tuple5<InA, InB, InC, InD, InE>& in,
-                             Tuple1<OutA>* out) {
-  (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
-                 base::internal::UnwrapTraits<InB>::Unwrap(in.b),
-                 base::internal::UnwrapTraits<InC>::Unwrap(in.c),
-                 base::internal::UnwrapTraits<InD>::Unwrap(in.d),
-                 base::internal::UnwrapTraits<InE>::Unwrap(in.e),
-                 &out->a);
-}
-
-template<class ObjT, class Method,
-         class InA, class InB, class InC, class InD, class InE, class InF,
-         class OutA>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const Tuple6<InA, InB, InC, InD, InE, InF>& in,
-                             Tuple1<OutA>* out) {
-  (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
-                 base::internal::UnwrapTraits<InB>::Unwrap(in.b),
-                 base::internal::UnwrapTraits<InC>::Unwrap(in.c),
-                 base::internal::UnwrapTraits<InD>::Unwrap(in.d),
-                 base::internal::UnwrapTraits<InE>::Unwrap(in.e),
-                 base::internal::UnwrapTraits<InF>::Unwrap(in.f),
-                 &out->a);
-}
-
-// Dispatchers with 2 out params.
-
-template<class ObjT, class Method,
-         class OutA, class OutB>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const Tuple0& in,
-                             Tuple2<OutA, OutB>* out) {
-  (obj->*method)(&out->a, &out->b);
-}
-
-template<class ObjT, class Method, class InA,
-         class OutA, class OutB>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const InA& in,
-                             Tuple2<OutA, OutB>* out) {
-  (obj->*method)(in, &out->a, &out->b);
-}
-
-template<class ObjT, class Method, class InA,
-         class OutA, class OutB>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const Tuple1<InA>& in,
-                             Tuple2<OutA, OutB>* out) {
-  (obj->*method)(
-      base::internal::UnwrapTraits<InA>::Unwrap(in.a), &out->a, &out->b);
-}
-
-template<class ObjT, class Method, class InA, class InB,
-         class OutA, class OutB>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const Tuple2<InA, InB>& in,
-                             Tuple2<OutA, OutB>* out) {
-  (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
-                 base::internal::UnwrapTraits<InB>::Unwrap(in.b),
-                 &out->a,
-                 &out->b);
-}
-
-template<class ObjT, class Method, class InA, class InB, class InC,
-         class OutA, class OutB>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const Tuple3<InA, InB, InC>& in,
-                             Tuple2<OutA, OutB>* out) {
-  (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
-                 base::internal::UnwrapTraits<InB>::Unwrap(in.b),
-                 base::internal::UnwrapTraits<InC>::Unwrap(in.c),
-                 &out->a,
-                 &out->b);
-}
-
-template<class ObjT, class Method, class InA, class InB, class InC, class InD,
-         class OutA, class OutB>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const Tuple4<InA, InB, InC, InD>& in,
-                             Tuple2<OutA, OutB>* out) {
-  (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
-                 base::internal::UnwrapTraits<InB>::Unwrap(in.b),
-                 base::internal::UnwrapTraits<InC>::Unwrap(in.c),
-                 base::internal::UnwrapTraits<InD>::Unwrap(in.d),
-                 &out->a,
-                 &out->b);
-}
-
-template<class ObjT, class Method,
-         class InA, class InB, class InC, class InD, class InE,
-         class OutA, class OutB>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const Tuple5<InA, InB, InC, InD, InE>& in,
-                             Tuple2<OutA, OutB>* out) {
-  (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
-                 base::internal::UnwrapTraits<InB>::Unwrap(in.b),
-                 base::internal::UnwrapTraits<InC>::Unwrap(in.c),
-                 base::internal::UnwrapTraits<InD>::Unwrap(in.d),
-                 base::internal::UnwrapTraits<InE>::Unwrap(in.e),
-                 &out->a,
-                 &out->b);
-}
-
-template<class ObjT, class Method,
-         class InA, class InB, class InC, class InD, class InE, class InF,
-         class OutA, class OutB>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const Tuple6<InA, InB, InC, InD, InE, InF>& in,
-                             Tuple2<OutA, OutB>* out) {
-  (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
-                 base::internal::UnwrapTraits<InB>::Unwrap(in.b),
-                 base::internal::UnwrapTraits<InC>::Unwrap(in.c),
-                 base::internal::UnwrapTraits<InD>::Unwrap(in.d),
-                 base::internal::UnwrapTraits<InE>::Unwrap(in.e),
-                 base::internal::UnwrapTraits<InF>::Unwrap(in.f),
-                 &out->a,
-                 &out->b);
-}
-
-// Dispatchers with 3 out params.
-
-template<class ObjT, class Method,
-         class OutA, class OutB, class OutC>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const Tuple0& in,
-                             Tuple3<OutA, OutB, OutC>* out) {
-  (obj->*method)(&out->a, &out->b, &out->c);
-}
-
-template<class ObjT, class Method, class InA,
-         class OutA, class OutB, class OutC>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const InA& in,
-                             Tuple3<OutA, OutB, OutC>* out) {
-  (obj->*method)(in, &out->a, &out->b, &out->c);
-}
-
-template<class ObjT, class Method, class InA,
-         class OutA, class OutB, class OutC>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const Tuple1<InA>& in,
-                             Tuple3<OutA, OutB, OutC>* out) {
-  (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
-                 &out->a,
-                 &out->b,
-                 &out->c);
-}
-
-template<class ObjT, class Method, class InA, class InB,
-         class OutA, class OutB, class OutC>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const Tuple2<InA, InB>& in,
-                             Tuple3<OutA, OutB, OutC>* out) {
-  (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
-                 base::internal::UnwrapTraits<InB>::Unwrap(in.b),
-                 &out->a,
-                 &out->b,
-                 &out->c);
-}
-
-template<class ObjT, class Method, class InA, class InB, class InC,
-         class OutA, class OutB, class OutC>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const Tuple3<InA, InB, InC>& in,
-                             Tuple3<OutA, OutB, OutC>* out) {
-  (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
-                 base::internal::UnwrapTraits<InB>::Unwrap(in.b),
-                 base::internal::UnwrapTraits<InC>::Unwrap(in.c),
-                 &out->a,
-                 &out->b,
-                 &out->c);
-}
-
-template<class ObjT, class Method, class InA, class InB, class InC, class InD,
-         class OutA, class OutB, class OutC>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const Tuple4<InA, InB, InC, InD>& in,
-                             Tuple3<OutA, OutB, OutC>* out) {
-  (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
-                 base::internal::UnwrapTraits<InB>::Unwrap(in.b),
-                 base::internal::UnwrapTraits<InC>::Unwrap(in.c),
-                 base::internal::UnwrapTraits<InD>::Unwrap(in.d),
-                 &out->a,
-                 &out->b,
-                 &out->c);
-}
-
-template<class ObjT, class Method,
-         class InA, class InB, class InC, class InD, class InE,
-         class OutA, class OutB, class OutC>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const Tuple5<InA, InB, InC, InD, InE>& in,
-                             Tuple3<OutA, OutB, OutC>* out) {
-  (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
-                 base::internal::UnwrapTraits<InB>::Unwrap(in.b),
-                 base::internal::UnwrapTraits<InC>::Unwrap(in.c),
-                 base::internal::UnwrapTraits<InD>::Unwrap(in.d),
-                 base::internal::UnwrapTraits<InE>::Unwrap(in.e),
-                 &out->a,
-                 &out->b,
-                 &out->c);
-}
-
-template<class ObjT, class Method,
-         class InA, class InB, class InC, class InD, class InE, class InF,
-         class OutA, class OutB, class OutC>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const Tuple6<InA, InB, InC, InD, InE, InF>& in,
-                             Tuple3<OutA, OutB, OutC>* out) {
-  (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
-                 base::internal::UnwrapTraits<InB>::Unwrap(in.b),
-                 base::internal::UnwrapTraits<InC>::Unwrap(in.c),
-                 base::internal::UnwrapTraits<InD>::Unwrap(in.d),
-                 base::internal::UnwrapTraits<InE>::Unwrap(in.e),
-                 base::internal::UnwrapTraits<InF>::Unwrap(in.f),
-                 &out->a,
-                 &out->b,
-                 &out->c);
-}
-
-// Dispatchers with 4 out params.
-
-template<class ObjT, class Method,
-         class OutA, class OutB, class OutC, class OutD>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const Tuple0& in,
-                             Tuple4<OutA, OutB, OutC, OutD>* out) {
-  (obj->*method)(&out->a, &out->b, &out->c, &out->d);
-}
-
-template<class ObjT, class Method, class InA,
-         class OutA, class OutB, class OutC, class OutD>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const InA& in,
-                             Tuple4<OutA, OutB, OutC, OutD>* out) {
-  (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in),
-                 &out->a,
-                 &out->b,
-                 &out->c,
-                 &out->d);
-}
-
-template<class ObjT, class Method, class InA,
-         class OutA, class OutB, class OutC, class OutD>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const Tuple1<InA>& in,
-                             Tuple4<OutA, OutB, OutC, OutD>* out) {
-  (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
-                 &out->a,
-                 &out->b,
-                 &out->c,
-                 &out->d);
-}
-
-template<class ObjT, class Method, class InA, class InB,
-         class OutA, class OutB, class OutC, class OutD>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const Tuple2<InA, InB>& in,
-                             Tuple4<OutA, OutB, OutC, OutD>* out) {
-  (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
-                 base::internal::UnwrapTraits<InB>::Unwrap(in.b),
-                 &out->a,
-                 &out->b,
-                 &out->c,
-                 &out->d);
-}
-
-template<class ObjT, class Method, class InA, class InB, class InC,
-         class OutA, class OutB, class OutC, class OutD>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const Tuple3<InA, InB, InC>& in,
-                             Tuple4<OutA, OutB, OutC, OutD>* out) {
-  (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
-                 base::internal::UnwrapTraits<InB>::Unwrap(in.b),
-                 base::internal::UnwrapTraits<InC>::Unwrap(in.c),
-                 &out->a,
-                 &out->b,
-                 &out->c,
-                 &out->d);
-}
-
-template<class ObjT, class Method, class InA, class InB, class InC, class InD,
-         class OutA, class OutB, class OutC, class OutD>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const Tuple4<InA, InB, InC, InD>& in,
-                             Tuple4<OutA, OutB, OutC, OutD>* out) {
-  (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
-                 base::internal::UnwrapTraits<InB>::Unwrap(in.b),
-                 base::internal::UnwrapTraits<InC>::Unwrap(in.c),
-                 base::internal::UnwrapTraits<InD>::Unwrap(in.d),
-                 &out->a,
-                 &out->b,
-                 &out->c,
-                 &out->d);
-}
-
-template<class ObjT, class Method,
-         class InA, class InB, class InC, class InD, class InE,
-         class OutA, class OutB, class OutC, class OutD>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const Tuple5<InA, InB, InC, InD, InE>& in,
-                             Tuple4<OutA, OutB, OutC, OutD>* out) {
-  (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
-                 base::internal::UnwrapTraits<InB>::Unwrap(in.b),
-                 base::internal::UnwrapTraits<InC>::Unwrap(in.c),
-                 base::internal::UnwrapTraits<InD>::Unwrap(in.d),
-                 base::internal::UnwrapTraits<InE>::Unwrap(in.e),
-                 &out->a,
-                 &out->b,
-                 &out->c,
-                 &out->d);
-}
-
-template<class ObjT, class Method,
-         class InA, class InB, class InC, class InD, class InE, class InF,
-         class OutA, class OutB, class OutC, class OutD>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const Tuple6<InA, InB, InC, InD, InE, InF>& in,
-                             Tuple4<OutA, OutB, OutC, OutD>* out) {
-  (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
-                 base::internal::UnwrapTraits<InB>::Unwrap(in.b),
-                 base::internal::UnwrapTraits<InC>::Unwrap(in.c),
-                 base::internal::UnwrapTraits<InD>::Unwrap(in.d),
-                 base::internal::UnwrapTraits<InE>::Unwrap(in.e),
-                 base::internal::UnwrapTraits<InF>::Unwrap(in.f),
-                 &out->a,
-                 &out->b,
-                 &out->c,
-                 &out->d);
-}
-
-// Dispatchers with 5 out params.
-
-template<class ObjT, class Method,
-         class OutA, class OutB, class OutC, class OutD, class OutE>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const Tuple0& in,
-                             Tuple5<OutA, OutB, OutC, OutD, OutE>* out) {
-  (obj->*method)(&out->a, &out->b, &out->c, &out->d, &out->e);
-}
-
-template<class ObjT, class Method, class InA,
-         class OutA, class OutB, class OutC, class OutD, class OutE>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const InA& in,
-                             Tuple5<OutA, OutB, OutC, OutD, OutE>* out) {
-  (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in),
-                 &out->a,
-                 &out->b,
-                 &out->c,
-                 &out->d,
-                 &out->e);
-}
-
-template<class ObjT, class Method, class InA,
-         class OutA, class OutB, class OutC, class OutD, class OutE>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const Tuple1<InA>& in,
-                             Tuple5<OutA, OutB, OutC, OutD, OutE>* out) {
-  (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
-                 &out->a,
-                 &out->b,
-                 &out->c,
-                 &out->d,
-                 &out->e);
-}
-
-template<class ObjT, class Method, class InA, class InB,
-         class OutA, class OutB, class OutC, class OutD, class OutE>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const Tuple2<InA, InB>& in,
-                             Tuple5<OutA, OutB, OutC, OutD, OutE>* out) {
-  (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
-                 base::internal::UnwrapTraits<InB>::Unwrap(in.b),
-                 &out->a,
-                 &out->b,
-                 &out->c,
-                 &out->d,
-                 &out->e);
-}
-
-template<class ObjT, class Method, class InA, class InB, class InC,
-         class OutA, class OutB, class OutC, class OutD, class OutE>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const Tuple3<InA, InB, InC>& in,
-                             Tuple5<OutA, OutB, OutC, OutD, OutE>* out) {
-  (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
-                 base::internal::UnwrapTraits<InB>::Unwrap(in.b),
-                 base::internal::UnwrapTraits<InC>::Unwrap(in.c),
-                 &out->a,
-                 &out->b,
-                 &out->c,
-                 &out->d,
-                 &out->e);
-}
-
-template<class ObjT, class Method, class InA, class InB, class InC, class InD,
-         class OutA, class OutB, class OutC, class OutD, class OutE>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const Tuple4<InA, InB, InC, InD>& in,
-                             Tuple5<OutA, OutB, OutC, OutD, OutE>* out) {
-  (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
-                 base::internal::UnwrapTraits<InB>::Unwrap(in.b),
-                 base::internal::UnwrapTraits<InC>::Unwrap(in.c),
-                 base::internal::UnwrapTraits<InD>::Unwrap(in.d),
-                 &out->a,
-                 &out->b,
-                 &out->c,
-                 &out->d,
-                 &out->e);
-}
-
-template<class ObjT, class Method,
-         class InA, class InB, class InC, class InD, class InE,
-         class OutA, class OutB, class OutC, class OutD, class OutE>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const Tuple5<InA, InB, InC, InD, InE>& in,
-                             Tuple5<OutA, OutB, OutC, OutD, OutE>* out) {
-  (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
-                 base::internal::UnwrapTraits<InB>::Unwrap(in.b),
-                 base::internal::UnwrapTraits<InC>::Unwrap(in.c),
-                 base::internal::UnwrapTraits<InD>::Unwrap(in.d),
-                 base::internal::UnwrapTraits<InE>::Unwrap(in.e),
-                 &out->a,
-                 &out->b,
-                 &out->c,
-                 &out->d,
-                 &out->e);
-}
-
-template<class ObjT, class Method,
-         class InA, class InB, class InC, class InD, class InE, class InF,
-         class OutA, class OutB, class OutC, class OutD, class OutE>
-inline void DispatchToMethod(ObjT* obj, Method method,
-                             const Tuple6<InA, InB, InC, InD, InE, InF>& in,
-                             Tuple5<OutA, OutB, OutC, OutD, OutE>* out) {
-  (obj->*method)(base::internal::UnwrapTraits<InA>::Unwrap(in.a),
-                 base::internal::UnwrapTraits<InB>::Unwrap(in.b),
-                 base::internal::UnwrapTraits<InC>::Unwrap(in.c),
-                 base::internal::UnwrapTraits<InD>::Unwrap(in.d),
-                 base::internal::UnwrapTraits<InE>::Unwrap(in.e),
-                 base::internal::UnwrapTraits<InF>::Unwrap(in.f),
-                 &out->a,
-                 &out->b,
-                 &out->c,
-                 &out->d,
-                 &out->e);
+                             const Tuple<InTs...>& in,
+                             Tuple<OutTs...>* out) {
+  DispatchToMethodImpl(obj, method, in, out,
+                       MakeIndexSequence<sizeof...(InTs)>(),
+                       MakeIndexSequence<sizeof...(OutTs)>());
 }
 
 #endif  // BASE_TUPLE_H__