Revved to chromium 2a04445358913b81ed786927172647b701b73113 refs/remotes/origin/HEAD
diff --git a/base/android/java/src/org/chromium/base/ApiCompatibilityUtils.java b/base/android/java/src/org/chromium/base/ApiCompatibilityUtils.java
index a4d8e0b..2af146b 100644
--- a/base/android/java/src/org/chromium/base/ApiCompatibilityUtils.java
+++ b/base/android/java/src/org/chromium/base/ApiCompatibilityUtils.java
@@ -85,7 +85,7 @@
     }
 
     /**
-     * @see android.view.View#setTextDirection(int)
+     * @see android.view.View#setTextAlignment(int)
      */
     public static void setTextAlignment(View view, int textAlignment) {
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
@@ -96,6 +96,17 @@
     }
 
     /**
+     * @see android.view.View#setTextDirection(int)
+     */
+    public static void setTextDirection(View view, int textDirection) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
+            view.setTextDirection(textDirection);
+        } else {
+            // Do nothing. RTL text isn't supported before JB MR1.
+        }
+    }
+
+    /**
      * @see android.view.ViewGroup.MarginLayoutParams#setMarginEnd(int)
      */
     public static void setMarginEnd(MarginLayoutParams layoutParams, int end) {
diff --git a/base/android/java/src/org/chromium/base/ApplicationStatus.java b/base/android/java/src/org/chromium/base/ApplicationStatus.java
index c706dfd..af02ea2 100644
--- a/base/android/java/src/org/chromium/base/ApplicationStatus.java
+++ b/base/android/java/src/org/chromium/base/ApplicationStatus.java
@@ -114,19 +114,19 @@
 
         application.registerWindowFocusChangedListener(
                 new BaseChromiumApplication.WindowFocusChangedListener() {
-            @Override
-            public void onWindowFocusChanged(Activity activity, boolean hasFocus) {
-                if (!hasFocus || activity == sActivity) return;
+                    @Override
+                    public void onWindowFocusChanged(Activity activity, boolean hasFocus) {
+                        if (!hasFocus || activity == sActivity) return;
 
-                int state = getStateForActivity(activity);
+                        int state = getStateForActivity(activity);
 
-                if (state != ActivityState.DESTROYED && state != ActivityState.STOPPED) {
-                    sActivity = activity;
-                }
+                        if (state != ActivityState.DESTROYED && state != ActivityState.STOPPED) {
+                            sActivity = activity;
+                        }
 
-                // TODO(dtrainor): Notify of active activity change?
-            }
-        });
+                        // TODO(dtrainor): Notify of active activity change?
+                    }
+                });
 
         application.registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
             @Override
diff --git a/base/android/java/src/org/chromium/base/SecureRandomInitializer.java b/base/android/java/src/org/chromium/base/SecureRandomInitializer.java
new file mode 100644
index 0000000..457e2ef
--- /dev/null
+++ b/base/android/java/src/org/chromium/base/SecureRandomInitializer.java
@@ -0,0 +1,42 @@
+// Copyright 2014 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.
+
+package org.chromium.base;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.security.SecureRandom;
+
+/**
+ * This class contains code to initialize a SecureRandom generator securely on Android platforms
+ * <= 4.3. See
+ * {@link http://android-developers.blogspot.com/2013/08/some-securerandom-thoughts.html}.
+ */
+public class SecureRandomInitializer {
+    private static final int NUM_RANDOM_BYTES = 16;
+
+    private static byte[] sSeedBytes = new byte[NUM_RANDOM_BYTES];
+
+    /**
+     * Safely initializes the random number generator, by seeding it with data from /dev/urandom.
+     */
+    public static void initialize(SecureRandom generator) throws IOException {
+        FileInputStream fis = null;
+        try {
+            fis = new FileInputStream("/dev/urandom");
+            if (fis.read(sSeedBytes) != sSeedBytes.length) {
+                throw new IOException("Failed to get enough random data.");
+            }
+            generator.setSeed(sSeedBytes);
+        } finally {
+            try {
+                if (fis != null) {
+                    fis.close();
+                }
+            } catch (IOException e) {
+                // Ignore exception closing the device.
+            }
+        }
+    }
+}
diff --git a/base/android/java/src/org/chromium/base/SysUtils.java b/base/android/java/src/org/chromium/base/SysUtils.java
index 1108d9e..eabef61 100644
--- a/base/android/java/src/org/chromium/base/SysUtils.java
+++ b/base/android/java/src/org/chromium/base/SysUtils.java
@@ -106,11 +106,9 @@
         if (CommandLine.isInitialized()) {
             if (CommandLine.getInstance().hasSwitch(BaseSwitches.LOW_END_DEVICE_MODE)) {
                 int mode = Integer.parseInt(CommandLine.getInstance().getSwitchValue(
-                  BaseSwitches.LOW_END_DEVICE_MODE));
-                if (mode == 1)
-                    return true;
-                if (mode == 0)
-                    return false;
+                        BaseSwitches.LOW_END_DEVICE_MODE));
+                if (mode == 1) return true;
+                if (mode == 0) return false;
             }
         }
 
diff --git a/base/android/java/src/org/chromium/base/SystemMessageHandler.java b/base/android/java/src/org/chromium/base/SystemMessageHandler.java
index 42c8987..10f8d55 100644
--- a/base/android/java/src/org/chromium/base/SystemMessageHandler.java
+++ b/base/android/java/src/org/chromium/base/SystemMessageHandler.java
@@ -37,7 +37,7 @@
     private SystemMessageHandler(long messagePumpDelegateNative) {
         mMessagePumpDelegateNative = messagePumpDelegateNative;
         tryEnableSyncBarrierDetection();
-     }
+    }
 
     @Override
     public void handleMessage(Message msg) {
@@ -154,7 +154,7 @@
             disableSyncBarrierDetection();
         }
         return null;
-     }
+    }
 
     @CalledByNative
     private static SystemMessageHandler create(long messagePumpDelegateNative) {
diff --git a/base/android/java/src/org/chromium/base/TraceEvent.java b/base/android/java/src/org/chromium/base/TraceEvent.java
index c7b81ee..b67d32d 100644
--- a/base/android/java/src/org/chromium/base/TraceEvent.java
+++ b/base/android/java/src/org/chromium/base/TraceEvent.java
@@ -175,9 +175,9 @@
      */
     @CalledByNative
     public static void setEnabled(boolean enabled) {
-       sEnabled = enabled;
-       ThreadUtils.getUiThreadLooper().setMessageLogging(
-           enabled ? LooperMonitorHolder.sInstance : null);
+        sEnabled = enabled;
+        ThreadUtils.getUiThreadLooper().setMessageLogging(
+                enabled ? LooperMonitorHolder.sInstance : null);
     }
 
     /**
diff --git a/base/android/java/src/org/chromium/base/library_loader/LibraryLoaderHelper.java b/base/android/java/src/org/chromium/base/library_loader/LibraryLoaderHelper.java
index 6a8f1eb..58198ae 100644
--- a/base/android/java/src/org/chromium/base/library_loader/LibraryLoaderHelper.java
+++ b/base/android/java/src/org/chromium/base/library_loader/LibraryLoaderHelper.java
@@ -238,7 +238,7 @@
             if (files != null) {
                 for (File file : files) {
                     if (!file.delete()) {
-                      Log.e(TAG, "Failed to remove " + file.getAbsolutePath());
+                        Log.e(TAG, "Failed to remove " + file.getAbsolutePath());
                     }
                 }
             }
diff --git a/base/android/java/src/org/chromium/base/library_loader/Linker.java b/base/android/java/src/org/chromium/base/library_loader/Linker.java
index cc30af4..2b3cb09 100644
--- a/base/android/java/src/org/chromium/base/library_loader/Linker.java
+++ b/base/android/java/src/org/chromium/base/library_loader/Linker.java
@@ -755,8 +755,7 @@
 
             String libName = System.mapLibraryName(library);
 
-            if (sLoadedLibraries == null)
-              sLoadedLibraries = new HashMap<String, LibInfo>();
+            if (sLoadedLibraries == null) sLoadedLibraries = new HashMap<String, LibInfo>();
 
             if (sLoadedLibraries.containsKey(libName)) {
                 if (DEBUG) Log.i(TAG, "Not loading " + libName + " twice");
diff --git a/base/android/jni_generator/java/src/org/chromium/example/jni_generator/SampleForTests.java b/base/android/jni_generator/java/src/org/chromium/example/jni_generator/SampleForTests.java
index c3a1df5..732fe6e 100644
--- a/base/android/jni_generator/java/src/org/chromium/example/jni_generator/SampleForTests.java
+++ b/base/android/jni_generator/java/src/org/chromium/example/jni_generator/SampleForTests.java
@@ -91,212 +91,215 @@
 // object binds to.
 @JNINamespace("base::android")
 class SampleForTests {
-  // Classes can store their C++ pointer counter part as an int that is normally initialized by
-  // calling out a nativeInit() function.
-  long mNativeCPPObject;
+    // Classes can store their C++ pointer counter part as an int that is normally initialized by
+    // calling out a nativeInit() function.
+    long mNativeCPPObject;
 
-  // You can define methods and attributes on the java class just like any other.
-  // Methods without the @CalledByNative annotation won't be exposed to JNI.
-  public SampleForTests() {
-  }
+    // You can define methods and attributes on the java class just like any other.
+    // Methods without the @CalledByNative annotation won't be exposed to JNI.
+    public SampleForTests() {
+    }
 
-  public void startExample() {
-      // Calls native code and holds a pointer to the C++ class.
-      mNativeCPPObject = nativeInit("myParam");
-  }
+    public void startExample() {
+        // Calls native code and holds a pointer to the C++ class.
+        mNativeCPPObject = nativeInit("myParam");
+    }
 
-  public void doStuff() {
-      // This will call CPPClass::Method() using nativePtr as a pointer to the object. This must be
-      // done to:
-      // * avoid leaks.
-      // * using finalizers are not allowed to destroy the cpp class.
-      nativeMethod(mNativeCPPObject);
-  }
+    public void doStuff() {
+        // This will call CPPClass::Method() using nativePtr as a pointer to the object. This must
+        // be done to:
+        // * avoid leaks.
+        // * using finalizers are not allowed to destroy the cpp class.
+        nativeMethod(mNativeCPPObject);
+    }
 
-  public void finishExample() {
-      // We're done, so let's destroy nativePtr object.
-      nativeDestroy(mNativeCPPObject);
-  }
+    public void finishExample() {
+        // We're done, so let's destroy nativePtr object.
+        nativeDestroy(mNativeCPPObject);
+    }
 
-  // -----------------------------------------------------------------------------------------------
-  // The following methods demonstrate exporting Java methods for invocation from C++ code.
-  // Java functions are mapping into C global functions by prefixing the method name with
-  // "Java_<Class>_"
-  // This is triggered by the @CalledByNative annotation; the methods may be named as you wish.
+    // ---------------------------------------------------------------------------------------------
+    // The following methods demonstrate exporting Java methods for invocation from C++ code.
+    // Java functions are mapping into C global functions by prefixing the method name with
+    // "Java_<Class>_"
+    // This is triggered by the @CalledByNative annotation; the methods may be named as you wish.
 
-  // Exported to C++ as:
-  //   Java_Example_javaMethod(JNIEnv* env, jobject obj, jint foo, jint bar)
-  // Typically the C++ code would have obtained the jobject via the Init() call described above.
-  @CalledByNative
-  public int javaMethod(int foo,
-                        int bar) {
-      return 0;
-  }
+    // Exported to C++ as:
+    // Java_Example_javaMethod(JNIEnv* env, jobject obj, jint foo, jint bar)
+    // Typically the C++ code would have obtained the jobject via the Init() call described above.
+    @CalledByNative
+    public int javaMethod(int foo, int bar) {
+        return 0;
+    }
 
-  // Exported to C++ as Java_Example_staticJavaMethod(JNIEnv* env)
-  // Note no jobject argument, as it is static.
-  @CalledByNative
-  public static boolean staticJavaMethod() {
-      return true;
-  }
+    // Exported to C++ as Java_Example_staticJavaMethod(JNIEnv* env)
+    // Note no jobject argument, as it is static.
+    @CalledByNative
+    public static boolean staticJavaMethod() {
+        return true;
+    }
 
-  // No prefix, so this method is package private. It will still be exported.
-  @CalledByNative
-  void packagePrivateJavaMethod() {}
+    // No prefix, so this method is package private. It will still be exported.
+    @CalledByNative
+    void packagePrivateJavaMethod() {
+    }
 
-  // Note the "Unchecked" suffix. By default, @CalledByNative will always generate bindings that
-  // call CheckException(). With "@CalledByNativeUnchecked", the client C++ code is responsible to
-  // call ClearException() and act as appropriate.
-  // See more details at the "@CalledByNativeUnchecked" annotation.
-  @CalledByNativeUnchecked
-  void methodThatThrowsException() throws Exception {}
+    // Note the "Unchecked" suffix. By default, @CalledByNative will always generate bindings that
+    // call CheckException(). With "@CalledByNativeUnchecked", the client C++ code is responsible to
+    // call ClearException() and act as appropriate.
+    // See more details at the "@CalledByNativeUnchecked" annotation.
+    @CalledByNativeUnchecked
+    void methodThatThrowsException() throws Exception {}
 
-  // The generator is not confused by inline comments:
-  // @CalledByNative void thisShouldNotAppearInTheOutput();
-  // @CalledByNativeUnchecked public static void neitherShouldThis(int foo);
+    // The generator is not confused by inline comments:
+    // @CalledByNative void thisShouldNotAppearInTheOutput();
+    // @CalledByNativeUnchecked public static void neitherShouldThis(int foo);
 
-  /**
-   * The generator is not confused by block comments:
-   * @CalledByNative void thisShouldNotAppearInTheOutputEither();
-   * @CalledByNativeUnchecked public static void andDefinitelyNotThis(int foo);
-   */
+    /**
+     * The generator is not confused by block comments:
+     * @CalledByNative void thisShouldNotAppearInTheOutputEither();
+     * @CalledByNativeUnchecked public static void andDefinitelyNotThis(int foo);
+     */
 
-  // String constants that look like comments don't confuse the generator:
-  private String mArrgh = "*/*";
+    // String constants that look like comments don't confuse the generator:
+    private String mArrgh = "*/*";
 
-  //------------------------------------------------------------------------------------------------
-  // Java fields which are accessed from C++ code only must be annotated with @AccessedByNative to
-  // prevent them being eliminated when unreferenced code is stripped.
-  @AccessedByNative
-  private int mJavaField;
+    // ---------------------------------------------------------------------------------------------
+    // Java fields which are accessed from C++ code only must be annotated with @AccessedByNative to
+    // prevent them being eliminated when unreferenced code is stripped.
+    @AccessedByNative
+    private int mJavaField;
 
-  //------------------------------------------------------------------------------------------------
-  // The following methods demonstrate declaring methods to call into C++ from Java.
-  // The generator detects the "native" and "static" keywords, the type and name of the first
-  // parameter, and the "native" prefix to the function name to determine the C++ function
-  // signatures. Besides these constraints the methods can be freely named.
+    // ---------------------------------------------------------------------------------------------
+    // The following methods demonstrate declaring methods to call into C++ from Java.
+    // The generator detects the "native" and "static" keywords, the type and name of the first
+    // parameter, and the "native" prefix to the function name to determine the C++ function
+    // signatures. Besides these constraints the methods can be freely named.
 
-  // This declares a C++ function which the application code must implement:
-  //   static jint Init(JNIEnv* env, jobject obj);
-  // The jobject parameter refers back to this java side object instance.
-  // The implementation must return the pointer to the C++ object cast to jint.
-  // The caller of this method should store it, and supply it as a the nativeCPPClass param to
-  // subsequent native method calls (see the methods below that take an "int native..." as first
-  // param).
-  private native long nativeInit(String param);
+    // This declares a C++ function which the application code must implement:
+    // static jint Init(JNIEnv* env, jobject obj);
+    // The jobject parameter refers back to this java side object instance.
+    // The implementation must return the pointer to the C++ object cast to jint.
+    // The caller of this method should store it, and supply it as a the nativeCPPClass param to
+    // subsequent native method calls (see the methods below that take an "int native..." as first
+    // param).
+    private native long nativeInit(String param);
 
-  // This defines a function binding to the associated C++ class member function. The name is
-  // derived from |nativeDestroy| and |nativeCPPClass| to arrive at CPPClass::Destroy() (i.e. native
-  // prefixes stripped).
-  // The |nativeCPPClass| is automatically cast to type CPPClass* in order to obtain the object on
-  // which to invoke the member function.
-  private native void nativeDestroy(long nativeCPPClass);
+    // This defines a function binding to the associated C++ class member function. The name is
+    // derived from |nativeDestroy| and |nativeCPPClass| to arrive at CPPClass::Destroy() (i.e.
+    // native
+    // prefixes stripped).
+    // The |nativeCPPClass| is automatically cast to type CPPClass* in order to obtain the object on
+    // which to invoke the member function.
+    private native void nativeDestroy(long nativeCPPClass);
 
-  // This declares a C++ function which the application code must implement:
-  //   static jdouble GetDoubleFunction(JNIEnv* env, jobject obj);
-  // The jobject parameter refers back to this java side object instance.
-  private native double nativeGetDoubleFunction();
+    // This declares a C++ function which the application code must implement:
+    // static jdouble GetDoubleFunction(JNIEnv* env, jobject obj);
+    // The jobject parameter refers back to this java side object instance.
+    private native double nativeGetDoubleFunction();
 
-  // Similar to nativeGetDoubleFunction(), but here the C++ side will receive a jclass rather than
-  // jobject param, as the function is declared static.
-  private static native float nativeGetFloatFunction();
+    // Similar to nativeGetDoubleFunction(), but here the C++ side will receive a jclass rather than
+    // jobject param, as the function is declared static.
+    private static native float nativeGetFloatFunction();
 
-  // This function takes a non-POD datatype. We have a list mapping them to their full classpath in
-  // jni_generator.py JavaParamToJni. If you require a new datatype, make sure you add to that
-  // function.
-  private native void nativeSetNonPODDatatype(Rect rect);
+    // This function takes a non-POD datatype. We have a list mapping them to their full classpath
+    // in
+    // jni_generator.py JavaParamToJni. If you require a new datatype, make sure you add to that
+    // function.
+    private native void nativeSetNonPODDatatype(Rect rect);
 
-  // This declares a C++ function which the application code must implement:
-  //   static ScopedJavaLocalRef<jobject> GetNonPODDatatype(JNIEnv* env, jobject obj);
-  // The jobject parameter refers back to this java side object instance.
-  // Note that it returns a ScopedJavaLocalRef<jobject> so that you don' have to worry about
-  // deleting the JNI local reference.  This is similar with Strings and arrays.
-  private native Object nativeGetNonPODDatatype();
+    // This declares a C++ function which the application code must implement:
+    // static ScopedJavaLocalRef<jobject> GetNonPODDatatype(JNIEnv* env, jobject obj);
+    // The jobject parameter refers back to this java side object instance.
+    // Note that it returns a ScopedJavaLocalRef<jobject> so that you don' have to worry about
+    // deleting the JNI local reference. This is similar with Strings and arrays.
+    private native Object nativeGetNonPODDatatype();
 
-  // Similar to nativeDestroy above, this will cast nativeCPPClass into pointer of CPPClass type and
-  // call its Method member function.
-  private native int nativeMethod(long nativeCPPClass);
+    // Similar to nativeDestroy above, this will cast nativeCPPClass into pointer of CPPClass type
+    // and
+    // call its Method member function.
+    private native int nativeMethod(long nativeCPPClass);
 
-  // Similar to nativeMethod above, but here the C++ fully qualified class name is taken from the
-  // annotation rather than parameter name, which can thus be chosen freely.
-  @NativeClassQualifiedName("CPPClass::InnerClass")
-  private native double nativeMethodOtherP0(long nativePtr);
+    // Similar to nativeMethod above, but here the C++ fully qualified class name is taken from the
+    // annotation rather than parameter name, which can thus be chosen freely.
+    @NativeClassQualifiedName("CPPClass::InnerClass")
+    private native double nativeMethodOtherP0(long nativePtr);
 
-  // This "struct" will be created by the native side using |createInnerStructA|,
-  // and used by the java-side somehow.
-  // Note that |@CalledByNative| has to contain the inner class name.
-  static class InnerStructA {
-      private final long mLong;
-      private final int mInt;
-      private final String mString;
+    // This "struct" will be created by the native side using |createInnerStructA|,
+    // and used by the java-side somehow.
+    // Note that |@CalledByNative| has to contain the inner class name.
+    static class InnerStructA {
+        private final long mLong;
+        private final int mInt;
+        private final String mString;
 
-      private InnerStructA(long l, int i, String s) {
-          mLong = l;
-          mInt = i;
-          mString = s;
-      }
+        private InnerStructA(long l, int i, String s) {
+            mLong = l;
+            mInt = i;
+            mString = s;
+        }
 
-      @CalledByNative("InnerStructA")
-      private static InnerStructA create(long l, int i, String s) {
-          return new InnerStructA(l, i, s);
-      }
-  }
+        @CalledByNative("InnerStructA")
+        private static InnerStructA create(long l, int i, String s) {
+            return new InnerStructA(l, i, s);
+        }
+    }
 
-  private List<InnerStructA> mListInnerStructA = new ArrayList<InnerStructA>();
+    private List<InnerStructA> mListInnerStructA = new ArrayList<InnerStructA>();
 
-  @CalledByNative
-  private void addStructA(InnerStructA a) {
-      // Called by the native side to append another element.
-      mListInnerStructA.add(a);
-  }
+    @CalledByNative
+    private void addStructA(InnerStructA a) {
+        // Called by the native side to append another element.
+        mListInnerStructA.add(a);
+    }
 
-  @CalledByNative
-  private void iterateAndDoSomething() {
-      Iterator<InnerStructA> it = mListInnerStructA.iterator();
-      while (it.hasNext()) {
-          InnerStructA element = it.next();
-          // Now, do something with element.
-      }
-      // Done, clear the list.
-      mListInnerStructA.clear();
-  }
+    @CalledByNative
+    private void iterateAndDoSomething() {
+        Iterator<InnerStructA> it = mListInnerStructA.iterator();
+        while (it.hasNext()) {
+            InnerStructA element = it.next();
+            // Now, do something with element.
+        }
+        // Done, clear the list.
+        mListInnerStructA.clear();
+    }
 
-  // This "struct" will be created by the java side passed to native, which
-  // will use its getters.
-  // Note that |@CalledByNative| has to contain the inner class name.
-  static class InnerStructB {
-      private final long mKey;
-      private final String mValue;
+    // This "struct" will be created by the java side passed to native, which
+    // will use its getters.
+    // Note that |@CalledByNative| has to contain the inner class name.
+    static class InnerStructB {
+        private final long mKey;
+        private final String mValue;
 
-      private InnerStructB(long k, String v) {
-          mKey = k;
-          mValue = v;
-      }
+        private InnerStructB(long k, String v) {
+            mKey = k;
+            mValue = v;
+        }
 
-      @CalledByNative("InnerStructB")
-      private long getKey() {
-          return mKey;
-      }
+        @CalledByNative("InnerStructB")
+        private long getKey() {
+            return mKey;
+        }
 
-      @CalledByNative("InnerStructB")
-      private String getValue() {
-          return mValue;
-      }
-  }
+        @CalledByNative("InnerStructB")
+        private String getValue() {
+            return mValue;
+        }
+    }
 
-  List<InnerStructB> mListInnerStructB = new ArrayList<InnerStructB>();
+    List<InnerStructB> mListInnerStructB = new ArrayList<InnerStructB>();
 
-  void iterateAndDoSomethingWithMap() {
-      Iterator<InnerStructB> it = mListInnerStructB.iterator();
-      while (it.hasNext()) {
-          InnerStructB element = it.next();
-          // Now, do something with element.
-          nativeAddStructB(mNativeCPPObject, element);
-      }
-      nativeIterateAndDoSomethingWithStructB(mNativeCPPObject);
-  }
+    void iterateAndDoSomethingWithMap() {
+        Iterator<InnerStructB> it = mListInnerStructB.iterator();
+        while (it.hasNext()) {
+            InnerStructB element = it.next();
+            // Now, do something with element.
+            nativeAddStructB(mNativeCPPObject, element);
+        }
+        nativeIterateAndDoSomethingWithStructB(mNativeCPPObject);
+    }
 
-  native void nativeAddStructB(long nativeCPPClass, InnerStructB b);
-  native void nativeIterateAndDoSomethingWithStructB(long nativeCPPClass);
-  native String nativeReturnAString(long nativeCPPClass);
+    native void nativeAddStructB(long nativeCPPClass, InnerStructB b);
+    native void nativeIterateAndDoSomethingWithStructB(long nativeCPPClass);
+    native String nativeReturnAString(long nativeCPPClass);
 }
diff --git a/base/base.isolate b/base/base.isolate
index 762d915..0416935 100644
--- a/base/base.isolate
+++ b/base/base.isolate
@@ -23,12 +23,18 @@
         ],
       },
     }],
+    ['OS=="linux" and asan==1', {
+      'variables': {
+        'files': [
+          '../third_party/llvm-build/Release+Asserts/lib/libstdc++.so.6',
+        ],
+      },
+    }],
     ['asan==1', {
       'variables': {
         'files': [
           '../tools/valgrind/asan/',
           '../third_party/llvm-build/Release+Asserts/bin/llvm-symbolizer',
-          '../third_party/llvm-build/Release+Asserts/lib/libstdc++.so.6',
         ],
       },
     }],
diff --git a/base/debug/proc_maps_linux_unittest.cc b/base/debug/proc_maps_linux_unittest.cc
index fc8ced6..4be5a0f 100644
--- a/base/debug/proc_maps_linux_unittest.cc
+++ b/base/debug/proc_maps_linux_unittest.cc
@@ -167,7 +167,7 @@
          MappedMemoryRegion::EXECUTE | MappedMemoryRegion::PRIVATE},
   };
 
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); ++i) {
+  for (size_t i = 0; i < arraysize(kTestCases); ++i) {
     SCOPED_TRACE(
         base::StringPrintf("kTestCases[%zu] = %s", i, kTestCases[i].input));
 
diff --git a/base/debug/stack_trace_posix.cc b/base/debug/stack_trace_posix.cc
index ae40d7c..25acbe0 100644
--- a/base/debug/stack_trace_posix.cc
+++ b/base/debug/stack_trace_posix.cc
@@ -343,7 +343,7 @@
   const int kRegisterPadding = 16;
 #endif
 
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(registers); i++) {
+  for (size_t i = 0; i < arraysize(registers); i++) {
     PrintToStderr(registers[i].label);
     internal::itoa_r(registers[i].value, buf, sizeof(buf),
                      16, kRegisterPadding);
diff --git a/base/files/file_proxy_unittest.cc b/base/files/file_proxy_unittest.cc
index 0034a1c..b5ed395 100644
--- a/base/files/file_proxy_unittest.cc
+++ b/base/files/file_proxy_unittest.cc
@@ -267,7 +267,7 @@
   CreateProxy(File::FLAG_CREATE | File::FLAG_WRITE, &proxy);
 
   const char data[] = "foo!";
-  int data_bytes = ARRAYSIZE_UNSAFE(data);
+  int data_bytes = arraysize(data);
   proxy.Write(0, data, data_bytes,
               Bind(&FileProxyTest::DidWrite, weak_factory_.GetWeakPtr()));
   MessageLoop::current()->Run();
diff --git a/base/i18n/icu_string_conversions_unittest.cc b/base/i18n/icu_string_conversions_unittest.cc
index 04c3b92..107e240 100644
--- a/base/i18n/icu_string_conversions_unittest.cc
+++ b/base/i18n/icu_string_conversions_unittest.cc
@@ -234,7 +234,7 @@
 };
 
 TEST(ICUStringConversionsTest, ConvertBetweenCodepageAndWide) {
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kConvertCodepageCases); ++i) {
+  for (size_t i = 0; i < arraysize(kConvertCodepageCases); ++i) {
     SCOPED_TRACE(base::StringPrintf(
                      "Test[%" PRIuS "]: <encoded: %s> <codepage: %s>", i,
                      kConvertCodepageCases[i].encoded,
@@ -301,7 +301,7 @@
 }
 
 TEST(ICUStringConversionsTest, ConvertBetweenCodepageAndUTF16) {
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kConvertCodepageCases); ++i) {
+  for (size_t i = 0; i < arraysize(kConvertCodepageCases); ++i) {
     SCOPED_TRACE(base::StringPrintf(
                      "Test[%" PRIuS "]: <encoded: %s> <codepage: %s>", i,
                      kConvertCodepageCases[i].encoded,
@@ -355,7 +355,7 @@
 };
 TEST(ICUStringConversionsTest, ConvertToUtf8AndNormalize) {
   std::string result;
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kConvertAndNormalizeCases); ++i) {
+  for (size_t i = 0; i < arraysize(kConvertAndNormalizeCases); ++i) {
     SCOPED_TRACE(base::StringPrintf(
                      "Test[%" PRIuS "]: <encoded: %s> <codepage: %s>", i,
                      kConvertAndNormalizeCases[i].encoded,
diff --git a/base/i18n/number_formatting_unittest.cc b/base/i18n/number_formatting_unittest.cc
index da6397d..3b0718d 100644
--- a/base/i18n/number_formatting_unittest.cc
+++ b/base/i18n/number_formatting_unittest.cc
@@ -27,7 +27,7 @@
     {-42, "-42", "-42"},
   };
 
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
+  for (size_t i = 0; i < arraysize(cases); ++i) {
     i18n::SetICUDefaultLocale("en");
     testing::ResetFormatters();
     EXPECT_EQ(cases[i].expected_english,
@@ -72,7 +72,7 @@
     {-42.7, 3, "-42.700", "-42,700"},
   };
 
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
+  for (size_t i = 0; i < arraysize(cases); ++i) {
     i18n::SetICUDefaultLocale("en");
     testing::ResetFormatters();
     EXPECT_EQ(cases[i].expected_english,
diff --git a/base/i18n/rtl_unittest.cc b/base/i18n/rtl_unittest.cc
index 2d923ac..87ac87d 100644
--- a/base/i18n/rtl_unittest.cc
+++ b/base/i18n/rtl_unittest.cc
@@ -96,7 +96,7 @@
       LEFT_TO_RIGHT },
    };
 
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i)
+  for (size_t i = 0; i < arraysize(cases); ++i)
     EXPECT_EQ(cases[i].direction,
               GetFirstStrongCharacterDirection(WideToUTF16(cases[i].text)));
 }
@@ -158,7 +158,7 @@
       LEFT_TO_RIGHT },
    };
 
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i)
+  for (size_t i = 0; i < arraysize(cases); ++i)
     EXPECT_EQ(cases[i].direction,
               GetLastStrongCharacterDirection(WideToUTF16(cases[i].text)));
 }
@@ -236,7 +236,7 @@
       LEFT_TO_RIGHT },
    };
 
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i)
+  for (size_t i = 0; i < arraysize(cases); ++i)
     EXPECT_EQ(cases[i].direction,
               GetStringDirection(WideToUTF16(cases[i].text)));
 }
@@ -355,7 +355,7 @@
   for (size_t i = 0; i < 2; ++i) {
     // Toggle the application default text direction (to try each direction).
     SetRTL(!IsRTL());
-    for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
+    for (size_t i = 0; i < arraysize(cases); ++i) {
       string16 input = WideToUTF16(cases[i].path);
       string16 output = GetDisplayStringInLTRDirectionality(input);
       // Test the expected wrapping behavior for the current UI directionality.
diff --git a/base/json/string_escape_unittest.cc b/base/json/string_escape_unittest.cc
index 7d82f9b..3eb4e8e 100644
--- a/base/json/string_escape_unittest.cc
+++ b/base/json/string_escape_unittest.cc
@@ -23,7 +23,7 @@
     {"c<>d", "c\\u003C>d"},
   };
 
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
+  for (size_t i = 0; i < arraysize(cases); ++i) {
     const char* in_ptr = cases[i].to_escape;
     std::string in_str = in_ptr;
 
@@ -81,7 +81,7 @@
     {L"c<>d", "c\\u003C>d"},
   };
 
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
+  for (size_t i = 0; i < arraysize(cases); ++i) {
     string16 in = WideToUTF16(cases[i].to_escape);
 
     std::string out;
@@ -162,7 +162,7 @@
     {"\xe5\xc4\x4f\x05\xb6\xfd\0", "\\u00E5\\u00C4O\\u0005\\u00B6\\u00FD"},
   };
 
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
+  for (size_t i = 0; i < arraysize(cases); ++i) {
     std::string in = std::string(cases[i].to_escape);
     EXPECT_FALSE(IsStringUTF8(in));
 
@@ -173,7 +173,7 @@
   }
 
   const char kEmbedNull[] = { '\xab', '\x39', '\0', '\x9f', '\xab' };
-  std::string in(kEmbedNull, ARRAYSIZE_UNSAFE(kEmbedNull));
+  std::string in(kEmbedNull, arraysize(kEmbedNull));
   EXPECT_FALSE(IsStringUTF8(in));
   EXPECT_EQ(std::string("\\u00AB9\\u0000\\u009F\\u00AB"),
             EscapeBytesAsInvalidJSONString(in, false));
diff --git a/base/mac/mac_util_unittest.mm b/base/mac/mac_util_unittest.mm
index aae40a6..6a1acb3 100644
--- a/base/mac/mac_util_unittest.mm
+++ b/base/mac/mac_util_unittest.mm
@@ -92,7 +92,7 @@
     { "/Applications/Google Foo.app/bar/Foo Helper.app/quux/Foo Helper",
         "/Applications/Google Foo.app" },
   };
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(valid_inputs); i++) {
+  for (size_t i = 0; i < arraysize(valid_inputs); i++) {
     out = GetAppBundlePath(FilePath(valid_inputs[i].in));
     EXPECT_FALSE(out.empty()) << "loop: " << i;
     EXPECT_STREQ(valid_inputs[i].expected_out,
diff --git a/base/memory/discardable_memory_emulated.cc b/base/memory/discardable_memory_emulated.cc
index f9097b1..9820e2e 100644
--- a/base/memory/discardable_memory_emulated.cc
+++ b/base/memory/discardable_memory_emulated.cc
@@ -15,16 +15,31 @@
 const size_t kEmulatedSoftMemoryLimit = 32 * 1024 * 1024;
 const size_t kEmulatedHardMemoryLimitExpirationTimeMs = 1000;
 
-struct SharedState {
-  SharedState()
-      : manager(kEmulatedMemoryLimit,
-                kEmulatedSoftMemoryLimit,
-                TimeDelta::FromMilliseconds(
-                    kEmulatedHardMemoryLimitExpirationTimeMs)) {}
+// internal::DiscardableMemoryManager has an explicit constructor that takes
+// a number of memory limit parameters. The LeakyLazyInstanceTraits doesn't
+// handle the case. Thus, we need our own class here.
+struct DiscardableMemoryManagerLazyInstanceTraits {
+  // Leaky as discardable memory clients can use this after the exit handler
+  // has been called.
+  static const bool kRegisterOnExit = false;
+#ifndef NDEBUG
+  static const bool kAllowedToAccessOnNonjoinableThread = true;
+#endif
 
-  internal::DiscardableMemoryManager manager;
+  static internal::DiscardableMemoryManager* New(void* instance) {
+    return new (instance) internal::DiscardableMemoryManager(
+        kEmulatedMemoryLimit,
+        kEmulatedSoftMemoryLimit,
+        TimeDelta::FromMilliseconds(kEmulatedHardMemoryLimitExpirationTimeMs));
+  }
+  static void Delete(internal::DiscardableMemoryManager* instance) {
+    instance->~DiscardableMemoryManager();
+  }
 };
-LazyInstance<SharedState>::Leaky g_shared_state = LAZY_INSTANCE_INITIALIZER;
+
+LazyInstance<internal::DiscardableMemoryManager,
+             DiscardableMemoryManagerLazyInstanceTraits>
+    g_manager = LAZY_INSTANCE_INITIALIZER;
 
 }  // namespace
 
@@ -33,29 +48,29 @@
 DiscardableMemoryEmulated::DiscardableMemoryEmulated(size_t bytes)
     : bytes_(bytes),
       is_locked_(false) {
-  g_shared_state.Pointer()->manager.Register(this, bytes);
+  g_manager.Pointer()->Register(this, bytes);
 }
 
 DiscardableMemoryEmulated::~DiscardableMemoryEmulated() {
   if (is_locked_)
     Unlock();
-  g_shared_state.Pointer()->manager.Unregister(this);
+  g_manager.Pointer()->Unregister(this);
 }
 
 // static
 bool DiscardableMemoryEmulated::ReduceMemoryUsage() {
-  return g_shared_state.Pointer()->manager.ReduceMemoryUsage();
+  return g_manager.Pointer()->ReduceMemoryUsage();
 }
 
 // static
 void DiscardableMemoryEmulated::ReduceMemoryUsageUntilWithinLimit(
     size_t bytes) {
-  g_shared_state.Pointer()->manager.ReduceMemoryUsageUntilWithinLimit(bytes);
+  g_manager.Pointer()->ReduceMemoryUsageUntilWithinLimit(bytes);
 }
 
 // static
 void DiscardableMemoryEmulated::PurgeForTesting() {
-  g_shared_state.Pointer()->manager.PurgeAll();
+  g_manager.Pointer()->PurgeAll();
 }
 
 bool DiscardableMemoryEmulated::Initialize() {
@@ -66,7 +81,7 @@
   DCHECK(!is_locked_);
 
   bool purged = false;
-  if (!g_shared_state.Pointer()->manager.AcquireLock(this, &purged))
+  if (!g_manager.Pointer()->AcquireLock(this, &purged))
     return DISCARDABLE_MEMORY_LOCK_STATUS_FAILED;
 
   is_locked_ = true;
@@ -76,7 +91,7 @@
 
 void DiscardableMemoryEmulated::Unlock() {
   DCHECK(is_locked_);
-  g_shared_state.Pointer()->manager.ReleaseLock(this);
+  g_manager.Pointer()->ReleaseLock(this);
   is_locked_ = false;
 }
 
diff --git a/base/memory/discardable_memory_mach.cc b/base/memory/discardable_memory_mach.cc
index 1051569..c6681b1 100644
--- a/base/memory/discardable_memory_mach.cc
+++ b/base/memory/discardable_memory_mach.cc
@@ -19,13 +19,29 @@
 // address space usage gets too high (e.g. 512 MBytes).
 const size_t kMachMemoryLimit = 512 * 1024 * 1024;
 
-struct SharedState {
-  SharedState()
-      : manager(kMachMemoryLimit, kMachMemoryLimit, TimeDelta::Max()) {}
+// internal::DiscardableMemoryManager has an explicit constructor that takes
+// a number of memory limit parameters. The LeakyLazyInstanceTraits doesn't
+// handle the case. Thus, we need our own class here.
+struct DiscardableMemoryManagerLazyInstanceTraits {
+  // Leaky as discardable memory clients can use this after the exit handler
+  // has been called.
+  static const bool kRegisterOnExit = false;
+#ifndef NDEBUG
+  static const bool kAllowedToAccessOnNonjoinableThread = true;
+#endif
 
-  internal::DiscardableMemoryManager manager;
+  static internal::DiscardableMemoryManager* New(void* instance) {
+    return new (instance) internal::DiscardableMemoryManager(
+        kMachMemoryLimit, kMachMemoryLimit, TimeDelta::Max());
+  }
+  static void Delete(internal::DiscardableMemoryManager* instance) {
+    instance->~DiscardableMemoryManager();
+  }
 };
-LazyInstance<SharedState>::Leaky g_shared_state = LAZY_INSTANCE_INITIALIZER;
+
+LazyInstance<internal::DiscardableMemoryManager,
+             DiscardableMemoryManagerLazyInstanceTraits>
+    g_manager = LAZY_INSTANCE_INITIALIZER;
 
 // The VM subsystem allows tagging of memory and 240-255 is reserved for
 // application use (see mach/vm_statistics.h). Pick 252 (after chromium's atomic
@@ -38,13 +54,13 @@
 
 DiscardableMemoryMach::DiscardableMemoryMach(size_t bytes)
     : memory_(0, 0), bytes_(mach_vm_round_page(bytes)), is_locked_(false) {
-  g_shared_state.Pointer()->manager.Register(this, bytes);
+  g_manager.Pointer()->Register(this, bytes);
 }
 
 DiscardableMemoryMach::~DiscardableMemoryMach() {
   if (is_locked_)
     Unlock();
-  g_shared_state.Pointer()->manager.Unregister(this);
+  g_manager.Pointer()->Unregister(this);
 }
 
 // static
@@ -61,7 +77,7 @@
   DCHECK(!is_locked_);
 
   bool purged = false;
-  if (!g_shared_state.Pointer()->manager.AcquireLock(this, &purged))
+  if (!g_manager.Pointer()->AcquireLock(this, &purged))
     return DISCARDABLE_MEMORY_LOCK_STATUS_FAILED;
 
   is_locked_ = true;
@@ -71,7 +87,7 @@
 
 void DiscardableMemoryMach::Unlock() {
   DCHECK(is_locked_);
-  g_shared_state.Pointer()->manager.ReleaseLock(this);
+  g_manager.Pointer()->ReleaseLock(this);
   is_locked_ = false;
 }
 
diff --git a/base/memory/discardable_memory_unittest.cc b/base/memory/discardable_memory_unittest.cc
index a111cfc..2bdc079 100644
--- a/base/memory/discardable_memory_unittest.cc
+++ b/base/memory/discardable_memory_unittest.cc
@@ -65,13 +65,13 @@
   const scoped_ptr<DiscardableMemory> memory(CreateLockedMemory(kSize));
   ASSERT_TRUE(memory);
   void* addr = memory->Memory();
-  ASSERT_NE(static_cast<void*>(NULL), addr);
+  ASSERT_NE(nullptr, addr);
 
   memory->Unlock();
 
   EXPECT_NE(DISCARDABLE_MEMORY_LOCK_STATUS_FAILED, memory->Lock());
   addr = memory->Memory();
-  ASSERT_NE(static_cast<void*>(NULL), addr);
+  ASSERT_NE(nullptr, addr);
 
   memory->Unlock();
 }
diff --git a/base/metrics/field_trial_unittest.cc b/base/metrics/field_trial_unittest.cc
index b3a6eb3..b474ddb 100644
--- a/base/metrics/field_trial_unittest.cc
+++ b/base/metrics/field_trial_unittest.cc
@@ -963,7 +963,7 @@
     { 0.95, kDefaultGroupName },
   };
 
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
+  for (size_t i = 0; i < arraysize(test_cases); ++i) {
     TestFieldTrialObserver observer;
     scoped_refptr<FieldTrial> trial(
        FieldTrial::CreateSimulatedFieldTrial(kTrialName, 100, kDefaultGroupName,
diff --git a/base/strings/OWNERS b/base/strings/OWNERS
index d6f2324..5381872 100644
--- a/base/strings/OWNERS
+++ b/base/strings/OWNERS
@@ -1 +1,2 @@
-per-file safe_sprintf*=markus@chromium.org
+per-file safe_sprintf*=jln@chromium.org
+per-file safe_sprintf*=mdempsky@chromium.org
diff --git a/base/strings/safe_sprintf.h b/base/strings/safe_sprintf.h
index cbd7d0c..2d17320 100644
--- a/base/strings/safe_sprintf.h
+++ b/base/strings/safe_sprintf.h
@@ -218,220 +218,20 @@
 
 }  // namespace internal
 
-// TODO(markus): C++11 has a much more concise and readable solution for
-//   expressing what we are doing here.
-
-template<class T0, class T1, class T2, class T3, class T4,
-         class T5, class T6, class T7, class T8, class T9>
-ssize_t SafeSNPrintf(char* buf, size_t N, const char* fmt,
-                     T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4,
-                     T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) {
+template<typename... Args>
+ssize_t SafeSNPrintf(char* buf, size_t N, const char* fmt, Args... args) {
   // Use Arg() object to record type information and then copy arguments to an
   // array to make it easier to iterate over them.
-  const internal::Arg arg_array[] = {
-    arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9
-  };
-  return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array));
+  const internal::Arg arg_array[] = { args... };
+  return internal::SafeSNPrintf(buf, N, fmt, arg_array, sizeof...(args));
 }
 
-template<size_t N,
-         class T0, class T1, class T2, class T3, class T4,
-         class T5, class T6, class T7, class T8, class T9>
-ssize_t SafeSPrintf(char (&buf)[N], const char* fmt,
-                    T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4,
-                    T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) {
+template<size_t N, typename... Args>
+ssize_t SafeSPrintf(char (&buf)[N], const char* fmt, Args... args) {
   // Use Arg() object to record type information and then copy arguments to an
   // array to make it easier to iterate over them.
-  const internal::Arg arg_array[] = {
-    arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9
-  };
-  return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array));
-}
-
-template<class T0, class T1, class T2, class T3, class T4,
-         class T5, class T6, class T7, class T8>
-ssize_t SafeSNPrintf(char* buf, size_t N, const char* fmt,
-                     T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4,
-                     T5 arg5, T6 arg6, T7 arg7, T8 arg8) {
-  // Use Arg() object to record type information and then copy arguments to an
-  // array to make it easier to iterate over them.
-  const internal::Arg arg_array[] = {
-    arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8
-  };
-  return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array));
-}
-
-template<size_t N,
-         class T0, class T1, class T2, class T3, class T4, class T5,
-         class T6, class T7, class T8>
-ssize_t SafeSPrintf(char (&buf)[N], const char* fmt,
-                    T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4,
-                    T5 arg5, T6 arg6, T7 arg7, T8 arg8) {
-  // Use Arg() object to record type information and then copy arguments to an
-  // array to make it easier to iterate over them.
-  const internal::Arg arg_array[] = {
-    arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8
-  };
-  return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array));
-}
-
-template<class T0, class T1, class T2, class T3, class T4, class T5,
-         class T6, class T7>
-ssize_t SafeSNPrintf(char* buf, size_t N, const char* fmt,
-                     T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4,
-                     T5 arg5, T6 arg6, T7 arg7) {
-  // Use Arg() object to record type information and then copy arguments to an
-  // array to make it easier to iterate over them.
-  const internal::Arg arg_array[] = {
-    arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7
-  };
-  return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array));
-}
-
-template<size_t N,
-         class T0, class T1, class T2, class T3, class T4, class T5,
-         class T6, class T7>
-ssize_t SafeSPrintf(char (&buf)[N], const char* fmt,
-                    T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4,
-                    T5 arg5, T6 arg6, T7 arg7) {
-  // Use Arg() object to record type information and then copy arguments to an
-  // array to make it easier to iterate over them.
-  const internal::Arg arg_array[] = {
-    arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7
-  };
-  return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array));
-}
-
-template<class T0, class T1, class T2, class T3, class T4, class T5,
-         class T6>
-ssize_t SafeSNPrintf(char* buf, size_t N, const char* fmt,
-                     T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4,
-                     T5 arg5, T6 arg6) {
-  // Use Arg() object to record type information and then copy arguments to an
-  // array to make it easier to iterate over them.
-  const internal::Arg arg_array[] = {
-    arg0, arg1, arg2, arg3, arg4, arg5, arg6
-  };
-  return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array));
-}
-
-template<size_t N,
-         class T0, class T1, class T2, class T3, class T4, class T5,
-         class T6>
-ssize_t SafeSPrintf(char (&buf)[N], const char* fmt,
-                    T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5,
-                    T6 arg6) {
-  // Use Arg() object to record type information and then copy arguments to an
-  // array to make it easier to iterate over them.
-  const internal::Arg arg_array[] = {
-    arg0, arg1, arg2, arg3, arg4, arg5, arg6
-  };
-  return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array));
-}
-
-template<class T0, class T1, class T2, class T3, class T4, class T5>
-ssize_t SafeSNPrintf(char* buf, size_t N, const char* fmt,
-                     T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) {
-  // Use Arg() object to record type information and then copy arguments to an
-  // array to make it easier to iterate over them.
-  const internal::Arg arg_array[] = { arg0, arg1, arg2, arg3, arg4, arg5 };
-  return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array));
-}
-
-template<size_t N,
-         class T0, class T1, class T2, class T3, class T4, class T5>
-ssize_t SafeSPrintf(char (&buf)[N], const char* fmt,
-                    T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) {
-  // Use Arg() object to record type information and then copy arguments to an
-  // array to make it easier to iterate over them.
-  const internal::Arg arg_array[] = { arg0, arg1, arg2, arg3, arg4, arg5 };
-  return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array));
-}
-
-template<class T0, class T1, class T2, class T3, class T4>
-ssize_t SafeSNPrintf(char* buf, size_t N, const char* fmt,
-                     T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) {
-  // Use Arg() object to record type information and then copy arguments to an
-  // array to make it easier to iterate over them.
-  const internal::Arg arg_array[] = { arg0, arg1, arg2, arg3, arg4 };
-  return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array));
-}
-
-template<size_t N, class T0, class T1, class T2, class T3, class T4>
-ssize_t SafeSPrintf(char (&buf)[N], const char* fmt, T0 arg0, T1 arg1,
-                    T2 arg2, T3 arg3, T4 arg4) {
-  // Use Arg() object to record type information and then copy arguments to an
-  // array to make it easier to iterate over them.
-  const internal::Arg arg_array[] = { arg0, arg1, arg2, arg3, arg4 };
-  return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array));
-}
-
-template<class T0, class T1, class T2, class T3>
-ssize_t SafeSNPrintf(char* buf, size_t N, const char* fmt,
-                     T0 arg0, T1 arg1, T2 arg2, T3 arg3) {
-  // Use Arg() object to record type information and then copy arguments to an
-  // array to make it easier to iterate over them.
-  const internal::Arg arg_array[] = { arg0, arg1, arg2, arg3 };
-  return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array));
-}
-
-template<size_t N, class T0, class T1, class T2, class T3>
-ssize_t SafeSPrintf(char (&buf)[N], const char* fmt,
-                    T0 arg0, T1 arg1, T2 arg2, T3 arg3) {
-  // Use Arg() object to record type information and then copy arguments to an
-  // array to make it easier to iterate over them.
-  const internal::Arg arg_array[] = { arg0, arg1, arg2, arg3 };
-  return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array));
-}
-
-template<class T0, class T1, class T2>
-ssize_t SafeSNPrintf(char* buf, size_t N, const char* fmt,
-                     T0 arg0, T1 arg1, T2 arg2) {
-  // Use Arg() object to record type information and then copy arguments to an
-  // array to make it easier to iterate over them.
-  const internal::Arg arg_array[] = { arg0, arg1, arg2 };
-  return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array));
-}
-
-template<size_t N, class T0, class T1, class T2>
-ssize_t SafeSPrintf(char (&buf)[N], const char* fmt, T0 arg0, T1 arg1,
-                    T2 arg2) {
-  // Use Arg() object to record type information and then copy arguments to an
-  // array to make it easier to iterate over them.
-  const internal::Arg arg_array[] = { arg0, arg1, arg2 };
-  return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array));
-}
-
-template<class T0, class T1>
-ssize_t SafeSNPrintf(char* buf, size_t N, const char* fmt, T0 arg0, T1 arg1) {
-  // Use Arg() object to record type information and then copy arguments to an
-  // array to make it easier to iterate over them.
-  const internal::Arg arg_array[] = { arg0, arg1 };
-  return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array));
-}
-
-template<size_t N, class T0, class T1>
-ssize_t SafeSPrintf(char (&buf)[N], const char* fmt, T0 arg0, T1 arg1) {
-  // Use Arg() object to record type information and then copy arguments to an
-  // array to make it easier to iterate over them.
-  const internal::Arg arg_array[] = { arg0, arg1 };
-  return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array));
-}
-
-template<class T0>
-ssize_t SafeSNPrintf(char* buf, size_t N, const char* fmt, T0 arg0) {
-  // Use Arg() object to record type information and then copy arguments to an
-  // array to make it easier to iterate over them.
-  const internal::Arg arg_array[] = { arg0 };
-  return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array));
-}
-
-template<size_t N, class T0>
-ssize_t SafeSPrintf(char (&buf)[N], const char* fmt, T0 arg0) {
-  // Use Arg() object to record type information and then copy arguments to an
-  // array to make it easier to iterate over them.
-  const internal::Arg arg_array[] = { arg0 };
-  return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array));
+  const internal::Arg arg_array[] = { args... };
+  return internal::SafeSNPrintf(buf, N, fmt, arg_array, sizeof...(args));
 }
 
 // Fast-path when we don't actually need to substitute any arguments.
diff --git a/base/strings/safe_sprintf_unittest.cc b/base/strings/safe_sprintf_unittest.cc
index 98ecd24..02c75f9 100644
--- a/base/strings/safe_sprintf_unittest.cc
+++ b/base/strings/safe_sprintf_unittest.cc
@@ -264,6 +264,13 @@
   EXPECT_EQ(10, SafeSNPrintf(buf, 11, "%c%c%c%c%c%c%c%c%c%c",
                              1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
   EXPECT_EQ("\1\2\3\4\5\6\7\10\11\12", std::string(buf));
+
+  EXPECT_EQ(11, SafeSPrintf(buf, "%c%c%c%c%c%c%c%c%c%c%c",
+                            1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11));
+  EXPECT_EQ("\1\2\3\4\5\6\7\10\11\12\13", std::string(buf));
+  EXPECT_EQ(11, SafeSNPrintf(buf, 12, "%c%c%c%c%c%c%c%c%c%c%c",
+                             1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11));
+  EXPECT_EQ("\1\2\3\4\5\6\7\10\11\12\13", std::string(buf));
 }
 
 TEST(SafeSPrintfTest, DataTypes) {
diff --git a/base/strings/string_number_conversions_unittest.cc b/base/strings/string_number_conversions_unittest.cc
index 134ba01..4787614 100644
--- a/base/strings/string_number_conversions_unittest.cc
+++ b/base/strings/string_number_conversions_unittest.cc
@@ -73,7 +73,7 @@
     {kuint64max, "18446744073709551615"},
   };
 
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i)
+  for (size_t i = 0; i < arraysize(cases); ++i)
     EXPECT_EQ(cases[i].output, Uint64ToString(cases[i].input));
 }
 
@@ -96,7 +96,7 @@
     {size_t_max, size_t_max_string},
   };
 
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i)
+  for (size_t i = 0; i < arraysize(cases); ++i)
     EXPECT_EQ(cases[i].output, Uint64ToString(cases[i].input));
 }
 
@@ -132,7 +132,7 @@
     {"99999999999", INT_MAX, false},
   };
 
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
+  for (size_t i = 0; i < arraysize(cases); ++i) {
     int output = 0;
     EXPECT_EQ(cases[i].success, StringToInt(cases[i].input, &output));
     EXPECT_EQ(cases[i].output, output);
@@ -196,7 +196,7 @@
     {"99999999999", UINT_MAX, false},
   };
 
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
+  for (size_t i = 0; i < arraysize(cases); ++i) {
     unsigned output = 0;
     EXPECT_EQ(cases[i].success, StringToUint(cases[i].input, &output));
     EXPECT_EQ(cases[i].output, output);
@@ -266,7 +266,7 @@
     {"99999999999999999999", kint64max, false},
   };
 
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
+  for (size_t i = 0; i < arraysize(cases); ++i) {
     int64 output = 0;
     EXPECT_EQ(cases[i].success, StringToInt64(cases[i].input, &output));
     EXPECT_EQ(cases[i].output, output);
@@ -333,7 +333,7 @@
     {"18446744073709551616", kuint64max, false},
   };
 
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
+  for (size_t i = 0; i < arraysize(cases); ++i) {
     uint64 output = 0;
     EXPECT_EQ(cases[i].success, StringToUint64(cases[i].input, &output));
     EXPECT_EQ(cases[i].output, output);
@@ -402,7 +402,7 @@
     {size_t_max_string, size_t_max, true},
   };
 
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
+  for (size_t i = 0; i < arraysize(cases); ++i) {
     size_t output = 0;
     EXPECT_EQ(cases[i].success, StringToSizeT(cases[i].input, &output));
     EXPECT_EQ(cases[i].output, output);
@@ -465,7 +465,7 @@
     {"0x", 0, false},
   };
 
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
+  for (size_t i = 0; i < arraysize(cases); ++i) {
     int output = 0;
     EXPECT_EQ(cases[i].success, HexStringToInt(cases[i].input, &output));
     EXPECT_EQ(cases[i].output, output);
@@ -525,7 +525,7 @@
     {"0x", 0, false},
   };
 
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
+  for (size_t i = 0; i < arraysize(cases); ++i) {
     uint32 output = 0;
     EXPECT_EQ(cases[i].success, HexStringToUInt(cases[i].input, &output));
     EXPECT_EQ(cases[i].output, output);
@@ -582,7 +582,7 @@
     {"0x", 0, false},
   };
 
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
+  for (size_t i = 0; i < arraysize(cases); ++i) {
     int64 output = 0;
     EXPECT_EQ(cases[i].success, HexStringToInt64(cases[i].input, &output));
     EXPECT_EQ(cases[i].output, output);
@@ -644,7 +644,7 @@
     {"0x", 0, false},
   };
 
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
+  for (size_t i = 0; i < arraysize(cases); ++i) {
     uint64 output = 0;
     EXPECT_EQ(cases[i].success, HexStringToUInt64(cases[i].input, &output));
     EXPECT_EQ(cases[i].output, output);
@@ -686,7 +686,7 @@
   };
 
 
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
+  for (size_t i = 0; i < arraysize(cases); ++i) {
     std::vector<uint8> output;
     std::vector<uint8> compare;
     EXPECT_EQ(cases[i].success, HexStringToBytes(cases[i].input, &output)) <<
@@ -735,7 +735,7 @@
     {"", 0.0, false},
   };
 
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
+  for (size_t i = 0; i < arraysize(cases); ++i) {
     double output;
     errno = 1;
     EXPECT_EQ(cases[i].success, StringToDouble(cases[i].input, &output));
@@ -768,7 +768,7 @@
     {1.33503e+009, "1335030000"},
   };
 
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
+  for (size_t i = 0; i < arraysize(cases); ++i) {
     EXPECT_EQ(cases[i].expected, DoubleToString(cases[i].input));
   }
 
diff --git a/base/strings/string_split_unittest.cc b/base/strings/string_split_unittest.cc
index 998b61f..32bbe28 100644
--- a/base/strings/string_split_unittest.cc
+++ b/base/strings/string_split_unittest.cc
@@ -312,7 +312,7 @@
     { "b\tat",   2, "b",  "at" },
     { "b\t at",  2, "b",  "at" },
   };
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i) {
+  for (size_t i = 0; i < arraysize(data); ++i) {
     std::vector<std::string> results;
     SplitStringAlongWhitespace(data[i].input, &results);
     ASSERT_EQ(data[i].expected_result_count, results.size());
diff --git a/base/strings/string_util_unittest.cc b/base/strings/string_util_unittest.cc
index d46bc9b..a3e8992 100644
--- a/base/strings/string_util_unittest.cc
+++ b/base/strings/string_util_unittest.cc
@@ -539,7 +539,7 @@
     { "FOO", "foo" },
   };
 
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(lowercase_cases); ++i) {
+  for (size_t i = 0; i < arraysize(lowercase_cases); ++i) {
     EXPECT_TRUE(LowerCaseEqualsASCII(ASCIIToUTF16(lowercase_cases[i].src_a),
                                      lowercase_cases[i].dst));
     EXPECT_TRUE(LowerCaseEqualsASCII(lowercase_cases[i].src_a,
@@ -576,7 +576,7 @@
     {100LL*1024*1024*1024, "100 GB"},
   };
 
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
+  for (size_t i = 0; i < arraysize(cases); ++i) {
     EXPECT_EQ(ASCIIToUTF16(cases[i].expected),
               FormatBytesUnlocalized(cases[i].bytes));
   }
@@ -603,7 +603,7 @@
     {"abababab", 2, "ab", "c", "abccc"},
   };
 
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); i++) {
+  for (size_t i = 0; i < arraysize(cases); i++) {
     string16 str = ASCIIToUTF16(cases[i].str);
     ReplaceSubstringsAfterOffset(&str, cases[i].start_offset,
                                  ASCIIToUTF16(cases[i].find_this),
@@ -633,7 +633,7 @@
     {"abababab", 2, "ab", "c", "abcabab"},
   };
 
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); i++) {
+  for (size_t i = 0; i < arraysize(cases); i++) {
     string16 str = ASCIIToUTF16(cases[i].str);
     ReplaceFirstSubstringAfterOffset(&str, cases[i].start_offset,
                                      ASCIIToUTF16(cases[i].find_this),
@@ -1148,7 +1148,7 @@
     { L"% 10s", false },
     { L"% 10ls", true }
   };
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i)
+  for (size_t i = 0; i < arraysize(cases); ++i)
     EXPECT_EQ(cases[i].portable, base::IsWprintfFormatPortable(cases[i].input));
 }
 
@@ -1191,7 +1191,7 @@
     { "test", "t", "test", "testestest", true },
   };
 
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
+  for (size_t i = 0; i < arraysize(cases); ++i) {
     std::string output;
     bool result = ReplaceChars(cases[i].input,
                                cases[i].replace_chars,
diff --git a/base/strings/utf_offset_string_conversions_unittest.cc b/base/strings/utf_offset_string_conversions_unittest.cc
index b50e1b6..529939f 100644
--- a/base/strings/utf_offset_string_conversions_unittest.cc
+++ b/base/strings/utf_offset_string_conversions_unittest.cc
@@ -34,7 +34,7 @@
     {"A\xF0\x90\x8C\x80z", 6, 4},
     {"A\xF0\x90\x8C\x80z", kNpos, kNpos},
   };
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(utf8_to_utf16_cases); ++i) {
+  for (size_t i = 0; i < arraysize(utf8_to_utf16_cases); ++i) {
     const size_t offset = utf8_to_utf16_cases[i].input_offset;
     std::vector<size_t> offsets;
     offsets.push_back(offset);
@@ -64,7 +64,7 @@
       {{'A', 0xd800, 0xdf00, 'z'}, 3, 5},
       {{'A', 0xd800, 0xdf00, 'z'}, 4, 6},
   };
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(utf16_to_utf8_cases); ++i) {
+  for (size_t i = 0; i < arraysize(utf16_to_utf8_cases); ++i) {
     size_t offset = utf16_to_utf8_cases[i].input_offset;
     std::vector<size_t> offsets;
     offsets.push_back(offset);
diff --git a/base/strings/utf_string_conversions_unittest.cc b/base/strings/utf_string_conversions_unittest.cc
index 08009c4..009af7c 100644
--- a/base/strings/utf_string_conversions_unittest.cc
+++ b/base/strings/utf_string_conversions_unittest.cc
@@ -94,7 +94,7 @@
 #endif
   };
 
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(convert_cases); i++) {
+  for (size_t i = 0; i < arraysize(convert_cases); i++) {
     std::wstring converted;
     EXPECT_EQ(convert_cases[i].success,
               UTF8ToWide(convert_cases[i].utf8,
@@ -172,7 +172,7 @@
     {L"\xdc01Hello", "\xef\xbf\xbdHello", false},
   };
 
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(convert_cases); i++) {
+  for (size_t i = 0; i < arraysize(convert_cases); i++) {
     std::string converted;
     EXPECT_EQ(convert_cases[i].success,
               WideToUTF8(convert_cases[i].utf32,
diff --git a/base/sync_socket_win.cc b/base/sync_socket_win.cc
index a8deedb..e508816 100644
--- a/base/sync_socket_win.cc
+++ b/base/sync_socket_win.cc
@@ -150,7 +150,7 @@
       if (::GetLastError() == ERROR_IO_PENDING) {
         HANDLE events[] = { io_event->handle(), cancel_event->handle() };
         const int wait_result = WaitForMultipleObjects(
-            ARRAYSIZE_UNSAFE(events), events, FALSE,
+            arraysize(events), events, FALSE,
             timeout_in_ms == INFINITE ?
                 timeout_in_ms :
                 static_cast<DWORD>(
diff --git a/base/version_unittest.cc b/base/version_unittest.cc
index 2a2309e..3119c39 100644
--- a/base/version_unittest.cc
+++ b/base/version_unittest.cc
@@ -53,7 +53,7 @@
     {"f.1", 0, false},
   };
 
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
+  for (size_t i = 0; i < arraysize(cases); ++i) {
     Version version(cases[i].input);
     EXPECT_EQ(cases[i].success, version.IsValid());
     if (cases[i].success)
@@ -78,7 +78,7 @@
     {"1.0.0", "1.0", 0},
     {"1.0.3", "1.0.20", -1},
   };
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
+  for (size_t i = 0; i < arraysize(cases); ++i) {
     Version lhs(cases[i].lhs);
     Version rhs(cases[i].rhs);
     EXPECT_EQ(lhs.CompareTo(rhs), cases[i].expected) <<
@@ -108,7 +108,7 @@
     {"1.3.9", "1.3.*", 0},
     {"1.2.0.0.0.0", "1.2.*", 0},
   };
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
+  for (size_t i = 0; i < arraysize(cases); ++i) {
     const Version version(cases[i].lhs);
     const int result = version.CompareToWildcardString(cases[i].rhs);
     EXPECT_EQ(result, cases[i].expected) << cases[i].lhs << "?" << cases[i].rhs;
@@ -132,7 +132,7 @@
     {"*", false},
     {"*.2", false},
   };
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
+  for (size_t i = 0; i < arraysize(cases); ++i) {
     EXPECT_EQ(Version::IsValidWildcardString(cases[i].version),
         cases[i].expected) << cases[i].version << "?" << cases[i].expected;
   }